@north-light/api 0.0.0-stage → 0.3.414
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 +18 -0
- package/README.md +66 -2
- package/dist/api/__tests__/error-codes.test.d.ts +1 -0
- package/dist/api/__tests__/error-codes.test.js +79 -0
- package/dist/api/__tests__/integration/client.test.d.ts +1 -0
- package/dist/api/__tests__/integration/client.test.js +276 -0
- package/dist/api/client.d.ts +501 -0
- package/dist/api/client.js +1281 -0
- package/dist/api/command-manifest/index.d.ts +3 -0
- package/dist/api/command-manifest/index.js +3 -0
- package/dist/api/command-manifest/manifest.d.ts +51 -0
- package/dist/api/command-manifest/manifest.js +332 -0
- package/dist/api/command-manifest/result.d.ts +25 -0
- package/dist/api/command-manifest/result.js +97 -0
- package/dist/api/command-manifest/schema.d.ts +28 -0
- package/dist/api/command-manifest/schema.js +856 -0
- package/dist/api/dto/analytics.d.ts +184 -0
- package/dist/api/dto/analytics.js +3 -0
- package/dist/api/dto/attach.d.ts +22 -0
- package/dist/api/dto/attach.js +13 -0
- package/dist/api/dto/bash-jobs.d.ts +24 -0
- package/dist/api/dto/bash-jobs.js +9 -0
- package/dist/api/dto/bash.d.ts +17 -0
- package/dist/api/dto/bash.js +1 -0
- package/dist/api/dto/broker-ops.d.ts +187 -0
- package/dist/api/dto/broker-ops.js +6 -0
- package/dist/api/dto/broker-signals.d.ts +25 -0
- package/dist/api/dto/broker-signals.js +1 -0
- package/dist/api/dto/broker.d.ts +86 -0
- package/dist/api/dto/broker.js +20 -0
- package/dist/api/dto/canvas.d.ts +359 -0
- package/dist/api/dto/canvas.js +2 -0
- package/dist/api/dto/chat-inventory.d.ts +56 -0
- package/dist/api/dto/chat-inventory.js +11 -0
- package/dist/api/dto/common.d.ts +29 -0
- package/dist/api/dto/common.js +15 -0
- package/dist/api/dto/config.d.ts +46 -0
- package/dist/api/dto/config.js +3 -0
- package/dist/api/dto/crons.d.ts +158 -0
- package/dist/api/dto/crons.js +10 -0
- package/dist/api/dto/custom-objects.d.ts +66 -0
- package/dist/api/dto/custom-objects.js +1 -0
- package/dist/api/dto/delivery.d.ts +71 -0
- package/dist/api/dto/delivery.js +7 -0
- package/dist/api/dto/docs.d.ts +135 -0
- package/dist/api/dto/docs.js +8 -0
- package/dist/api/dto/files.d.ts +21 -0
- package/dist/api/dto/files.js +1 -0
- package/dist/api/dto/focus.d.ts +24 -0
- package/dist/api/dto/focus.js +10 -0
- package/dist/api/dto/grants.d.ts +28 -0
- package/dist/api/dto/grants.js +1 -0
- package/dist/api/dto/health.d.ts +116 -0
- package/dist/api/dto/health.js +2 -0
- package/dist/api/dto/human-requests.d.ts +113 -0
- package/dist/api/dto/human-requests.js +4 -0
- package/dist/api/dto/human.d.ts +28 -0
- package/dist/api/dto/human.js +4 -0
- package/dist/api/dto/inbox.d.ts +273 -0
- package/dist/api/dto/inbox.js +4 -0
- package/dist/api/dto/lifecycle.d.ts +88 -0
- package/dist/api/dto/lifecycle.js +3 -0
- package/dist/api/dto/limits.d.ts +29 -0
- package/dist/api/dto/limits.js +2 -0
- package/dist/api/dto/mail.d.ts +44 -0
- package/dist/api/dto/mail.js +1 -0
- package/dist/api/dto/messages.d.ts +104 -0
- package/dist/api/dto/messages.js +2 -0
- package/dist/api/dto/model-config.d.ts +25 -0
- package/dist/api/dto/model-config.js +1 -0
- package/dist/api/dto/modelauth.d.ts +132 -0
- package/dist/api/dto/modelauth.js +4 -0
- package/dist/api/dto/node-events.d.ts +65 -0
- package/dist/api/dto/node-events.js +4 -0
- package/dist/api/dto/node-outcomes.d.ts +88 -0
- package/dist/api/dto/node-outcomes.js +2 -0
- package/dist/api/dto/node-records.d.ts +35 -0
- package/dist/api/dto/node-records.js +5 -0
- package/dist/api/dto/nodes.d.ts +371 -0
- package/dist/api/dto/nodes.js +3 -0
- package/dist/api/dto/objects.d.ts +172 -0
- package/dist/api/dto/objects.js +5 -0
- package/dist/api/dto/profiles.d.ts +117 -0
- package/dist/api/dto/profiles.js +4 -0
- package/dist/api/dto/recovery.d.ts +104 -0
- package/dist/api/dto/recovery.js +1 -0
- package/dist/api/dto/reports.d.ts +95 -0
- package/dist/api/dto/reports.js +2 -0
- package/dist/api/dto/review-comments.d.ts +146 -0
- package/dist/api/dto/review-comments.js +5 -0
- package/dist/api/dto/reviews.d.ts +113 -0
- package/dist/api/dto/reviews.js +5 -0
- package/dist/api/dto/run-events.d.ts +295 -0
- package/dist/api/dto/run-events.js +6 -0
- package/dist/api/dto/structured-requests.d.ts +64 -0
- package/dist/api/dto/structured-requests.js +5 -0
- package/dist/api/dto/subscriptions.d.ts +14 -0
- package/dist/api/dto/subscriptions.js +2 -0
- package/dist/api/dto/worktree.d.ts +55 -0
- package/dist/api/dto/worktree.js +6 -0
- package/dist/api/error-codes.d.ts +259 -0
- package/dist/api/error-codes.js +56 -0
- package/dist/api/errors.d.ts +47 -0
- package/dist/api/errors.js +66 -0
- package/dist/api/index.d.ts +48 -0
- package/dist/api/index.js +45 -0
- package/dist/api/long-poll.d.ts +59 -0
- package/dist/api/long-poll.js +67 -0
- package/dist/api/node-transport.d.ts +18 -0
- package/dist/api/node-transport.js +105 -0
- package/dist/api/plugin-manifest-schema.d.ts +233 -0
- package/dist/api/plugin-manifest-schema.js +23 -0
- package/dist/api/routes.d.ts +164 -0
- package/dist/api/routes.js +197 -0
- package/dist/api/runtime-version.d.ts +31 -0
- package/dist/api/runtime-version.js +50 -0
- package/dist/core/asset-root.d.ts +7 -0
- package/dist/core/asset-root.js +18 -0
- package/dist/core/canvas/boot-id.d.ts +6 -0
- package/dist/core/canvas/boot-id.js +26 -0
- package/dist/core/canvas/paths.d.ts +72 -0
- package/dist/core/canvas/paths.js +163 -0
- package/dist/core/canvas/pid.d.ts +391 -0
- package/dist/core/canvas/pid.js +948 -0
- package/dist/core/command-plugins/bundle.d.ts +149 -0
- package/dist/core/command-plugins/bundle.js +588 -0
- package/dist/core/command-plugins/endpoint.d.ts +24 -0
- package/dist/core/command-plugins/endpoint.js +51 -0
- package/dist/core/config.d.ts +233 -0
- package/dist/core/config.js +1120 -0
- package/dist/core/env-name.d.ts +6 -0
- package/dist/core/env-name.js +9 -0
- package/dist/core/errors.d.ts +38 -0
- package/dist/core/errors.js +90 -0
- package/dist/core/events/emit.d.ts +6 -0
- package/dist/core/events/emit.js +42 -0
- package/dist/core/events/envelope.d.ts +2 -0
- package/dist/core/events/envelope.js +84 -0
- package/dist/core/events/errors.d.ts +4 -0
- package/dist/core/events/errors.js +69 -0
- package/dist/core/events/operation-id.d.ts +4 -0
- package/dist/core/events/operation-id.js +24 -0
- package/dist/core/events/serialize.d.ts +4 -0
- package/dist/core/events/serialize.js +199 -0
- package/dist/core/events/source.d.ts +16 -0
- package/dist/core/events/source.js +31 -0
- package/dist/core/events/types.d.ts +68 -0
- package/dist/core/events/types.js +11 -0
- package/dist/core/exclusive-lock.d.ts +34 -0
- package/dist/core/exclusive-lock.js +197 -0
- package/dist/core/fs-utils.d.ts +44 -0
- package/dist/core/fs-utils.js +208 -0
- package/dist/core/help.d.ts +309 -0
- package/dist/core/help.js +406 -0
- package/dist/core/human/page-catalog.d.ts +57 -0
- package/dist/core/human/page-catalog.js +172 -0
- package/dist/core/installed-plugins.d.ts +2 -0
- package/dist/core/installed-plugins.js +79 -0
- package/dist/core/io.d.ts +122 -0
- package/dist/core/io.js +373 -0
- package/dist/core/keybindings/attach-control.d.ts +49 -0
- package/dist/core/keybindings/attach-control.js +42 -0
- package/dist/core/keybindings/catalog.d.ts +18 -0
- package/dist/core/keybindings/catalog.js +257 -0
- package/dist/core/keybindings/types.d.ts +42 -0
- package/dist/core/keybindings/types.js +1 -0
- package/dist/core/layout.d.ts +34 -0
- package/dist/core/layout.js +106 -0
- package/dist/core/locked-file.d.ts +27 -0
- package/dist/core/locked-file.js +118 -0
- package/dist/core/log.d.ts +9 -0
- package/dist/core/log.js +89 -0
- package/dist/core/manifest.d.ts +5 -0
- package/dist/core/manifest.js +15 -0
- package/dist/core/plugin-env.d.ts +8 -0
- package/dist/core/plugin-env.js +31 -0
- package/dist/core/plugin-extensions.d.ts +29 -0
- package/dist/core/plugin-extensions.js +191 -0
- package/dist/core/plugin-swap-lock.d.ts +9 -0
- package/dist/core/plugin-swap-lock.js +31 -0
- package/dist/core/preview-result-path.d.ts +4 -0
- package/dist/core/preview-result-path.js +26 -0
- package/dist/core/profiles/env-store.d.ts +22 -0
- package/dist/core/profiles/env-store.js +163 -0
- package/dist/core/profiles/fuzzy-match.d.ts +19 -0
- package/dist/core/profiles/fuzzy-match.js +92 -0
- package/dist/core/profiles/manifest.d.ts +120 -0
- package/dist/core/profiles/manifest.js +529 -0
- package/dist/core/rate-limit-scope.d.ts +25 -0
- package/dist/core/rate-limit-scope.js +64 -0
- package/dist/core/render.d.ts +12 -0
- package/dist/core/render.js +138 -0
- package/dist/core/resolver.d.ts +14 -0
- package/dist/core/resolver.js +111 -0
- package/dist/core/runtime/branded-host.d.ts +55 -0
- package/dist/core/runtime/branded-host.js +485 -0
- package/dist/core/runtime/broker/daemon-ops.d.ts +65 -0
- package/dist/core/runtime/broker/daemon-ops.js +177 -0
- package/dist/core/runtime/broker/signal-stream.d.ts +30 -0
- package/dist/core/runtime/broker/signal-stream.js +149 -0
- package/dist/core/scope.d.ts +32 -0
- package/dist/core/scope.js +184 -0
- package/dist/core/scoped-state/db.d.ts +17 -0
- package/dist/core/scoped-state/db.js +247 -0
- package/dist/core/scoped-state/migrate.d.ts +8 -0
- package/dist/core/scoped-state/migrate.js +187 -0
- package/dist/core/scoped-state/paths.d.ts +9 -0
- package/dist/core/scoped-state/paths.js +27 -0
- package/dist/core/scoped-state/profiles.d.ts +27 -0
- package/dist/core/scoped-state/profiles.js +93 -0
- package/dist/core/scoped-state/providers.d.ts +24 -0
- package/dist/core/scoped-state/providers.js +19 -0
- package/dist/core/scoped-state/schema.d.ts +6 -0
- package/dist/core/scoped-state/schema.js +43 -0
- package/dist/core/scoped-state/settings.d.ts +28 -0
- package/dist/core/scoped-state/settings.js +83 -0
- package/dist/core/spaces/open-beneath.d.ts +71 -0
- package/dist/core/spaces/open-beneath.js +581 -0
- package/dist/core/sqlite-statements.d.ts +4 -0
- package/dist/core/sqlite-statements.js +17 -0
- package/dist/core/subscription-state.d.ts +121 -0
- package/dist/core/subscription-state.js +287 -0
- package/dist/core/user-settings.d.ts +377 -0
- package/dist/core/user-settings.js +458 -0
- package/dist/daemon/broker-signals/bus.d.ts +30 -0
- package/dist/daemon/broker-signals/bus.js +87 -0
- package/dist/daemon/manage.d.ts +176 -0
- package/dist/daemon/manage.js +664 -0
- package/dist/daemon/pidfile.d.ts +8 -0
- package/dist/daemon/pidfile.js +37 -0
- package/dist/daemon/startup-policy.d.ts +1 -0
- package/dist/daemon/startup-policy.js +1 -0
- package/dist/native/linux.d.ts +29 -0
- package/dist/native/linux.js +20 -0
- package/dist/shared/env.d.ts +116 -0
- package/dist/shared/env.js +271 -0
- package/dist/shared/generated-context.d.ts +83 -0
- package/dist/shared/generated-context.js +235 -0
- package/dist/shared/inbox-entry-body.d.ts +22 -0
- package/dist/shared/inbox-entry-body.js +116 -0
- package/dist/shared/predicates.d.ts +2 -0
- package/dist/shared/predicates.js +4 -0
- package/dist/shared/working-activity.d.ts +9 -0
- package/dist/shared/working-activity.js +27 -0
- package/dist/types.d.ts +562 -0
- package/dist/types.js +186 -0
- package/package.json +47 -4
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// pidfile.ts — the lean crtrd pidfile + liveness helpers, split out of crtrd.ts
|
|
2
|
+
// so the CLI's daemon front door (`daemon/manage.ts` → `ensureDaemon`) can
|
|
3
|
+
// resolve "is the daemon up?" WITHOUT importing crtrd.ts, whose module graph
|
|
4
|
+
// pulls the entire canvas state store (`core/canvas/index.js` → `openDb`). A
|
|
5
|
+
// `crtr` CLI process asking whether crtrd is running must not, by that question
|
|
6
|
+
// alone, open canvas.db — this module keeps that path fs/process-only.
|
|
7
|
+
//
|
|
8
|
+
// PURITY: Node built-ins + `core/canvas/paths.ts` (pure path builder) + the
|
|
9
|
+
// db-free `core/canvas/pid.ts` liveness probe. Never `openDb` / crtrd.ts / any
|
|
10
|
+
// canvas state accessor. crtrd.ts imports + re-exports these to preserve its
|
|
11
|
+
// historical export surface (tests, `commands/sys/daemon.ts`).
|
|
12
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { crtrHome } from '../core/canvas/paths.js';
|
|
15
|
+
import { isPidAlive } from '../core/canvas/pid.js';
|
|
16
|
+
import { envPidfileOverride } from '../shared/env.js';
|
|
17
|
+
// Re-exported so `isPidAlive` stays reachable from the daemon layer's public
|
|
18
|
+
// surface (crtrd.ts already re-exports it; callers may reach it either way).
|
|
19
|
+
export { isPidAlive };
|
|
20
|
+
/** Absolute path to crtrd's pidfile. `CRTR_PIDFILE` overrides for tests. */
|
|
21
|
+
export function pidfilePath() {
|
|
22
|
+
return envPidfileOverride() ?? join(crtrHome(), 'crtrd.pid');
|
|
23
|
+
}
|
|
24
|
+
/** Read the pid stored in the pidfile, or null if absent / malformed. */
|
|
25
|
+
export function readPidfile() {
|
|
26
|
+
const p = pidfilePath();
|
|
27
|
+
if (!existsSync(p))
|
|
28
|
+
return null;
|
|
29
|
+
const raw = readFileSync(p, 'utf8').trim();
|
|
30
|
+
const n = Number(raw);
|
|
31
|
+
return Number.isFinite(n) && n > 0 ? n : null;
|
|
32
|
+
}
|
|
33
|
+
/** True when a crtrd process is already running (pidfile exists + pid alive). */
|
|
34
|
+
export function isDaemonRunning() {
|
|
35
|
+
const pid = readPidfile();
|
|
36
|
+
return pid !== null && isPidAlive(pid);
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const DAEMON_STARTUP_WINDOW_MS: number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DAEMON_STARTUP_WINDOW_MS = 5 * 60 * 1_000;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Socket } from 'node:net';
|
|
2
|
+
export interface LinuxNative {
|
|
3
|
+
peerCred(fd: number): {
|
|
4
|
+
pid: number;
|
|
5
|
+
uid: number;
|
|
6
|
+
gid: number;
|
|
7
|
+
};
|
|
8
|
+
openat2(dirfd: number, path: string, flags: number, resolve: number): number;
|
|
9
|
+
fdPath(fd: number): string;
|
|
10
|
+
fstat(fd: number): {
|
|
11
|
+
uid: number;
|
|
12
|
+
gid: number;
|
|
13
|
+
mode: number;
|
|
14
|
+
nlink: number;
|
|
15
|
+
dev: bigint;
|
|
16
|
+
ino: bigint;
|
|
17
|
+
};
|
|
18
|
+
sendFds(socketFd: number, data: string, fds: number[]): void;
|
|
19
|
+
recvFds(socketFd: number): {
|
|
20
|
+
data: string;
|
|
21
|
+
fds: number[];
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare const O_PATH = 2097152;
|
|
25
|
+
export declare const O_CLOEXEC = 524288;
|
|
26
|
+
export declare const RESOLVE_NO_SYMLINKS = 4;
|
|
27
|
+
export declare const RESOLVE_BENEATH = 8;
|
|
28
|
+
export declare function loadLinuxNative(): LinuxNative | undefined;
|
|
29
|
+
export declare function peerUid(socket: Socket): number;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
export const O_PATH = 0x200000;
|
|
3
|
+
export const O_CLOEXEC = 0x80000;
|
|
4
|
+
export const RESOLVE_NO_SYMLINKS = 0x04;
|
|
5
|
+
export const RESOLVE_BENEATH = 0x08;
|
|
6
|
+
export function loadLinuxNative() {
|
|
7
|
+
if (process.platform !== 'linux')
|
|
8
|
+
return undefined;
|
|
9
|
+
// One prebuilt addon per architecture (see scripts/ensure-native-linux.mjs).
|
|
10
|
+
return createRequire(import.meta.url)(`./linux/${process.arch}/addon.node`);
|
|
11
|
+
}
|
|
12
|
+
export function peerUid(socket) {
|
|
13
|
+
const fd = socket._handle?.fd;
|
|
14
|
+
if (fd === undefined || fd < 0)
|
|
15
|
+
throw new Error('unix socket peer fd is unavailable');
|
|
16
|
+
const native = loadLinuxNative();
|
|
17
|
+
if (!native)
|
|
18
|
+
throw new Error('Linux peer credentials are unavailable');
|
|
19
|
+
return native.peerCred(fd).uid;
|
|
20
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/** The current node's id (`CRTR_NODE_ID`), or undefined outside a node. */
|
|
2
|
+
export declare function envNodeId(): string | undefined;
|
|
3
|
+
/** Find the single launch snapshot mounted by the launcher into this process's
|
|
4
|
+
* Linux namespace. Cron bash has no CRTR_NODE_ID, but its creator's mounted
|
|
5
|
+
* launch snapshot supplies config and granted-command projection without
|
|
6
|
+
* claiming the cron is a node. Its broker relay may already have closed when
|
|
7
|
+
* the cron fires; still classify the sandbox so CLI bootstrap never falls back
|
|
8
|
+
* to host stores or person authority. Neither CRTR_NODE_ID, CRTR_ANCHOR, nor
|
|
9
|
+
* the caller-editable CRTR_API_SOCKET selects the launch identity. */
|
|
10
|
+
export declare function sandboxCliNodeId(): string | undefined;
|
|
11
|
+
/** A Linux app command uses its mounted launch snapshot, not host user stores. */
|
|
12
|
+
export declare function isSandboxedNode(): boolean;
|
|
13
|
+
/** The app that owns the current node, supplied in its broker launch identity. */
|
|
14
|
+
export declare function envGrantee(): string | undefined;
|
|
15
|
+
/** Set to '1' by `nodeEnv` for an app-started run's brokers, which admit inbox
|
|
16
|
+
* mail only between agent runs. Terminal nodes also carry `CRTR_RUN_ID`, so
|
|
17
|
+
* that variable is not this signal. */
|
|
18
|
+
export declare const INBOX_BETWEEN_TURNS_ENV = "CRTR_INBOX_BETWEEN_TURNS";
|
|
19
|
+
export declare function envInboxBetweenTurns(): boolean;
|
|
20
|
+
/** The current run's scope allow-list; null means the row inherits everything. */
|
|
21
|
+
export declare function envScopes(): readonly string[] | null;
|
|
22
|
+
/** Whether a launched scope list covers a capability. Null means not narrowed. */
|
|
23
|
+
export declare function scopeAllowed(scopes: readonly string[] | null | undefined, scope: string): boolean;
|
|
24
|
+
export declare function envExecutionId(): string | undefined;
|
|
25
|
+
/** The current node's target profile id (`CRTR_PROFILE_ID`), or undefined. */
|
|
26
|
+
export declare function envProfileId(): string | undefined;
|
|
27
|
+
/** The current node's working directory (`CRTR_NODE_CWD`), or undefined. */
|
|
28
|
+
export declare function envNodeCwd(): string | undefined;
|
|
29
|
+
/** An explicit model-routing override for this turn (`CRTR_MODEL_INTENT`), or
|
|
30
|
+
* undefined. Cleared (not read) via `delete process.env['CRTR_MODEL_INTENT']`
|
|
31
|
+
* in `runtime/broker.ts` — a mutation, not a read, so it stays there. */
|
|
32
|
+
export declare function envModelIntent(): string | undefined;
|
|
33
|
+
/** Whether the launch recipe requires this broker to keep its exact provider/model. */
|
|
34
|
+
export declare function envModelExact(): boolean;
|
|
35
|
+
/** The raw `CRTR_HOME` override, unresolved. Use `crtrHome()`
|
|
36
|
+
* (`core/canvas/paths.ts`) to get the resolved canvas-home path; use this
|
|
37
|
+
* only when a caller needs the override itself — to check whether one is
|
|
38
|
+
* set, or to propagate it verbatim into a child process's env. */
|
|
39
|
+
export declare function envHomeOverride(): string | undefined;
|
|
40
|
+
/** The raw installed-runtime directory override, unresolved. */
|
|
41
|
+
export declare function envRuntimeHomeOverride(): string | undefined;
|
|
42
|
+
/** Dead-provider watchdog timeout (`CRTR_STREAM_WATCHDOG_MS`), 5 minutes by
|
|
43
|
+
* default. See `runtime/stream-watchdog.ts` for what it guards. */
|
|
44
|
+
export declare function envStreamWatchdogMs(): number;
|
|
45
|
+
/** The canvas inbox watcher's poll tick (`CRTR_WATCHER_TICK_MS`). */
|
|
46
|
+
export declare function envWatcherTickMs(): number;
|
|
47
|
+
/** Claim backstop while broker signals are connected (`CRTR_WATCHER_BACKSTOP_MS`). */
|
|
48
|
+
export declare function envWatcherBackstopMs(): number;
|
|
49
|
+
/** The canvas inbox watcher's debounce window (`CRTR_WATCHER_DEBOUNCE_MS`). */
|
|
50
|
+
export declare function envWatcherDebounceMs(): number;
|
|
51
|
+
/** No-new-message window before a recap is shown (`CRTR_RECAP_IDLE_MS`), 60s
|
|
52
|
+
* by default. */
|
|
53
|
+
export declare function envRecapIdleMs(): number;
|
|
54
|
+
/** Explicit recap-model override (`CRTR_RECAP_MODEL`), trimmed; undefined if
|
|
55
|
+
* unset or blank. */
|
|
56
|
+
export declare function envRecapModelOverride(): string | undefined;
|
|
57
|
+
/** The bash safety-valve deadline (`CRTR_BASH_VALVE_MS`), 5 minutes by
|
|
58
|
+
* default; undocumented test-only override so the E2E valve check doesn't
|
|
59
|
+
* sleep 5 minutes. */
|
|
60
|
+
export declare function envBashValveMs(): number;
|
|
61
|
+
/** How long an AUTO-backgrounded bash job may run before the daemon cancels it
|
|
62
|
+
* unless the agent claims it (`CRTR_BASH_AUTO_BG_DEADLINE_MS`), 60s by default;
|
|
63
|
+
* undocumented test-only override so the deadline check doesn't wait a minute. */
|
|
64
|
+
export declare function envBashAutoBgDeadlineMs(): number;
|
|
65
|
+
/** Explicit pidfile path override (`CRTR_PIDFILE`, tests only); undefined if
|
|
66
|
+
* unset or blank. */
|
|
67
|
+
export declare function envPidfileOverride(): string | undefined;
|
|
68
|
+
/** The broker engine module spec (`CRTR_BROKER_ENGINE`, the T11 test seam),
|
|
69
|
+
* defaulting to the real SDK. `runtime/host.ts` layers `inv.env` ahead of
|
|
70
|
+
* this (a launch-time override mirrored into the child's env, since
|
|
71
|
+
* spawn-env.ts's default-deny allowlist strips `CRTR_*` from ambient env). */
|
|
72
|
+
export declare function envBrokerEngine(): string;
|
|
73
|
+
/** Test-only pi-binary substitution (`CRTR_PI_BINARY`) so the integration
|
|
74
|
+
* harness can point a real `crtr node new` at a deterministic fake-pi
|
|
75
|
+
* vehicle. Undefined in production. */
|
|
76
|
+
export declare function envPiBinaryOverride(): string | undefined;
|
|
77
|
+
/** Whether implicit daemon autostart is suppressed for this invocation
|
|
78
|
+
* (`CRTR_NO_DAEMON_AUTOSTART=1`). */
|
|
79
|
+
export declare function envNoDaemonAutostart(): boolean;
|
|
80
|
+
/** The `--tcp` fallback for crtrd's opt-in TCP listener (`CRTRD_TCP`), raw
|
|
81
|
+
* (`host:port` or undefined — absent means unix socket only). */
|
|
82
|
+
export declare function envCrtrdTcp(): string | undefined;
|
|
83
|
+
/** The opt-in bearer token guarding crtrd's TCP listener (`CRTRD_TOKEN`).
|
|
84
|
+
* Unset (or blank) → undefined, and the TCP listener performs NO auth check
|
|
85
|
+
* at all — exactly today's behavior. The unix socket never checks this,
|
|
86
|
+
* set or not. */
|
|
87
|
+
export declare function envCrtrdToken(): string | undefined;
|
|
88
|
+
/** Kill switch for the host-exports writer/pruner (`CRTR_NO_EXPORTS=1`). */
|
|
89
|
+
export declare function envNoExports(): boolean;
|
|
90
|
+
/** Verbose-diagnostics gate for otherwise-silent best-effort catches
|
|
91
|
+
* (`CRTR_DEBUG=1`). Distinct from `CRTR_DEBUG_PID_LIVENESS`
|
|
92
|
+
* (`core/canvas/pid.ts`), a different, unrelated var. */
|
|
93
|
+
export declare function envDebug(): boolean;
|
|
94
|
+
/** Live-broker automatic-revive cap override (`CRTR_MAX_LIVE_BROKERS`); wins
|
|
95
|
+
* over `readConfig('user').brokerThresholds.automaticReviveCap` when set. */
|
|
96
|
+
export declare function envMaxLiveBrokers(): number | undefined;
|
|
97
|
+
/** Live-broker warning threshold override (`CRTR_WARN_LIVE_BROKERS`); wins
|
|
98
|
+
* over `readConfig('user').brokerThresholds.warning` when set. */
|
|
99
|
+
export declare function envWarnLiveBrokers(): number | undefined;
|
|
100
|
+
/** Test-only unattended-park interval override (`CRTR_TEST_UNATTENDED_PARK_MS`),
|
|
101
|
+
* gated by `envNoDaemonAutostart()` at the call site; no production default. */
|
|
102
|
+
export declare function envTestUnattendedParkMs(): number | undefined;
|
|
103
|
+
/** Production unattended-park interval override (`CRTR_UNATTENDED_PARK_MS`), in
|
|
104
|
+
* milliseconds; wins over the user-scope config value
|
|
105
|
+
* (`readConfig('user').lifecycle.unattendedParkMs`, itself defaulting to 15
|
|
106
|
+
* min) whenever set, autostart or not. Unlike `CRTR_TEST_UNATTENDED_PARK_MS`
|
|
107
|
+
* this is not gated on `envNoDaemonAutostart()`: it is the env escape hatch
|
|
108
|
+
* above the configured knob a deployment sets to tune how long an eligible
|
|
109
|
+
* resident idles before its parking turn. */
|
|
110
|
+
export declare function envUnattendedParkMs(): number | undefined;
|
|
111
|
+
/** Test-only park-summary grace-period override
|
|
112
|
+
* (`CRTR_TEST_PARK_SUMMARY_GRACE_MS`); no production default. */
|
|
113
|
+
export declare function envTestParkSummaryGraceMs(): number | undefined;
|
|
114
|
+
/** The bounded lifetime shared by the daemon's pending-park sweep and its
|
|
115
|
+
* in-broker isolated turn. */
|
|
116
|
+
export declare function parkSummaryGraceMs(): number;
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
// The reader-side surface for every environment variable crouter reads back
|
|
2
|
+
// out of `process.env`, outside `core/runtime/spawn-env.ts`'s writer
|
|
3
|
+
// allowlist. That module documents what a broker child is ADMITTED to see;
|
|
4
|
+
// this one documents what crouter itself reads. Two families:
|
|
5
|
+
//
|
|
6
|
+
// - Identity: raw passthrough (`string | undefined`, exactly what
|
|
7
|
+
// `process.env[name]` returns). Every existing call site keeps its own
|
|
8
|
+
// established fallback (`?? ''`, `|| null`, `?? cfg.cwd`, a presence
|
|
9
|
+
// check, ...) — the fallback has always been call-site-owned, not
|
|
10
|
+
// var-owned, so centralizing it here would be a behavior change, not a
|
|
11
|
+
// dedup. `CRTR_HOME` also has a resolved-path accessor, `crtrHome()` in
|
|
12
|
+
// `core/canvas/paths.ts`; that stays the canonical way to get the
|
|
13
|
+
// resolved canvas home; `envHomeOverride()` here is for the handful of
|
|
14
|
+
// sites that want the raw override value itself (to check presence or
|
|
15
|
+
// propagate it verbatim to a child env).
|
|
16
|
+
//
|
|
17
|
+
// - Tuning: parsed, with the default baked into the accessor. Each of
|
|
18
|
+
// these had exactly one parse site before this module existed; the
|
|
19
|
+
// parse logic moved here unchanged so a second site, if one appears,
|
|
20
|
+
// reads the single implementation instead of re-deriving it.
|
|
21
|
+
//
|
|
22
|
+
// `CRTR_DIR_NAME` is NOT here — it is a plain exported string constant
|
|
23
|
+
// (`types.ts`), never read off `process.env`.
|
|
24
|
+
import { lstatSync, readFileSync, readdirSync } from 'node:fs';
|
|
25
|
+
import { join } from 'node:path';
|
|
26
|
+
import { covers } from '@north-light/identity';
|
|
27
|
+
// Identity
|
|
28
|
+
/** The current node's id (`CRTR_NODE_ID`), or undefined outside a node. */
|
|
29
|
+
export function envNodeId() {
|
|
30
|
+
return process.env['CRTR_NODE_ID'];
|
|
31
|
+
}
|
|
32
|
+
/** Find the single launch snapshot mounted by the launcher into this process's
|
|
33
|
+
* Linux namespace. Cron bash has no CRTR_NODE_ID, but its creator's mounted
|
|
34
|
+
* launch snapshot supplies config and granted-command projection without
|
|
35
|
+
* claiming the cron is a node. Its broker relay may already have closed when
|
|
36
|
+
* the cron fires; still classify the sandbox so CLI bootstrap never falls back
|
|
37
|
+
* to host stores or person authority. Neither CRTR_NODE_ID, CRTR_ANCHOR, nor
|
|
38
|
+
* the caller-editable CRTR_API_SOCKET selects the launch identity. */
|
|
39
|
+
export function sandboxCliNodeId() {
|
|
40
|
+
if (process.platform !== 'linux')
|
|
41
|
+
return undefined;
|
|
42
|
+
try {
|
|
43
|
+
const root = '/run/crtr/nodes';
|
|
44
|
+
const mounted = new Set(readFileSync('/proc/self/mountinfo', 'utf8').split('\n').map((line) => line.split(' ')[4]));
|
|
45
|
+
const ids = readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory() &&
|
|
46
|
+
/^[a-zA-Z0-9][a-zA-Z0-9-]{0,127}$/.test(entry.name) &&
|
|
47
|
+
mounted.has(join(root, entry.name)) &&
|
|
48
|
+
lstatSync(join(root, entry.name, 'broker-launch.json'), { throwIfNoEntry: false })?.isFile());
|
|
49
|
+
return ids.length === 1 ? ids[0].name : undefined;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** A Linux app command uses its mounted launch snapshot, not host user stores. */
|
|
56
|
+
export function isSandboxedNode() {
|
|
57
|
+
return sandboxCliNodeId() !== undefined;
|
|
58
|
+
}
|
|
59
|
+
/** The app that owns the current node, supplied in its broker launch identity. */
|
|
60
|
+
export function envGrantee() {
|
|
61
|
+
return process.env['CRTR_GRANTEE'];
|
|
62
|
+
}
|
|
63
|
+
/** Set to '1' by `nodeEnv` for an app-started run's brokers, which admit inbox
|
|
64
|
+
* mail only between agent runs. Terminal nodes also carry `CRTR_RUN_ID`, so
|
|
65
|
+
* that variable is not this signal. */
|
|
66
|
+
export const INBOX_BETWEEN_TURNS_ENV = 'CRTR_INBOX_BETWEEN_TURNS';
|
|
67
|
+
export function envInboxBetweenTurns() {
|
|
68
|
+
return process.env[INBOX_BETWEEN_TURNS_ENV] === '1';
|
|
69
|
+
}
|
|
70
|
+
/** The current run's scope allow-list; null means the row inherits everything. */
|
|
71
|
+
export function envScopes() {
|
|
72
|
+
const raw = process.env['CRTR_SCOPES'];
|
|
73
|
+
return raw === undefined ? null : raw === '' ? [] : raw.split(',');
|
|
74
|
+
}
|
|
75
|
+
/** Whether a launched scope list covers a capability. Null means not narrowed. */
|
|
76
|
+
export function scopeAllowed(scopes, scope) {
|
|
77
|
+
if (scopes === null || scopes === undefined)
|
|
78
|
+
return true;
|
|
79
|
+
return scopes.some((held) => covers(held, scope));
|
|
80
|
+
}
|
|
81
|
+
export function envExecutionId() {
|
|
82
|
+
return process.env['CRTR_EXECUTION_ID'];
|
|
83
|
+
}
|
|
84
|
+
/** The current node's target profile id (`CRTR_PROFILE_ID`), or undefined. */
|
|
85
|
+
export function envProfileId() {
|
|
86
|
+
return process.env['CRTR_PROFILE_ID'];
|
|
87
|
+
}
|
|
88
|
+
/** The current node's working directory (`CRTR_NODE_CWD`), or undefined. */
|
|
89
|
+
export function envNodeCwd() {
|
|
90
|
+
return process.env['CRTR_NODE_CWD'];
|
|
91
|
+
}
|
|
92
|
+
/** An explicit model-routing override for this turn (`CRTR_MODEL_INTENT`), or
|
|
93
|
+
* undefined. Cleared (not read) via `delete process.env['CRTR_MODEL_INTENT']`
|
|
94
|
+
* in `runtime/broker.ts` — a mutation, not a read, so it stays there. */
|
|
95
|
+
export function envModelIntent() {
|
|
96
|
+
return process.env['CRTR_MODEL_INTENT'];
|
|
97
|
+
}
|
|
98
|
+
/** Whether the launch recipe requires this broker to keep its exact provider/model. */
|
|
99
|
+
export function envModelExact() {
|
|
100
|
+
return process.env['CRTR_MODEL_EXACT'] === '1';
|
|
101
|
+
}
|
|
102
|
+
/** The raw `CRTR_HOME` override, unresolved. Use `crtrHome()`
|
|
103
|
+
* (`core/canvas/paths.ts`) to get the resolved canvas-home path; use this
|
|
104
|
+
* only when a caller needs the override itself — to check whether one is
|
|
105
|
+
* set, or to propagate it verbatim into a child process's env. */
|
|
106
|
+
export function envHomeOverride() {
|
|
107
|
+
return process.env['CRTR_HOME'];
|
|
108
|
+
}
|
|
109
|
+
/** The raw installed-runtime directory override, unresolved. */
|
|
110
|
+
export function envRuntimeHomeOverride() {
|
|
111
|
+
return process.env['CRTR_RUNTIME_HOME'];
|
|
112
|
+
}
|
|
113
|
+
// Tuning
|
|
114
|
+
/** Generic `Number(raw)` parse with a positive-finite guard, shared by every
|
|
115
|
+
* millisecond tuning var below (each previously reimplemented this locally,
|
|
116
|
+
* identically). */
|
|
117
|
+
function parsePositiveMs(raw, fallback) {
|
|
118
|
+
if (raw === undefined)
|
|
119
|
+
return fallback;
|
|
120
|
+
const n = Number(raw);
|
|
121
|
+
return Number.isFinite(n) && n > 0 ? n : fallback;
|
|
122
|
+
}
|
|
123
|
+
const DEFAULT_STREAM_WATCHDOG_MS = 5 * 60_000; // 5 minutes.
|
|
124
|
+
/** Dead-provider watchdog timeout (`CRTR_STREAM_WATCHDOG_MS`), 5 minutes by
|
|
125
|
+
* default. See `runtime/stream-watchdog.ts` for what it guards. */
|
|
126
|
+
export function envStreamWatchdogMs() {
|
|
127
|
+
return parsePositiveMs(process.env['CRTR_STREAM_WATCHDOG_MS'], DEFAULT_STREAM_WATCHDOG_MS);
|
|
128
|
+
}
|
|
129
|
+
const DEFAULT_WATCHER_TICK_MS = 800;
|
|
130
|
+
/** The canvas inbox watcher's poll tick (`CRTR_WATCHER_TICK_MS`). */
|
|
131
|
+
export function envWatcherTickMs() {
|
|
132
|
+
return parsePositiveMs(process.env['CRTR_WATCHER_TICK_MS'], DEFAULT_WATCHER_TICK_MS);
|
|
133
|
+
}
|
|
134
|
+
const DEFAULT_WATCHER_BACKSTOP_MS = 60_000;
|
|
135
|
+
/** Claim backstop while broker signals are connected (`CRTR_WATCHER_BACKSTOP_MS`). */
|
|
136
|
+
export function envWatcherBackstopMs() {
|
|
137
|
+
return parsePositiveMs(process.env['CRTR_WATCHER_BACKSTOP_MS'], DEFAULT_WATCHER_BACKSTOP_MS);
|
|
138
|
+
}
|
|
139
|
+
const DEFAULT_WATCHER_DEBOUNCE_MS = 1000;
|
|
140
|
+
/** The canvas inbox watcher's debounce window (`CRTR_WATCHER_DEBOUNCE_MS`). */
|
|
141
|
+
export function envWatcherDebounceMs() {
|
|
142
|
+
return parsePositiveMs(process.env['CRTR_WATCHER_DEBOUNCE_MS'], DEFAULT_WATCHER_DEBOUNCE_MS);
|
|
143
|
+
}
|
|
144
|
+
const DEFAULT_RECAP_IDLE_MS = 60_000;
|
|
145
|
+
/** No-new-message window before a recap is shown (`CRTR_RECAP_IDLE_MS`), 60s
|
|
146
|
+
* by default. */
|
|
147
|
+
export function envRecapIdleMs() {
|
|
148
|
+
return parsePositiveMs(process.env['CRTR_RECAP_IDLE_MS'], DEFAULT_RECAP_IDLE_MS);
|
|
149
|
+
}
|
|
150
|
+
/** Explicit recap-model override (`CRTR_RECAP_MODEL`), trimmed; undefined if
|
|
151
|
+
* unset or blank. */
|
|
152
|
+
export function envRecapModelOverride() {
|
|
153
|
+
const raw = process.env['CRTR_RECAP_MODEL'];
|
|
154
|
+
return raw !== undefined && raw.trim() !== '' ? raw.trim() : undefined;
|
|
155
|
+
}
|
|
156
|
+
const DEFAULT_BASH_VALVE_MS = 5 * 60 * 1000;
|
|
157
|
+
/** The bash safety-valve deadline (`CRTR_BASH_VALVE_MS`), 5 minutes by
|
|
158
|
+
* default; undocumented test-only override so the E2E valve check doesn't
|
|
159
|
+
* sleep 5 minutes. */
|
|
160
|
+
export function envBashValveMs() {
|
|
161
|
+
return parsePositiveMs(process.env['CRTR_BASH_VALVE_MS'], DEFAULT_BASH_VALVE_MS);
|
|
162
|
+
}
|
|
163
|
+
const DEFAULT_BASH_AUTO_BG_DEADLINE_MS = 60 * 1000;
|
|
164
|
+
/** How long an AUTO-backgrounded bash job may run before the daemon cancels it
|
|
165
|
+
* unless the agent claims it (`CRTR_BASH_AUTO_BG_DEADLINE_MS`), 60s by default;
|
|
166
|
+
* undocumented test-only override so the deadline check doesn't wait a minute. */
|
|
167
|
+
export function envBashAutoBgDeadlineMs() {
|
|
168
|
+
return parsePositiveMs(process.env['CRTR_BASH_AUTO_BG_DEADLINE_MS'], DEFAULT_BASH_AUTO_BG_DEADLINE_MS);
|
|
169
|
+
}
|
|
170
|
+
/** Explicit pidfile path override (`CRTR_PIDFILE`, tests only); undefined if
|
|
171
|
+
* unset or blank. */
|
|
172
|
+
export function envPidfileOverride() {
|
|
173
|
+
const raw = process.env['CRTR_PIDFILE'];
|
|
174
|
+
return raw !== undefined && raw !== '' ? raw : undefined;
|
|
175
|
+
}
|
|
176
|
+
const DEFAULT_BROKER_ENGINE = '@earendil-works/pi-coding-agent';
|
|
177
|
+
/** The broker engine module spec (`CRTR_BROKER_ENGINE`, the T11 test seam),
|
|
178
|
+
* defaulting to the real SDK. `runtime/host.ts` layers `inv.env` ahead of
|
|
179
|
+
* this (a launch-time override mirrored into the child's env, since
|
|
180
|
+
* spawn-env.ts's default-deny allowlist strips `CRTR_*` from ambient env). */
|
|
181
|
+
export function envBrokerEngine() {
|
|
182
|
+
return process.env['CRTR_BROKER_ENGINE'] ?? DEFAULT_BROKER_ENGINE;
|
|
183
|
+
}
|
|
184
|
+
/** Test-only pi-binary substitution (`CRTR_PI_BINARY`) so the integration
|
|
185
|
+
* harness can point a real `crtr node new` at a deterministic fake-pi
|
|
186
|
+
* vehicle. Undefined in production. */
|
|
187
|
+
export function envPiBinaryOverride() {
|
|
188
|
+
return process.env['CRTR_PI_BINARY'];
|
|
189
|
+
}
|
|
190
|
+
/** Whether implicit daemon autostart is suppressed for this invocation
|
|
191
|
+
* (`CRTR_NO_DAEMON_AUTOSTART=1`). */
|
|
192
|
+
export function envNoDaemonAutostart() {
|
|
193
|
+
return process.env['CRTR_NO_DAEMON_AUTOSTART'] === '1';
|
|
194
|
+
}
|
|
195
|
+
/** The `--tcp` fallback for crtrd's opt-in TCP listener (`CRTRD_TCP`), raw
|
|
196
|
+
* (`host:port` or undefined — absent means unix socket only). */
|
|
197
|
+
export function envCrtrdTcp() {
|
|
198
|
+
return process.env['CRTRD_TCP'];
|
|
199
|
+
}
|
|
200
|
+
/** The opt-in bearer token guarding crtrd's TCP listener (`CRTRD_TOKEN`).
|
|
201
|
+
* Unset (or blank) → undefined, and the TCP listener performs NO auth check
|
|
202
|
+
* at all — exactly today's behavior. The unix socket never checks this,
|
|
203
|
+
* set or not. */
|
|
204
|
+
export function envCrtrdToken() {
|
|
205
|
+
const raw = process.env['CRTRD_TOKEN'];
|
|
206
|
+
return raw !== undefined && raw !== '' ? raw : undefined;
|
|
207
|
+
}
|
|
208
|
+
/** Kill switch for the host-exports writer/pruner (`CRTR_NO_EXPORTS=1`). */
|
|
209
|
+
export function envNoExports() {
|
|
210
|
+
return process.env['CRTR_NO_EXPORTS'] === '1';
|
|
211
|
+
}
|
|
212
|
+
/** Verbose-diagnostics gate for otherwise-silent best-effort catches
|
|
213
|
+
* (`CRTR_DEBUG=1`). Distinct from `CRTR_DEBUG_PID_LIVENESS`
|
|
214
|
+
* (`core/canvas/pid.ts`), a different, unrelated var. */
|
|
215
|
+
export function envDebug() {
|
|
216
|
+
return process.env['CRTR_DEBUG'] === '1';
|
|
217
|
+
}
|
|
218
|
+
// Precedence — broker-supervision.ts's threshold/interval overrides. Each
|
|
219
|
+
// returns the raw parsed value with NO default: the caller supplies the
|
|
220
|
+
// default (user config for the broker thresholds and the unattended-park
|
|
221
|
+
// interval, a hardcoded constant for the test-only park-summary grace), and
|
|
222
|
+
// env wins over it when set. Undefined, unparseable, or non-positive all mean
|
|
223
|
+
// "no override" — the caller's own default applies.
|
|
224
|
+
function parsePositiveInteger(raw) {
|
|
225
|
+
if (raw === undefined || raw === '')
|
|
226
|
+
return undefined;
|
|
227
|
+
const n = Number(raw);
|
|
228
|
+
return Number.isSafeInteger(n) && n >= 1 ? n : undefined;
|
|
229
|
+
}
|
|
230
|
+
/** Live-broker automatic-revive cap override (`CRTR_MAX_LIVE_BROKERS`); wins
|
|
231
|
+
* over `readConfig('user').brokerThresholds.automaticReviveCap` when set. */
|
|
232
|
+
export function envMaxLiveBrokers() {
|
|
233
|
+
return parsePositiveInteger(process.env['CRTR_MAX_LIVE_BROKERS']);
|
|
234
|
+
}
|
|
235
|
+
/** Live-broker warning threshold override (`CRTR_WARN_LIVE_BROKERS`); wins
|
|
236
|
+
* over `readConfig('user').brokerThresholds.warning` when set. */
|
|
237
|
+
export function envWarnLiveBrokers() {
|
|
238
|
+
return parsePositiveInteger(process.env['CRTR_WARN_LIVE_BROKERS']);
|
|
239
|
+
}
|
|
240
|
+
function parsePositiveMsNoDefault(raw) {
|
|
241
|
+
if (raw === undefined)
|
|
242
|
+
return undefined;
|
|
243
|
+
const n = Number(raw);
|
|
244
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
245
|
+
}
|
|
246
|
+
/** Test-only unattended-park interval override (`CRTR_TEST_UNATTENDED_PARK_MS`),
|
|
247
|
+
* gated by `envNoDaemonAutostart()` at the call site; no production default. */
|
|
248
|
+
export function envTestUnattendedParkMs() {
|
|
249
|
+
return parsePositiveMsNoDefault(process.env['CRTR_TEST_UNATTENDED_PARK_MS']);
|
|
250
|
+
}
|
|
251
|
+
/** Production unattended-park interval override (`CRTR_UNATTENDED_PARK_MS`), in
|
|
252
|
+
* milliseconds; wins over the user-scope config value
|
|
253
|
+
* (`readConfig('user').lifecycle.unattendedParkMs`, itself defaulting to 15
|
|
254
|
+
* min) whenever set, autostart or not. Unlike `CRTR_TEST_UNATTENDED_PARK_MS`
|
|
255
|
+
* this is not gated on `envNoDaemonAutostart()`: it is the env escape hatch
|
|
256
|
+
* above the configured knob a deployment sets to tune how long an eligible
|
|
257
|
+
* resident idles before its parking turn. */
|
|
258
|
+
export function envUnattendedParkMs() {
|
|
259
|
+
return parsePositiveMsNoDefault(process.env['CRTR_UNATTENDED_PARK_MS']);
|
|
260
|
+
}
|
|
261
|
+
/** Test-only park-summary grace-period override
|
|
262
|
+
* (`CRTR_TEST_PARK_SUMMARY_GRACE_MS`); no production default. */
|
|
263
|
+
export function envTestParkSummaryGraceMs() {
|
|
264
|
+
return parsePositiveMsNoDefault(process.env['CRTR_TEST_PARK_SUMMARY_GRACE_MS']);
|
|
265
|
+
}
|
|
266
|
+
const DEFAULT_PARK_SUMMARY_GRACE_MS = 5 * 60_000;
|
|
267
|
+
/** The bounded lifetime shared by the daemon's pending-park sweep and its
|
|
268
|
+
* in-broker isolated turn. */
|
|
269
|
+
export function parkSummaryGraceMs() {
|
|
270
|
+
return envTestParkSummaryGraceMs() ?? DEFAULT_PARK_SUMMARY_GRACE_MS;
|
|
271
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** Custom message carrying the node's session-start bearings. */
|
|
2
|
+
export declare const CONTEXT_INTRO_CUSTOM_TYPE = "crtr-context";
|
|
3
|
+
/** Custom message carrying an ambient situational-context update. */
|
|
4
|
+
export declare const SITUATIONAL_CONTEXT_CUSTOM_TYPE = "crtr-situational-context";
|
|
5
|
+
/** Custom message used when a context-size nudge waits for the next turn. */
|
|
6
|
+
export declare const CONTEXT_NUDGE_CUSTOM_TYPE = "crtr-context-nudge";
|
|
7
|
+
/** Custom message that opens a review companion's visible transcript. */
|
|
8
|
+
export declare const REVIEW_BOUNDARY_CUSTOM_TYPE = "crtr-review-boundary";
|
|
9
|
+
/** Generic completion mandate issued by the terminal-node stop guard. */
|
|
10
|
+
export declare const STALL_REPROMPT: string;
|
|
11
|
+
/** The daemon's parking mandate for an isolated turn. It leaves current truth,
|
|
12
|
+
* supporting material when needed, lasting lessons, and one deferred update;
|
|
13
|
+
* the main conversation remains untouched and resumes without a fresh cycle. */
|
|
14
|
+
export declare const PARK_SUMMARY_PROMPT: string;
|
|
15
|
+
/** Static recovery prompts shared by the broker producer and display classifier. */
|
|
16
|
+
export declare const AUTH_FAULT_RECOVERY_BODY = "Provider credentials were just updated (a new login landed). Your previous turn stopped on a provider authentication failure. Continue from where you left off and retry the work that failed.";
|
|
17
|
+
export declare const CONNECTION_FAULT_RECOVERY_BODY = "The network connection is back online. Your previous turn stopped on a connection error (the network was down). Continue from where you left off and retry the work that failed.";
|
|
18
|
+
/** A run node's connection retry. Its broker never probes the network (its
|
|
19
|
+
* model calls go through the daemon), so it cannot claim the network is back;
|
|
20
|
+
* the attempt itself is the probe. */
|
|
21
|
+
export declare const RUN_CONNECTION_FAULT_RETRY_BODY = "Your previous turn stopped on a connection error reaching the model provider. Retrying now: continue from where you left off and retry the work that failed.";
|
|
22
|
+
export declare const PROVIDER_FAULT_RECOVERY_BODY = "Your previous turn stopped on a provider fault. Continue from where you left off and retry the work that failed.";
|
|
23
|
+
export type ModelFallbackRecoveryReason = 'credential' | 'not-found';
|
|
24
|
+
/** Format the stop guard's dynamic structured-output mandate. */
|
|
25
|
+
export declare function formatStructuredOutputReprompt(schema: string, requestId: string): string;
|
|
26
|
+
/** Keep model-fallback guidance editable without making it a reader contract. */
|
|
27
|
+
export declare function formatModelFallbackRecovery(previousModel: string, nextModel: string, reason: ModelFallbackRecoveryReason): string;
|
|
28
|
+
export interface GeneratedContextMessageLike {
|
|
29
|
+
role?: string;
|
|
30
|
+
customType?: string;
|
|
31
|
+
content?: unknown;
|
|
32
|
+
}
|
|
33
|
+
export type CardEntryDisposition = 'report' | 'human-answer' | 'human-canceled';
|
|
34
|
+
export interface CardEntry {
|
|
35
|
+
disposition: CardEntryDisposition;
|
|
36
|
+
kind: string;
|
|
37
|
+
body: string;
|
|
38
|
+
ref?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface CardSender {
|
|
41
|
+
id: string;
|
|
42
|
+
updates: number;
|
|
43
|
+
finished: boolean;
|
|
44
|
+
entries: CardEntry[];
|
|
45
|
+
}
|
|
46
|
+
/** An already-resolved inbox entry supplied to the pure digest formatter. */
|
|
47
|
+
export interface InboxCardEntry {
|
|
48
|
+
kind: string;
|
|
49
|
+
body: string;
|
|
50
|
+
ref?: string;
|
|
51
|
+
disposition?: CardEntryDisposition;
|
|
52
|
+
}
|
|
53
|
+
/** An already-resolved sender section supplied to the pure digest formatter. */
|
|
54
|
+
export interface InboxCardSection {
|
|
55
|
+
id: string;
|
|
56
|
+
entries: readonly InboxCardEntry[];
|
|
57
|
+
}
|
|
58
|
+
export interface GeneratedCard {
|
|
59
|
+
kind: string;
|
|
60
|
+
facts: Readonly<Record<string, string>>;
|
|
61
|
+
body: string;
|
|
62
|
+
senders: CardSender[];
|
|
63
|
+
}
|
|
64
|
+
/** Plain text from a generated message's string or text-block content. */
|
|
65
|
+
export declare function generatedContextText(message: GeneratedContextMessageLike): string;
|
|
66
|
+
/** Wrap a user-role runtime message in its whole-message card envelope. */
|
|
67
|
+
export declare function formatCard(kind: string, facts: Record<string, string | number | boolean | undefined>, body: string): string;
|
|
68
|
+
/** Wrap a card whose body is DATA, not markup — the only escape on the API
|
|
69
|
+
* path, so a caller can neither emit a malformed card nor smuggle markup into
|
|
70
|
+
* one. `formatCard` keeps its raw body for the trusted crouter producers that
|
|
71
|
+
* deliberately nest markup (bearings blocks, the inbox `<from>`/`<entry>`
|
|
72
|
+
* grammar `parseInboxBody` depends on). */
|
|
73
|
+
export declare function formatDataCard(kind: string, facts: Record<string, string | number | boolean | undefined>, body: string): string;
|
|
74
|
+
/** Parse a runtime envelope, with pre-envelope customType compatibility. */
|
|
75
|
+
export declare function parseCard(message: GeneratedContextMessageLike): GeneratedCard | null;
|
|
76
|
+
/** Whether an inbox entry is the person's own words. A `human-answer` entry
|
|
77
|
+
* whose body is itself a runtime card is a runtime notice — review approvals
|
|
78
|
+
* were delivered that way before they became plain prose — never speech. */
|
|
79
|
+
export declare function isHumanWordsEntry(entry: CardEntry): boolean;
|
|
80
|
+
/** Explain how an inbox entry's ref is read without guessing its filesystem location. */
|
|
81
|
+
export declare function formatInboxRefInstruction(ref: string): string;
|
|
82
|
+
/** Format a complete inbox card from report bodies resolved by the caller. */
|
|
83
|
+
export declare function formatInboxCard(sections: readonly InboxCardSection[]): string;
|