@mono-agent/agent-app 0.20.11 → 0.21.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 +260 -98
- package/dist/adapter-send-tools.d.ts +3 -2
- package/dist/adapter-send-tools.d.ts.map +1 -1
- package/dist/adapter-send-tools.js +15 -5
- package/dist/adapter-send-tools.js.map +1 -1
- package/dist/app-controller-channels.d.ts +6 -0
- package/dist/app-controller-channels.d.ts.map +1 -1
- package/dist/app-controller-channels.js +29 -2
- package/dist/app-controller-channels.js.map +1 -1
- package/dist/app-controller-continuation.d.ts.map +1 -1
- package/dist/app-controller-continuation.js +2 -3
- package/dist/app-controller-continuation.js.map +1 -1
- package/dist/app-controller-lifecycle.d.ts +4 -0
- package/dist/app-controller-lifecycle.d.ts.map +1 -1
- package/dist/app-controller-lifecycle.js +7 -0
- package/dist/app-controller-lifecycle.js.map +1 -1
- package/dist/app-controller-maintenance.d.ts +3 -1
- package/dist/app-controller-maintenance.d.ts.map +1 -1
- package/dist/app-controller-maintenance.js +3 -0
- package/dist/app-controller-maintenance.js.map +1 -1
- package/dist/app-controller-monitors.d.ts +26 -0
- package/dist/app-controller-monitors.d.ts.map +1 -0
- package/dist/app-controller-monitors.js +127 -0
- package/dist/app-controller-monitors.js.map +1 -0
- package/dist/app-controller-responder.d.ts +9 -17
- package/dist/app-controller-responder.d.ts.map +1 -1
- package/dist/app-controller-responder.js +54 -86
- package/dist/app-controller-responder.js.map +1 -1
- package/dist/app-controller-traceability.d.ts.map +1 -1
- package/dist/app-controller-traceability.js +3 -0
- package/dist/app-controller-traceability.js.map +1 -1
- package/dist/app-controller-types.d.ts +1 -0
- package/dist/app-controller-types.d.ts.map +1 -1
- package/dist/app-controller-utils.d.ts +1 -5
- package/dist/app-controller-utils.d.ts.map +1 -1
- package/dist/app-controller-utils.js +4 -21
- package/dist/app-controller-utils.js.map +1 -1
- package/dist/app-controller.d.ts +26 -10
- package/dist/app-controller.d.ts.map +1 -1
- package/dist/app-controller.js +39 -1
- package/dist/app-controller.js.map +1 -1
- package/dist/artifact-retention.js +11 -0
- package/dist/artifact-retention.js.map +1 -1
- package/dist/background.d.ts +0 -6
- package/dist/background.d.ts.map +1 -1
- package/dist/background.js +5 -58
- package/dist/background.js.map +1 -1
- package/dist/channel-drivers/slack.d.ts.map +1 -1
- package/dist/channel-drivers/slack.js +18 -0
- package/dist/channel-drivers/slack.js.map +1 -1
- package/dist/channel-drivers/telegram.d.ts.map +1 -1
- package/dist/channel-drivers/telegram.js +26 -0
- package/dist/channel-drivers/telegram.js.map +1 -1
- package/dist/channel-drivers/tui.d.ts +68 -8
- package/dist/channel-drivers/tui.d.ts.map +1 -1
- package/dist/channel-drivers/tui.js +407 -89
- package/dist/channel-drivers/tui.js.map +1 -1
- package/dist/channel-runtime-controls.d.ts +2 -1
- package/dist/channel-runtime-controls.d.ts.map +1 -1
- package/dist/channel-runtime-controls.js +79 -22
- package/dist/channel-runtime-controls.js.map +1 -1
- package/dist/cli-args.d.ts +5 -8
- package/dist/cli-args.d.ts.map +1 -1
- package/dist/cli-args.js +33 -52
- package/dist/cli-args.js.map +1 -1
- package/dist/cli-background-command.d.ts.map +1 -1
- package/dist/cli-background-command.js +4 -0
- package/dist/cli-background-command.js.map +1 -1
- package/dist/cli-commands.d.ts.map +1 -1
- package/dist/cli-commands.js +24 -2
- package/dist/cli-commands.js.map +1 -1
- package/dist/cli-help.d.ts +26 -0
- package/dist/cli-help.d.ts.map +1 -1
- package/dist/cli-help.js +58 -53
- package/dist/cli-help.js.map +1 -1
- package/dist/cli-init-command.d.ts +1 -2
- package/dist/cli-init-command.d.ts.map +1 -1
- package/dist/cli-init-command.js +31 -71
- package/dist/cli-init-command.js.map +1 -1
- package/dist/cli-install-skill-command.d.ts.map +1 -1
- package/dist/cli-install-skill-command.js +12 -3
- package/dist/cli-install-skill-command.js.map +1 -1
- package/dist/config-reference.d.ts +1 -0
- package/dist/config-reference.d.ts.map +1 -1
- package/dist/config-reference.js +217 -60
- package/dist/config-reference.js.map +1 -1
- package/dist/configured-agent.d.ts +27 -4
- package/dist/configured-agent.d.ts.map +1 -1
- package/dist/configured-agent.js +159 -112
- package/dist/configured-agent.js.map +1 -1
- package/dist/conversation-title.d.ts.map +1 -1
- package/dist/conversation-title.js +9 -2
- package/dist/conversation-title.js.map +1 -1
- package/dist/cron-control-store.d.ts.map +1 -1
- package/dist/cron-control-store.js +4 -2
- package/dist/cron-control-store.js.map +1 -1
- package/dist/doctor.d.ts +7 -13
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +406 -770
- package/dist/doctor.js.map +1 -1
- package/dist/first-run-readiness.d.ts.map +1 -1
- package/dist/first-run-readiness.js +0 -6
- package/dist/first-run-readiness.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interaction-bridge.d.ts +3 -3
- package/dist/interaction-bridge.d.ts.map +1 -1
- package/dist/interaction-bridge.js +27 -10
- package/dist/interaction-bridge.js.map +1 -1
- package/dist/launchd.d.ts +2 -0
- package/dist/launchd.d.ts.map +1 -1
- package/dist/launchd.js +3 -0
- package/dist/launchd.js.map +1 -1
- package/dist/local-tui-session.d.ts +14 -0
- package/dist/local-tui-session.d.ts.map +1 -0
- package/dist/local-tui-session.js +100 -0
- package/dist/local-tui-session.js.map +1 -0
- package/dist/mcp-apps.d.ts.map +1 -1
- package/dist/mcp-apps.js +3 -0
- package/dist/mcp-apps.js.map +1 -1
- package/dist/memory-journal.d.ts +53 -0
- package/dist/memory-journal.d.ts.map +1 -0
- package/dist/memory-journal.js +586 -0
- package/dist/memory-journal.js.map +1 -0
- package/dist/memory-recall.d.ts.map +1 -1
- package/dist/memory-recall.js +16 -2
- package/dist/memory-recall.js.map +1 -1
- package/dist/memory-remember.d.ts +49 -0
- package/dist/memory-remember.d.ts.map +1 -0
- package/dist/memory-remember.js +190 -0
- package/dist/memory-remember.js.map +1 -0
- package/dist/memory-retrieval.d.ts +33 -0
- package/dist/memory-retrieval.d.ts.map +1 -1
- package/dist/memory-retrieval.js +43 -0
- package/dist/memory-retrieval.js.map +1 -1
- package/dist/model-effort-capabilities.d.ts +8 -9
- package/dist/model-effort-capabilities.d.ts.map +1 -1
- package/dist/model-effort-capabilities.js +17 -35
- package/dist/model-effort-capabilities.js.map +1 -1
- package/dist/modules/base.d.ts +3 -4
- package/dist/modules/base.d.ts.map +1 -1
- package/dist/modules/base.js +4 -6
- package/dist/modules/base.js.map +1 -1
- package/dist/modules/catalog.d.ts.map +1 -1
- package/dist/modules/catalog.js +11 -9
- package/dist/modules/catalog.js.map +1 -1
- package/dist/modules/known-tools.d.ts +2 -2
- package/dist/modules/known-tools.d.ts.map +1 -1
- package/dist/modules/known-tools.js +7 -0
- package/dist/modules/known-tools.js.map +1 -1
- package/dist/monitor-channel-routing.d.ts +20 -0
- package/dist/monitor-channel-routing.d.ts.map +1 -0
- package/dist/monitor-channel-routing.js +73 -0
- package/dist/monitor-channel-routing.js.map +1 -0
- package/dist/monitors-command.d.ts +23 -0
- package/dist/monitors-command.d.ts.map +1 -0
- package/dist/monitors-command.js +217 -0
- package/dist/monitors-command.js.map +1 -0
- package/dist/monitors-config.d.ts +77 -0
- package/dist/monitors-config.d.ts.map +1 -0
- package/dist/monitors-config.js +150 -0
- package/dist/monitors-config.js.map +1 -0
- package/dist/monitors-context.d.ts +58 -0
- package/dist/monitors-context.d.ts.map +1 -0
- package/dist/monitors-context.js +194 -0
- package/dist/monitors-context.js.map +1 -0
- package/dist/monitors-runtime.d.ts +36 -0
- package/dist/monitors-runtime.d.ts.map +1 -0
- package/dist/monitors-runtime.js +103 -0
- package/dist/monitors-runtime.js.map +1 -0
- package/dist/monitors-service.d.ts +71 -0
- package/dist/monitors-service.d.ts.map +1 -0
- package/dist/monitors-service.js +1796 -0
- package/dist/monitors-service.js.map +1 -0
- package/dist/monitors-store.d.ts +93 -0
- package/dist/monitors-store.d.ts.map +1 -0
- package/dist/monitors-store.js +313 -0
- package/dist/monitors-store.js.map +1 -0
- package/dist/notify-destinations.d.ts +3 -2
- package/dist/notify-destinations.d.ts.map +1 -1
- package/dist/notify-destinations.js +6 -7
- package/dist/notify-destinations.js.map +1 -1
- package/dist/posted-reply-history.d.ts.map +1 -1
- package/dist/posted-reply-history.js +40 -3
- package/dist/posted-reply-history.js.map +1 -1
- package/dist/proactive-notify.d.ts +20 -1
- package/dist/proactive-notify.d.ts.map +1 -1
- package/dist/proactive-notify.js +56 -3
- package/dist/proactive-notify.js.map +1 -1
- package/dist/process-job-channel-routing.js +2 -1
- package/dist/process-job-channel-routing.js.map +1 -1
- package/dist/process-job-output-tail.d.ts +53 -0
- package/dist/process-job-output-tail.d.ts.map +1 -0
- package/dist/process-job-output-tail.js +257 -0
- package/dist/process-job-output-tail.js.map +1 -0
- package/dist/process-jobs-config.d.ts +1 -1
- package/dist/process-jobs-config.js +1 -1
- package/dist/process-jobs-config.js.map +1 -1
- package/dist/process-jobs-context.d.ts +11 -1
- package/dist/process-jobs-context.d.ts.map +1 -1
- package/dist/process-jobs-context.js +55 -11
- package/dist/process-jobs-context.js.map +1 -1
- package/dist/process-jobs-protection.js +1 -1
- package/dist/process-jobs-protection.js.map +1 -1
- package/dist/process-jobs-runtime.d.ts.map +1 -1
- package/dist/process-jobs-runtime.js +15 -12
- package/dist/process-jobs-runtime.js.map +1 -1
- package/dist/process-jobs-service.d.ts.map +1 -1
- package/dist/process-jobs-service.js +118 -172
- package/dist/process-jobs-service.js.map +1 -1
- package/dist/process-jobs-store.d.ts +3 -1
- package/dist/process-jobs-store.d.ts.map +1 -1
- package/dist/process-jobs-store.js +4 -1
- package/dist/process-jobs-store.js.map +1 -1
- package/dist/process-output-redaction.d.ts +58 -0
- package/dist/process-output-redaction.d.ts.map +1 -0
- package/dist/process-output-redaction.js +311 -0
- package/dist/process-output-redaction.js.map +1 -0
- package/dist/project-skills.d.ts +11 -5
- package/dist/project-skills.d.ts.map +1 -1
- package/dist/project-skills.js +88 -39
- package/dist/project-skills.js.map +1 -1
- package/dist/provider-auth-checks.d.ts +27 -0
- package/dist/provider-auth-checks.d.ts.map +1 -0
- package/dist/provider-auth-checks.js +349 -0
- package/dist/provider-auth-checks.js.map +1 -0
- package/dist/provider-auth-observations.d.ts +22 -0
- package/dist/provider-auth-observations.d.ts.map +1 -0
- package/dist/provider-auth-observations.js +139 -0
- package/dist/provider-auth-observations.js.map +1 -0
- package/dist/provider-auth-operator.d.ts +19 -0
- package/dist/provider-auth-operator.d.ts.map +1 -0
- package/dist/provider-auth-operator.js +560 -0
- package/dist/provider-auth-operator.js.map +1 -0
- package/dist/provider-auth-status.d.ts +20 -0
- package/dist/provider-auth-status.d.ts.map +1 -0
- package/dist/provider-auth-status.js +235 -0
- package/dist/provider-auth-status.js.map +1 -0
- package/dist/provider-model-catalog.d.ts +95 -0
- package/dist/provider-model-catalog.d.ts.map +1 -0
- package/dist/provider-model-catalog.js +550 -0
- package/dist/provider-model-catalog.js.map +1 -0
- package/dist/provider-setup.d.ts +26 -13
- package/dist/provider-setup.d.ts.map +1 -1
- package/dist/provider-setup.js +106 -130
- package/dist/provider-setup.js.map +1 -1
- package/dist/readiness-probe-worker.d.ts +1 -2
- package/dist/readiness-probe-worker.d.ts.map +1 -1
- package/dist/readiness-probe-worker.js +3 -8
- package/dist/readiness-probe-worker.js.map +1 -1
- package/dist/readiness-probe.d.ts +1 -1
- package/dist/readiness-probe.d.ts.map +1 -1
- package/dist/readiness-probe.js +3 -33
- package/dist/readiness-probe.js.map +1 -1
- package/dist/reply-artifacts.d.ts +3 -1
- package/dist/reply-artifacts.d.ts.map +1 -1
- package/dist/reply-artifacts.js +45 -10
- package/dist/reply-artifacts.js.map +1 -1
- package/dist/request-model-override.d.ts +14 -37
- package/dist/request-model-override.d.ts.map +1 -1
- package/dist/request-model-override.js +105 -143
- package/dist/request-model-override.js.map +1 -1
- package/dist/request-scoped-mcp.d.ts +3 -0
- package/dist/request-scoped-mcp.d.ts.map +1 -1
- package/dist/request-scoped-mcp.js +1 -1
- package/dist/request-scoped-mcp.js.map +1 -1
- package/dist/run-history.d.ts.map +1 -1
- package/dist/run-history.js +56 -13
- package/dist/run-history.js.map +1 -1
- package/dist/runtime-option-extensions.d.ts +2 -4
- package/dist/runtime-option-extensions.d.ts.map +1 -1
- package/dist/runtime-option-extensions.js +4 -8
- package/dist/runtime-option-extensions.js.map +1 -1
- package/dist/runtime-routes.d.ts +5 -5
- package/dist/runtime-routes.d.ts.map +1 -1
- package/dist/runtime-routes.js +29 -18
- package/dist/runtime-routes.js.map +1 -1
- package/dist/sandbox-settings-cleanup.d.ts +15 -0
- package/dist/sandbox-settings-cleanup.d.ts.map +1 -0
- package/dist/sandbox-settings-cleanup.js +88 -0
- package/dist/sandbox-settings-cleanup.js.map +1 -0
- package/dist/seen-conversations.d.ts +4 -3
- package/dist/seen-conversations.d.ts.map +1 -1
- package/dist/seen-conversations.js +6 -5
- package/dist/seen-conversations.js.map +1 -1
- package/dist/session-history.d.ts +14 -0
- package/dist/session-history.d.ts.map +1 -1
- package/dist/session-history.js +120 -5
- package/dist/session-history.js.map +1 -1
- package/dist/systemd-command.d.ts +8 -0
- package/dist/systemd-command.d.ts.map +1 -0
- package/dist/systemd-command.js +206 -0
- package/dist/systemd-command.js.map +1 -0
- package/dist/systemd.d.ts +51 -0
- package/dist/systemd.d.ts.map +1 -0
- package/dist/systemd.js +299 -0
- package/dist/systemd.js.map +1 -0
- package/dist/tool-output-artifacts.d.ts +4 -0
- package/dist/tool-output-artifacts.d.ts.map +1 -0
- package/dist/tool-output-artifacts.js +17 -0
- package/dist/tool-output-artifacts.js.map +1 -0
- package/dist/trigger-overrides.d.ts +6 -0
- package/dist/trigger-overrides.d.ts.map +1 -1
- package/dist/trigger-overrides.js +36 -4
- package/dist/trigger-overrides.js.map +1 -1
- package/dist/tui-command.d.ts +0 -45
- package/dist/tui-command.d.ts.map +1 -1
- package/dist/tui-command.js +27 -264
- package/dist/tui-command.js.map +1 -1
- package/dist/untrusted-text.d.ts +36 -0
- package/dist/untrusted-text.d.ts.map +1 -0
- package/dist/untrusted-text.js +150 -0
- package/dist/untrusted-text.js.map +1 -0
- package/dist/web-command.d.ts +3 -0
- package/dist/web-command.d.ts.map +1 -1
- package/dist/web-command.js +112 -7
- package/dist/web-command.js.map +1 -1
- package/dist/web-request-coordinator.d.ts +19 -0
- package/dist/web-request-coordinator.d.ts.map +1 -0
- package/dist/web-request-coordinator.js +242 -0
- package/dist/web-request-coordinator.js.map +1 -0
- package/dist/wizard/answers.d.ts +3 -9
- package/dist/wizard/answers.d.ts.map +1 -1
- package/dist/wizard/answers.js +11 -36
- package/dist/wizard/answers.js.map +1 -1
- package/dist/wizard/from-flags.d.ts +1 -2
- package/dist/wizard/from-flags.d.ts.map +1 -1
- package/dist/wizard/from-flags.js +8 -3
- package/dist/wizard/from-flags.js.map +1 -1
- package/dist/wizard/model-discovery.d.ts +7 -8
- package/dist/wizard/model-discovery.d.ts.map +1 -1
- package/dist/wizard/model-discovery.js +58 -431
- package/dist/wizard/model-discovery.js.map +1 -1
- package/dist/wizard/presets.js +2 -2
- package/dist/wizard/presets.js.map +1 -1
- package/dist/wizard/prompts.d.ts +13 -12
- package/dist/wizard/prompts.d.ts.map +1 -1
- package/dist/wizard/prompts.js +25 -45
- package/dist/wizard/prompts.js.map +1 -1
- package/dist/wizard/run.d.ts.map +1 -1
- package/dist/wizard/run.js +30 -153
- package/dist/wizard/run.js.map +1 -1
- package/package.json +18 -18
- package/schema/mono-agent.config.schema.json +301 -53
- package/skills/mono-agent-composer/SKILL.md +5 -5
- package/skills/mono-agent-composer/references/config-blueprint.md +61 -47
- package/skills/mono-agent-composer/references/discovery-questions.md +18 -18
- package/skills/mono-agent-composer/references/feature-coverage.md +39 -21
- package/skills/mono-agent-composer/references/package-map.md +26 -17
- package/skills/mono-agent-composer/references/playbooks.md +39 -28
- package/skills/mono-agent-composer/references/validation.md +4 -3
- package/dist/codex-model-catalog.d.ts +0 -15
- package/dist/codex-model-catalog.d.ts.map +0 -1
- package/dist/codex-model-catalog.js +0 -220
- package/dist/codex-model-catalog.js.map +0 -1
- package/dist/configuration-proposal-main.d.ts +0 -3
- package/dist/configuration-proposal-main.d.ts.map +0 -1
- package/dist/configuration-proposal-main.js +0 -13
- package/dist/configuration-proposal-main.js.map +0 -1
- package/dist/configuration-proposal-tool.d.ts +0 -33
- package/dist/configuration-proposal-tool.d.ts.map +0 -1
- package/dist/configuration-proposal-tool.js +0 -188
- package/dist/configuration-proposal-tool.js.map +0 -1
- package/dist/local-configuration.d.ts +0 -99
- package/dist/local-configuration.d.ts.map +0 -1
- package/dist/local-configuration.js +0 -1330
- package/dist/local-configuration.js.map +0 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared deterministic checks for model-authored free text that the host is
|
|
3
|
+
* about to display to an operator or persist durably.
|
|
4
|
+
*
|
|
5
|
+
* These are defense in depth, not a guarantee. `SECURITY.md` is explicit that
|
|
6
|
+
* free-form model, user, and tool text may still contain sensitive data: what
|
|
7
|
+
* follows catches known credential shapes and this agent's own configured
|
|
8
|
+
* secrets, not every conceivable secret. Callers reject rather than redact, so
|
|
9
|
+
* a partial match never produces a silently mangled value that still reports
|
|
10
|
+
* success.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Reject terminal and bidi control characters. Ordinary Unicode text and LF
|
|
14
|
+
* newlines stay intact; what goes is anything that could clear, overwrite, or
|
|
15
|
+
* visually reorder text an operator later reads.
|
|
16
|
+
*/
|
|
17
|
+
export declare function containsUnsafeReviewControl(value: string): boolean;
|
|
18
|
+
/** Whether the text carries a value shaped like a well-known credential. */
|
|
19
|
+
export declare function containsSecretLikeValue(value: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The live credential values this process actually holds, taken from
|
|
22
|
+
* environment variables whose NAME looks credential-bearing. Matching against
|
|
23
|
+
* these is exact rather than heuristic: it catches the agent echoing back a
|
|
24
|
+
* secret it was configured with, which no shape rule can promise.
|
|
25
|
+
*/
|
|
26
|
+
export declare function knownEnvironmentSecretValues(env: Record<string, string | undefined>): readonly string[];
|
|
27
|
+
/**
|
|
28
|
+
* Whether the text contains any of this agent's own configured secret values.
|
|
29
|
+
*
|
|
30
|
+
* Both sides are NFKC-folded before comparison. Callers normalize the text they
|
|
31
|
+
* are about to store, so comparing it against a raw environment value would
|
|
32
|
+
* miss a credential that is itself configured in a compatibility form (a
|
|
33
|
+
* fullwidth password matches only once both sides agree on a domain).
|
|
34
|
+
*/
|
|
35
|
+
export declare function containsKnownSecretValue(value: string, secrets: readonly string[]): boolean;
|
|
36
|
+
//# sourceMappingURL=untrusted-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"untrusted-text.d.ts","sourceRoot":"","sources":["../src/untrusted-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA+DH;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAYlE;AA4BD,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAK9D;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,MAAM,EAAE,CAWvG;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAS3F"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared deterministic checks for model-authored free text that the host is
|
|
3
|
+
* about to display to an operator or persist durably.
|
|
4
|
+
*
|
|
5
|
+
* These are defense in depth, not a guarantee. `SECURITY.md` is explicit that
|
|
6
|
+
* free-form model, user, and tool text may still contain sensitive data: what
|
|
7
|
+
* follows catches known credential shapes and this agent's own configured
|
|
8
|
+
* secrets, not every conceivable secret. Callers reject rather than redact, so
|
|
9
|
+
* a partial match never produces a silently mangled value that still reports
|
|
10
|
+
* success.
|
|
11
|
+
*/
|
|
12
|
+
const BIDI_CONTROL = /\p{Bidi_Control}/u;
|
|
13
|
+
/**
|
|
14
|
+
* Well-known credential shapes that are dangerous even with no surrounding
|
|
15
|
+
* label: OpenAI, GitHub, and Slack tokens, bearer headers, and Telegram bot
|
|
16
|
+
* tokens. Each requires a credential-specific alphabet and length, so prose
|
|
17
|
+
* that merely mentions `sk-` does not match.
|
|
18
|
+
*/
|
|
19
|
+
const SECRET_LIKE_VALUE = new RegExp([
|
|
20
|
+
// OpenAI, including project/service-account forms.
|
|
21
|
+
String.raw `sk-[A-Za-z0-9_-]{12,}`,
|
|
22
|
+
// GitHub classic/OAuth/refresh/server/user tokens, plus fine-grained PATs.
|
|
23
|
+
String.raw `gh[pousr]_[A-Za-z0-9]{20,}`,
|
|
24
|
+
String.raw `github_pat_[A-Za-z0-9_]{20,}`,
|
|
25
|
+
// Slack bot/user/app-level tokens.
|
|
26
|
+
String.raw `xox[baprs]-[A-Za-z0-9-]{12,}`,
|
|
27
|
+
String.raw `xapp-[A-Za-z0-9-]{12,}`,
|
|
28
|
+
// AWS access key ids, long-term (AKIA) and temporary STS (ASIA).
|
|
29
|
+
String.raw `A(?:KIA|SIA)[A-Z0-9]{16}`,
|
|
30
|
+
// Telegram bot tokens.
|
|
31
|
+
String.raw `\d{6,12}:[A-Za-z0-9_-]{20,}`,
|
|
32
|
+
].map((shape) => String.raw `\b${shape}\b`).join("|")
|
|
33
|
+
// Bearer carries its own delimiter, so it is matched separately from the
|
|
34
|
+
// word-bounded shapes above. The payload must look like a token: `\S{12,}`
|
|
35
|
+
// also matched ordinary prose such as "Bearer authentication". Basic is
|
|
36
|
+
// handled by decoding rather than by length — see containsBasicCredential.
|
|
37
|
+
+ String.raw `|\bBearer\s+[A-Za-z0-9+/._~-]{16,}={0,2}`,
|
|
38
|
+
// Case-insensitive: a lowercase `bearer ` or `akia…` is the same credential.
|
|
39
|
+
"iu");
|
|
40
|
+
/** Environment variable names whose values are treated as live credentials. */
|
|
41
|
+
const CREDENTIAL_ENV_NAME = /(?:api.?key|credential|password|secret|token)/iu;
|
|
42
|
+
/**
|
|
43
|
+
* Names whose value is provably a variable name or a filesystem location rather
|
|
44
|
+
* than a credential, mirroring the `env`/`path` carve-out that
|
|
45
|
+
* `secretBearingPointer` already applies to config pointers.
|
|
46
|
+
*
|
|
47
|
+
* Deliberately narrow. An earlier revision also excluded `_TOKENS`, `_NAME`,
|
|
48
|
+
* and `_URL`, which dropped genuine credential holders such as
|
|
49
|
+
* `SERVICE_API_TOKENS` and `SLACK_APP_TOKENS` from the scan — and because this
|
|
50
|
+
* helper is shared by security-sensitive persistence guards, so that weakened multiple surfaces
|
|
51
|
+
* at once. The residual cost is accepted and documented: a credential-named
|
|
52
|
+
* budget such as `..._KEEP_RECENT_TOKENS=8000` still makes the literal `8000`
|
|
53
|
+
* unstorable through `Remember`. Favouring a false rejection over a persisted
|
|
54
|
+
* credential is the intended trade here.
|
|
55
|
+
*/
|
|
56
|
+
const NON_CREDENTIAL_ENV_NAME = /(?:_ENV|_ENV_VAR|_PATH|_FILE|_DIR)$/iu;
|
|
57
|
+
/**
|
|
58
|
+
* Shortest environment value worth matching.
|
|
59
|
+
*
|
|
60
|
+
* Deliberately low: a short PIN or numeric key is still a credential, and this
|
|
61
|
+
* guard is shared by other persistence checks, so raising it to reduce
|
|
62
|
+
* false positives would quietly widen what both surfaces let through. The
|
|
63
|
+
* name-based exclusion above is the targeted fix for operational settings.
|
|
64
|
+
*/
|
|
65
|
+
const MIN_KNOWN_SECRET_LENGTH = 4;
|
|
66
|
+
/**
|
|
67
|
+
* Reject terminal and bidi control characters. Ordinary Unicode text and LF
|
|
68
|
+
* newlines stay intact; what goes is anything that could clear, overwrite, or
|
|
69
|
+
* visually reorder text an operator later reads.
|
|
70
|
+
*/
|
|
71
|
+
export function containsUnsafeReviewControl(value) {
|
|
72
|
+
for (const character of value) {
|
|
73
|
+
const codePoint = character.codePointAt(0);
|
|
74
|
+
if ((codePoint <= 0x1f && codePoint !== 0x0a)
|
|
75
|
+
|| (codePoint >= 0x7f && codePoint <= 0x9f)
|
|
76
|
+
|| BIDI_CONTROL.test(character)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* HTTP Basic payloads are base64 of `user:password`, which can be as short as
|
|
84
|
+
* four characters and can contain non-UTF-8 legacy bytes. Decode the candidate
|
|
85
|
+
* instead: a real pair contains a colon and no control bytes, while prose that
|
|
86
|
+
* merely names the scheme ("Basic authentication") does not.
|
|
87
|
+
*/
|
|
88
|
+
const BASIC_SCHEME = /\bBasic\s+([A-Za-z0-9+/]{2,}={0,2})(?![A-Za-z0-9+/=])/giu;
|
|
89
|
+
function containsBasicCredential(value) {
|
|
90
|
+
for (const match of value.matchAll(BASIC_SCHEME)) {
|
|
91
|
+
const payload = match[1];
|
|
92
|
+
if (payload === undefined)
|
|
93
|
+
continue;
|
|
94
|
+
const unpaddedPayload = payload.replace(/=+$/u, "");
|
|
95
|
+
if (unpaddedPayload.length % 4 === 1)
|
|
96
|
+
continue;
|
|
97
|
+
const bytes = Buffer.from(payload, "base64");
|
|
98
|
+
// Buffer's base64 decoder is intentionally permissive. Require a canonical
|
|
99
|
+
// round trip so malformed prose is never reinterpreted as a credential.
|
|
100
|
+
if (bytes.toString("base64").replace(/=+$/u, "") !== unpaddedPayload)
|
|
101
|
+
continue;
|
|
102
|
+
if (bytes.includes(0x3a)
|
|
103
|
+
&& !bytes.some((byte) => byte <= 0x1f || byte === 0x7f))
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
/** Whether the text carries a value shaped like a well-known credential. */
|
|
109
|
+
export function containsSecretLikeValue(value) {
|
|
110
|
+
// Callers outside Remember also use this guard. Fold compatibility
|
|
111
|
+
// characters here so no caller can accidentally scan a weaker raw form.
|
|
112
|
+
const normalized = value.normalize("NFKC");
|
|
113
|
+
return SECRET_LIKE_VALUE.test(normalized) || containsBasicCredential(normalized);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The live credential values this process actually holds, taken from
|
|
117
|
+
* environment variables whose NAME looks credential-bearing. Matching against
|
|
118
|
+
* these is exact rather than heuristic: it catches the agent echoing back a
|
|
119
|
+
* secret it was configured with, which no shape rule can promise.
|
|
120
|
+
*/
|
|
121
|
+
export function knownEnvironmentSecretValues(env) {
|
|
122
|
+
return Object.entries(env)
|
|
123
|
+
.filter(([name, value]) => CREDENTIAL_ENV_NAME.test(name)
|
|
124
|
+
&& !NON_CREDENTIAL_ENV_NAME.test(name)
|
|
125
|
+
// Remember persists in NFKC form. Retain a value when either its raw or
|
|
126
|
+
// folded representation reaches the floor so compatibility ligatures
|
|
127
|
+
// cannot disappear from the configured-secret set before comparison.
|
|
128
|
+
&& value !== undefined
|
|
129
|
+
&& Math.max(value.length, value.normalize("NFKC").length) >= MIN_KNOWN_SECRET_LENGTH)
|
|
130
|
+
.map(([, value]) => value);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Whether the text contains any of this agent's own configured secret values.
|
|
134
|
+
*
|
|
135
|
+
* Both sides are NFKC-folded before comparison. Callers normalize the text they
|
|
136
|
+
* are about to store, so comparing it against a raw environment value would
|
|
137
|
+
* miss a credential that is itself configured in a compatibility form (a
|
|
138
|
+
* fullwidth password matches only once both sides agree on a domain).
|
|
139
|
+
*/
|
|
140
|
+
export function containsKnownSecretValue(value, secrets) {
|
|
141
|
+
const folded = value.normalize("NFKC");
|
|
142
|
+
return secrets.some((secret) => {
|
|
143
|
+
const foldedSecret = secret.normalize("NFKC");
|
|
144
|
+
return value.includes(secret)
|
|
145
|
+
|| folded.includes(foldedSecret)
|
|
146
|
+
|| folded.includes(secret)
|
|
147
|
+
|| value.includes(foldedSecret);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=untrusted-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"untrusted-text.js","sourceRoot":"","sources":["../src/untrusted-text.ts"],"names":[],"mappings":"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"}
|
package/dist/web-command.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ interface StartWebServerOptions {
|
|
|
19
19
|
readonly host?: string;
|
|
20
20
|
readonly port?: number;
|
|
21
21
|
readonly theme?: WebTheme;
|
|
22
|
+
readonly name?: string;
|
|
22
23
|
readonly registryDirs?: readonly string[];
|
|
23
24
|
readonly stateDir?: string;
|
|
24
25
|
readonly env?: Record<string, string | undefined>;
|
|
@@ -37,6 +38,7 @@ export interface RunWebCommandOptions {
|
|
|
37
38
|
readonly host?: string;
|
|
38
39
|
readonly port?: number;
|
|
39
40
|
readonly theme?: string;
|
|
41
|
+
readonly name?: string;
|
|
40
42
|
readonly loopback?: boolean;
|
|
41
43
|
readonly follow?: boolean;
|
|
42
44
|
readonly lines?: number;
|
|
@@ -87,6 +89,7 @@ export interface RunWebCommandDeps {
|
|
|
87
89
|
stop(): void;
|
|
88
90
|
};
|
|
89
91
|
readonly homeDir?: string;
|
|
92
|
+
readonly systemd?: import("./systemd.js").SystemdDeps;
|
|
90
93
|
}
|
|
91
94
|
export interface TailscaleServeOwnership {
|
|
92
95
|
readonly schema: typeof TAILSCALE_OWNERSHIP_SCHEMA;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-command.d.ts","sourceRoot":"","sources":["../src/web-command.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AA4BhD,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAGZ,yBAAyB,EAC1B,MAAM,cAAc,CAAC;AAetB,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AAE9E,OAAO,EAAE,yCAAyC,EAAE,MAAM,wCAAwC,CAAC;AAEnG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AASlE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAC1C,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAGrC,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AAGtE,QAAA,MAAM,0BAA0B,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"web-command.d.ts","sourceRoot":"","sources":["../src/web-command.ts"],"names":[],"mappings":"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"}
|
package/dist/web-command.js
CHANGED
|
@@ -37,6 +37,9 @@ const TAILSCALE_STATUS_RETRY_MS = 200;
|
|
|
37
37
|
const WEB_PACKAGE_NAME = "@mono-agent/web";
|
|
38
38
|
const WEB_THEMES = ["evergreen", "ocean", "plum", "terracotta"];
|
|
39
39
|
const DEFAULT_WEB_THEME = "evergreen";
|
|
40
|
+
// Mirrors WEB_CONSOLE_NAME_MAX_CHARACTERS in @mono-agent/web; declared locally so this
|
|
41
|
+
// command keeps its type-only dependency on the lazily loaded web package.
|
|
42
|
+
const WEB_CONSOLE_NAME_MAX_CHARACTERS = 80;
|
|
40
43
|
export function webPaths(homeDir) {
|
|
41
44
|
return managedWebPaths(homeDir);
|
|
42
45
|
}
|
|
@@ -45,16 +48,17 @@ export function renderWebHelp() {
|
|
|
45
48
|
"mono-agent web — always-on multi-agent web console",
|
|
46
49
|
"",
|
|
47
50
|
" mono-agent web",
|
|
48
|
-
" mono-agent web start [--host <addr> | --loopback] [--port <n>] [--theme <name>]",
|
|
49
|
-
" mono-agent web restart [--host <addr> | --loopback] [--port <n>] [--theme <name>]",
|
|
51
|
+
" mono-agent web start [--host <addr> | --loopback] [--port <n>] [--theme <name>] [--name <label>]",
|
|
52
|
+
" mono-agent web restart [--host <addr> | --loopback] [--port <n>] [--theme <name>] [--name <label>]",
|
|
50
53
|
" mono-agent web stop | status",
|
|
51
54
|
" mono-agent web logs [--follow|-f] [--lines <n>]",
|
|
52
|
-
" mono-agent web run [--host <addr> | --loopback] [--port <n>] [--theme <name>]",
|
|
55
|
+
" mono-agent web run [--host <addr> | --loopback] [--port <n>] [--theme <name>] [--name <label>]",
|
|
53
56
|
" mono-agent web reset --all --yes",
|
|
54
57
|
"",
|
|
55
58
|
`Default bind: ${DEFAULT_WEB_HOST}:${String(DEFAULT_WEB_PORT)} (LAN/Tailnet reachable; no app login).`,
|
|
56
59
|
`Themes: ${WEB_THEMES.join(", ")} (default: ${DEFAULT_WEB_THEME}).`,
|
|
57
|
-
"--
|
|
60
|
+
"--name sets the installed PWA label, browser tab title, and rail brand; --name - restores the hostname default.",
|
|
61
|
+
"--loopback narrows the bind to 127.0.0.1. macOS start/restart claim a free Tailscale Serve HTTPS port; Linux HTTPS routes are externally managed.",
|
|
58
62
|
"",
|
|
59
63
|
].join("\n");
|
|
60
64
|
}
|
|
@@ -74,6 +78,40 @@ export async function runWebCommand(options, deps = {}) {
|
|
|
74
78
|
stdout.write(renderWebHelp());
|
|
75
79
|
return 2;
|
|
76
80
|
}
|
|
81
|
+
if ((deps.platform ?? process.platform) === "linux" && action !== "run" && action !== "reset") {
|
|
82
|
+
if (action === undefined)
|
|
83
|
+
stdout.write(renderWebHelp());
|
|
84
|
+
const { runSystemdWebCommand } = await import("./systemd-command.js");
|
|
85
|
+
const { isSystemdUserManagerUnavailable } = await import("./systemd.js");
|
|
86
|
+
try {
|
|
87
|
+
return await runSystemdWebCommand(options, {
|
|
88
|
+
...deps.systemd,
|
|
89
|
+
...(deps.homeDir === undefined ? {} : { homeDir: deps.homeDir }),
|
|
90
|
+
stdout, stderr,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (!isSystemdUserManagerUnavailable(error) || (action !== undefined && action !== "status"))
|
|
95
|
+
throw error;
|
|
96
|
+
if (action === undefined) {
|
|
97
|
+
await statusWeb(options, deps, false);
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
return await statusWeb(options, deps, true);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if ((deps.platform ?? process.platform) === "linux" && action === "reset") {
|
|
104
|
+
const { withSystemdLock, SYSTEMD_WEB_IDENTITY } = await import("./systemd.js");
|
|
105
|
+
try {
|
|
106
|
+
return await withSystemdLock(SYSTEMD_WEB_IDENTITY, {
|
|
107
|
+
...deps.systemd, ...(deps.homeDir === undefined ? {} : { homeDir: deps.homeDir }),
|
|
108
|
+
}, () => resetWeb(options, deps));
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
stderr.write(ui.errorLine(`Linux web reset failed: ${errorMessage(error)}`));
|
|
112
|
+
return 1;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
77
115
|
if (action === undefined) {
|
|
78
116
|
stdout.write(renderWebHelp());
|
|
79
117
|
await statusWeb(options, deps, false);
|
|
@@ -108,9 +146,15 @@ function validateWebFlags(action, options) {
|
|
|
108
146
|
if (options.theme !== undefined && !isWebTheme(options.theme)) {
|
|
109
147
|
return `--theme must be one of: ${WEB_THEMES.join(", ")}.`;
|
|
110
148
|
}
|
|
111
|
-
if (
|
|
149
|
+
if (options.name !== undefined) {
|
|
150
|
+
const nameError = invalidWebConsoleName(options.name);
|
|
151
|
+
if (nameError !== undefined)
|
|
152
|
+
return nameError;
|
|
153
|
+
}
|
|
154
|
+
if ((options.host !== undefined || options.port !== undefined || options.theme !== undefined
|
|
155
|
+
|| options.name !== undefined || options.loopback === true)
|
|
112
156
|
&& action !== "start" && action !== "restart" && action !== "run") {
|
|
113
|
-
return "--host, --port, --theme, and --loopback are only supported for web start, restart, or run.";
|
|
157
|
+
return "--host, --port, --theme, --name, and --loopback are only supported for web start, restart, or run.";
|
|
114
158
|
}
|
|
115
159
|
if ((options.follow === true || options.lines !== undefined) && action !== "logs") {
|
|
116
160
|
return "--follow and --lines are only supported for mono-agent web logs.";
|
|
@@ -129,6 +173,7 @@ async function runWebForeground(options, deps) {
|
|
|
129
173
|
const host = effectiveHost(options);
|
|
130
174
|
const port = options.port ?? DEFAULT_WEB_PORT;
|
|
131
175
|
const theme = selectedWebTheme(options.theme);
|
|
176
|
+
const consoleName = selectedWebConsoleName(options.name);
|
|
132
177
|
const paths = webPaths(deps.homeDir);
|
|
133
178
|
await (deps.prepareState ?? defaultPrepareWebState)({ stateDir: paths.stateDir, env: options.env });
|
|
134
179
|
const registryDir = resolveGlobalTraceRegistryDir(options.env);
|
|
@@ -136,7 +181,15 @@ async function runWebForeground(options, deps) {
|
|
|
136
181
|
let handle;
|
|
137
182
|
try {
|
|
138
183
|
const startServer = deps.startServer ?? defaultStartWebServer;
|
|
139
|
-
handle = await startServer({
|
|
184
|
+
handle = await startServer({
|
|
185
|
+
host,
|
|
186
|
+
port,
|
|
187
|
+
theme,
|
|
188
|
+
...(consoleName === undefined ? {} : { name: consoleName }),
|
|
189
|
+
registryDirs: [registryDir],
|
|
190
|
+
stateDir: paths.stateDir,
|
|
191
|
+
env: options.env,
|
|
192
|
+
});
|
|
140
193
|
}
|
|
141
194
|
catch (error) {
|
|
142
195
|
stderr.write(ui.errorLine(`mono-agent web failed to start: ${errorMessage(error)}`));
|
|
@@ -242,6 +295,10 @@ async function startWebBackground(options, deps, restart) {
|
|
|
242
295
|
stderr.write(ui.errorLine(`mono-agent web is already managed by launchd; use \`mono-agent web restart --theme ${options.theme}\` to change its theme.`));
|
|
243
296
|
return 1;
|
|
244
297
|
}
|
|
298
|
+
if (options.name !== undefined) {
|
|
299
|
+
stderr.write(ui.errorLine(`mono-agent web is already managed by launchd; use \`mono-agent web restart --name ${shellQuote(options.name)}\` to change its name.`));
|
|
300
|
+
return 1;
|
|
301
|
+
}
|
|
245
302
|
if (helper.loaded) {
|
|
246
303
|
try {
|
|
247
304
|
const loadedHelper = await (deps.inspectMaintenanceService ?? launchdWebMaintenanceInfo)(launchctl, uid);
|
|
@@ -394,6 +451,7 @@ async function startWebBackground(options, deps, restart) {
|
|
|
394
451
|
const host = effectiveHost(options, priorRecord?.host);
|
|
395
452
|
const port = options.port ?? priorRecord?.port ?? DEFAULT_WEB_PORT;
|
|
396
453
|
const theme = selectedWebTheme(options.theme, priorRecord?.theme);
|
|
454
|
+
const consoleName = selectedWebConsoleName(options.name, priorRecord?.name);
|
|
397
455
|
if (existingPlist !== undefined) {
|
|
398
456
|
try {
|
|
399
457
|
pendingMaintenanceIntent = await maintainStoppedWebLogsBeforePublication(paths, pendingMaintenanceIntent, deps.now ?? Date.now);
|
|
@@ -430,6 +488,7 @@ async function startWebBackground(options, deps, restart) {
|
|
|
430
488
|
host,
|
|
431
489
|
port,
|
|
432
490
|
theme,
|
|
491
|
+
...(consoleName === undefined ? {} : { name: consoleName }),
|
|
433
492
|
updatedAt: new Date((deps.now ?? Date.now)()).toISOString(),
|
|
434
493
|
};
|
|
435
494
|
const plist = buildWebPlistXml({
|
|
@@ -440,6 +499,7 @@ async function startWebBackground(options, deps, restart) {
|
|
|
440
499
|
host,
|
|
441
500
|
port,
|
|
442
501
|
theme,
|
|
502
|
+
...(consoleName === undefined ? {} : { name: consoleName }),
|
|
443
503
|
stdoutPath: paths.launchd.stdoutPath,
|
|
444
504
|
stderrPath: paths.launchd.stderrPath,
|
|
445
505
|
environment,
|
|
@@ -613,6 +673,7 @@ async function statusWeb(options, deps, strictExit) {
|
|
|
613
673
|
const host = record?.host ?? DEFAULT_WEB_HOST;
|
|
614
674
|
const port = record?.port ?? DEFAULT_WEB_PORT;
|
|
615
675
|
const theme = record?.theme ?? DEFAULT_WEB_THEME;
|
|
676
|
+
const consoleName = record?.name;
|
|
616
677
|
let service = { loaded: false };
|
|
617
678
|
let helper = { loaded: false };
|
|
618
679
|
if ((deps.platform ?? process.platform) === "darwin") {
|
|
@@ -719,6 +780,9 @@ async function statusWeb(options, deps, strictExit) {
|
|
|
719
780
|
: "stopped"],
|
|
720
781
|
["bind", recordRead.kind === "invalid" ? "invalid service record" : `${host}:${String(port)}`],
|
|
721
782
|
["theme", recordRead.kind === "invalid" ? "invalid service record" : theme],
|
|
783
|
+
["name", recordRead.kind === "invalid"
|
|
784
|
+
? "invalid service record"
|
|
785
|
+
: consoleName ?? "— (machine hostname)"],
|
|
722
786
|
["state", paths.stateDir],
|
|
723
787
|
["pid", service.pid === undefined ? "—" : String(service.pid)],
|
|
724
788
|
["log maintenance", maintenanceSummary],
|
|
@@ -773,6 +837,16 @@ async function resetWeb(options, deps) {
|
|
|
773
837
|
const stderr = deps.stderr ?? process.stderr;
|
|
774
838
|
const stdout = deps.stdout ?? process.stdout;
|
|
775
839
|
const paths = webPaths(deps.homeDir);
|
|
840
|
+
if ((deps.platform ?? process.platform) === "linux") {
|
|
841
|
+
const { inspectSystemd, readSystemdDefinition, SYSTEMD_WEB_IDENTITY } = await import("./systemd.js");
|
|
842
|
+
const systemdDeps = { ...deps.systemd, ...(deps.homeDir === undefined ? {} : { homeDir: deps.homeDir }) };
|
|
843
|
+
const service = await inspectSystemd(SYSTEMD_WEB_IDENTITY, systemdDeps).catch(() => undefined);
|
|
844
|
+
const definition = await readSystemdDefinition(SYSTEMD_WEB_IDENTITY, systemdDeps);
|
|
845
|
+
if (definition !== undefined || (service?.pid ?? 0) > 0 || service?.activeState === "activating") {
|
|
846
|
+
stderr.write(ui.errorLine("Run mono-agent web stop before resetting the systemd console."));
|
|
847
|
+
return 1;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
776
850
|
if ((deps.platform ?? process.platform) === "darwin") {
|
|
777
851
|
const launchctl = deps.launchctl ?? makeLaunchctlRunner();
|
|
778
852
|
const uid = (deps.getuid ?? requiredUid)();
|
|
@@ -843,6 +917,35 @@ function selectedWebTheme(value, priorTheme) {
|
|
|
843
917
|
return priorTheme ?? DEFAULT_WEB_THEME;
|
|
844
918
|
return value;
|
|
845
919
|
}
|
|
920
|
+
/**
|
|
921
|
+
* Console label precedence: this invocation's flag, then the persisted record, then
|
|
922
|
+
* undefined so the worker falls back to the machine hostname. A single hyphen resets
|
|
923
|
+
* the persisted choice to that fallback.
|
|
924
|
+
*/
|
|
925
|
+
function selectedWebConsoleName(value, priorName) {
|
|
926
|
+
if (value === undefined)
|
|
927
|
+
return priorName;
|
|
928
|
+
const name = value.trim();
|
|
929
|
+
return name === "-" ? undefined : name;
|
|
930
|
+
}
|
|
931
|
+
/** Reject labels the manifest, launchd argv, or launcher cannot carry faithfully. */
|
|
932
|
+
function invalidWebConsoleName(value) {
|
|
933
|
+
const name = value.trim();
|
|
934
|
+
if (name.length === 0)
|
|
935
|
+
return "--name must not be empty.";
|
|
936
|
+
if (/[\u0000-\u001f\u007f-\u009f\u2028-\u202e]/u.test(name)) {
|
|
937
|
+
return "--name must not contain control characters, line separators, or bidirectional overrides.";
|
|
938
|
+
}
|
|
939
|
+
if ([...name].length > WEB_CONSOLE_NAME_MAX_CHARACTERS) {
|
|
940
|
+
return `--name must be at most ${String(WEB_CONSOLE_NAME_MAX_CHARACTERS)} characters.`;
|
|
941
|
+
}
|
|
942
|
+
return undefined;
|
|
943
|
+
}
|
|
944
|
+
function shellQuote(value) {
|
|
945
|
+
if (/^[A-Za-z0-9_./:@%+=,-]+$/u.test(value))
|
|
946
|
+
return value;
|
|
947
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
948
|
+
}
|
|
846
949
|
async function ensureWebDirectories(paths) {
|
|
847
950
|
for (const path of [
|
|
848
951
|
dirname(paths.stateDir),
|
|
@@ -1556,6 +1659,8 @@ async function readServiceRecord(path) {
|
|
|
1556
1659
|
if (!isRecord(value) || value.schema !== WEB_SERVICE_SCHEMA || typeof value.host !== "string"
|
|
1557
1660
|
|| !Number.isSafeInteger(value.port) || value.port < 1 || value.port > 65_535
|
|
1558
1661
|
|| (value.theme !== undefined && !isWebTheme(value.theme))
|
|
1662
|
+
|| (value.name !== undefined
|
|
1663
|
+
&& (typeof value.name !== "string" || invalidWebConsoleName(value.name) !== undefined))
|
|
1559
1664
|
|| typeof value.updatedAt !== "string") {
|
|
1560
1665
|
return { kind: "invalid", detail: "the web service record has an invalid schema; repair or remove ~/.mono-agent/web/service.json" };
|
|
1561
1666
|
}
|