@m6d/cortex-cli 0.12.1 → 0.14.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/README.md +193 -128
- package/package.json +16 -5
- package/src/cli.ts +19 -12
- package/src/commands/apply.ts +186 -0
- package/src/commands/{cc.ts → management.ts} +173 -112
- package/src/commands/new.ts +83 -84
- package/src/commands/setup.ts +610 -0
- package/src/contracts/charts/chart-spec.ts +1 -1
- package/src/contracts/client-tools/index.ts +3 -3
- package/src/contracts/{runtime → datasets}/datasets.ts +7 -42
- package/src/contracts/datasets/index.ts +3 -0
- package/src/contracts/egress-policy/index.ts +16 -0
- package/src/contracts/{egress → egress-policy}/scrub.ts +34 -5
- package/src/contracts/{egress → egress-policy}/url.ts +22 -9
- package/src/contracts/errors/index.ts +38 -0
- package/src/contracts/json/index.ts +5 -0
- package/src/contracts/manifest/index.ts +973 -0
- package/src/contracts/manifest-file/index.ts +16 -0
- package/src/contracts/markdown/index.ts +1 -1
- package/src/contracts/pattern/index.ts +276 -0
- package/src/contracts/server/index.ts +349 -0
- package/src/contracts/server/reserved-names.fixtures.json +18 -0
- package/src/contracts/triggers/index.ts +112 -0
- package/src/contracts/wire/index.ts +67 -33
- package/src/{cc → management}/client.ts +33 -7
- package/src/{cc → management}/flags.ts +2 -1
- package/src/{cc → management}/profiles.ts +10 -8
- package/src/scaffold/files.ts +448 -284
- package/src/scaffold/ports.ts +12 -24
- package/src/scaffold/templates/cspell.json.txt +41 -0
- package/src/scaffold/templates/datasets.ts.txt +52 -0
- package/src/scaffold/templates/dockerignore.txt +6 -0
- package/src/scaffold/templates/fallowrc.jsonc.txt +8 -12
- package/src/scaffold/templates/gitignore.txt +1 -1
- package/src/scaffold/templates/server.ts.txt +40 -0
- package/src/scaffold/templates/setup.ts.txt +44 -0
- package/src/ui/prompts.ts +24 -38
- package/src/ui/report.ts +5 -15
- package/tsconfig.json +2 -3
- package/src/commands/graph.ts +0 -228
- package/src/commands/swagger.ts +0 -247
- package/src/config/load.ts +0 -122
- package/src/config/validate.ts +0 -46
- package/src/contracts/credentials/index.ts +0 -183
- package/src/contracts/egress/index.ts +0 -120
- package/src/contracts/graph/clients/embed.ts +0 -62
- package/src/contracts/graph/clients/neo4j.ts +0 -85
- package/src/contracts/graph/helpers.ts +0 -55
- package/src/contracts/graph/index.ts +0 -30
- package/src/contracts/graph/schema.ts +0 -65
- package/src/contracts/graph/types.ts +0 -125
- package/src/contracts/rich-text/index.ts +0 -220
- package/src/contracts/runtime/api.ts +0 -345
- package/src/contracts/runtime/auth.ts +0 -41
- package/src/contracts/runtime/grammar.ts +0 -169
- package/src/contracts/runtime/index.ts +0 -15
- package/src/contracts/runtime/models.ts +0 -50
- package/src/contracts/runtime/signature.ts +0 -255
- package/src/contracts/runtime/sync.ts +0 -196
- package/src/contracts/runtime/triggers.ts +0 -267
- package/src/graph/expand-domains.ts +0 -286
- package/src/graph/generate-cypher.ts +0 -201
- package/src/graph/seed.ts +0 -199
- package/src/graph/validate.ts +0 -78
- package/src/scaffold/features.ts +0 -190
- package/src/scaffold/templates/domains-README.md.txt +0 -16
- package/src/scaffold/templates/index.ts.txt +0 -18
- package/src/swagger/extract-endpoints.ts +0 -269
- package/src/swagger/generated-block.ts +0 -74
- package/src/swagger/openapi-schema.ts +0 -168
- package/src/swagger/parse-response.ts +0 -88
- package/src/swagger/types.ts +0 -25
- /package/src/contracts/{runtime → datasets}/dataset-sql-guide.ts +0 -0
- /package/src/contracts/{runtime → datasets}/dataset-sql.ts +0 -0
- /package/src/contracts/{runtime → datasets}/datasets.fixtures.json +0 -0
- /package/src/{cc → management}/output.ts +0 -0
package/README.md
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
# @m6d/cortex-cli
|
|
2
2
|
|
|
3
|
-
The `cortex` command line: scaffold Cortex
|
|
4
|
-
|
|
3
|
+
The `cortex` command line: scaffold a Cortex project, and manage a Cortex deployment from the
|
|
4
|
+
terminal.
|
|
5
5
|
|
|
6
6
|
```sh
|
|
7
7
|
bunx @m6d/cortex-cli new my-app # from nowhere — scaffolds a project
|
|
8
|
-
bunx cortex
|
|
9
|
-
bunx cortex
|
|
8
|
+
bunx cortex agents list # against the Cortex you logged in to
|
|
9
|
+
bunx cortex apply # make it match ./cortex.manifest.ts
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
Commands are noun-first
|
|
13
|
-
resource
|
|
12
|
+
Commands are noun-first, `cortex <resource> <procedure>`, except `new`, which acts on no existing
|
|
13
|
+
resource, `setup` and `apply`, which act on a whole deployment, and `login`, `logout` and `status`,
|
|
14
|
+
which act on your profiles. Run `cortex --help`, then `cortex <resource> --help`.
|
|
14
15
|
|
|
15
16
|
```sh
|
|
16
17
|
bun add -d @m6d/cortex-cli
|
|
@@ -21,155 +22,219 @@ you how to install Bun when it is genuinely absent.
|
|
|
21
22
|
|
|
22
23
|
## `cortex new`
|
|
23
24
|
|
|
24
|
-
Scaffolds `./<name>`: a
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
Scaffolds `./<name>`: a backend for Cortex agents, and Cortex itself to run them on.
|
|
26
|
+
|
|
27
|
+
- `server.ts` is a Cortex server built with `defineServer` from `@m6d/cortex`: one variable
|
|
28
|
+
(`userName`) and one native tool (`rollDice`), mounted at `/cortex` by `index.ts`.
|
|
29
|
+
- `cortex.manifest.ts` declares a `helper` agent on that server, for `cortex apply`.
|
|
30
|
+
- `docker-compose.yml` runs Cortex's app, worker and engine on the one `syscodeia/cortex` image,
|
|
31
|
+
with Postgres, Redis and MinIO. Only the app and the engine publish host ports. They and the
|
|
32
|
+
backend's port are picked at scaffold time from what was free.
|
|
33
|
+
- `.env` holds every setting: Cortex's secrets, the backend's key and name, the model provider, and
|
|
34
|
+
the `CORTEX_URL` and `CORTEX_KEY` the CLI reaches this checkout's Cortex with. It is not
|
|
35
|
+
committed: `setup.ts` writes it from `.env.example` on every `bun install`, generating each
|
|
36
|
+
secret left blank, so a fresh clone gets its own secrets and a stack that never shares the
|
|
37
|
+
original's volumes. `.dockerignore` keeps both out of images.
|
|
38
|
+
- `bun run dev` starts Cortex (`docker compose up`), the backend and `bun cortex setup --wait --yes` in
|
|
39
|
+
an mprocs dashboard. `bun run dev:agent` runs the same through `concurrently`, one labelled log for
|
|
40
|
+
coding agents and CI.
|
|
41
|
+
- eslint, prettier, cspell, fallow and tsconfig are inlined, so `bun run verify` works standalone.
|
|
42
|
+
|
|
43
|
+
It then runs `bun install`, and `git init` unless the target is already inside a work tree. An
|
|
44
|
+
existing non-empty directory is an error. So is a name like `cortex` or `cortex.`, since the
|
|
45
|
+
manifest takes its id from the name and Cortex keeps the id `cortex` for its own.
|
|
28
46
|
|
|
29
47
|
```sh
|
|
30
|
-
bunx @m6d/cortex-cli new
|
|
48
|
+
bunx @m6d/cortex-cli new shop --datasets
|
|
31
49
|
```
|
|
32
50
|
|
|
33
|
-
On a TTY it asks only what the flags left open
|
|
34
|
-
the
|
|
51
|
+
On a TTY it asks only what the flags left open: the name, whether to set up the `helper` agent on
|
|
52
|
+
the first `bun run dev`, and if so the model provider (name, base URL, API key, model). It checks
|
|
53
|
+
the provider with one chat message to the model, and reuses it for embeddings when it serves the
|
|
54
|
+
stack's embedding model. With no TTY it never prompts and behaves as `--yes`, so a missing name is a
|
|
35
55
|
hard error rather than a hang.
|
|
36
56
|
|
|
37
|
-
| Flag
|
|
38
|
-
|
|
|
39
|
-
| `--
|
|
40
|
-
| `--
|
|
41
|
-
| `--
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
`sync` rewrites each endpoint's params, body, and response schemas in place and prints only the
|
|
63
|
-
files it changed; unchanged ones live in the footer count. `check` writes nothing, reports the drift
|
|
64
|
-
it found, and exits 2 — which is what makes it a CI step.
|
|
65
|
-
|
|
66
|
-
An endpoint file pointing at a route the spec no longer serves is `MISSING`. `sync` prints those
|
|
67
|
-
last, so they are the thing you read, and still exits 0: writing is its job. `check` counts them as
|
|
68
|
-
a finding, same as drift.
|
|
69
|
-
|
|
70
|
-
`-d, --domains-dir <path>` is declared on the `swagger` group, so it works on either side of the
|
|
71
|
-
verb. It defaults to `src/domains`, resolved relative to the config file.
|
|
72
|
-
|
|
73
|
-
## `cortex graph seed`
|
|
74
|
-
|
|
75
|
-
Loads every domain the config declares — server-level `knowledge.domains` and per-agent ones,
|
|
76
|
-
deduped — and seeds Neo4j with the concepts, endpoints, services, and rules they declare, then
|
|
77
|
-
embeds them. Reports per domain, because a domain is the unit you edit. No
|
|
78
|
-
flags.
|
|
57
|
+
| Flag | Default | Writes |
|
|
58
|
+
| ------------------------ | ------- | ------------------------------------------------------------------------------------------- |
|
|
59
|
+
| `--datasets` | off | `datasets.ts`, an in-memory `orders` table served as a dataset host, and its manifest entry |
|
|
60
|
+
| `--setup` / `--no-setup` | on | `cortex setup` among the processes `bun run dev` starts |
|
|
61
|
+
| `--yes` | | Accept the defaults instead of asking; setup then runs with no model provider |
|
|
62
|
+
|
|
63
|
+
The image runs at the Cortex release that was current when this CLI was published
|
|
64
|
+
(`CORTEX_VERSION` in the shell picks another); the backend depends on the `@m6d/cortex` release of
|
|
65
|
+
that time. A server name stops at Cortex's 100 characters, so a longer project name is
|
|
66
|
+
registered cut to that length.
|
|
67
|
+
|
|
68
|
+
## `cortex setup`
|
|
69
|
+
|
|
70
|
+
Registers a `cortex new` project's backend in its Cortex, then applies its manifest. It reads the
|
|
71
|
+
backend's name, URL and key (`CORTEX_SERVER_*`) and the model provider (`MODEL_PROVIDER_*`) from
|
|
72
|
+
`.env`, and goes in the one order Cortex accepts: the server key's secret, the provider's key and
|
|
73
|
+
the provider, the server on the provider's model, a sync of the server, then the apply. Each step
|
|
74
|
+
creates what is missing and keeps what exists, so a second run changes nothing. A key's secret is
|
|
75
|
+
named for its value (`openai-api-key-1a2b3c4d`), so a changed key gets a new secret the provider or
|
|
76
|
+
server moves to, and whatever else presents the old one keeps it. A provider or server under
|
|
77
|
+
`.env`'s name that calls another URL belongs to something else: setup leaves it alone and stops. So
|
|
78
|
+
does a `MODEL_PROVIDER_*` set only in part, or a provider URL on this machine or a private network
|
|
79
|
+
that `EGRESS_ALLOWED_HOSTS` in `.env` does not admit. A server with no model yet gets the provider's.
|
|
79
80
|
|
|
80
81
|
```sh
|
|
81
|
-
|
|
82
|
+
bun cortex setup # asks for a model provider when .env has none
|
|
83
|
+
bun cortex setup --wait --yes # what `bun run dev` runs
|
|
82
84
|
```
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
`--wait` waits up to 10 minutes for Cortex to answer, long enough for a first start to pull the
|
|
87
|
+
image. Without `-p`, setup sets up the Cortex `.env` names: a different `CORTEX_URL` exported in the
|
|
88
|
+
shell, which Bun lets win over `.env`, ends the run. The retried sync, a minute while Cortex cannot
|
|
89
|
+
reach the backend, gives up at once on any other refusal. With no model provider and `--yes`, it
|
|
90
|
+
registers the server and applies nothing: Cortex publishes no agent without a model. The run that
|
|
91
|
+
first creates something says how to sign in, with the password only on a terminal.
|
|
86
92
|
|
|
87
|
-
##
|
|
93
|
+
## Management commands
|
|
88
94
|
|
|
89
|
-
Manage a
|
|
90
|
-
|
|
95
|
+
Manage a Cortex deployment from the terminal. The commands come from
|
|
96
|
+
Cortex's own management API (`/api/management/openapi.json`), fetched
|
|
91
97
|
on each run and cached, so the tree always matches the deployment you point
|
|
92
98
|
at and a new procedure needs no CLI release.
|
|
93
99
|
|
|
94
100
|
```sh
|
|
95
|
-
cortex
|
|
96
|
-
cortex
|
|
97
|
-
cortex
|
|
98
|
-
cortex
|
|
99
|
-
cortex
|
|
100
|
-
cortex
|
|
101
|
-
cortex
|
|
101
|
+
cortex login # asks for the URL and a management key
|
|
102
|
+
cortex status
|
|
103
|
+
cortex agents list
|
|
104
|
+
cortex agents create --slug support --name Support --serverId <uuid>
|
|
105
|
+
cortex tools create --json tool.json --publish
|
|
106
|
+
cortex tools list -o json | jq '.items[].name'
|
|
107
|
+
cortex logout
|
|
102
108
|
```
|
|
103
109
|
|
|
104
|
-
Profiles live in `~/.cortex/
|
|
105
|
-
|
|
106
|
-
`
|
|
110
|
+
Profiles live in `~/.cortex/profiles.json` (owner-only). `-p, --profile <name>`,
|
|
111
|
+
a global option, picks one for any command, and names the one `login` saves
|
|
112
|
+
and `logout` forgets (`default` otherwise). `CORTEX_URL` and `CORTEX_KEY`, both
|
|
113
|
+
set, win over the current profile, for CI and for a project's `.env`; a
|
|
114
|
+
profile `-p` names wins over them. `CORTEX_HOME` relocates the directory.
|
|
107
115
|
|
|
108
|
-
The grammar is `cortex
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
116
|
+
The grammar is `cortex <router> <procedure> [id] [flags]`, with routers as
|
|
117
|
+
the API names them (`datasetHosts`, `modelProviders`). Each top-level input
|
|
118
|
+
field is a flag typed from the API's schema; nested values take JSON, and
|
|
119
|
+
`--json <file|->` supplies a whole body that flags then override. A required
|
|
120
|
+
field left out, `id` included, is asked for on a terminal and named as the
|
|
121
|
+
missing flag or positional otherwise. Listings take `--pageIndex`, `--pageSize`, `--q`, and `--all` to
|
|
122
|
+
walk every page. `-o json` prints the raw result for pipes.
|
|
114
123
|
|
|
115
124
|
Writes to agents, tools, services, skills, triggers, and dataset hosts save
|
|
116
125
|
drafts.
|
|
117
126
|
`--publish` on a write the API marks publishable (`update`, and a `create`
|
|
118
127
|
whose result is complete enough) runs that entity's publish procedure right
|
|
119
|
-
after; without it the command says so and names the command.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
draft host publishes only after `
|
|
128
|
+
after; without it the command says so and names the command. Fields the API
|
|
129
|
+
marks live (`x-live-fields`) take effect without a publish, from agents'
|
|
130
|
+
next turn, and the command names them: a trigger's
|
|
131
|
+
`credentialName`, `fireCredentialName` and model, say, or a dataset host's
|
|
132
|
+
`url`, `credentials` and `timeoutMs`. `cortex datasetHosts sync <id>` reads a host's manifest, and a
|
|
133
|
+
draft host publishes only after `datasetHosts test` reached it once.
|
|
134
|
+
|
|
135
|
+
## `cortex apply`
|
|
136
|
+
|
|
137
|
+
Makes Cortex match a manifest, in one transaction: what is new is
|
|
138
|
+
created, what changed is updated and republished, and what the manifest
|
|
139
|
+
created and does not list is deleted. Rows it did not create are never
|
|
140
|
+
touched, and a name one of them holds fails the apply.
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
cortex apply # ./cortex.manifest.ts
|
|
144
|
+
cortex apply deploy/manifest.json --dry-run
|
|
145
|
+
cortex apply -p prod
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The path defaults to exactly `./cortex.manifest.ts` in the directory you run
|
|
149
|
+
in. TypeScript and JSON load the same way: the file's default export is the
|
|
150
|
+
manifest. `defineManifest` from `@m6d/cortex` types one as you write it:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
import { defineManifest } from "@m6d/cortex";
|
|
154
|
+
|
|
155
|
+
export default defineManifest({
|
|
156
|
+
id: "shop",
|
|
157
|
+
tools: [
|
|
158
|
+
{
|
|
159
|
+
type: "http",
|
|
160
|
+
name: "findOrder",
|
|
161
|
+
description: "Find one order by id.",
|
|
162
|
+
url: "https://shop.example.com/orders/{orderId}",
|
|
163
|
+
method: "GET",
|
|
164
|
+
readOnly: true,
|
|
165
|
+
inputSchema: {
|
|
166
|
+
type: "object",
|
|
167
|
+
properties: { orderId: { type: "string" } },
|
|
168
|
+
required: ["orderId"],
|
|
169
|
+
},
|
|
170
|
+
audience: { agents: ["support"] },
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
An `openapi` source makes every operation of an OpenAPI document a tool the
|
|
177
|
+
manifest owns, so a backend with many endpoints needs no entry per tool:
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
openapi: [
|
|
181
|
+
{
|
|
182
|
+
name: "shop",
|
|
183
|
+
url: "https://shop.example.com/openapi.json",
|
|
184
|
+
credentials: [{ header: "Authorization", prefix: "Bearer ", credential: null }],
|
|
185
|
+
pinned: ["findOrder"],
|
|
186
|
+
// A GET runs at once; any other method waits for the end user's approval.
|
|
187
|
+
approval: { never: ["addOrderNote"], always: ["exportOrders"] },
|
|
188
|
+
audience: { agents: ["support"] },
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Every apply reads the document first, without the source's credentials. An
|
|
194
|
+
operation it adds is created, a changed one updated, and a dropped one
|
|
195
|
+
deleted. A source with credentials is read only over https, or from a host
|
|
196
|
+
the deployment allows, since the document says where they go. A source needs the `tools` write permission even when nothing
|
|
197
|
+
changes. Each tool is named after its `operationId`, made an identifier of at
|
|
198
|
+
most 64 characters; an operation Cortex cannot import is left
|
|
199
|
+
out. Two operations that come out with one name are told apart by a number
|
|
200
|
+
(`getOrders`, `getOrders2`) in the order of their paths. The apply fails
|
|
201
|
+
when `pinned` or `approval` names a tool no operation has (`unknown_tool`)
|
|
202
|
+
or any name such a collision decided (`ambiguous_tool`), since a path the
|
|
203
|
+
document adds or drops could move it to another endpoint. It also fails when an
|
|
204
|
+
operation's name is already a listed tool's or another source's.
|
|
205
|
+
|
|
206
|
+
The manifest is checked against the contract before anything is sent, then
|
|
207
|
+
sent as written, so Cortex fills its own defaults. It goes to the
|
|
208
|
+
management API (`manifests/sync`, or `manifests/preview` with `--dry-run`,
|
|
209
|
+
which changes nothing) under the same profile the management commands use, so
|
|
210
|
+
the key needs `publishing:publish` and the write permission of every kind the
|
|
211
|
+
apply changes. The output lists each changed entry under its kind: `+`
|
|
212
|
+
created, `~` updated, `-` deleted. A trigger the apply creates, or whose
|
|
213
|
+
`fireCredential` it drops, gets a fire secret, printed once below the summary
|
|
214
|
+
and never again.
|
|
215
|
+
|
|
216
|
+
References between entries (mentions, service scopes, which role a
|
|
217
|
+
credential or secret plays) are judged on the state the apply leaves, so
|
|
218
|
+
the order the manifest lists them in does not matter. A dataset host's
|
|
219
|
+
credentials are the exception: its catalog is read with them before the
|
|
220
|
+
apply, so they are judged on the deployment as it stands. A credential a
|
|
221
|
+
trigger fires with cannot go to a host in the same apply that drops
|
|
222
|
+
it; drop it first, then apply again.
|
|
125
223
|
|
|
126
224
|
## Global options
|
|
127
225
|
|
|
128
|
-
| Option
|
|
129
|
-
|
|
|
130
|
-
| `-v, --verbose`
|
|
131
|
-
| `-
|
|
132
|
-
| `-
|
|
133
|
-
|
|
134
|
-
`swagger` and `graph` read the project and take `-c, --config <path>` (default
|
|
135
|
-
`./cortex.config.ts`) on the group or the verb. `new` and `cc` do not touch a
|
|
136
|
-
project and have no such flag.
|
|
137
|
-
|
|
138
|
-
Config discovery is that exact filename in the directory you run in, with no upward search. There is
|
|
139
|
-
no `--cwd`: Bun auto-loads `.env` relative to the process cwd before any of our code runs, so
|
|
140
|
-
reading another directory's config from here would pair it with the wrong environment. `cd` first,
|
|
141
|
-
or point `--config` at the file.
|
|
142
|
-
|
|
143
|
-
The config is inert data — a plain object literal the CLI imports. Any key that is present but
|
|
144
|
-
evaluates to `undefined`, usually a missing environment variable, is listed by path and stops the
|
|
145
|
-
run.
|
|
146
|
-
|
|
147
|
-
`graph seed` runs standalone: it never constructs or serves your `@m6d/cortex-server` — it only
|
|
148
|
-
imports your `cortex.config.ts` (whose own imports may pull the server's modules in, inertly).
|
|
149
|
-
Its Neo4j client, its embedder and its `GRAPH_SCHEMA` come from the graph contract the server
|
|
150
|
-
reads the graph back with (each package vendors its own copy at pack time; the server re-exports
|
|
151
|
-
it) — one contract, shared from both ends. Seeding stamps the schema
|
|
152
|
-
version it wrote onto the graph; if that graph already carries a different one, the CLI says so and
|
|
153
|
-
seeds anyway, noting that nodes from the old schema are not removed. Skew is caught on the reading
|
|
154
|
-
side, where it matters: the server checks the stamp on its first resolve and refuses a graph it
|
|
155
|
-
cannot read.
|
|
156
|
-
|
|
157
|
-
`swagger` writes `.endpoint.ts` source whose generated block has to satisfy the server's own
|
|
158
|
-
`EndpointDef`, so a codegen that outran the installed version is a loud type error in your
|
|
159
|
-
`bun run check`.
|
|
160
|
-
|
|
161
|
-
Your `cortex.config.ts` imports `@m6d/cortex-server` for `defineAgent`, so a project without it
|
|
162
|
-
installed fails on the import — reported as an unloadable config, with the missing package named.
|
|
226
|
+
| Option | Description |
|
|
227
|
+
| ---------------------- | -------------------------------------------- |
|
|
228
|
+
| `-v, --verbose` | Print full errors and the commands being run |
|
|
229
|
+
| `-p, --profile <name>` | Which saved profile to use |
|
|
230
|
+
| `-V, --version` | Output the version number |
|
|
231
|
+
| `-h, --help` | Display help for command |
|
|
163
232
|
|
|
164
233
|
## Exit codes
|
|
165
234
|
|
|
166
|
-
| Command
|
|
167
|
-
|
|
|
168
|
-
| `new`
|
|
169
|
-
| `
|
|
170
|
-
| `
|
|
171
|
-
|
|
|
172
|
-
|
|
173
|
-
_Couldn't run_ means no config file, an unloadable config (a missing `@m6d/cortex-server` in the
|
|
174
|
-
project reads as one), undefined values in it, an absent domains directory, or an unreachable
|
|
175
|
-
Swagger host or Neo4j.
|
|
235
|
+
| Command | 0 | 1 |
|
|
236
|
+
| ------- | ---------------------------------------------------------- | --------------------------------------------------- |
|
|
237
|
+
| `new` | Files written — even if `bun install` failed | Bad target, missing name, cancelled |
|
|
238
|
+
| `setup` | Set up, or the server registered with no model to apply on | Not a project, or Cortex refused or was unreachable |
|
|
239
|
+
| `apply` | Applied, or previewed with `--dry-run` | Invalid manifest, or refused |
|
|
240
|
+
| others | The procedure ran | It failed, or couldn't run |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m6d/cortex-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Scaffold and
|
|
3
|
+
"version": "0.14.0",
|
|
4
|
+
"description": "Scaffold Cortex projects and manage a Cortex deployment",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"@clack/prompts": "^1.7.0",
|
|
25
25
|
"@commander-js/extra-typings": "^15.0.0",
|
|
26
26
|
"commander": "^15.0.0",
|
|
27
|
-
"picocolors": "^1.1.1"
|
|
27
|
+
"picocolors": "^1.1.1",
|
|
28
|
+
"zod": "^4.6.5"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@cortex/contracts": "workspace:*",
|
|
@@ -35,7 +36,17 @@
|
|
|
35
36
|
"access": "public"
|
|
36
37
|
},
|
|
37
38
|
"releaseWatchPaths": [
|
|
38
|
-
"
|
|
39
|
-
"packages/cortex-
|
|
39
|
+
"apps/cortex",
|
|
40
|
+
"packages/cortex-typescript",
|
|
41
|
+
"internal/contracts/src/client-tools",
|
|
42
|
+
"internal/contracts/src/datasets",
|
|
43
|
+
"internal/contracts/src/egress-policy",
|
|
44
|
+
"internal/contracts/src/errors",
|
|
45
|
+
"internal/contracts/src/json",
|
|
46
|
+
"internal/contracts/src/manifest",
|
|
47
|
+
"internal/contracts/src/manifest-file",
|
|
48
|
+
"internal/contracts/src/server",
|
|
49
|
+
"internal/contracts/src/triggers",
|
|
50
|
+
"internal/contracts/src/wire"
|
|
40
51
|
]
|
|
41
52
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { Command, Help } from "@commander-js/extra-typings";
|
|
2
2
|
|
|
3
3
|
import pkg from "../package.json";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { registerApply } from "@/commands/apply";
|
|
5
|
+
import { registerManagement } from "@/commands/management";
|
|
6
6
|
import { registerNew } from "@/commands/new";
|
|
7
|
-
import {
|
|
7
|
+
import { registerSetup } from "@/commands/setup";
|
|
8
8
|
import * as report from "@/ui/report";
|
|
9
9
|
|
|
10
10
|
const program = new Command()
|
|
11
11
|
.name("cortex")
|
|
12
|
-
.description("Scaffold and
|
|
12
|
+
.description("Scaffold Cortex projects and manage a Cortex deployment.")
|
|
13
13
|
.option("-v, --verbose", "Print full errors and the commands being run")
|
|
14
|
+
.option("-p, --profile <name>", "Which saved profile to use")
|
|
14
15
|
.version(pkg.version, "-V, --version", "Output the version number")
|
|
15
16
|
.helpOption("-h, --help", "Display help for command")
|
|
16
17
|
// The implicit `help [command]` would print as a third, ungrouped section and
|
|
@@ -19,25 +20,31 @@ const program = new Command()
|
|
|
19
20
|
// Commander appends ` [options]` to any command that has some. Left in, the
|
|
20
21
|
// first command to grow a flag widens the whole list and the two-group screen
|
|
21
22
|
// stops matching. `cortex <command> --help` lists them.
|
|
23
|
+
// Every command's help lists the root's options too, `--profile` among them.
|
|
22
24
|
.configureHelp({
|
|
25
|
+
showGlobalOptions: true,
|
|
23
26
|
subcommandTerm: function (cmd) {
|
|
24
27
|
return new Help().subcommandTerm(cmd).replace(" [options]", "");
|
|
25
28
|
},
|
|
26
29
|
})
|
|
27
|
-
.addHelpText(
|
|
30
|
+
.addHelpText(
|
|
31
|
+
"after",
|
|
32
|
+
"\nEvery other command comes from the Cortex you logged in to:\n`cortex <resource> <procedure>`. Run `cortex <resource> --help` to see a resource's.",
|
|
33
|
+
);
|
|
28
34
|
|
|
29
35
|
// Each command owns its help group, so the two headings survive these files being
|
|
30
36
|
// rewritten. Registration order fixes the order the groups print in.
|
|
31
37
|
registerNew(program);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// The
|
|
35
|
-
// before parsing; it looks at argv to decide whether it needs to
|
|
36
|
-
|
|
38
|
+
registerSetup(program);
|
|
39
|
+
registerApply(program);
|
|
40
|
+
// The management commands come from Cortex's API, so this one may fetch
|
|
41
|
+
// before parsing; it looks at argv to decide whether it needs to, which it
|
|
42
|
+
// does only when argv names none of the commands registered before it.
|
|
43
|
+
await registerManagement(program, process.argv.slice(2));
|
|
37
44
|
|
|
38
45
|
// Commander's own errors print and exit on their own, and every failure the
|
|
39
|
-
// commands predict goes through `report.fail`. Anything
|
|
40
|
-
// bug — in the CLI, or in
|
|
46
|
+
// commands predict goes through `report.fail`. Anything reaching here is a
|
|
47
|
+
// bug — in the CLI, or in Cortex — and it gets the same grammar
|
|
41
48
|
// rather than a raw Bun stack dump.
|
|
42
49
|
await program.parseAsync().catch(function (error: unknown) {
|
|
43
50
|
const verbose = program.opts().verbose === true;
|