@diagonal-hq/cli 0.0.0-stage → 0.1.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/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ Copyright (c) 2026 Diagonal Software Corp. All rights reserved.
2
+
3
+ This software is the proprietary property of Diagonal Software Corp. ("Diagonal"). It is
4
+ licensed, not sold.
5
+
6
+ Diagonal grants you a limited, non-exclusive, non-transferable, revocable
7
+ license to install and use this software only to develop, check, build, and
8
+ deploy workspaces for the Diagonal platform, in accordance with your agreement
9
+ with Diagonal.
10
+
11
+ You may not:
12
+
13
+ - modify, adapt, translate, or create derivative works of this software;
14
+ - copy, distribute, sublicense, sell, or otherwise make this software available
15
+ to any third party, except as an unmodified dependency of a Diagonal
16
+ workspace;
17
+ - use this software with any service other than the Diagonal platform;
18
+ - remove or change this notice.
19
+
20
+ This license ends automatically when you stop using the Diagonal platform or
21
+ when you breach its terms.
22
+
23
+ THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
25
+ FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL DIAGONAL BE
26
+ LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27
+ CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE
28
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,95 @@
1
- # Temporary Holding Version
1
+ # `@diagonal-hq/cli`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ This package is the authoring SDK for file-based workspaces. A workspace repository installs it as a dev dependency. It gives these things:
4
+
5
+ - The configuration helpers: `defineConfig`, `defineResource`, `definePage`, `defineEmail`, `defineNavigation`, and the `field` builders. Each `define*` function returns its first argument. Each `field.<type>(options)` call returns `{ $field, ...options }`, where `$field` is the stored field type. The package root exports them as ESM JavaScript with declarations, so a Vite build or a Node script can import a configuration file.
6
+ - Types for the helpers, `WorkflowConfig`, and the `Sdk` and `React` globals.
7
+ - Editor types for the workflow script SDK: `@diagonal/workflow`, `@diagonal/workflow/testing`, and `@diagonal/workflow/workspace`.
8
+ - The `diagonal check` command. It runs the same build and checks that a platform deploy runs, including the workflow tests.
9
+ - The `diagonal workflows` and `diagonal run` commands. They list the deployed workflows and run a manual workflow by its file path.
10
+
11
+ ## Check a workspace
12
+
13
+ ```bash
14
+ npm install
15
+ npm run check
16
+ ```
17
+
18
+ `npm run check` runs `diagonal check .`. The command options are:
19
+
20
+ ```text
21
+ diagonal check [dir] [--json]
22
+ ```
23
+
24
+ - `dir` is the workspace root. The default is the current directory.
25
+ - `--json` prints `{ "ok": boolean, "diagnostics": [...] }`.
26
+
27
+ Each diagnostic prints as `path:line:column severity message`. The command exits with 1 when an error exists, with 2 for a usage error, and with 0 otherwise.
28
+
29
+ ## Run a deployed workflow
30
+
31
+ `diagonal workflows` and `diagonal run` call the runtime API of a deployed workspace. Set two environment variables first:
32
+
33
+ - `DIAGONAL_URL` is the workspace URL, for example `https://acme.diagonal.app`.
34
+ - `DIAGONAL_API_KEY` is an API key of an account with `manage_workflows`.
35
+
36
+ ```text
37
+ diagonal workflows [--json]
38
+ diagonal run <path> [--input '<json object>'] [--json]
39
+ ```
40
+
41
+ - `diagonal workflows` prints the path, the trigger type, and the title of each workflow of the active deployment. `--json` prints the API response, which also has each workflow id and version id.
42
+ - `diagonal run workflows/seed-catalog.ts` runs the manual workflow at that path in the active deployment and waits for it. It prints the terminal status, the execution id, and the output. `--input` gives the workflow input as a JSON object. `--json` prints the API response.
43
+
44
+ `diagonal run` exits with 0 when the run succeeds, with 1 when the request or the run fails, and with 2 for a usage error or a missing environment variable. A workflow that is not manual, or a path that the active deployment does not have, is a request failure.
45
+
46
+ ## What the checks do
47
+
48
+ The build reads each file with a parser. It runs only the workflow tests.
49
+
50
+ - `defineConfig`, `defineResource`, `defineNavigation`, and the first argument of `definePage` and `defineEmail` must be static literals. The `field.<type>({...})` calls are the only calls that the build accepts in this data.
51
+ - The build removes imports from `@diagonal-hq/cli`. It reads imports from `@diagonal/runtime`, the old name of the package, the same way. Pages, layouts, components, and workflow scripts can import workspace files through `@app/`. Workflow scripts can also import `@diagonal/workflow` and `@diagonal/workflow/workspace`. Other external imports in these source files are rejected.
52
+ - The second argument of `definePage` and `defineEmail`, and the default export of a layout or component file, must be one function.
53
+ - Pages, layouts, components, and emails go through the page lint gate: syntax, scope, the component return shape, and a type check against the page Sdk contract and the workspace resources. A page can name a resource by id or by slug, for example `Sdk.resource('members')`.
54
+ - Each `workflows/<name>.ts` is a script workflow. It has one `export const config = { title, trigger, runAs? } satisfies WorkflowConfig` and one `export default defineWorkflow(...)`. The config must be a static literal. The build validates it: the trigger fields, the resources (by slug, name, or id), the workflow paths of `workflowEvent` triggers, and the run-as rules. A `recordEvent`, `recordSchedule`, `scheduled`, or `workflowEvent` workflow needs `runAs`.
55
+ - The build removes the config and the `@diagonal-hq/cli` imports from the workflow, with spaces in their place, and compiles the rest with the workflow script compiler against the workspace resources. A compiler error has the line and column of the workflow file.
56
+ - `workflows/<name>.test.ts` tests `workflows/<name>.ts` with `node:test` and `node:assert`. It imports the workflow, `runWorkflow` and `MockTransport` from `@diagonal/workflow/testing`, and the resource ids from `@diagonal/workflow/workspace`. The build transpiles the test and the workflows and runs them in one Node process. The process can read only its own temporary directory, cannot start processes, and has an empty environment. Each failing test is an error at the test. A test file without a workflow is an error.
57
+ - The build ignores the files at the root other than `diagonal.config.ts`, dotfiles, and `node_modules`.
58
+
59
+ ## Editor types
60
+
61
+ A page, layout, component, or workflow can import any other file of the workspace by its path from the root with `@app/`, for example `import { formatPrice } from '@app/lib/money'`. The extension is optional, and a folder's `index` file is found. The build links each imported file into the importing page or workflow, so the files need no folder of their own; a file outside the build's folders, such as `lib/`, is built only when something imports it. An imported module can import other `@app/` files, `@diagonal-hq/cli`, and, in a workflow, `@diagonal/workflow`. Add `"@app/*": ["./*"]` to the `paths` of `tsconfig.json` so the editor resolves them too.
62
+
63
+ Add a `tsconfig.json` with `"types": ["@diagonal-hq/cli", "node"]` and `@types/node` as a dev dependency. `dist/globals.d.ts` gives the `Sdk` global from the generated page Sdk contract (`dist/sdk-contract.d.ts`). The editor does not know the workspace resources and components, so `Sdk.resource(...)` and `Sdk.Custom.*` have loose types there. `diagonal check` types them.
64
+
65
+ `dist/workflow/` holds the declarations of the workflow script SDK. Map the module names to them with `paths`:
66
+
67
+ ```json
68
+ "paths": {
69
+ "@diagonal/workflow": ["./node_modules/@diagonal-hq/cli/dist/workflow/index.d.ts"],
70
+ "@diagonal/workflow/testing": ["./node_modules/@diagonal-hq/cli/dist/workflow/testing/index.d.ts"],
71
+ "@diagonal/workflow/workspace": ["./node_modules/@diagonal-hq/cli/dist/workflow/workspace.d.ts"]
72
+ }
73
+ ```
74
+
75
+ In the editor, `resources` from `@diagonal/workflow/workspace` maps every name to a string, and record data is untyped. `diagonal check` compiles against the workspace resources and their fields.
76
+
77
+ `globals.d.ts` at the package root has loose `Sdk` and `React` types. The source `index.d.ts` uses them before the package is built.
78
+
79
+ ## Build the package
80
+
81
+ `npm run build:cli-package` (`scripts/build-cli-package.mjs`) writes `dist/` and packs `public/runtime-sdk/diagonal-hq-cli-<version>.tgz`. It also writes a copy as `diagonal-runtime-<version>.tgz`, the URL that workspaces made before the rename depend on. `dist/cli.mjs` bundles every dependency, the TypeScript lib files, the workflow script compiler with the script SDK sources, and the bundled script SDK that workflow tests import, so the command needs no Diagonal checkout. The script needs the page Sdk contract and `scripts/generated/typeCheckLibs.mjs`. `npm run generate-typescript` makes both and then runs the script.
82
+
83
+ `node scripts/smoke-cli-package.mjs [tarball]` installs the packed tarball in a copy of the chamber template outside the repository. It checks the packed file list, imports the helpers through the `exports` map, runs `tsc` against the packed declarations, and runs `diagonal check`. The `generated-assets` job of PR CI runs it.
84
+
85
+ ## Publish the package
86
+
87
+ The `Publish npm package` workflow (`.github/workflows/publish-npm-package.yml`) publishes the package to npm. It runs only from `main`.
88
+
89
+ 1. Set `version` in `package.json` to a version that npm does not have. A version with a prerelease part, such as `0.2.0-next.1`, gets the `next` tag. Other versions get `latest`.
90
+ 2. Merge the change to `main`.
91
+ 3. Run the workflow from the Actions tab and select `cli`.
92
+
93
+ The build job builds the package, packs it, and runs the smoke test on the tarball. The publish job runs in the `npm-publish` environment and publishes those exact bytes with npm trusted publishing. It does not build again. It refuses a version that npm already has.
94
+
95
+ npm must list `Diagonal-HQ/diagonal`, the `publish-npm-package.yml` workflow, and the `npm-publish` environment as the trusted publisher of `@diagonal-hq/cli`.
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // The installed package has no path aliases.
3
+ // oxlint-disable-next-line local/no-relative-imports
4
+ import { main } from '../dist/cli.mjs';
5
+
6
+ process.exitCode = await main(process.argv.slice(2), {
7
+ cwd: process.cwd(),
8
+ env: process.env,
9
+ stdout: process.stdout,
10
+ stderr: process.stderr
11
+ });