@pulse-compute/cli 0.0.0 → 1.0.0-beta.2

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 (191) hide show
  1. package/API.md +572 -0
  2. package/CHANGELOG.md +71 -0
  3. package/README.md +71 -1
  4. package/bin/pulse.js +15 -0
  5. package/bin/pulsewasm-extract.js +22 -0
  6. package/cli-spec.json +575 -0
  7. package/completions/_pulse +106 -0
  8. package/completions/pulse.bash +31 -0
  9. package/completions/pulse.fish +76 -0
  10. package/docs/README.md +77 -0
  11. package/docs/architecture/current-contracts.md +470 -0
  12. package/docs/architecture/overview.md +93 -0
  13. package/docs/architecture/vision.md +515 -0
  14. package/docs/concepts/bodies.md +186 -0
  15. package/docs/concepts/compilation-and-lowering.md +496 -0
  16. package/docs/concepts/contracts-and-providers.md +158 -0
  17. package/docs/concepts/effects-and-continuations.md +300 -0
  18. package/docs/concepts/entities-and-adapters.md +71 -0
  19. package/docs/concepts/package-owned-lowering.md +175 -0
  20. package/docs/concepts/targets-and-hosts.md +70 -0
  21. package/docs/contributing/README.md +38 -0
  22. package/docs/contributing/adding-core-provider.md +315 -0
  23. package/docs/contributing/adding-first-party-lowerer.md +327 -0
  24. package/docs/contributing/entities-lowering.md +91 -0
  25. package/docs/contributing/package-lowerer-contract.md +383 -0
  26. package/docs/contributing/pulse-aware-packages.md +149 -0
  27. package/docs/examples.md +112 -0
  28. package/docs/fixtures/inspect-fetch-composition.selected.json +181 -0
  29. package/docs/getting-started.md +128 -0
  30. package/docs/guides/compatibility-imports.md +60 -0
  31. package/docs/guides/deploying-fastly.md +188 -0
  32. package/docs/guides/deploying-node.md +143 -0
  33. package/docs/guides/events.md +233 -0
  34. package/docs/guides/fastly-capabilities.md +153 -0
  35. package/docs/guides/fetching-and-composition.md +101 -0
  36. package/docs/guides/grip.md +94 -0
  37. package/docs/guides/json-schemas.md +233 -0
  38. package/docs/guides/migrating-from-express.md +192 -0
  39. package/docs/guides/project-lifecycle.md +143 -0
  40. package/docs/guides/routing.md +202 -0
  41. package/docs/guides/troubleshooting.md +47 -0
  42. package/docs/maintainers/README.md +60 -0
  43. package/docs/maintainers/codex-maintainer.md +71 -0
  44. package/docs/maintainers/documentation-deployment.md +147 -0
  45. package/docs/maintainers/documentation-system.md +58 -0
  46. package/docs/maintainers/documentation-versioning.md +65 -0
  47. package/docs/maintainers/maintainer-charter.md +100 -0
  48. package/docs/maintainers/maintenance-policy.json +809 -0
  49. package/docs/maintainers/maintenance-policy.md +124 -0
  50. package/docs/maintainers/npm-publishing.md +154 -0
  51. package/docs/maintainers/plugin-readiness.json +19 -0
  52. package/docs/maintainers/plugin-readiness.md +31 -0
  53. package/docs/maintainers/public-site.md +158 -0
  54. package/docs/maintainers/release-acceptance.md +293 -0
  55. package/docs/maintainers/release-manifest.md +89 -0
  56. package/docs/maintainers/repository-setup.md +145 -0
  57. package/docs/maintainers/scope-policy.md +105 -0
  58. package/docs/maintainers/support-and-triage.md +74 -0
  59. package/docs/maintainers/testing.md +334 -0
  60. package/docs/packages/README.md +60 -0
  61. package/docs/packages/assets.md +85 -0
  62. package/docs/packages/cli.md +190 -0
  63. package/docs/packages/crypto.md +78 -0
  64. package/docs/packages/entities.md +129 -0
  65. package/docs/packages/grip.md +82 -0
  66. package/docs/packages/implementation-packages.md +122 -0
  67. package/docs/packages/jwt.md +55 -0
  68. package/docs/packages/provider-fastly.md +243 -0
  69. package/docs/packages/pulse.md +159 -0
  70. package/docs/packages/runtime.md +265 -0
  71. package/docs/packages/s3.md +101 -0
  72. package/docs/preview-scope.md +142 -0
  73. package/docs/reference/README.md +33 -0
  74. package/docs/reference/cli-spec.json +575 -0
  75. package/docs/reference/cli.md +457 -0
  76. package/docs/reference/compatibility-matrix.md +169 -0
  77. package/docs/reference/diagnostics.md +1872 -0
  78. package/docs/reference/documentation-versions.json +22 -0
  79. package/docs/reference/environment.md +347 -0
  80. package/docs/reference/handler-authoring.md +264 -0
  81. package/docs/reference/project-config.md +582 -0
  82. package/docs/reference/project-config.schema.json +981 -0
  83. package/docs/reference/release-manifest.json +441 -0
  84. package/docs/reference/shell-completion.md +23 -0
  85. package/documentation-site.json +668 -0
  86. package/documentation-versions.json +22 -0
  87. package/examples/01-hello-json/.pulse/.gitignore +3 -0
  88. package/examples/01-hello-json/.pulse/config.ts +16 -0
  89. package/examples/01-hello-json/README.md +119 -0
  90. package/examples/01-hello-json/package.json +20 -0
  91. package/examples/01-hello-json/src/index.ts +9 -0
  92. package/examples/01-hello-json/tests/pulse.harness.ts +22 -0
  93. package/examples/01-hello-json/tsconfig.json +14 -0
  94. package/examples/02-request-schema/.pulse/.gitignore +3 -0
  95. package/examples/02-request-schema/.pulse/config.ts +17 -0
  96. package/examples/02-request-schema/README.md +145 -0
  97. package/examples/02-request-schema/package.json +20 -0
  98. package/examples/02-request-schema/src/index.ts +18 -0
  99. package/examples/02-request-schema/src/schemas.ts +20 -0
  100. package/examples/02-request-schema/tests/pulse.harness.ts +37 -0
  101. package/examples/02-request-schema/tsconfig.json +14 -0
  102. package/examples/03-fetch-composition/.pulse/.gitignore +3 -0
  103. package/examples/03-fetch-composition/.pulse/config.ts +31 -0
  104. package/examples/03-fetch-composition/README.md +210 -0
  105. package/examples/03-fetch-composition/package.json +20 -0
  106. package/examples/03-fetch-composition/src/index.ts +60 -0
  107. package/examples/03-fetch-composition/tests/pulse.harness.ts +47 -0
  108. package/examples/03-fetch-composition/tsconfig.json +14 -0
  109. package/examples/05-fastly-capabilities/.pulse/.gitignore +3 -0
  110. package/examples/05-fastly-capabilities/.pulse/config.ts +57 -0
  111. package/examples/05-fastly-capabilities/README.md +257 -0
  112. package/examples/05-fastly-capabilities/package.json +22 -0
  113. package/examples/05-fastly-capabilities/src/index.ts +55 -0
  114. package/examples/05-fastly-capabilities/tests/pulse.harness.ts +66 -0
  115. package/examples/05-fastly-capabilities/tsconfig.json +14 -0
  116. package/examples/07-opaque-proxy/.pulse/.gitignore +3 -0
  117. package/examples/07-opaque-proxy/.pulse/config.ts +38 -0
  118. package/examples/07-opaque-proxy/README.md +150 -0
  119. package/examples/07-opaque-proxy/package.json +21 -0
  120. package/examples/07-opaque-proxy/src/index.ts +9 -0
  121. package/examples/07-opaque-proxy/tests/pulse.harness.ts +25 -0
  122. package/examples/07-opaque-proxy/tsconfig.json +14 -0
  123. package/examples/09-router-lowering/.pulse/.gitignore +3 -0
  124. package/examples/09-router-lowering/.pulse/config.ts +22 -0
  125. package/examples/09-router-lowering/README.md +287 -0
  126. package/examples/09-router-lowering/package.json +22 -0
  127. package/examples/09-router-lowering/src/index.ts +65 -0
  128. package/examples/09-router-lowering/tests/pulse.harness.ts +91 -0
  129. package/examples/09-router-lowering/tsconfig.json +14 -0
  130. package/examples/10-entities-tools/.pulse/.gitignore +4 -0
  131. package/examples/10-entities-tools/.pulse/config.ts +23 -0
  132. package/examples/10-entities-tools/README.md +165 -0
  133. package/examples/10-entities-tools/package.json +21 -0
  134. package/examples/10-entities-tools/src/handlers.ts +15 -0
  135. package/examples/10-entities-tools/src/index.ts +31 -0
  136. package/examples/10-entities-tools/src/schemas.ts +18 -0
  137. package/examples/10-entities-tools/tests/pulse.harness.ts +40 -0
  138. package/examples/10-entities-tools/tools-facade.cjs +158 -0
  139. package/examples/10-entities-tools/tsconfig.json +14 -0
  140. package/examples/11-events/.pulse/.gitignore +4 -0
  141. package/examples/11-events/.pulse/config.ts +24 -0
  142. package/examples/11-events/README.md +194 -0
  143. package/examples/11-events/package.json +20 -0
  144. package/examples/11-events/src/index.ts +27 -0
  145. package/examples/11-events/src/schemas.ts +19 -0
  146. package/examples/11-events/tests/pulse.harness.ts +34 -0
  147. package/examples/11-events/tsconfig.json +15 -0
  148. package/examples/12-mcp-proxy/.pulse/.gitignore +3 -0
  149. package/examples/12-mcp-proxy/.pulse/config.ts +25 -0
  150. package/examples/12-mcp-proxy/README.md +149 -0
  151. package/examples/12-mcp-proxy/package.json +20 -0
  152. package/examples/12-mcp-proxy/src/index.ts +17 -0
  153. package/examples/12-mcp-proxy/tests/pulse.harness.ts +29 -0
  154. package/examples/12-mcp-proxy/tsconfig.json +14 -0
  155. package/examples/13-jwt-es256/.pulse/config.ts +19 -0
  156. package/examples/13-jwt-es256/README.md +195 -0
  157. package/examples/13-jwt-es256/package.json +21 -0
  158. package/examples/13-jwt-es256/src/index.ts +21 -0
  159. package/examples/13-jwt-es256/tests/pulse.harness.ts +54 -0
  160. package/examples/13-jwt-es256/tsconfig.json +14 -0
  161. package/examples/README.md +36 -0
  162. package/package.json +66 -6
  163. package/project-config.schema.json +981 -0
  164. package/release-manifest.json +441 -0
  165. package/src/command-spec.js +279 -0
  166. package/src/completion.js +113 -0
  167. package/src/diagnostics.js +350 -0
  168. package/src/documentation.js +45 -0
  169. package/src/index.d.ts +133 -0
  170. package/src/index.js +15 -0
  171. package/src/internal/command-executor.d.ts +29 -0
  172. package/src/internal/command-executor.js +143 -0
  173. package/src/internal/command-plan.d.ts +9 -0
  174. package/src/internal/command-plan.js +73 -0
  175. package/src/internal/command-reporter.d.ts +15 -0
  176. package/src/internal/command-reporter.js +133 -0
  177. package/src/internal/command-request.d.ts +35 -0
  178. package/src/internal/command-request.js +154 -0
  179. package/src/internal/node-http.js +54 -0
  180. package/src/internal/project-context.d.ts +66 -0
  181. package/src/internal/project-context.js +175 -0
  182. package/src/project-config-reference.js +4 -0
  183. package/src/project-config-schema.d.ts +23 -0
  184. package/src/project-config-schema.js +271 -0
  185. package/src/project-config.js +724 -0
  186. package/src/project-execution.js +2946 -0
  187. package/src/provider-drivers.js +3 -0
  188. package/src/target-support.js +3 -0
  189. package/src/typescript-module-loader.js +269 -0
  190. package/src/workflow.js +78 -0
  191. package/src/workspace.js +82 -0
@@ -0,0 +1,350 @@
1
+ 'use strict';
2
+
3
+ const CLI_DIAGNOSTICS_VERSION = 'pulse.cli-diagnostics.v1';
4
+ const { documentationUrl } = require('./documentation.js');
5
+ const DIAGNOSTICS_REFERENCE = documentationUrl('docs/reference/diagnostics.md');
6
+ const DIAGNOSTIC_STABILITY = 'preview-stable';
7
+
8
+ function entry(category, options = {}) {
9
+ return Object.freeze({
10
+ category,
11
+ exitCode: options.exitCode,
12
+ httpStatus: options.httpStatus,
13
+ remediation: Object.freeze([...(options.remediation || [])])
14
+ });
15
+ }
16
+
17
+ const DIAGNOSTIC_DEFINITIONS = Object.freeze({
18
+ PULSE_COMMAND_UNKNOWN: entry('usage', { exitCode: 2, remediation: ['Run `pulse --help` and choose one of the documented commands.'] }),
19
+ PULSE_ARGUMENT_MISSING: entry('usage', { exitCode: 2, remediation: ['Provide the missing flag value and rerun the command.', 'Run `pulse --help` for the command signature.'] }),
20
+ PULSE_ARGUMENT_UNEXPECTED: entry('usage', { exitCode: 2, remediation: ['Remove the unsupported argument or use the documented flag.', 'Run `pulse --help` for the command signature.'] }),
21
+ PULSE_PROVIDER_FLAG_REMOVED: entry('usage', { exitCode: 2, remediation: ['Select `host` and `target` in a `.pulse/config.ts` profile.', 'Use `pulse compile` for provider-neutral Wasm or `pulse build` for the configured deployment target.'] }),
22
+ PULSE_SOURCE_ONLY_REMOVED: entry('usage', { exitCode: 2, remediation: ['Run `pulse build`; native builds emit generated source and provider Wasm together.'] }),
23
+
24
+ PULSE_CONFIG_NOT_FOUND: entry('project', { exitCode: 2, remediation: ['Run `pulse init` to create `.pulse/config.ts`.', 'Ensure the command runs inside the intended project directory.'] }),
25
+ PULSE_PROFILE_SELECTION_REQUIRED: entry('project', { exitCode: 2, remediation: ['Pass `--profile`, set `PULSE_PROFILE`, or configure `pulse.defaultProfile`.'] }),
26
+ PULSE_PROFILE_UNKNOWN: entry('project', { exitCode: 2, remediation: ['Select one of the profiles declared next to the reserved `pulse` object.'] }),
27
+ PULSE_CONFIG_PLAN_PARITY_FAILED: entry('project', { exitCode: 3, remediation: ['Keep the config factory within the sealed static grammar and report the divergent plan hashes.'] }),
28
+ PULSE_TEST_HARNESS_NOT_FOUND: entry('test', { exitCode: 2, remediation: ['Create the workspace-relative file configured by `pulse.tests`.'] }),
29
+ PULSE_TEST_HARNESS_EXPORT_INVALID: entry('test', { exitCode: 2, remediation: ['Export an ordered case array or an object containing a `cases` array.'] }),
30
+ PULSE_TEST_EXPECT_INVALID: entry('test', { exitCode: 2, remediation: ['Use the documented expectation shape for the selected HTTP or event case.', 'Event emitted-frame expectations must be ordered arrays of canonical frames.'] }),
31
+ PULSE_TEST_EVENT_INVALID: entry('test', { exitCode: 2, remediation: ['Use a discriminated `kind: "event"` case with one bounded type, schema or schemaId, and schema-dependent payload.', 'Inspect the event catalog with `pulse inspect --json`.'] }),
32
+ PULSE_TARGET_IMPLEMENTATION_PENDING: entry('capability', { exitCode: 3, remediation: ['Select a native profile for build, test, or dev.', 'Use inspect or doctor to retain the JavaScript selection without fallback.'] }),
33
+ PULSE_JAVASCRIPT_APPLICATION_PLAN_INVALID: entry('project', { exitCode: 3, remediation: ['Rebuild the JavaScript application plan from the configured entry and sealed reachable graph.'] }),
34
+ PULSE_JAVASCRIPT_APPLICATION_GRAPH_FAILED: entry('compile', { exitCode: 3, remediation: ['Fix the first reachable-graph diagnostic before loading the JavaScript application.'] }),
35
+ PULSE_JAVASCRIPT_APPLICATION_ENTRY_INVALID: entry('project', { exitCode: 3, remediation: ['Default-export a Router, Pulse application, or managed handler from a project-owned entry module.'] }),
36
+ PULSE_JAVASCRIPT_APPLICATION_EXPORT_INVALID: entry('project', { exitCode: 3, remediation: ['Default-export a Router, Pulse application, or managed handler.'] }),
37
+ PULSE_JAVASCRIPT_APPLICATION_UNAVAILABLE: entry('capability', { exitCode: 3, remediation: ['Inspect the application-plan blockers and select only explicitly realized package and provider capabilities.', 'Pulse will not fall back to native or another target automatically.'] }),
38
+ PULSE_JAVASCRIPT_PACKAGE_REALIZATION_UNAVAILABLE: entry('capability', { exitCode: 3, remediation: ['Use a package with an explicit JavaScript realization or select a native target.', 'Inspect package target support with `pulse inspect --json`.'] }),
39
+ PULSE_PACKAGE_JAVASCRIPT_REALIZATION_NOT_IMPLEMENTED: entry('capability', { exitCode: 3, remediation: ['Select the native target for this package or wait for its declared JavaScript realization.', 'No automatic fallback occurs.'] }),
40
+ PULSE_JAVASCRIPT_PACKAGE_PLAN_MISSING: entry('internal', { exitCode: 3, remediation: ['Rebuild the JavaScript plan and retain the graph and plan hashes when reporting the inconsistency.'] }),
41
+ PULSE_JAVASCRIPT_PACKAGE_ESM_UNSUPPORTED: entry('capability', { exitCode: 3, remediation: ['Use a CommonJS-compatible package entry for the current Node loader or defer the package to a later JavaScript bundling contract.'] }),
42
+ PULSE_JAVASCRIPT_PACKAGE_MODULE_UNAVAILABLE: entry('capability', { exitCode: 3, remediation: ['Install the exact package selected by the reachable graph in the application workspace.'] }),
43
+ PULSE_JAVASCRIPT_GRAPH_EDGE_AMBIGUOUS: entry('internal', { exitCode: 3, remediation: ['Retain the graph manifest and report the duplicate runtime edge.'] }),
44
+ PULSE_JAVASCRIPT_GRAPH_MODULE_MISSING: entry('internal', { exitCode: 3, remediation: ['Rebuild the JavaScript plan from the exact source tree and retain the graph manifest.'] }),
45
+ PULSE_JAVASCRIPT_IMPORT_NOT_IN_GRAPH: entry('compile', { exitCode: 3, remediation: ['Keep runtime imports within the sealed reachable graph and avoid evaluation-time dynamic loading.'] }),
46
+ PULSE_JAVASCRIPT_MODULE_NOT_FOUND: entry('project', { exitCode: 3, remediation: ['Restore the graph-owned project module or rebuild the plan after the source change.'] }),
47
+ PULSE_JAVASCRIPT_MODULE_OUTSIDE_WORKSPACE: entry('safety', { exitCode: 3, remediation: ['Keep every graph-owned project module inside the authoritative Pulse workspace.'] }),
48
+ PULSE_JAVASCRIPT_MODULE_SOURCE_CHANGED: entry('safety', { exitCode: 3, remediation: ['Rebuild the JavaScript application plan after changing a project module.'] }),
49
+ PULSE_JAVASCRIPT_MODULE_COMPILE_FAILED: entry('compile', { exitCode: 3, remediation: ['Fix the TypeScript or JavaScript syntax in the graph-owned project module.'] }),
50
+ PULSE_JAVASCRIPT_EXTERNAL_MODULE_UNAVAILABLE: entry('capability', { exitCode: 3, remediation: ['Install or explicitly declare the external module required by the JavaScript target.'] }),
51
+ PULSE_JAVASCRIPT_MODULE_KIND_UNSUPPORTED: entry('internal', { exitCode: 3, remediation: ['Retain the application plan and report the unsupported module kind.'] }),
52
+ PULSE_RUNTIME_APPLICATION_EXPORT_INVALID: entry('project', { exitCode: 3, remediation: ['Default-export a Router, Pulse application, or managed handler.'] }),
53
+ PULSE_CONFIG_LOAD_FAILED: entry('project', { exitCode: 2, remediation: ['Fix the config import or runtime error.', 'Use `pulse doctor --json` to inspect the underlying cause.'] }),
54
+ PULSE_ENTRY_NOT_FOUND: entry('project', { exitCode: 2, remediation: ['Create the configured entry file or correct `pulse.entry` in `.pulse/config.ts`.'] }),
55
+ PULSE_PROJECT_ROOT_MISSING: entry('project', { exitCode: 2, remediation: ['Create or correct the positional project directory.'] }),
56
+ PULSE_PROVIDER_UNSUPPORTED: entry('provider', { exitCode: 2, remediation: ['Select a bare provider id or an exact installed scoped provider package name.'] }),
57
+ PULSE_PROVIDER_PACKAGE_NOT_FOUND: entry('provider', { exitCode: 2, remediation: ['Install the exact configured provider package in the project.', 'Confirm that its package manifest exports `./toolchain`.'] }),
58
+ PULSE_PROVIDER_TOOLCHAIN_LOAD_FAILED: entry('provider', { exitCode: 3, remediation: ['Inspect the selected provider package and its dependency installation.', 'Treat provider toolchains as trusted project build code.'] }),
59
+ PULSE_PROVIDER_TOOLCHAIN_INVALID: entry('provider', { exitCode: 3, remediation: ['Use a provider package implementing `pulse.provider-toolchain.v1` at `./toolchain`.', 'Confirm the declared package name, provider id, and driver shape.'] }),
60
+ PULSE_INIT_NOT_EMPTY: entry('project', { exitCode: 2, remediation: ['Choose an empty directory or pass `--force` only when overwriting is intentional.'] }),
61
+ PULSE_INIT_FILE_EXISTS: entry('project', { exitCode: 2, remediation: ['Remove the conflicting file or choose another target directory.'] }),
62
+ PULSE_BUILD_OUT_UNSAFE: entry('safety', { exitCode: 2, remediation: ['Choose an output directory that is a real child of the project root.', 'Do not use `..`, external absolute paths, or symbolic-link traversal.'] }),
63
+ PULSE_BUILD_PROVIDER_REQUIRED: entry('provider', { exitCode: 2, remediation: ['Select an executable host in the active `.pulse/config.ts` profile.', 'Use `pulse compile` when only provider-neutral Wasm is required.'] }),
64
+ PULSE_EXPERIMENTAL_NATIVE_SIZE_UNSUPPORTED: entry('capability', { exitCode: 2, remediation: ['Select a profile with `target: "native"` or use `pulse compile`.', 'Remove `--experimental-native-size` for JavaScript build output.'] }),
65
+ PULSE_NODE_VERSION_UNSUPPORTED: entry('toolchain', { exitCode: 5, remediation: ['Use a Node.js version matching `^22.14.0 || ^24.0.0` and rerun `pulse doctor`.'] }),
66
+ PULSE_CONFIG_IMPLICIT: entry('project', { exitCode: 2, remediation: ['Run `pulse init` or create `.pulse/config.ts` to make workspace ownership explicit.'] }),
67
+ PULSE_PROVIDER_COMPILE_ONLY: entry('capability', { exitCode: 2, remediation: ['Select an executable provider before running `pulse dev` or `pulse test`.'] }),
68
+ PULSE_FETCH_IMPLEMENTATION_UNAVAILABLE: entry('toolchain', { exitCode: 5, remediation: ['Use a Node.js version matching `^22.14.0 || ^24.0.0`, or disable live network fetch and configure deterministic fetch fixtures.'] }),
69
+
70
+ PULSE_HANDLER_ASYNC_REQUIRED: entry('compile', { exitCode: 3, remediation: ['Declare every managed handler, middleware function, and error handler with `async`.', 'Native lowering erases the wrapper; no Promise runtime or Asyncify support is added.'] }),
71
+ PULSE_PROJECT_COMPILE_FAILED: entry('compile', { exitCode: 3, remediation: ['Read the nested diagnostics and fix the first reported source or schema error.', 'Run `pulse inspect --json` or `pulse doctor --json` for structured diagnostics.'] }),
72
+ PULSE_CANONICAL_COMPILE_FAILED: entry('compile', { exitCode: 3, remediation: ['Rewrite the handler using the documented canonical API subset.', 'Run `pulse inspect --json` to see unsupported source forms.'] }),
73
+ PULSE_CANONICAL_NATIVE_PLAN_FAILED: entry('compile', { exitCode: 3, remediation: ['Inspect the native-plan diagnostics and rewrite unsupported canonical control flow.', 'Run `pulse inspect --json` to view the provider-neutral plan boundary.'] }),
74
+ PULSE_CANONICAL_NATIVE_AS_GENERATION_FAILED: entry('compile', { exitCode: 3, remediation: ['Inspect the generated-native diagnostic and rewrite unsupported canonical expressions.', 'Retain the plan hash and diagnostic detail when reporting a compiler defect.'] }),
75
+ PULSE_CANONICAL_NATIVE_COMPILE_FAILED: entry('toolchain', { exitCode: 5, remediation: ['Restore the lockfile-pinned AssemblyScript dependency and rerun `pulse doctor`.', 'Retain the generated diagnostic detail if AssemblyScript rejects valid Pulse output.'] }),
76
+ PULSE_PACKAGE_LOWERING_FAILED: entry('compile', { exitCode: 3, remediation: ['Fix the package-owned API call shape reported in the nested diagnostic.', 'Keep package effects in the documented static positions.'] }),
77
+ PULSE_NATIVE_IMPORT_UNSUPPORTED: entry('compile', { exitCode: 3, remediation: ['Remove or isolate the runtime dependency, use a trusted Pulse capability, or select an explicit JavaScript target when available.', 'Pulse will not change targets automatically.'] }),
78
+ PULSE_PACKAGE_SUBPATH_UNSUPPORTED: entry('compile', { exitCode: 3, remediation: ['Import the package through its documented Pulse lowerable facade, or keep the package behind a JavaScript-only boundary.', 'Run `pulse inspect --json` to review package ownership and native eligibility.'] }),
79
+ PULSE_PACKAGE_REEXPORT_LOWERING_DEFERRED: entry('compile', { exitCode: 3, remediation: ['Import the package-owned facade directly until helper/re-export lowering is enabled by the package contract.', 'The graph records the owning package; no fallback occurs.'] }),
80
+ PULSE_APPLICATION_ENTRY_LIFECYCLE_SIDE_EFFECT: entry('compile', { exitCode: 3, remediation: ['Keep the configured application entry import-safe and move provider lifecycle startup to a separate runner.', 'Use the provider lifecycle through CLI delegation rather than starting infrastructure during application import.'] }),
81
+ PULSE_PACKAGE_BINDING_OWNERSHIP_AMBIGUOUS: entry('compile', { exitCode: 3, remediation: ['Remove the ambiguous re-export or give each package-owned helper one unambiguous source owner.'] }),
82
+ PULSE_PACKAGE_CONTRACT_NOT_RECOGNIZED: entry('compile', { exitCode: 3, remediation: ['Verify the trusted package manifest and direct facade import, then retain the graph and package diagnostics when reporting the issue.'] }),
83
+ PULSE_SCHEMA_COMPILE_FAILED: entry('schema', { exitCode: 3, remediation: ['Fix the declared schema source, exported type, or supported field shape.', 'Run `pulse doctor --json` to inspect schema diagnostics.'] }),
84
+ PULSE_CANONICAL_SCHEMA_MISSING: entry('schema', { exitCode: 3, remediation: ['Declare the referenced schema ID in the default-exported registry selected by pulse.schema.'] }),
85
+ PULSE_SCHEMA_JSON_DECLARATIONS_RETIRED: entry('schema', { exitCode: 2, remediation: ['Move schema declarations into a default-exported defineSchemaRegistry(...) module.', 'Point pulse.schema at that workspace-relative module.'] }),
86
+ PULSE_SCHEMA_CODEC_REALIZATION_PENDING: entry('schema', { exitCode: 3, remediation: ['Rebuild from the authoritative pulse.schema registry with a compiler that realizes the declared shape on both targets.', 'Pulse will not fall back to generic JSON automatically.'] }),
87
+ PULSE_CANONICAL_SCHEMA_ID_LITERAL_REQUIRED: entry('schema', { exitCode: 3, remediation: ['Use a static string literal for the schema ID.'] }),
88
+ PULSE_SCHEMA_ID_INVALID: entry('schema', { exitCode: 3, httpStatus: 500, remediation: ['Use a non-empty schema ID declared by the authoritative pulse.schema registry.'] }),
89
+ PULSE_SCHEMA_REQUIRED: entry('schema', { exitCode: 3, httpStatus: 500, remediation: ['Supply a statically declared schema ID at every strict JSON boundary.'] }),
90
+ PULSE_SCHEMA_REFERENCE: entry('schema', { exitCode: 3, httpStatus: 500, remediation: ['Reference an ID declared by the authoritative pulse.schema registry.'] }),
91
+ PULSE_SCHEMA_CODECS_UNAVAILABLE: entry('schema', { exitCode: 3, httpStatus: 500, remediation: ['Rebuild or redeploy the application with its generated schema codec table.'] }),
92
+ PULSE_SCHEMA_CONTENT_TYPE: entry('request', { exitCode: 4, httpStatus: 415, remediation: ['Send a JSON content type accepted by the configured schema policy.'] }),
93
+ PULSE_SCHEMA_JSON_MALFORMED: entry('request', { exitCode: 4, httpStatus: 400, remediation: ['Send syntactically valid JSON before schema validation.'] }),
94
+ PULSE_RESPONSE_CASE_MISSING: entry('schema', { exitCode: 3, remediation: ['Declare the referenced response case in pulse.schema.'] }),
95
+ PULSE_RESPONSE_CASE_REFERENCE: entry('schema', { exitCode: 3, httpStatus: 500, remediation: ['Use a response-case ID declared by pulse.schema.'] }),
96
+ PULSE_RESPONSE_DESCRIPTOR_INVALID: entry('schema', { exitCode: 3, httpStatus: 500, remediation: ['Pass an object descriptor or a registered response-case string to ctx.json.'] }),
97
+ PULSE_RESPONSE_DESCRIPTOR_LITERAL_REQUIRED: entry('schema', { exitCode: 3, remediation: ['Use an object literal or a registered response-case string literal as the ctx.json response descriptor.'] }),
98
+ PULSE_FETCH_SCHEMA_WITHOUT_JSON: entry('runtime', { exitCode: 4, httpStatus: 500, remediation: ['Use schema only together with the outbound fetch json field.'] }),
99
+ PULSE_SCHEMA_ID_DUPLICATE: entry('schema', { exitCode: 3, remediation: ['Give every declared schema a unique stable ID.'] }),
100
+ PULSE_SCHEMA_SOURCE_REQUIRED: entry('schema', { exitCode: 3, remediation: ['Set the schema declaration `source` to a project-relative TypeScript file.'] }),
101
+ PULSE_SCHEMA_TYPE_REQUIRED: entry('schema', { exitCode: 3, remediation: ['Set the schema declaration `type` to an exported TypeScript type name.'] }),
102
+
103
+ PULSE_TEST_PROVIDER_REQUIRED: entry('capability', { exitCode: 2, remediation: ['Select an executable provider for `pulse test`.'] }),
104
+ PULSE_DEV_PROVIDER_UNSUPPORTED: entry('capability', { exitCode: 2, remediation: ['Select an executable provider for `pulse dev`.'] }),
105
+ PULSE_PROVIDER_CAPABILITY_MISSING: entry('capability', { exitCode: 3, httpStatus: 501, remediation: ['Configure the required provider binding or select a provider that implements the capability.', 'Run `pulse inspect --json` to view required capabilities and bindings.'] }),
106
+ PULSE_PROVIDER_CAPABILITY_UNSUPPORTED: entry('capability', { exitCode: 3, httpStatus: 501, remediation: ['Remove the unsupported capability or select a compatible provider.'] }),
107
+ PULSE_EVENT_TARGET_UNSUPPORTED: entry('capability', { exitCode: 3, httpStatus: 501, remediation: ['Select a target whose descriptor and provider event driver satisfy every reachable event requirement.', 'Use `pulse inspect --json` to review event target support; Pulse will not select another target automatically.'] }),
108
+ PULSE_FASTLY_EVENT_INGRESS_UNSUPPORTED: entry('provider', { exitCode: 3, httpStatus: 501, remediation: ['Select Node JavaScript or Node Native for event execution, or use `none` for compile-only inspection.', 'Do not map event ingress through HTTP or GRIP.'] }),
109
+ PULSE_FASTLY_EVENT_EMIT_UNSUPPORTED: entry('provider', { exitCode: 3, httpStatus: 501, remediation: ['Remove the reachable event.emit requirement or select Node JavaScript or Node Native.', 'Pulse will not substitute logging, HTTP, GRIP, or another target.'] }),
110
+ PULSE_FASTLY_BACKEND_REQUIRED: entry('provider', { exitCode: 3, remediation: ['Declare a static Fastly backend binding for the requested origin, or explicitly enable dynamic backends.'] }),
111
+ PULSE_FASTLY_BACKEND_BINDINGS_INVALID: entry('provider', { exitCode: 2, remediation: ['Correct the Fastly `backends` map in the active `.pulse/config.ts` profile.'] }),
112
+ PULSE_FASTLY_KV_BINDINGS_INVALID: entry('provider', { exitCode: 2, remediation: ['Correct the Fastly `kv` binding map in the active `.pulse/config.ts` profile.'] }),
113
+ PULSE_FASTLY_GRIP_FANOUT_BACKEND_REQUIRED: entry('provider', { exitCode: 3, remediation: ['Configure the Fastly Fanout backend required by `grip.hold`.'] }),
114
+ PULSE_FASTLY_GRIP_PUBLISH_BINDING_REQUIRED: entry('provider', { exitCode: 3, remediation: ['Configure the Fastly GRIP publish backend and URL binding.'] }),
115
+
116
+ PULSE_BODY_DECODE: entry('request', { exitCode: 4, httpStatus: 400, remediation: ['Send valid JSON or text matching the documented request shape.'] }),
117
+ PULSE_SCHEMA_DECODE: entry('request', { exitCode: 4, httpStatus: 400, remediation: ['Send JSON with the required content type and schema fields.', 'Use `pulse test` with a failing case to reproduce the validation error locally.'] }),
118
+ PULSE_BODY_TOO_LARGE: entry('request', { exitCode: 4, httpStatus: 413, remediation: ['Reduce the request payload or increase the configured structured-body limit deliberately.'] }),
119
+ PULSE_REQUEST_BODY_TOO_LARGE: entry('request', { exitCode: 4, httpStatus: 413, remediation: ['Reduce the request payload or increase `dev.maxBodyBytes` deliberately.'] }),
120
+ PULSE_BODY_UNAVAILABLE: entry('runtime', { exitCode: 4, httpStatus: 500, remediation: ['Ensure the provider supplied a structured body snapshot before decoding it.'] }),
121
+ PULSE_OPAQUE_BODY_INSPECTION: entry('runtime', { exitCode: 4, httpStatus: 400, remediation: ['Return or proxy the opaque response directly; do not call JSON, text, bytes, or transform helpers.'] }),
122
+ PULSE_RESPONSE_ENCODE: entry('runtime', { exitCode: 4, httpStatus: 500, remediation: ['Return a value supported by the selected response or schema encoder.'] }),
123
+ PULSE_SCHEMA_ENCODE: entry('runtime', { exitCode: 4, httpStatus: 500, remediation: ['Return a value that satisfies the declared response schema.'] }),
124
+ PULSE_FETCH_TIMEOUT: entry('runtime', { exitCode: 4, httpStatus: 504, remediation: ['Check the origin and timeout policy, then retry.', 'Use a configured fetch fixture in tests for deterministic reproduction.'] }),
125
+ PULSE_FETCH_NETWORK: entry('runtime', { exitCode: 4, httpStatus: 502, remediation: ['Check the origin URL, backend binding, and local network access.'] }),
126
+ PULSE_FETCH_URL_INVALID: entry('runtime', { exitCode: 4, httpStatus: 400, remediation: ['Use an absolute supported URL or a correctly configured provider backend.'] }),
127
+ PULSE_CONTINUATION_EXPIRED: entry('runtime', { exitCode: 4, httpStatus: 504, remediation: ['Increase the continuation TTL only if the provider operation is expected to take longer.'] }),
128
+ PULSE_CONTINUATION_DOUBLE_RESUME: entry('runtime', { exitCode: 4, httpStatus: 500, remediation: ['Report this as a Pulse runtime/provider bug with the continuation trace.'] }),
129
+
130
+ PULSE_FASTLY_CLI_UNAVAILABLE: entry('toolchain', { exitCode: 5, remediation: ['Install the Fastly CLI with Homebrew, a supported package manager, or an official release.', 'Ensure `fastly` is on PATH, or set `PULSE_FASTLY_BIN` in CI.'] }),
131
+ PULSE_FASTLY_CLI_INSPECTION_FAILED: entry('toolchain', { exitCode: 5, remediation: ['Run `fastly version` directly and fix the Fastly CLI installation.'] }),
132
+ PULSE_VICEROY_UNAVAILABLE: entry('toolchain', { exitCode: 5, remediation: ['Unset `PULSE_VICEROY_BIN` to let the Fastly CLI manage its local Compute engine.', 'If an override is required, point `PULSE_VICEROY_BIN` at an executable Viceroy binary.'] }),
133
+ PULSE_VICEROY_INSPECTION_FAILED: entry('toolchain', { exitCode: 5, remediation: ['Inspect or replace the explicitly selected Viceroy override, or unset it to restore Fastly CLI ownership.'] }),
134
+ PULSE_FASTLY_SERVE_START_FAILED: entry('toolchain', { exitCode: 5, remediation: ['Run `fastly compute serve` directly in the generated package and inspect its output.'] }),
135
+ PULSE_FASTLY_SERVE_START_TIMEOUT: entry('toolchain', { exitCode: 5, remediation: ['Inspect Fastly CLI output and local port availability, then retry.'] }),
136
+ PULSE_FASTLY_REQUEST_TIMEOUT: entry('toolchain', { exitCode: 5, httpStatus: 504, remediation: ['Inspect the local Fastly Compute service and backend fixture before retrying.'] })
137
+ });
138
+
139
+ const DIAGNOSTIC_SUMMARIES = Object.freeze({
140
+ PULSE_COMMAND_UNKNOWN: 'The requested pulse command is not part of the supported CLI.',
141
+ PULSE_ARGUMENT_MISSING: 'A command-line option that requires a value was supplied without one.',
142
+ PULSE_ARGUMENT_UNEXPECTED: 'The command received an option or positional argument it does not accept.',
143
+ PULSE_PROVIDER_FLAG_REMOVED: 'Provider selection is project configuration, not a command-line override.',
144
+ PULSE_SOURCE_ONLY_REMOVED: 'The former source-only JavaScript packaging mode is no longer part of native builds.',
145
+ PULSE_CONFIG_NOT_FOUND: 'Project discovery did not find an explicit Pulse configuration file.',
146
+ PULSE_PROFILE_SELECTION_REQUIRED: 'No project profile was selected by CLI, environment, or default configuration.',
147
+ PULSE_PROFILE_UNKNOWN: 'The selected profile is absent from the project declaration.',
148
+ PULSE_CONFIG_PLAN_PARITY_FAILED: 'Static and runtime configuration normalization produced different canonical plans.',
149
+ PULSE_TEST_HARNESS_NOT_FOUND: 'The configured workspace-relative test harness does not exist.',
150
+ PULSE_TEST_HARNESS_EXPORT_INVALID: 'The configured harness does not export the required ordered case collection.',
151
+ PULSE_TEST_EXPECT_INVALID: 'A project test case uses an invalid expectation shape for its HTTP or event discriminant.',
152
+ PULSE_TEST_EVENT_INVALID: 'A discriminated event test case is missing or violates the canonical bounded event-frame shape.',
153
+ PULSE_TARGET_IMPLEMENTATION_PENDING: 'The selected execution target is explicit but not implemented for this command.',
154
+ PULSE_JAVASCRIPT_APPLICATION_PLAN_INVALID: 'The JavaScript loader received a value outside the normalized application-plan contract.',
155
+ PULSE_JAVASCRIPT_APPLICATION_GRAPH_FAILED: 'The sealed reachable graph could not be built for JavaScript application loading.',
156
+ PULSE_JAVASCRIPT_APPLICATION_ENTRY_INVALID: 'The JavaScript plan entry is not a project-owned application module.',
157
+ PULSE_JAVASCRIPT_APPLICATION_EXPORT_INVALID: 'The JavaScript entry does not export a managed Pulse application.',
158
+ PULSE_JAVASCRIPT_APPLICATION_UNAVAILABLE: 'The selected JavaScript application has one or more explicit target blockers.',
159
+ PULSE_JAVASCRIPT_PACKAGE_REALIZATION_UNAVAILABLE: 'A reachable Pulse-aware package has no JavaScript realization for the selected target.',
160
+ PULSE_PACKAGE_JAVASCRIPT_REALIZATION_NOT_IMPLEMENTED: 'A reachable Pulse-aware package explicitly declares that its JavaScript realization is not implemented.',
161
+ PULSE_JAVASCRIPT_PACKAGE_PLAN_MISSING: 'The graph selected a package module that is absent from the JavaScript application plan.',
162
+ PULSE_JAVASCRIPT_PACKAGE_ESM_UNSUPPORTED: 'The current graph-backed Node loader cannot require the selected ESM-only package entry.',
163
+ PULSE_JAVASCRIPT_PACKAGE_MODULE_UNAVAILABLE: 'The graph-selected JavaScript package module cannot be loaded from the application workspace.',
164
+ PULSE_JAVASCRIPT_GRAPH_EDGE_AMBIGUOUS: 'The sealed JavaScript graph contains more than one runtime edge for the same import.',
165
+ PULSE_JAVASCRIPT_GRAPH_MODULE_MISSING: 'A JavaScript graph edge or entry references a missing graph module.',
166
+ PULSE_JAVASCRIPT_IMPORT_NOT_IN_GRAPH: 'Runtime evaluation requested an import absent from the sealed reachable graph.',
167
+ PULSE_JAVASCRIPT_MODULE_NOT_FOUND: 'A graph-owned project module is absent at JavaScript load time.',
168
+ PULSE_JAVASCRIPT_MODULE_OUTSIDE_WORKSPACE: 'A graph-owned project module escapes the authoritative workspace.',
169
+ PULSE_JAVASCRIPT_MODULE_SOURCE_CHANGED: 'A graph-owned project module changed after the JavaScript plan was created.',
170
+ PULSE_JAVASCRIPT_MODULE_COMPILE_FAILED: 'A graph-owned TypeScript or JavaScript module could not be transpiled for the Node loader.',
171
+ PULSE_JAVASCRIPT_EXTERNAL_MODULE_UNAVAILABLE: 'A declared external module is unavailable to the JavaScript application loader.',
172
+ PULSE_JAVASCRIPT_MODULE_KIND_UNSUPPORTED: 'The JavaScript loader encountered a module kind outside its sealed contract.',
173
+ PULSE_RUNTIME_APPLICATION_EXPORT_INVALID: 'The application value is not a Router, Pulse application, or managed handler.',
174
+ PULSE_CONFIG_LOAD_FAILED: 'The selected project configuration threw or failed while being loaded.',
175
+ PULSE_ENTRY_NOT_FOUND: 'The configured canonical handler entry file does not exist.',
176
+ PULSE_PROJECT_ROOT_MISSING: 'The selected project directory does not exist.',
177
+ PULSE_PROVIDER_UNSUPPORTED: 'The selected provider value is not a supported shorthand or package selection.',
178
+ PULSE_PROVIDER_PACKAGE_NOT_FOUND: 'The exact configured provider package does not expose a resolvable toolchain entry.',
179
+ PULSE_PROVIDER_TOOLCHAIN_LOAD_FAILED: 'The selected provider package toolchain failed while loading.',
180
+ PULSE_PROVIDER_TOOLCHAIN_INVALID: 'The selected provider package does not satisfy the versioned toolchain contract.',
181
+ PULSE_INIT_NOT_EMPTY: 'Project initialization would write into a non-empty directory without explicit force.',
182
+ PULSE_INIT_FILE_EXISTS: 'Project initialization would replace an existing file that is not safe to overwrite.',
183
+ PULSE_BUILD_OUT_UNSAFE: 'The resolved build output can escape or alias outside the project root.',
184
+ PULSE_BUILD_PROVIDER_REQUIRED: 'pulse build requires a configured deployment provider; provider-neutral output belongs to pulse compile.',
185
+ PULSE_EXPERIMENTAL_NATIVE_SIZE_UNSUPPORTED: 'The experimental Native size optimizer cannot be used for a JavaScript build target.',
186
+ PULSE_NODE_VERSION_UNSUPPORTED: 'The active Node.js version is outside the supported release range.',
187
+ PULSE_CONFIG_IMPLICIT: 'A command is relying on an implicit project shape instead of an explicit configuration.',
188
+ PULSE_PROVIDER_COMPILE_ONLY: 'The none provider cannot execute development-server or project-test behavior.',
189
+ PULSE_FETCH_IMPLEMENTATION_UNAVAILABLE: 'No supported local fetch implementation is available for the requested operation.',
190
+ PULSE_HANDLER_ASYNC_REQUIRED: 'A managed handler in a conventional Pulse project is missing its required async wrapper.',
191
+ PULSE_PROJECT_COMPILE_FAILED: 'Whole-project compilation failed and contains one or more nested diagnostics.',
192
+ PULSE_CANONICAL_COMPILE_FAILED: 'The handler uses a source form outside the canonical Beta authoring subset.',
193
+ PULSE_CANONICAL_NATIVE_PLAN_FAILED: 'The canonical handler could not be represented by the provider-neutral native execution-plan contract.',
194
+ PULSE_CANONICAL_NATIVE_AS_GENERATION_FAILED: 'The validated native plan could not be rendered into the bounded AssemblyScript state-machine source.',
195
+ PULSE_CANONICAL_NATIVE_COMPILE_FAILED: 'The provider-neutral native plan could not be compiled into Pulse-owned WebAssembly.',
196
+ PULSE_PACKAGE_LOWERING_FAILED: 'A package-owned API call could not be lowered into its canonical effect contract.',
197
+ PULSE_NATIVE_IMPORT_UNSUPPORTED: 'A reachable runtime import has no trusted Pulse native contract.',
198
+ PULSE_PACKAGE_SUBPATH_UNSUPPORTED: 'A Pulse-aware package was imported through a subpath that is not native-lowerable.',
199
+ PULSE_PACKAGE_REEXPORT_LOWERING_DEFERRED: 'A package-owned helper is graph-owned but reaches application code through a project re-export whose lowering remains deferred.',
200
+ PULSE_APPLICATION_ENTRY_LIFECYCLE_SIDE_EFFECT: 'The configured application entry graph starts a known provider lifecycle during module evaluation.',
201
+ PULSE_PACKAGE_BINDING_OWNERSHIP_AMBIGUOUS: 'A project binding or re-export resolves to more than one package-owned symbol.',
202
+ PULSE_PACKAGE_CONTRACT_NOT_RECOGNIZED: 'The graph selected a trusted package contract that the package recognizer did not recover from its owning source module.',
203
+ PULSE_SCHEMA_COMPILE_FAILED: 'An explicitly declared JSON schema could not be compiled.',
204
+ PULSE_CANONICAL_SCHEMA_MISSING: 'The handler references a schema ID that is absent from project configuration.',
205
+ PULSE_SCHEMA_JSON_DECLARATIONS_RETIRED: 'Legacy jsonSchemas declarations are no longer accepted as schema authority.',
206
+ PULSE_SCHEMA_CODEC_REALIZATION_PENDING: 'The selected schema shape cannot be realized by every configured execution target.',
207
+ PULSE_CANONICAL_SCHEMA_ID_LITERAL_REQUIRED: 'A schema operation uses a value that is not a static string literal ID.',
208
+ PULSE_SCHEMA_ID_INVALID: 'A schema-bound operation received an invalid schema ID.',
209
+ PULSE_SCHEMA_REQUIRED: 'Strict JSON operation omitted its required registered schema ID.',
210
+ PULSE_SCHEMA_REFERENCE: 'A JSON operation references a schema absent from the compiled codec table.',
211
+ PULSE_SCHEMA_CODECS_UNAVAILABLE: 'A schema-bound JSON operation has no compiled codec table.',
212
+ PULSE_SCHEMA_CONTENT_TYPE: 'A schema-bound JSON input uses a content type rejected by policy.',
213
+ PULSE_SCHEMA_JSON_MALFORMED: 'A schema-bound JSON input is not syntactically valid JSON.',
214
+ PULSE_RESPONSE_CASE_MISSING: 'The handler references a response case absent from pulse.schema.',
215
+ PULSE_RESPONSE_CASE_REFERENCE: 'A runtime JSON response references an unknown compiled response case.',
216
+ PULSE_RESPONSE_DESCRIPTOR_INVALID: 'A runtime JSON response received an invalid descriptor.',
217
+ PULSE_RESPONSE_DESCRIPTOR_LITERAL_REQUIRED: 'A JSON response descriptor cannot be resolved statically.',
218
+ PULSE_FETCH_SCHEMA_WITHOUT_JSON: 'An outbound fetch schema was supplied without a semantic JSON payload.',
219
+ PULSE_SCHEMA_ID_DUPLICATE: 'Two or more configured schema declarations use the same stable ID.',
220
+ PULSE_SCHEMA_SOURCE_REQUIRED: 'A schema declaration is missing its project-relative TypeScript source file.',
221
+ PULSE_SCHEMA_TYPE_REQUIRED: 'A schema declaration is missing its exported TypeScript type name.',
222
+ PULSE_TEST_PROVIDER_REQUIRED: 'Project tests require an executable provider.',
223
+ PULSE_DEV_PROVIDER_UNSUPPORTED: 'The development server requires an executable provider.',
224
+ PULSE_PROVIDER_CAPABILITY_MISSING: 'The selected provider lacks a binding required by the compiled application.',
225
+ PULSE_PROVIDER_CAPABILITY_UNSUPPORTED: 'The selected provider cannot realize a capability required by the application.',
226
+ PULSE_EVENT_TARGET_UNSUPPORTED: 'The selected provider target cannot realize or test the reachable event plane.',
227
+ PULSE_FASTLY_EVENT_INGRESS_UNSUPPORTED: 'Fastly does not expose the host-neutral event ingress required by the application.',
228
+ PULSE_FASTLY_EVENT_EMIT_UNSUPPORTED: 'Fastly does not expose the host-neutral event acceptance operation required by the application.',
229
+ PULSE_FASTLY_BACKEND_REQUIRED: 'A static Fastly outbound origin has no configured backend and dynamic backends are disabled.',
230
+ PULSE_FASTLY_BACKEND_BINDINGS_INVALID: 'The Fastly backend binding map is not a valid string-to-string mapping.',
231
+ PULSE_FASTLY_KV_BINDINGS_INVALID: 'The Fastly KV binding map is not a valid string-to-string mapping.',
232
+ PULSE_FASTLY_GRIP_FANOUT_BACKEND_REQUIRED: 'A GRIP hold operation requires a configured Fastly Fanout backend.',
233
+ PULSE_FASTLY_GRIP_PUBLISH_BINDING_REQUIRED: 'A GRIP publish operation requires configured Fastly publish URL and backend bindings.',
234
+ PULSE_BODY_DECODE: 'A structured request body could not be decoded in the requested representation.',
235
+ PULSE_SCHEMA_DECODE: 'JSON input did not satisfy the explicitly declared schema and content-type policy.',
236
+ PULSE_BODY_TOO_LARGE: 'A structured body exceeded the configured bounded-body limit.',
237
+ PULSE_REQUEST_BODY_TOO_LARGE: 'An incoming development request exceeded dev.maxBodyBytes.',
238
+ PULSE_BODY_UNAVAILABLE: 'A structured body was requested when the provider had not supplied one.',
239
+ PULSE_OPAQUE_BODY_INSPECTION: 'Application code attempted to inspect or transform an opaque host-owned body.',
240
+ PULSE_RESPONSE_ENCODE: 'The selected response encoder cannot represent the returned value.',
241
+ PULSE_SCHEMA_ENCODE: 'The returned value does not satisfy its declared response schema.',
242
+ PULSE_FETCH_TIMEOUT: 'An outbound fetch did not complete before its timeout.',
243
+ PULSE_FETCH_NETWORK: 'An outbound fetch failed because the origin or network was unavailable.',
244
+ PULSE_FETCH_URL_INVALID: 'An outbound fetch uses an invalid or unsupported URL.',
245
+ PULSE_CONTINUATION_EXPIRED: 'A pending continuation exceeded its configured lifetime before resumption.',
246
+ PULSE_CONTINUATION_DOUBLE_RESUME: 'A provider attempted to resume the same continuation more than once.',
247
+ PULSE_FASTLY_CLI_UNAVAILABLE: 'The Fastly executable required for local target execution is unavailable.',
248
+ PULSE_FASTLY_CLI_INSPECTION_FAILED: 'Pulse could not inspect the installed Fastly CLI version.',
249
+ PULSE_VICEROY_UNAVAILABLE: 'The explicitly selected Viceroy override is unavailable.',
250
+ PULSE_VICEROY_INSPECTION_FAILED: 'Pulse could not inspect the explicitly selected Viceroy override.',
251
+ PULSE_FASTLY_SERVE_START_FAILED: 'The Fastly local Compute service failed before becoming ready.',
252
+ PULSE_FASTLY_SERVE_START_TIMEOUT: 'The Fastly local Compute service did not become ready before its startup timeout.',
253
+ PULSE_FASTLY_REQUEST_TIMEOUT: 'A request to the local Fastly Compute service exceeded its timeout.'
254
+ });
255
+
256
+ function titleForCode(code) {
257
+ const acronyms = new Set(['API', 'CLI', 'GRIP', 'HTTP', 'JSON', 'KV', 'URL']);
258
+ return String(code).replace(/^PULSE_/, '').split('_').map((part) => acronyms.has(part) ? part : part.charAt(0) + part.slice(1).toLowerCase()).join(' ');
259
+ }
260
+
261
+ const DIAGNOSTIC_CATALOG = Object.freeze(Object.fromEntries(
262
+ Object.entries(DIAGNOSTIC_DEFINITIONS).map(([code, descriptor]) => Object.freeze([code, Object.freeze({
263
+ ...descriptor,
264
+ title: titleForCode(code),
265
+ summary: DIAGNOSTIC_SUMMARIES[code],
266
+ stability: DIAGNOSTIC_STABILITY,
267
+ scope: 'public'
268
+ })]))
269
+ ));
270
+
271
+ const FAMILY_DEFAULTS = Object.freeze([
272
+ Object.freeze({ prefix: 'PULSE_CRYPTO_', descriptor: entry('capability', { exitCode: 3, remediation: ['Fix the effective profile crypto declaration or selected target realization.', 'Pulse will not detect or substitute another realization.'] }) }),
273
+ Object.freeze({ prefix: 'PULSE_CANONICAL_', descriptor: entry('compile', { exitCode: 3, remediation: ['Rewrite the source using the documented canonical API subset.', 'Run `pulse inspect --json` for structured compiler diagnostics.'] }) }),
274
+ Object.freeze({ prefix: 'PULSE_SCHEMA_', descriptor: entry('schema', { exitCode: 3, remediation: ['Fix the schema declaration or payload identified by the diagnostic.'] }) }),
275
+ Object.freeze({ prefix: 'PULSE_FASTLY_', descriptor: entry('provider', { exitCode: 5, remediation: ['Run `pulse doctor --json` and inspect the configured provider realization.'] }) }),
276
+ Object.freeze({ prefix: 'PULSE_PROFILE_', descriptor: entry('project', { exitCode: 2, remediation: ['Select a declared project profile explicitly.'] }) }),
277
+ Object.freeze({ prefix: 'PULSE_PACKAGE_', descriptor: entry('compile', { exitCode: 3, remediation: ['Inspect package ownership and target-support details with `pulse inspect --json`.', 'Use only documented package facades and direct opaque app.profile() composition tokens.'] }) }),
278
+ Object.freeze({ prefix: 'PULSE_WORKSPACE_', descriptor: entry('project', { exitCode: 2, remediation: ['Correct the authoritative workspace selection.'] }) }),
279
+ Object.freeze({ prefix: 'PULSE_TARGET_', descriptor: entry('capability', { exitCode: 3, remediation: ['Select an implemented target or use inspection-only commands.'] }) }),
280
+ Object.freeze({ prefix: 'PULSE_JAVASCRIPT_', descriptor: entry('capability', { exitCode: 3, remediation: ['Inspect the JavaScript application plan and its explicit target blockers.', 'Pulse will not change targets automatically.'] }) }),
281
+ Object.freeze({ prefix: 'PULSE_CONFIG_', descriptor: entry('project', { exitCode: 2, remediation: ['Fix `.pulse/config.ts` and rerun `pulse doctor`.'] }) }),
282
+ Object.freeze({ prefix: 'PULSE_TEST_', descriptor: entry('test', { exitCode: 4, remediation: ['Fix the configured test case or its expected result.'] }) }),
283
+ Object.freeze({ prefix: 'PULSE_FETCH_', descriptor: entry('runtime', { exitCode: 4, httpStatus: 502, remediation: ['Inspect the origin URL, provider binding, and fetch diagnostic detail.'] }) }),
284
+ Object.freeze({ prefix: 'PULSE_CONTINUATION_', descriptor: entry('runtime', { exitCode: 4, httpStatus: 500, remediation: ['Inspect the continuation trace and report unexpected lifecycle behavior.'] }) })
285
+ ]);
286
+
287
+ function diagnosticAnchor(code) {
288
+ return String(code || 'unknown').toLowerCase().replace(/_/g, '-');
289
+ }
290
+
291
+ function docsAnchor(code) {
292
+ return `${DIAGNOSTICS_REFERENCE}#${diagnosticAnchor(code)}`;
293
+ }
294
+
295
+ function describeDiagnostic(code) {
296
+ const normalized = code ? String(code) : undefined;
297
+ const catalogued = normalized ? DIAGNOSTIC_CATALOG[normalized] : undefined;
298
+ const found = catalogued
299
+ || FAMILY_DEFAULTS.find((entryValue) => normalized && normalized.startsWith(entryValue.prefix))?.descriptor
300
+ || entry('internal', { exitCode: 1, httpStatus: 500, remediation: ['Rerun with `--json` and retain the complete diagnostic for investigation.'] });
301
+ return Object.freeze({
302
+ version: CLI_DIAGNOSTICS_VERSION,
303
+ code: normalized,
304
+ title: catalogued ? catalogued.title : 'Uncatalogued Pulse diagnostic',
305
+ summary: catalogued ? catalogued.summary : 'The diagnostic is not part of the stable public CLI catalog; inspect its structured detail.',
306
+ category: found.category,
307
+ exitCode: found.exitCode || 1,
308
+ httpStatus: found.httpStatus || 500,
309
+ remediation: found.remediation,
310
+ stability: catalogued ? catalogued.stability : 'internal-or-forward-compatible',
311
+ scope: catalogued ? catalogued.scope : 'fallback',
312
+ docs: catalogued ? docsAnchor(normalized) : DIAGNOSTICS_REFERENCE
313
+ });
314
+ }
315
+
316
+ function decorateDiagnostic(value) {
317
+ if (!value || typeof value !== 'object') return value;
318
+ const descriptor = describeDiagnostic(value.code);
319
+ return Object.freeze({
320
+ ...value,
321
+ title: value.title || descriptor.title,
322
+ summary: value.summary || descriptor.summary,
323
+ category: value.category || descriptor.category,
324
+ remediation: value.remediation || descriptor.remediation,
325
+ stability: value.stability || descriptor.stability,
326
+ scope: value.scope || descriptor.scope,
327
+ docs: value.docs || descriptor.docs
328
+ });
329
+ }
330
+
331
+ function exitCodeForDiagnostic(code, fallback = 1) {
332
+ return code ? describeDiagnostic(code).exitCode : fallback;
333
+ }
334
+
335
+ function httpStatusForDiagnostic(code, fallback = 500) {
336
+ return code ? describeDiagnostic(code).httpStatus : fallback;
337
+ }
338
+
339
+ module.exports = Object.freeze({
340
+ CLI_DIAGNOSTICS_VERSION,
341
+ DIAGNOSTICS_REFERENCE,
342
+ DIAGNOSTIC_STABILITY,
343
+ DIAGNOSTIC_CATALOG,
344
+ diagnosticAnchor,
345
+ docsAnchor,
346
+ describeDiagnostic,
347
+ decorateDiagnostic,
348
+ exitCodeForDiagnostic,
349
+ httpStatusForDiagnostic
350
+ });
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ // Generated from release/pulse-release-manifest.json by wasm/scripts/sync-reference-docs.cjs.
4
+ const DOCUMENTATION_ORIGIN = "https://pulsecompute.io";
5
+ const DOCUMENTATION_BASE_PATH = "";
6
+ const DOCUMENTATION_VERSION = "v1.0.0-beta.2";
7
+ const DOCUMENTATION_LATEST_ALIAS = "latest";
8
+
9
+ function trimSlashes(value) { return String(value || '').replace(/^\/+|\/+$/g, ''); }
10
+ function cleanAnchor(value) { return value ? '#' + String(value).replace(/^#/, '') : ''; }
11
+ function sourceToRoute(sourcePath) {
12
+ const source = String(sourcePath).replace(/\\/g, '/').replace(/^\.\//, '');
13
+ if (source === 'docs/README.md') return '';
14
+ if (source === 'README.md') return 'project/';
15
+ if (source === 'API.md') return 'api/';
16
+ if (source === 'examples/README.md') return 'examples/';
17
+ const example = /^examples\/(.+)\/README\.md$/.exec(source);
18
+ if (example) return 'examples/' + example[1] + '/';
19
+ if (source.startsWith('docs/')) {
20
+ const relative = source.slice('docs/'.length);
21
+ if (relative.endsWith('/README.md')) return relative.slice(0, -'README.md'.length);
22
+ if (relative.endsWith('.md')) return relative.slice(0, -3) + '/';
23
+ }
24
+ throw new Error('No hosted documentation route for ' + sourcePath);
25
+ }
26
+ function documentationBaseUrl(versionSegment = DOCUMENTATION_VERSION) {
27
+ return DOCUMENTATION_ORIGIN + DOCUMENTATION_BASE_PATH + '/' + trimSlashes(versionSegment) + '/';
28
+ }
29
+ function documentationUrl(sourcePath = 'docs/README.md', anchor = '', options = {}) {
30
+ return documentationBaseUrl(options.versionSegment || DOCUMENTATION_VERSION) + sourceToRoute(sourcePath) + cleanAnchor(anchor);
31
+ }
32
+ function latestDocumentationUrl(sourcePath = 'docs/README.md', anchor = '') {
33
+ return documentationUrl(sourcePath, anchor, { versionSegment: DOCUMENTATION_LATEST_ALIAS });
34
+ }
35
+
36
+ module.exports = Object.freeze({
37
+ DOCUMENTATION_ORIGIN,
38
+ DOCUMENTATION_BASE_PATH,
39
+ DOCUMENTATION_VERSION,
40
+ DOCUMENTATION_LATEST_ALIAS,
41
+ sourceToRoute,
42
+ documentationBaseUrl,
43
+ documentationUrl,
44
+ latestDocumentationUrl
45
+ });
package/src/index.d.ts ADDED
@@ -0,0 +1,133 @@
1
+ /** Bare provider id or exact installed scoped package name exposing `./toolchain`. */
2
+ export type PulseProvider = string;
3
+ export interface PulseProviderConfig {
4
+ readonly kind: PulseProvider;
5
+ }
6
+ export type HeaderPair = readonly [name: string, value: string];
7
+
8
+ export interface PulseProjectRequest {
9
+ readonly method?: string;
10
+ readonly url?: string;
11
+ readonly path?: string;
12
+ readonly headers?: Readonly<Record<string, string>> | readonly HeaderPair[];
13
+ readonly body?: string;
14
+ }
15
+
16
+ export interface PulseProjectExpectedError {
17
+ readonly name?: string;
18
+ readonly code?: string;
19
+ readonly category?: string;
20
+ readonly message?: string;
21
+ }
22
+
23
+ export interface PulseProjectExpectation {
24
+ readonly status?: number;
25
+ readonly bodyClass?: 'structured' | 'opaque';
26
+ readonly json?: unknown;
27
+ readonly text?: string;
28
+ readonly headers?: Readonly<Record<string, string | readonly string[]>> | readonly (readonly [string, string | readonly string[]])[];
29
+ readonly error?: string | PulseProjectExpectedError;
30
+ }
31
+
32
+ export type PulseProjectEventFrame =
33
+ | { readonly type: string; readonly schema: null; readonly schemaId?: never; readonly payload?: never }
34
+ | { readonly type: string; readonly schema: string; readonly schemaId?: never; readonly payload: unknown }
35
+ | { readonly type: string; readonly schema?: never; readonly schemaId: null; readonly payload?: never }
36
+ | { readonly type: string; readonly schema?: never; readonly schemaId: string; readonly payload: unknown };
37
+
38
+ export interface PulseProjectEventExpectation {
39
+ readonly status?: 'completed' | 'failed';
40
+ readonly emitted?: readonly PulseProjectEventFrame[];
41
+ readonly error?: string | PulseProjectExpectedError;
42
+ }
43
+
44
+ export interface PulseProjectTestCaseFixtures {
45
+ readonly name: string;
46
+ readonly fetches?: Readonly<Record<string, unknown>>;
47
+ readonly config?: Readonly<Record<string, string>>;
48
+ readonly secrets?: Readonly<Record<string, string>>;
49
+ readonly kv?: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
50
+ /** Provider-local GRIP fixture inputs such as holdBody or holdChunks. */
51
+ readonly grip?: Readonly<Record<string, unknown>>;
52
+ readonly maxBodyBytes?: number;
53
+ readonly continuationTtlMs?: number;
54
+ }
55
+
56
+ export interface PulseProjectHttpTestCase extends PulseProjectTestCaseFixtures {
57
+ readonly kind?: 'http';
58
+ readonly request?: PulseProjectRequest;
59
+ readonly event?: never;
60
+ readonly expect: PulseProjectExpectation;
61
+ }
62
+
63
+ export interface PulseProjectEventTestCase extends PulseProjectTestCaseFixtures {
64
+ readonly kind: 'event';
65
+ readonly event: PulseProjectEventFrame;
66
+ readonly request?: never;
67
+ readonly expect: PulseProjectEventExpectation;
68
+ }
69
+
70
+ export type PulseProjectTestCase = PulseProjectHttpTestCase | PulseProjectEventTestCase;
71
+
72
+ export interface PulseSchemaConfig {
73
+ /** Schema declarations live exclusively in the module selected by pulse.schema. */
74
+ readonly contentTypePolicy?: 'accept-json-or-missing' | 'require-json';
75
+ readonly maxBytes?: number;
76
+ }
77
+
78
+ export interface PulseProjectDevConfig {
79
+ readonly host?: string;
80
+ readonly port?: number;
81
+ readonly watch?: boolean;
82
+ readonly maxBodyBytes?: number;
83
+ readonly networkFetch?: boolean;
84
+ readonly config?: Readonly<Record<string, string>>;
85
+ readonly secrets?: Readonly<Record<string, string>>;
86
+ readonly kv?: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
87
+ readonly fetches?: Readonly<Record<string, unknown>>;
88
+ }
89
+
90
+ export interface PulseProjectConfig {
91
+ readonly entry?: string;
92
+ readonly provider?: PulseProvider | PulseProviderConfig;
93
+ readonly outDir?: string;
94
+ readonly schemas?: PulseSchemaConfig;
95
+ readonly dev?: PulseProjectDevConfig;
96
+ }
97
+
98
+ export declare const PROJECT_CONFIG_VERSION: 'pulse.project-config.v4';
99
+ export declare function runPulseWorkflowCli(argv: readonly string[], io?: { cwd?: string; stdout?: NodeJS.WritableStream; stderr?: NodeJS.WritableStream }): Promise<{ status: number }>;
100
+
101
+ export interface PulseProjectConfigValidationIssue {
102
+ readonly path: string;
103
+ readonly message: string;
104
+ }
105
+
106
+ export declare const PROJECT_CONFIG_SCHEMA_VERSION: 'pulse.project-config-schema.v1';
107
+ export declare const projectConfigSchema: {
108
+ readonly PROJECT_CONFIG_SCHEMA_VERSION: 'pulse.project-config-schema.v1';
109
+ readonly PROJECT_CONFIG_JSON_SCHEMA: Readonly<Record<string, unknown>>;
110
+ readonly validateProjectConfigStructure: (input: unknown) => readonly PulseProjectConfigValidationIssue[];
111
+ readonly projectConfigSchemaDocument: () => Readonly<Record<string, unknown>>;
112
+ };
113
+
114
+
115
+ export interface PulseDiagnosticDescriptor {
116
+ readonly version: 'pulse.cli-diagnostics.v1';
117
+ readonly code?: string;
118
+ readonly title: string;
119
+ readonly summary: string;
120
+ readonly category: 'usage' | 'project' | 'safety' | 'compile' | 'schema' | 'capability' | 'provider' | 'request' | 'runtime' | 'toolchain' | 'test' | 'internal';
121
+ readonly exitCode: number;
122
+ readonly httpStatus: number;
123
+ readonly remediation: readonly string[];
124
+ readonly stability: 'preview-stable' | 'internal-or-forward-compatible';
125
+ readonly scope: 'public' | 'fallback';
126
+ readonly docs: string;
127
+ }
128
+
129
+ export declare const diagnostics: {
130
+ readonly describeDiagnostic: (code?: string) => PulseDiagnosticDescriptor;
131
+ readonly exitCodeForDiagnostic: (code?: string, fallback?: number) => number;
132
+ readonly httpStatusForDiagnostic: (code?: string, fallback?: number) => number;
133
+ };
package/src/index.js ADDED
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ const workflow = require('./workflow.js');
4
+ const projectConfig = require('./project-config.js');
5
+ const diagnostics = require('./diagnostics.js');
6
+ const projectConfigSchema = require('./project-config-schema.js');
7
+
8
+ module.exports = Object.freeze({
9
+ cli: require('@pulse-compute/wasm-compiler/cli'),
10
+ workflow,
11
+ projectConfig,
12
+ projectConfigSchema,
13
+ diagnostics,
14
+ runPulseWorkflowCli: workflow.runPulseWorkflowCli
15
+ });
@@ -0,0 +1,29 @@
1
+ import type { NormalizedCommandRequest, MetaCommandRequest } from './command-request';
2
+ import type { ProjectContext } from './project-context';
3
+ import type { CommandPlan } from './command-plan';
4
+
5
+ export interface CommandExecutionResult {
6
+ readonly status: number;
7
+ readonly help?: true;
8
+ readonly version?: string;
9
+ readonly completion?: string;
10
+ readonly bytes?: number;
11
+ readonly plan?: CommandPlan;
12
+ readonly result?: Readonly<Record<string, any>>;
13
+ }
14
+
15
+ export declare const EXECUTOR_IDS: readonly ['meta', 'init', 'artifact', 'compile', 'build', 'test', 'inspect', 'doctor', 'dev'];
16
+ export declare function executeCommandPlan(
17
+ plan: CommandPlan,
18
+ request: NormalizedCommandRequest | MetaCommandRequest,
19
+ options?: Readonly<{
20
+ projectContext?: ProjectContext;
21
+ cliVersion?: string;
22
+ environment?: NodeJS.ProcessEnv;
23
+ operations?: Readonly<Record<string, (...args: any[]) => any>>;
24
+ onEvent?: (event: Readonly<Record<string, any>>) => void;
25
+ signalSource?: NodeJS.Process;
26
+ }>
27
+ ): Promise<CommandExecutionResult>;
28
+ export declare function inspectArtifact(file: string): Readonly<Record<string, unknown>>;
29
+ export declare function summarizeExecutionError(error: unknown): Readonly<Record<string, unknown>>;