arcane-os 0.22.0 → 0.23.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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.23.0
4
+
5
+ - Rename the mail configuration file to `.arcane.env.json`. Upgrade existing
6
+ deployments by renaming `.env.json` in the directory where the mail command
7
+ runs, preserving its contents. Mail commands now read only the selected new
8
+ name and report `storage: '.arcane.env.json'`.
9
+ - Keep configuration independent of the SDK installation directory, including
10
+ an SDK nested beneath the site root. Preserve provider profiles, relative TLS
11
+ paths, other JSON settings and HTTPS/HTTP2 port 4433. Update help, references,
12
+ the purpose-gate report and generated-workspace Git ignores.
13
+
14
+ ## 0.22.1
15
+
16
+ - Change the mail gateway's default HTTPS/HTTP2 port from 8025 to 4433 in
17
+ the CLI and server configuration. Preserve explicit port overrides and the
18
+ existing occupied-port message; update current help, references and gate report.
19
+
3
20
  ## 0.22.0
4
21
 
5
22
  - Export `generateDocumentImportMaps()` from `arcane-os` for explicitly selected
package/README.md CHANGED
@@ -19,12 +19,13 @@ version-locked SDK runtime, while an integrated Arcane checkout uses its live
19
19
  `arcane/` runtime. Both profiles preserve the same app URLs, theme, packaging,
20
20
  event, cancellation, and browser run contracts.
21
21
 
22
- This checkout defines the `0.22.0` SDK contract. Applications pin one exact npm
22
+ This checkout defines the `0.23.0` SDK contract. Applications pin one exact npm
23
23
  version and lockfile; registry state is deliberately not baked into application
24
24
  artifacts.
25
25
 
26
- The [mail gateway](docs/reference/mail.md) serves HTTPS with HTTP/2 on port 8025,
27
- using certificate paths from `.env.json`, and defaults browser mail to
26
+ The [mail gateway](docs/reference/mail.md) serves HTTPS with HTTP/2 on port 4433,
27
+ using certificate paths from `.arcane.env.json` in the command's working
28
+ directory, and defaults browser mail to
28
29
  `/v1/mail` on the current domain. Multiple applications can share
29
30
  one server with explicit allowed origins. Subscription verification is disabled
30
31
  until a `verifySubscription` callback is configured; that callback receives the
@@ -32,7 +32,7 @@ and exits nonzero on failure. Machine output is defined by
32
32
  | `arcane update-check` | Performs one explicit, read-only npm dist-tag query for the installed SDK version. |
33
33
  | `arcane targets` | Lists target ids, declared status, formats, architectures, signing profiles, methods, and pairing reason. |
34
34
  | `arcane repo status\|pull\|push` | Runs one selected repository operation for the current app workspace. |
35
- | `arcane mail key set\|status\|delete` | Manages one server-only Resend API-key profile in `.env.json`. |
35
+ | `arcane mail key set\|status\|delete` | Manages one server-only Resend API-key profile in `.arcane.env.json`. |
36
36
  | `arcane mail send` | Performs one explicit, idempotency-keyed Resend attempt from a complete JSON report on redirected stdin. |
37
37
  | `arcane mail serve` | Starts one Arcane-to-Resend gateway with a server-only provider profile, a selected listener, and optional CORS and recipient configuration. |
38
38
 
@@ -48,7 +48,7 @@ meaning and cardinality rules:
48
48
  | `--workspace` | directory | Commands that select an external or integrated workspace; defaults to `.`. |
49
49
  | `--app` | app id or label | Workspace/app operations except shared scope and `verify-bundle`; optional diagnostic label for `mail serve`. |
50
50
  | `--arcane-root` | directory | `doctor`, native `build`/`run`, `native-doctor`, `native-prepare` |
51
- | `--host` / `--port` | host / integer 0–65535 | Browser `dev`/`run` default to HTTPS at `127.0.0.1:8000`; `mail serve` defaults to HTTPS with HTTP/2 at `0.0.0.0:8025` and accepts an explicit bind host. |
51
+ | `--host` / `--port` | host / integer 0–65535 | Browser `dev`/`run` default to HTTPS at `127.0.0.1:8000`; `mail serve` defaults to HTTPS with HTTP/2 at `0.0.0.0:4433` and accepts an explicit bind host. |
52
52
  | `--http-port` | integer 0–65535 | Browser `dev`/`run` HTTP redirect listener; defaults to `0`, which selects an available port. |
53
53
  | `--public` | flag | `dev`; binds to `0.0.0.0` unless `--host` explicitly selects another address. |
54
54
  | `--http` | flag | `dev` only; serves source and PWA routes on one HTTP listener selected by `--port`, without TLS. |
@@ -814,7 +814,7 @@ npm exec -- arcane repo status
814
814
 
815
815
  ### Resend credential profiles
816
816
 
817
- The mail commands read `.env.json` from the invocation directory on Windows,
817
+ The mail commands read `.arcane.env.json` from the invocation directory on Windows,
818
818
  Linux, and macOS. The credential subcommands select one profile in that file:
819
819
 
820
820
  ```text
@@ -825,7 +825,7 @@ arcane mail key delete [profile]
825
825
 
826
826
  `key set` reads the Resend API key from a hidden terminal prompt. The
827
827
  `--secret-stdin` form is for deliberately redirected non-interactive input and
828
- rejects a TTY before reading. The key is written to `.env.json` and is never
828
+ rejects a TTY before reading. The key is written to `.arcane.env.json` and is never
829
829
  accepted in argv or returned in status output. The optional profile defaults
830
830
  to `mail`, which selects top-level `RESEND_API_KEY`. Any other exact profile
831
831
  selects `MAIL_PROFILES[profile].RESEND_API_KEY`, with no default-key fallback.
@@ -838,10 +838,10 @@ The minimal file is:
838
838
  }
839
839
  ```
840
840
 
841
- Fill in the key before starting mail, and add `.env.json` to the project's
841
+ Fill in the key before starting mail, and add `.arcane.env.json` to the project's
842
842
  `.gitignore`; the SDK repository already ignores it. Set and delete preserve
843
843
  the file's other settings and profiles. Status returns the selected profile,
844
- `provider:'resend'`, `storage:'.env.json'`, and `exists`. Delete returns
844
+ `provider:'resend'`, `storage:'.arcane.env.json'`, and `exists`. Delete returns
845
845
  `exists:false` for both a removed and an already-absent credential.
846
846
 
847
847
  Programmatic `createToolchain().mail(...)` resolves the configuration directory
@@ -852,6 +852,12 @@ Existing Windows Credential Manager records remain untouched; the JSON reader
852
852
  does not migrate or fall back to them. Mail reads JSON directly and does not
853
853
  populate or depend on process environment variables for this key.
854
854
 
855
+ The SDK's installation directory does not affect this location. With an SDK
856
+ under `my-site/arcane-os-sdk/`, run the command from `my-site/` and keep
857
+ `my-site/.arcane.env.json` alongside that directory. Existing deployments using
858
+ SDK 0.22.1 or earlier must rename `.env.json` to `.arcane.env.json` while
859
+ preserving its contents; the loader reads only the new name.
860
+
855
861
  Missing files or missing/empty selected keys stop `send` and `serve` with the
856
862
  configuration path and exact JSON setting to fill in. Invalid JSON and file
857
863
  access failures remain observable without printing credential content.
@@ -887,7 +893,7 @@ Resend owns their accepted shape. The adapter removes the application-only
887
893
  `type` field and applies `--from` when supplied; otherwise the report or provider
888
894
  template supplies the sender. Direct CLI sending has
889
895
  no configured fallback recipients. The Resend credential comes only from the
890
- selected `.env.json` profile; omitting `--profile` selects `mail`. Neither the
896
+ selected `.arcane.env.json` profile; omitting `--profile` selects `mail`. Neither the
891
897
  key nor report content is accepted through argv or process environment variables.
892
898
 
893
899
  The caller owns the nonempty `--report-key`, which is forwarded unchanged.
@@ -909,10 +915,10 @@ loss after the attempt begins is ambiguous because Resend may have accepted it.
909
915
  `mail serve` starts one owned HTTPS gateway with HTTP/2:
910
916
 
911
917
  ```text
912
- arcane mail serve [--profile <profile>] [--from <verified-sender>] [--app <label>] [--origin <exact-origin>] [--allow-to <addresses>] [--host 0.0.0.0] [--port 8025] [--request-timeout <ms>]
918
+ arcane mail serve [--profile <profile>] [--from <verified-sender>] [--app <label>] [--origin <exact-origin>] [--allow-to <addresses>] [--host 0.0.0.0] [--port 4433] [--request-timeout <ms>]
913
919
  ```
914
920
 
915
- The selected `.env.json` profile supplies only the server-side Resend API key;
921
+ The selected `.arcane.env.json` profile supplies only the server-side Resend API key;
916
922
  omitting `--profile` selects `mail`.
917
923
 
918
924
  Add the listener's certificate configuration at the top level of the same file:
@@ -926,15 +932,15 @@ Add the listener's certificate configuration at the top level of the same file:
926
932
  ```
927
933
 
928
934
  Supply an existing PEM certificate chain and its private key. Paths resolve
929
- relative to `.env.json`, or may be absolute. They are shared across provider
935
+ relative to `.arcane.env.json`, or may be absolute. They are shared across provider
930
936
  profiles. Missing TLS settings name the fields to fill in before a listener
931
937
  opens; the TLS owner reports PEM file errors. Keep private-key material outside
932
- tracked source. The SDK repository already ignores `.arcane/` and `.env.json`.
938
+ tracked source. The SDK repository already ignores `.arcane/` and `.arcane.env.json`.
933
939
 
934
940
  The selected `node-http-server` module negotiates HTTP/2 with HTTP/1.1 fallback
935
- on the same HTTPS port, default `8025`, with no plain-HTTP listener. Callers use
941
+ on the same HTTPS port, default `4433`, with no plain-HTTP listener. Callers use
936
942
  a hostname covered by the certificate, such as
937
- `https://mail.example.com:8025/v1/mail`; `0.0.0.0` identifies the bind address.
943
+ `https://mail.example.com:4433/v1/mail`; `0.0.0.0` identifies the bind address.
938
944
  Restart the gateway after replacing renewed certificate files. Certificate
939
945
  issuance and renewal remain with the deployment's certificate owner.
940
946
 
@@ -13,7 +13,7 @@ gateway and is never included in browser or WebAssembly state.
13
13
  | `MailTransport.mjs` | Browser, WebView, or compatible Fetch host | Sends one already-persisted request to the configured Arcane gateway with the stable report key as its idempotency key. |
14
14
  | `arcane mail send` | Node on the local machine | Reads one complete provider-neutral report from redirected stdin and performs one explicit Resend attempt with a caller-owned idempotency key. |
15
15
  | `arcane mail serve` | Node on the configured host | Owns caller verification, protects the provider credential, applies explicitly configured recipient and origin settings, and makes one server-side Resend request. |
16
- | `arcane mail key ...` | Node on Windows, Linux, or macOS | Stores, inspects, or deletes a Resend API key in the selected `.env.json`. |
16
+ | `arcane mail key ...` | Node on Windows, Linux, or macOS | Stores, inspects, or deletes a Resend API key in the selected `.arcane.env.json`. |
17
17
 
18
18
  The browser never receives the Resend API key. The gateway never writes that
19
19
  key to source, argv, logs, events, fixtures, browser storage, or its public
@@ -56,7 +56,7 @@ browser import while preserving one shared CLI/toolchain implementation.
56
56
  Arcane Mail deliberately separates two credentials:
57
57
 
58
58
  - The **Resend API key** is provider authority. The Node process reads it from
59
- `.env.json`. `arcane mail key set [profile]` can store it there through hidden
59
+ `.arcane.env.json`. `arcane mail key set [profile]` can store it there through hidden
60
60
  input; `mail send` and `mail serve` read the selected profile inside that process.
61
61
  - The **subscription key** is the application user's subscription credential.
62
62
  When present, the browser sends it as `Authorization: Bearer <subscriptionKey>`,
@@ -272,7 +272,7 @@ committed acceptance result.
272
272
 
273
273
  ## Operate the CLI and gateway
274
274
 
275
- Create `.env.json` in the directory from which the mail command runs, then fill
275
+ Create `.arcane.env.json` in the directory from which the mail command runs, then fill
276
276
  in the provider key and the HTTPS certificate paths:
277
277
 
278
278
  ```json
@@ -283,7 +283,7 @@ in the provider key and the HTTPS certificate paths:
283
283
  }
284
284
  ```
285
285
 
286
- The SDK repository ignores `.env.json`. Keep the same entry in a consuming
286
+ The SDK repository ignores `.arcane.env.json`. Keep the same entry in a consuming
287
287
  project's `.gitignore`. This is a JSON configuration file; the mail commands
288
288
  read it directly without copying its contents into `process.env`.
289
289
 
@@ -306,12 +306,33 @@ An absent named profile does not fall back to the default key. The profile
306
306
  selects Resend provider credentials; it is separate from the incoming
307
307
  application name and subscriber key.
308
308
 
309
- Programmatic operations resolve `.env.json` from `options.cwd`, then
309
+ Programmatic operations resolve `.arcane.env.json` from `options.cwd`, then
310
310
  `options.workspaceRoot`, then `process.cwd()`, choosing the first supplied
311
311
  directory. The CLI uses its invocation directory. There is no upward directory
312
312
  search or dependency on a Windows installation directory or temporary-directory
313
313
  environment variable.
314
314
 
315
+ Keep the configuration in the deployment directory even when the SDK is nested
316
+ below it:
317
+
318
+ ```text
319
+ my-site/
320
+ ├── .arcane.env.json
321
+ └── arcane-os-sdk/
322
+ └── bin/arcane.mjs
323
+ ```
324
+
325
+ Run from `my-site`, for example:
326
+
327
+ ```sh
328
+ node ./arcane-os-sdk/bin/arcane.mjs mail serve --port 4433
329
+ ```
330
+
331
+ The SDK directory does not choose the configuration location. When upgrading
332
+ from SDK 0.22.1 or earlier, rename the existing `.env.json` to
333
+ `.arcane.env.json` in the invocation directory, preserving its contents.
334
+ The loader reads only `.arcane.env.json`.
335
+
315
336
  The existing key commands manage the same file:
316
337
 
317
338
  ```text
@@ -324,7 +345,7 @@ arcane mail key delete
324
345
  non-interactive alternative and rejects a TTY. Each command accepts an optional
325
346
  profile argument, defaulting to `mail`. Set and delete preserve other JSON
326
347
  settings and profiles; status reports existence without returning the key.
327
- Results identify `storage: '.env.json'`. An already-absent deletion succeeds
348
+ Results identify `storage: '.arcane.env.json'`. An already-absent deletion succeeds
328
349
  with `exists: false`.
329
350
 
330
351
  Existing Windows Credential Manager records remain untouched. The JSON path
@@ -364,10 +385,10 @@ deadline.
364
385
  Start the gateway:
365
386
 
366
387
  ```text
367
- npm exec -- arcane mail serve --profile mail --host 0.0.0.0 --port 8025
388
+ npm exec -- arcane mail serve --profile mail --host 0.0.0.0 --port 4433
368
389
  ```
369
390
 
370
- The default listener is `0.0.0.0:8025`; `--host` and `--port` select its bind
391
+ The default listener is `0.0.0.0:4433`; `--host` and `--port` select its bind
371
392
  address and port. The server can serve callers from multiple domains on the
372
393
  same machine. Route the page's `/v1/mail` to this listener, or configure an
373
394
  explicit shared endpoint in the caller.
@@ -376,12 +397,12 @@ explicit shared endpoint in the caller.
376
397
  `node-http-server` PEM API owns TLS and negotiates HTTP/2 or HTTP/1.1 on the
377
398
  same listener. It creates no additional plain-HTTP listener. The returned URL
378
399
  uses `https://`; `0.0.0.0` is the bind address, so callers use the deployed
379
- domain, for example `https://mail.example.com:8025/v1/mail`.
400
+ domain, for example `https://mail.example.com:4433/v1/mail`.
380
401
 
381
402
  Set `MAIL_TLS_CERT_PATH` to the PEM certificate chain and `MAIL_TLS_KEY_PATH`
382
403
  to its PEM private-key file. These top-level settings belong to the listener
383
404
  and apply regardless of the selected provider profile. Relative paths resolve
384
- from the directory containing `.env.json`; absolute paths are also accepted.
405
+ from the directory containing `.arcane.env.json`; absolute paths are also accepted.
385
406
  The certificate must cover the hostname callers use. One certificate may
386
407
  cover multiple names; the gateway does not require one certificate per calling
387
408
  application. Keep private-key files outside tracked source, such as in the
@@ -1,10 +1,10 @@
1
- [Roshi's Codex PRIME] The gateway review and its portable credential follow-up apply the same three purpose gates. The gateway removals preserve complete delivery outcomes, configured CORS and recipient policy, and the optional subscription verifier. Mail credentials now belong in the user-selected `.env.json`, with one portable Node implementation for Windows, Linux, and macOS and a compatible Node host as the Android adaptation boundary. The original gateway inventory below uses baseline `f055e05`; the credential follow-up reviews the Windows storage implementation present at SDK `0.18.0`. Commit, package, publication, and actual platform execution outcomes belong to the delivery record rather than to this source-review report.
1
+ [Roshi's Codex PRIME] The gateway review and its portable credential follow-up apply the same three purpose gates. The gateway removals preserve complete delivery outcomes, configured CORS and recipient policy, and the optional subscription verifier. Mail credentials now belong in the user-selected `.arcane.env.json`, with one portable Node implementation for Windows, Linux, and macOS and a compatible Node host as the Android adaptation boundary. The original gateway inventory below uses baseline `f055e05`; the credential follow-up reviews the Windows storage implementation present at SDK `0.18.0`. Commit, package, publication, and actual platform execution outcomes belong to the delivery record rather than to this source-review report.
2
2
 
3
3
  | Decision | Behavior | Why it matters | Source status at this review |
4
4
  | --- | --- | --- | --- |
5
5
  | Remove | Loopback-only admission, manual header reconstruction, address/origin normalization, local payload grammar, manual content-length scan, dead queue knobs | These restrict supported use, rewrite supplied values, or repeat work already owned elsewhere. | Removed from the inspected source; naming-only changes carry no runtime claim. |
6
6
  | Remove and replace | Local app-key hashes and X-Mail-Key authentication | The selected application plus bearer subscription contract needs an actual verifier, not a local shared-key comparison. | Removed. Optional `verifySubscription` implements the local integration contract; the remote endpoint adapter remains future work. Initial setup without that callback performs no caller authentication. |
7
- | Remove and replace | Windows-only credential process, native interop, helper timers, environment prerequisites, encoding and input/output limits | They prevent the required portable startup and perform work absent from the selected JSON storage path. | Replaced by direct `.env.json` access. Existing Windows credential records remain untouched. Default and named credential operations remain useful and are preserved. |
7
+ | Remove and replace | Windows-only credential process, native interop, helper timers, environment prerequisites, encoding and input/output limits | They prevent the required portable startup and perform work absent from the selected JSON storage path. | Replaced by direct `.arcane.env.json` access. Existing Windows credential records remain untouched. Default and named credential operations remain useful and are preserved. |
8
8
  | Simplify | Exact CORS policy, one configuration resolution, one provider request construction/serialization, optional observation | Preserve the intended result while eliminating repeated parsing, copies, policy structures, and absent-observer work. | Present in inspected source. Explicit nonempty origin lists remain authoritative; otherwise the nominal-domain default applies. |
9
9
  | Keep | Configured subscription authentication, explicit recipient policy/fallback, stable idempotency, real cancellation/deadlines, complete provider outcomes, concurrent requests and owned shutdown | These have concrete callers and determine whether mail is sent, retried, reported honestly, or stopped correctly. | Retained. Only a verifier result of `true` permits authenticated delivery; failures and cancellation prevent the provider attempt. |
10
10
 
@@ -35,7 +35,7 @@ The latest user-selected boundaries govern this review:
35
35
  - Explicit recipient allowlists and error-recipient fallback remain. A configured nonempty allowlist covers resolved `to`, `cc`, and `bcc` recipients; allowing additional provider fields must not bypass the selected recipient policy. With no allowlist, the policy performs no recipient scan. Per-address trimming, lowercasing, and local email grammar do not remain.
36
36
  - Caller-selected deadlines, the cancellation adapter, complete provider outcomes, retry classification, stable idempotency, and independently constructed snapshots for emitted observations remain. Shared mutable provider snapshots have not been selected.
37
37
  - Remove manual response content-length scanning, duplicate configuration/CORS construction, unobserved event payload creation, unused `allowZero`, and unused CLI queue options.
38
- - All SDK mail operations require a functional Windows, Linux, and macOS path, with Android adaptation at the host boundary. Read provider configuration directly from an ignored `.env.json`; an operating-system limitation notice does not satisfy the portable requirement. Default profile `mail` uses `RESEND_API_KEY`; other exact names use `MAIL_PROFILES[profile].RESEND_API_KEY`. Missing configuration must identify the file and setting to fill in. Existing Windows records remain untouched, without an automatic read or migration.
38
+ - All SDK mail operations require a functional Windows, Linux, and macOS path, with Android adaptation at the host boundary. Read provider configuration directly from an ignored `.arcane.env.json`; an operating-system limitation notice does not satisfy the portable requirement. Default profile `mail` uses `RESEND_API_KEY`; other exact names use `MAIL_PROFILES[profile].RESEND_API_KEY`. Missing configuration must identify the file and setting to fill in. Existing Windows records remain untouched, without an automatic read or migration.
39
39
 
40
40
  Source inspection during this report's handoff shows local app/email/sender/API-key format validators and loopback admission removed; origin values retained in one Set; complete provider JSON values or raw response text preserved; template-shaped provider requests no longer required to supply local text/HTML fields; and configuration passed once into `createConfiguredMailHandler`. Observer objects, pending Sets, callback closures, event payload reconstruction, and drain waits are absent when `onEvent` is omitted. An already-cancelled direct send stops before provider payload construction or serialization. Response writing no longer calculates content length. The fixed `/v1/mail` route accepts its query-bearing form, matching the portable endpoint parser. These are source observations, not executed behavior.
41
41
 
@@ -52,7 +52,7 @@ Configuration and foundational methods follow. Each baseline name is recorded so
52
52
  | `positiveInteger` | Resolves the retry delay; baseline exposes unused `allowZero`. | Y/Y/Y — Simplify. | The uncalled zero branch and its extra option/prose are removed. Current name: `readRetryDelayMs`, which resolves the actual retry-delay setting. |
53
53
  | `optionalTimeoutMs` | Reads body/provider deadlines only when supplied. | Y/Y/N — Keep. | Omitting a deadline produces no timer. Node timer-range handling prevents caller-selected delays from changing meaning. Current name remains `optionalTimeoutMs`. |
54
54
  | `normalizeRetryAfter` | Error and result constructors keep a usable retry delay. | Y/Y/N — Keep. | Retry scheduling consumes this value. It is control metadata, not a transformation of message content. Current name: `retryDelayOrZero`. |
55
- | `portNumber` | Startup resolves default or configured port, including ephemeral port zero. | Y/Y/Y — Remove wrapper; retain configuration value. | The HTTP owner handles actual port binding. Preserve default 8025 and explicit port zero; no extra port validator or domain policy is required. |
55
+ | `portNumber` | Startup resolves default or configured port, including ephemeral port zero. | Y/Y/Y — Remove wrapper; retain configuration value. | The HTTP owner handles actual port binding. Use the selected default 4433 and preserve explicit port zero; no extra port validator or domain policy is required. |
56
56
  | `validateSignal` | Direct send and server options accept caller cancellation. | Y/Y/Y — Remove wrapper; retain original signal. | Native signal operations already own their contract. Cancellation controllers/listeners and the abortable adapter remain. |
57
57
  | `validateApiKey` | Provider configuration supplies the credential used by Resend Fetch. | Y/Y/Y — Remove local format validator. | CLI credential retrieval reports missing provider credentials; Fetch/provider own actual transport validity. Never echo the credential. |
58
58
  | `validateAppId` | Validates application identity using the old lowercase-slug grammar. | Y/Y/Y — Remove the grammar and closed-list/equality admission. | Per-request identity matters and remains an ordinary string. Any application may use the shared server. Read the supplied identity for subscription verification without rewriting it; no standalone wrapper is needed solely to restrict spelling. |
@@ -311,7 +311,7 @@ The coupled CLI/browser actions below are necessary to avoid leaving contradicto
311
311
 
312
312
  | Coupled path/action | Gates and decision | Required result and evidence boundary |
313
313
  | --- | --- | --- |
314
- | `src/mail.mjs` `serveMail` old hidden app-key input and local auth options | Y/Y/Y — Reconciled with the optional verifier contract. | Obsolete shared-app-key prompt/options are removed. Current `serveMailGateway` forwards `options.verifySubscription` to the server and keeps provider credential operations and the provider API key separate. The portable follow-up resolves that provider credential from `.env.json`. |
314
+ | `src/mail.mjs` `serveMail` old hidden app-key input and local auth options | Y/Y/Y — Reconciled with the optional verifier contract. | Obsolete shared-app-key prompt/options are removed. Current `serveMailGateway` forwards `options.verifySubscription` to the server and keeps provider credential operations and the provider API key separate. The portable follow-up resolves that provider credential from `.arcane.env.json`. |
315
315
  | `src/mail.mjs` `recipientList` and origin list preparation | Y/Y/Y — Remove redundant rewriting, preserve configured policy values. | Gateway and CLI must not disagree about preserved recipients/origins. An exact allowlist is still an intentional policy. |
316
316
  | `src/mail.mjs` `withoutMailCredentials` | N/N/Y for recursive payload-key redaction — Remove. | It recursively traversed/copied complete results and deleted any content property named `apiKey` or `appKey`, including ordinary user payload fields. Keep actual transport credentials outside constructed public results at their owning boundary; do not rewrite the report based on property names. Source inspection shows this traversal removed. |
317
317
  | `src/mail.mjs` `completeSendFailure` | Y/Y/Y — Remove helper after preserving the complete result directly. | Failure output still contains the provider result, or a narrow wrapper for a non-object injected result. No recursive copying/redaction pass remains. |
@@ -378,7 +378,7 @@ Existing native credential records are neither read nor changed.
378
378
  | `setMailCredential`, `readMailCredential`, `getMailCredentialStatus`, `deleteMailCredential` | Y/Y/Y | Preserve all four operations and replace their implementation. Explicit set/delete update only the selected credential field while preserving other settings and profiles; read returns the selected key or null; status reports existence. File access uses portable Node APIs. |
379
379
  | `mailCredentialOptions`, `readMailProviderKey` | Y/Y/Y | Keep shared command configuration and consolidate the real send/serve duplicate key-read error path. Remove Windows runner, helper directory, and helper timeout forwarding. Missing configuration names the exact JSON setting and file before opening a listener or attempting delivery. |
380
380
  | CLI required profile flag and omitted invocation directory | Y/Y/Y | Make the profile optional with default `mail`, retaining explicit profiles. Forward the invocation directory through every mail operation, so the CLI reads the operator's selected file. Preserve hidden/stdin key entry and existing send/serve lifecycle. |
381
- | Repository and workspace-template `.gitignore` entry | Y/Y/N | Keep `.env.json` out of source control in this checkout and newly generated workspaces. The populated local file is outside the committed and published change. |
381
+ | Repository and workspace-template `.gitignore` entry | Y/Y/N | Keep `.arcane.env.json` out of source control in this checkout and newly generated workspaces. The populated local file is outside the committed and published change. |
382
382
 
383
383
  The credential path performs one file read per selected operation and one write
384
384
  only for an explicit set or a deletion that finds a credential. Startup reads
@@ -395,14 +395,14 @@ cancellation before writes, and CLI defaults. Local tests and checks were not ru
395
395
  ## HTTPS and HTTP/2 follow-up
396
396
 
397
397
  The user explicitly selected HTTPS with HTTP/2. The mail listener remains on
398
- its dedicated configured port, default 8025, with the published
398
+ its dedicated configured port, now default 4433, with the published
399
399
  `node-http-server` module owning TLS, protocol negotiation and listener/session
400
400
  shutdown. This increment preserves the provider attempt, report content,
401
401
  subscription callback, sender selection, recipient configuration and cancellation.
402
402
 
403
403
  | Method or action | Gates | Decision, callers, and concrete purpose |
404
404
  | --- | --- | --- |
405
- | `readMailServerSettings` | Y/Y/N | Read the same `.env.json` once for server startup, select the existing provider profile and resolve the two shared PEM path settings relative to that file. This avoids a second configuration read and platform-specific credential or certificate processes. |
405
+ | `readMailServerSettings` | Y/Y/N | Read the same `.arcane.env.json` once for server startup, select the existing provider profile and resolve the two shared PEM path settings relative to that file. This avoids a second configuration read and platform-specific credential or certificate processes. |
406
406
  | `readMailProviderKey` and `serveMailGateway` | Y/Y/N | Preserve the existing credential-injection interface and missing-provider error while consuming the already-read startup key. Require the selected TLS pair before binding; forward only the paths to the listener. Direct provider sending and key CRUD remain unchanged. |
407
407
  | `MAIL_TLS_CERT_PATH` and `MAIL_TLS_KEY_PATH` | Y/Y/N | Clear top-level names identify certificate and private-key file paths for one listener, independently of any provider profile or calling application. Missing settings and unusable JSON values name the field without printing its content. |
408
408
  | `startResendMailServer` TLS options | Y/Y/N | Add `certPath` and `keyPath` through the module's published PEM API. HTTPS-only mode creates one listener with HTTP/2 and HTTP/1.1 negotiation on the selected port. This internal source integration retains its existing HTTP behavior when neither path is supplied; it is not an npm package export. The public toolchain mail operation requires the JSON pair. |
@@ -423,3 +423,37 @@ JSON paths and missing TLS settings. Synthetic TLS selection is not evidence of
423
423
  an encrypted handshake. No local tests, checks, server launch, real TLS
424
424
  negotiation or provider send were performed for this follow-up review. Selected
425
425
  package and publication results belong to the delivery record.
426
+
427
+ ## Main mail port follow-up
428
+
429
+ The user selected 4433 as the main mail-server port. Both the CLI's omitted-port
430
+ setting and the server's programmatic default now select 4433. Explicit ports,
431
+ including ephemeral port zero, continue through the existing configuration.
432
+
433
+ The port setting passes Y/Y/N: the listener needs a bind port, deployments need
434
+ an override, and removing either would lose required behavior. Changing the two
435
+ defaults adds no runtime work or helper. TLS negotiation, the returned endpoint
436
+ and the occupied-port message already use the selected port. Existing test
437
+ source was updated for the omitted-port path; explicit-port cases were retained.
438
+ No local tests, checks or server launch were performed for this increment.
439
+
440
+ ## Deployment configuration filename follow-up
441
+
442
+ The user selected `.arcane.env.json` in the command's invocation directory,
443
+ independently of a nested SDK directory. `mailCredentialLocation` remains the
444
+ single filename owner for key operations, direct sending and server startup;
445
+ `mailCredentialStatus` reports the same new name. The directory precedence and
446
+ relative certificate-path resolution remain unchanged.
447
+
448
+ The filename change passes Y/Y/N: its name identifies Arcane configuration,
449
+ deployment ownership makes the location useful, and removing that configuration
450
+ would lose the provider and TLS settings. Additional filename fallbacks, upward
451
+ searches and automatic migrations fail N/N/Y and are omitted. This rename adds
452
+ no read, timer, helper or per-request work. Existing deployments rename their
453
+ file with its contents intact when adopting SDK 0.23.0. Repository and generated
454
+ workspace ignores include the new name and retain the old entry for existing
455
+ private files. Only the intended filename and status contract change; mail
456
+ payloads, profiles, other settings and lifecycle remain unchanged.
457
+
458
+ Existing credential and CLI test fixtures now use the selected name. Source
459
+ and diff were reviewed; local tests, checks and server execution were not run.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-os",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
5
5
  "type": "module",
6
6
  "main": "./src/index.mjs",
package/src/cli/main.mjs CHANGED
@@ -85,8 +85,8 @@ Usage:
85
85
  ${CLI_NAME} mail key status [profile]
86
86
  ${CLI_NAME} mail key delete [profile]
87
87
  ${CLI_NAME} mail send [--profile <profile>] [--from <address>] --report-key <id> --report-stdin [--request-timeout <ms>]
88
- ${CLI_NAME} mail serve [--profile <profile>] [--from <address>] [--app <label>] [--origin <origin>] [--allow-to <addresses>] [--host 0.0.0.0] [--port 8025] [--request-timeout <ms>]
89
- HTTPS/HTTP2; .env.json supplies RESEND_API_KEY, MAIL_TLS_CERT_PATH, and MAIL_TLS_KEY_PATH.
88
+ ${CLI_NAME} mail serve [--profile <profile>] [--from <address>] [--app <label>] [--origin <origin>] [--allow-to <addresses>] [--host 0.0.0.0] [--port 4433] [--request-timeout <ms>]
89
+ HTTPS/HTTP2; .arcane.env.json supplies RESEND_API_KEY, MAIL_TLS_CERT_PATH, and MAIL_TLS_KEY_PATH.
90
90
 
91
91
  Development:
92
92
  --public Bind dev to all IPv4 interfaces (0.0.0.0) and print network URLs.
@@ -698,7 +698,7 @@ function operationOptions(command,parsed,cwd){
698
698
  origin:values.origin,
699
699
  allowTo:values['allow-to'],
700
700
  host:values.host??'0.0.0.0',
701
- port:readPort(values.port,8025),
701
+ port:readPort(values.port,4433),
702
702
  requestTimeout:readMailRequestTimeout(values['request-timeout']),
703
703
  };
704
704
  }
@@ -11,7 +11,7 @@ export function mailCredentialLocation(options={}){
11
11
  throw new ArcaneError(ERROR_CODES.usage,'Mail credential profile must be a nonempty string.');
12
12
  }
13
13
  return {
14
- filePath:path.resolve(options.cwd??options.workspaceRoot??process.cwd(),'.env.json'),
14
+ filePath:path.resolve(options.cwd??options.workspaceRoot??process.cwd(),'.arcane.env.json'),
15
15
  profile,
16
16
  setting:profile==='mail'?'RESEND_API_KEY':`MAIL_PROFILES[${JSON.stringify(profile)}].RESEND_API_KEY`
17
17
  };
@@ -79,7 +79,7 @@ function configuredMailKey(settings,location){
79
79
  }
80
80
 
81
81
  function mailCredentialStatus(profile,exists){
82
- return {profile,provider:'resend',storage:'.env.json',exists};
82
+ return {profile,provider:'resend',storage:'.arcane.env.json',exists};
83
83
  }
84
84
 
85
85
  export async function setMailCredential(options={}){
@@ -113,7 +113,7 @@ function resolveMailServerConfiguration(options={}){
113
113
  host:options.host??'0.0.0.0',
114
114
  callerAuthentication:options.verifySubscription?'subscription':'none',
115
115
  onEvent:options.onEvent,
116
- port:options.port??8025,
116
+ port:options.port??4433,
117
117
  providerTimeoutMs:optionalTimeoutMs(options.providerTimeoutMs,'providerTimeoutMs'),
118
118
  requestIdFactory:options.requestIdFactory??randomUUID,
119
119
  retryableDelayMs:readRetryDelayMs(options.retryableDelayMs),
@@ -133,6 +133,7 @@ appropriate.
133
133
  'build/',
134
134
  '.arcane/',
135
135
  '.env.json',
136
+ '.arcane.env.json',
136
137
  '*.log',
137
138
  ''
138
139
  ].join('\n'));