@gajae-code/coding-agent 0.12.6 → 0.12.8
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 +22 -1
- package/dist/types/async/job-manager.d.ts +36 -1
- package/dist/types/commands/notify.d.ts +4 -0
- package/dist/types/config/file-lock.d.ts +3 -0
- package/dist/types/config/model-discovery-manager.d.ts +6 -1
- package/dist/types/config/model-registry.d.ts +2 -0
- package/dist/types/config/resolve-config-value.d.ts +2 -1
- package/dist/types/config/settings-schema.d.ts +17 -1
- package/dist/types/eval/backend.d.ts +2 -2
- package/dist/types/exec/bash-executor.d.ts +8 -10
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +0 -36
- package/dist/types/internal-urls/registry-helpers.d.ts +0 -18
- package/dist/types/main.d.ts +1 -0
- package/dist/types/modes/components/hook-selector.d.ts +20 -0
- package/dist/types/modes/components/notifications-settings-editor.d.ts +53 -4
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +4 -2
- package/dist/types/sdk/broker/broker.d.ts +5 -1
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +1 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +11 -3
- package/dist/types/sdk/bus/config.d.ts +75 -113
- package/dist/types/sdk/bus/discord-live-provider.d.ts +8 -2
- package/dist/types/sdk/bus/discord-provider.d.ts +19 -0
- package/dist/types/sdk/bus/index.d.ts +1 -1
- package/dist/types/sdk/bus/notification-orchestration.d.ts +127 -18
- package/dist/types/sdk/bus/notification-service.d.ts +31 -4
- package/dist/types/sdk/bus/session-control.d.ts +8 -3
- package/dist/types/sdk/bus/slack-live-provider.d.ts +9 -2
- package/dist/types/sdk/bus/slack-provider.d.ts +22 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -4
- package/dist/types/sdk/client/discovery.d.ts +2 -1
- package/dist/types/sdk/host/host.d.ts +2 -23
- package/dist/types/sdk/host/query/handlers.d.ts +2 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +4 -7
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/providers.d.ts +22 -0
- package/dist/types/sdk/session-directory.d.ts +1 -1
- package/dist/types/session/artifacts.d.ts +5 -8
- package/dist/types/session/client-bridge.d.ts +0 -14
- package/dist/types/session/internal/managed-session-scope.d.ts +17 -1
- package/dist/types/session/internal/managed-session-storage.d.ts +11 -4
- package/dist/types/session/internal/native-publish-outcome.d.ts +1 -0
- package/dist/types/session/internal/session-open-errors.d.ts +5 -0
- package/dist/types/session/messages.d.ts +1 -4
- package/dist/types/session/session-manager.d.ts +7 -6
- package/dist/types/session/session-storage.d.ts +2 -0
- package/dist/types/session/streaming-output.d.ts +0 -32
- package/dist/types/task/receipt.d.ts +1 -2
- package/dist/types/task/types.d.ts +43 -178
- package/dist/types/tools/bash.d.ts +1 -1
- package/dist/types/tools/fetch.d.ts +0 -3
- package/dist/types/tools/output-meta.d.ts +5 -37
- package/dist/types/tools/subagent.d.ts +15 -0
- package/dist/types/tools/todo-write.d.ts +3 -0
- package/dist/types/tools/tool-result.d.ts +0 -1
- package/package.json +10 -8
- package/scripts/build-sdk-package-smoke.ts +51 -0
- package/scripts/capture-notifications-settings-showcase.ts +1 -1
- package/src/async/job-manager.ts +430 -46
- package/src/cli/notify-cli.ts +204 -94
- package/src/commands/notify.ts +19 -8
- package/src/config/file-lock.ts +6 -0
- package/src/config/model-discovery-manager.ts +50 -8
- package/src/config/model-registry.ts +862 -75
- package/src/config/resolve-config-value.ts +10 -8
- package/src/config/settings-schema.ts +25 -15
- package/src/config/settings.ts +15 -15
- package/src/cursor.ts +13 -20
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +2 -3
- package/src/eval/backend.ts +2 -2
- package/src/exec/bash-executor.ts +151 -425
- package/src/gjc-runtime/session-state-sidecar.ts +12 -2
- package/src/gjc-runtime/ultragoal-runtime.ts +3 -280
- package/src/gjc-runtime/workflow-manifest.generated.json +1 -40
- package/src/gjc-runtime/workflow-manifest.ts +0 -12
- package/src/internal-urls/agent-protocol.ts +38 -98
- package/src/internal-urls/artifact-protocol.ts +17 -28
- package/src/internal-urls/docs-index.generated.ts +7 -7
- package/src/internal-urls/registry-helpers.ts +0 -62
- package/src/main.ts +43 -7
- package/src/modes/DESIGN.md +11 -11
- package/src/modes/acp/acp-agent.ts +0 -24
- package/src/modes/acp/acp-client-bridge.ts +11 -154
- package/src/modes/components/hook-selector.ts +155 -44
- package/src/modes/components/model-selector.ts +242 -49
- package/src/modes/components/notifications-settings-editor.ts +631 -85
- package/src/modes/controllers/extension-ui-controller.ts +114 -15
- package/src/modes/controllers/selector-controller.ts +464 -50
- package/src/prompts/tools/bash.md +2 -2
- package/src/sdk/acp/adapter.ts +9 -200
- package/src/sdk/broker/broker.ts +54 -10
- package/src/sdk/broker/lifecycle-ledger.ts +34 -1
- package/src/sdk/broker/lifecycle.ts +47 -50
- package/src/sdk/bus/chat-daemon-cli.ts +12 -5
- package/src/sdk/bus/chat-daemon-control.ts +35 -8
- package/src/sdk/bus/chat-daemon-runtime.ts +16 -2
- package/src/sdk/bus/config.ts +534 -286
- package/src/sdk/bus/discord-live-provider.ts +57 -2
- package/src/sdk/bus/discord-provider.ts +21 -0
- package/src/sdk/bus/index.ts +105 -359
- package/src/sdk/bus/notification-orchestration.ts +371 -68
- package/src/sdk/bus/notification-service.ts +431 -130
- package/src/sdk/bus/session-control.ts +119 -44
- package/src/sdk/bus/slack-live-provider.ts +78 -2
- package/src/sdk/bus/slack-provider.ts +24 -0
- package/src/sdk/bus/telegram-daemon-cli.ts +9 -2
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -4
- package/src/sdk/bus/telegram-daemon-control.ts +3 -3
- package/src/sdk/bus/telegram-daemon.ts +23 -15
- package/src/sdk/client/discovery.ts +10 -4
- package/src/sdk/host/host.ts +9 -187
- package/src/sdk/host/query/handlers.ts +20 -1
- package/src/sdk/host/reverse-leases.ts +42 -249
- package/src/sdk/index.ts +1 -0
- package/src/sdk/protocol/operation-inventory.generated.json +18 -0
- package/src/sdk/protocol/operation-registry.ts +5 -2
- package/src/sdk/providers.ts +51 -0
- package/src/sdk/session-directory.ts +1 -0
- package/src/sdk/session.ts +10 -7
- package/src/session/agent-session.ts +59 -202
- package/src/session/artifacts.ts +74 -211
- package/src/session/client-bridge.ts +0 -15
- package/src/session/internal/managed-session-scope.ts +981 -450
- package/src/session/internal/managed-session-storage.ts +362 -124
- package/src/session/internal/native-publish-outcome.ts +3 -1
- package/src/session/internal/session-open-errors.ts +11 -0
- package/src/session/messages.ts +7 -32
- package/src/session/session-manager.ts +48 -15
- package/src/session/session-storage.ts +72 -5
- package/src/session/streaming-output.ts +40 -198
- package/src/slash-commands/builtin-registry.ts +82 -4
- package/src/task/index.ts +237 -65
- package/src/task/receipt.ts +2 -4
- package/src/task/render.ts +0 -30
- package/src/task/types.ts +10 -34
- package/src/tools/ask.ts +1 -1
- package/src/tools/bash.ts +239 -818
- package/src/tools/eval.ts +4 -99
- package/src/tools/fetch.ts +15 -77
- package/src/tools/find.ts +3 -7
- package/src/tools/output-meta.ts +114 -696
- package/src/tools/search.ts +4 -9
- package/src/tools/subagent.ts +97 -75
- package/src/tools/telegram-send.ts +4 -2
- package/src/tools/todo-write.ts +47 -0
- package/src/tools/tool-result.ts +0 -1
- package/dist/types/gjc-runtime/ultragoal-review-source.d.ts +0 -83
- package/dist/types/utils/artifact-id.d.ts +0 -2
- package/src/gjc-runtime/ultragoal-review-source.ts +0 -378
- package/src/utils/artifact-id.ts +0 -6
|
@@ -21,9 +21,16 @@ export type ChatDaemonAction = "stop" | "reload";
|
|
|
21
21
|
* daemon transports. Generation 16 applies Telegram sound-policy configuration
|
|
22
22
|
* through shared notification parsing. Generation 17 bound managed-session
|
|
23
23
|
* replacement to exact native filesystem authority; generation 18 retired that
|
|
24
|
-
* binding, generation 19
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* binding, and generation 19 binds exact cleanup to parent/link-count authority
|
|
25
|
+
* while also adding durable provider-intent admission without changing lifecycle
|
|
26
|
+
* behavior. Generation 20 discovers isolated chat-only session endpoints when
|
|
27
|
+
* Telegram identity ownership is blocked. Discord generation 21 applies rustfmt
|
|
28
|
+
* and clippy-equivalent cleanup to the pi-shell process-tree authority (#3682).
|
|
29
|
+
* Discord generation 22 / slack generation 21 refreshes retained cleanup
|
|
30
|
+
* semantics; discord generation 23 / slack generation 22 hardens exact Bash
|
|
31
|
+
* process-tree ownership shared by chat daemon cleanup.
|
|
32
|
+
* Discord generation 24 / slack generation 23 apply provider-completeness and
|
|
33
|
+
* effective-enable admission to chat daemon lifecycle controls.
|
|
27
34
|
*/
|
|
28
35
|
export declare const CHAT_DAEMON_GENERATIONS: Readonly<Record<ChatDaemonKind, number>>;
|
|
29
36
|
export declare function chatDaemonGeneration(kind: ChatDaemonKind): number;
|
|
@@ -104,6 +111,7 @@ export declare class ChatDaemonController implements BuiltInDaemonController {
|
|
|
104
111
|
readonly kind: ChatDaemonKind;
|
|
105
112
|
constructor(settings: Settings, kind: ChatDaemonKind, deps?: ChatDaemonControlDeps);
|
|
106
113
|
private identity;
|
|
114
|
+
private effectivelyEnabled;
|
|
107
115
|
private alive;
|
|
108
116
|
status(): Promise<DaemonStatus>;
|
|
109
117
|
stop(opts?: DaemonOperationOptions): Promise<DaemonOperationResult>;
|
|
@@ -22,9 +22,29 @@ export interface TelegramActivationMarker {
|
|
|
22
22
|
export type TelegramActivationMarkers = Record<string, TelegramActivationMarker>;
|
|
23
23
|
/** Validate and clone activation markers crossing the settings boundary. */
|
|
24
24
|
export declare function readTelegramActivationMarkers(value?: unknown): TelegramActivationMarkers;
|
|
25
|
+
export type NotificationProvider = "telegram" | "discord" | "slack";
|
|
26
|
+
export type NotificationRuntime = "inactive" | "starting" | "ready" | "attached" | "blocked" | "failed";
|
|
27
|
+
export type ProviderSecretDisposition = "keep" | "replace" | "remove";
|
|
28
|
+
export type ProviderResolutionIssueCode = "missing" | "blank" | "wrong_type" | "invalid_container" | "contradictory";
|
|
29
|
+
export interface ProviderResolutionIssue {
|
|
30
|
+
path: string;
|
|
31
|
+
code: ProviderResolutionIssueCode;
|
|
32
|
+
}
|
|
33
|
+
export type NotificationProviderIssueCode = ProviderResolutionIssueCode;
|
|
34
|
+
export type NotificationProviderIssue = ProviderResolutionIssue;
|
|
35
|
+
export interface ProviderResolution {
|
|
36
|
+
provider: NotificationProvider;
|
|
37
|
+
configured: boolean;
|
|
38
|
+
quarantined: boolean;
|
|
39
|
+
desiredEnabled: boolean;
|
|
40
|
+
desiredSource: "explicit" | "legacy";
|
|
41
|
+
effectiveEnabled: boolean;
|
|
42
|
+
issues: readonly ProviderResolutionIssue[];
|
|
43
|
+
}
|
|
25
44
|
export interface NotificationSettingsSnapshot {
|
|
26
45
|
enabled: boolean;
|
|
27
46
|
telegram: {
|
|
47
|
+
enabled?: boolean;
|
|
28
48
|
botToken?: string;
|
|
29
49
|
chatId?: string;
|
|
30
50
|
activation?: Record<string, unknown>;
|
|
@@ -49,12 +69,14 @@ export interface NotificationSettingsSnapshot {
|
|
|
49
69
|
};
|
|
50
70
|
};
|
|
51
71
|
discord: {
|
|
72
|
+
enabled?: boolean;
|
|
52
73
|
botToken?: string;
|
|
53
74
|
applicationId?: string;
|
|
54
75
|
guildId?: string;
|
|
55
76
|
parentChannelId?: string;
|
|
56
77
|
};
|
|
57
78
|
slack: {
|
|
79
|
+
enabled?: boolean;
|
|
58
80
|
botToken?: string;
|
|
59
81
|
appToken?: string;
|
|
60
82
|
workspaceId?: string;
|
|
@@ -65,33 +87,38 @@ export interface NotificationSettingsSnapshot {
|
|
|
65
87
|
verbosity: "lean" | "verbose";
|
|
66
88
|
sessionScope: "all" | "primary";
|
|
67
89
|
idleTimeoutMs: number;
|
|
90
|
+
/** Safe provider-local validation issues. Raw values never cross this boundary. */
|
|
91
|
+
providerIssues?: Partial<Record<NotificationProvider, readonly ProviderResolutionIssue[]>>;
|
|
68
92
|
}
|
|
69
93
|
/**
|
|
70
94
|
* Narrow settings boundary for remote notification identity and behavior.
|
|
71
|
-
* Implementations
|
|
72
|
-
*
|
|
95
|
+
* Implementations return only user-global values; project settings and runtime
|
|
96
|
+
* overrides are intentionally excluded.
|
|
73
97
|
*/
|
|
74
98
|
export interface NotificationSettingsReader {
|
|
75
99
|
getNotificationSettingsSnapshot(): NotificationSettingsSnapshot;
|
|
76
100
|
getAgentDir(): string;
|
|
77
101
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Validate and snapshot the raw global notification configuration used by both
|
|
80
|
-
* the interactive host and the lightweight daemon process.
|
|
81
|
-
*/
|
|
102
|
+
/** Validate and snapshot raw global notification configuration without leaking invalid provider values. */
|
|
82
103
|
export declare function parseNotificationSettingsSnapshot(rawConfig?: unknown): NotificationSettingsSnapshot;
|
|
83
104
|
export interface NotificationConfig {
|
|
84
105
|
enabled: boolean;
|
|
85
106
|
botToken?: string;
|
|
86
107
|
activation?: TelegramActivationMarkers;
|
|
87
108
|
chatId?: string;
|
|
109
|
+
/** Optional nested Telegram intent metadata; absent means legacy configuration. */
|
|
110
|
+
telegram?: {
|
|
111
|
+
enabled?: boolean;
|
|
112
|
+
};
|
|
88
113
|
discord: {
|
|
114
|
+
enabled?: boolean;
|
|
89
115
|
botToken?: string;
|
|
90
116
|
applicationId?: string;
|
|
91
117
|
guildId?: string;
|
|
92
118
|
parentChannelId?: string;
|
|
93
119
|
};
|
|
94
120
|
slack: {
|
|
121
|
+
enabled?: boolean;
|
|
95
122
|
botToken?: string;
|
|
96
123
|
appToken?: string;
|
|
97
124
|
workspaceId?: string;
|
|
@@ -100,11 +127,6 @@ export interface NotificationConfig {
|
|
|
100
127
|
};
|
|
101
128
|
redact: boolean;
|
|
102
129
|
verbosity: "lean" | "verbose";
|
|
103
|
-
/**
|
|
104
|
-
* Which sessions may register a notification endpoint. `all` (default)
|
|
105
|
-
* preserves historical behavior; `primary` suppresses GJC-spawned children
|
|
106
|
-
* (those carrying {@link SPAWN_PROVENANCE_ENV}) unless they explicitly opt in.
|
|
107
|
-
*/
|
|
108
130
|
sessionScope: "all" | "primary";
|
|
109
131
|
sound: "all" | "important" | "none";
|
|
110
132
|
idleTimeoutMs: number;
|
|
@@ -124,62 +146,24 @@ export interface NotificationConfig {
|
|
|
124
146
|
enabled: boolean;
|
|
125
147
|
};
|
|
126
148
|
topics: {
|
|
127
|
-
/**
|
|
128
|
-
* Optional Telegram forum-topic name template with `{repo}`, `{branch}`,
|
|
129
|
-
* and `{title}` placeholders. Unset preserves the built-in
|
|
130
|
-
* `{repo}/{branch} - {title}` composition (with its title/repo/branch
|
|
131
|
-
* fallbacks).
|
|
132
|
-
*/
|
|
133
149
|
nameTemplate?: string;
|
|
134
150
|
};
|
|
151
|
+
providerIssues?: Partial<Record<NotificationProvider, readonly ProviderResolutionIssue[]>>;
|
|
135
152
|
}
|
|
136
153
|
/** Read typed global-only notification config from a narrow settings reader. */
|
|
137
154
|
export declare function getNotificationConfig(settings: NotificationSettingsReader): NotificationConfig;
|
|
138
|
-
declare const notificationConfigSchema: z.ZodObject<{
|
|
139
|
-
notifications: z.ZodOptional<z.ZodObject<{
|
|
140
|
-
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
141
|
-
discord: z.ZodOptional<z.ZodObject<{
|
|
142
|
-
botToken: z.ZodOptional<z.ZodString>;
|
|
143
|
-
applicationId: z.ZodOptional<z.ZodString>;
|
|
144
|
-
guildId: z.ZodOptional<z.ZodString>;
|
|
145
|
-
parentChannelId: z.ZodOptional<z.ZodString>;
|
|
146
|
-
}, z.core.$loose>>;
|
|
147
|
-
slack: z.ZodOptional<z.ZodObject<{
|
|
148
|
-
botToken: z.ZodOptional<z.ZodString>;
|
|
149
|
-
appToken: z.ZodOptional<z.ZodString>;
|
|
150
|
-
workspaceId: z.ZodOptional<z.ZodString>;
|
|
151
|
-
channelId: z.ZodOptional<z.ZodString>;
|
|
152
|
-
authorizedUserId: z.ZodOptional<z.ZodString>;
|
|
153
|
-
}, z.core.$loose>>;
|
|
154
|
-
redact: z.ZodOptional<z.ZodBoolean>;
|
|
155
|
-
verbosity: z.ZodOptional<z.ZodEnum<{
|
|
156
|
-
lean: "lean";
|
|
157
|
-
verbose: "verbose";
|
|
158
|
-
}>>;
|
|
159
|
-
}, z.core.$loose>>;
|
|
160
|
-
}, z.core.$loose>;
|
|
155
|
+
declare const notificationConfigSchema: z.ZodObject<{}, z.core.$loose>;
|
|
161
156
|
type NotificationConfigFile = z.infer<typeof notificationConfigSchema>;
|
|
162
157
|
/** Read daemon settings through the canonical validated config-file boundary. */
|
|
163
158
|
export declare function loadNotificationConfigFile(agentDir: string): LoadResult<NotificationConfigFile>;
|
|
164
|
-
export declare function notificationConfigFromFile(value: NotificationConfigFile):
|
|
159
|
+
export declare function notificationConfigFromFile(value: NotificationConfigFile): NotificationConfig;
|
|
165
160
|
export declare function hasNonBlankValue(value: string | undefined): boolean;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
* lifecycle enablement. Explicit environment values override the durable
|
|
169
|
-
* Telegram preference; otherwise streaming is available only to an active
|
|
170
|
-
* configured Telegram identity.
|
|
171
|
-
*/
|
|
172
|
-
export declare function isNotificationStreamingEnabled(input: {
|
|
173
|
-
cfg: NotificationConfig;
|
|
174
|
-
env: NodeJS.ProcessEnv;
|
|
175
|
-
}): boolean;
|
|
176
|
-
/** Is Telegram configured with usable non-blank boundary credentials? */
|
|
177
|
-
export declare function isTelegramConfigured(cfg: NotificationConfig): cfg is NotificationConfig & {
|
|
161
|
+
export declare function isProviderComplete(cfg: NotificationConfig, provider: NotificationProvider): boolean;
|
|
162
|
+
export declare function isTelegramComplete(cfg: NotificationConfig): cfg is NotificationConfig & {
|
|
178
163
|
botToken: string;
|
|
179
164
|
chatId: string;
|
|
180
165
|
};
|
|
181
|
-
|
|
182
|
-
export declare function isDiscordConfigured(cfg: Pick<NotificationConfig, "enabled" | "discord">): cfg is Pick<NotificationConfig, "enabled"> & {
|
|
166
|
+
export declare function isDiscordComplete(cfg: NotificationConfig): cfg is NotificationConfig & {
|
|
183
167
|
discord: {
|
|
184
168
|
botToken: string;
|
|
185
169
|
applicationId: string;
|
|
@@ -187,8 +171,7 @@ export declare function isDiscordConfigured(cfg: Pick<NotificationConfig, "enabl
|
|
|
187
171
|
parentChannelId: string;
|
|
188
172
|
};
|
|
189
173
|
};
|
|
190
|
-
|
|
191
|
-
export declare function isSlackConfigured(cfg: Pick<NotificationConfig, "enabled" | "slack">): cfg is Pick<NotificationConfig, "enabled"> & {
|
|
174
|
+
export declare function isSlackComplete(cfg: NotificationConfig): cfg is NotificationConfig & {
|
|
192
175
|
slack: {
|
|
193
176
|
botToken: string;
|
|
194
177
|
appToken: string;
|
|
@@ -196,80 +179,59 @@ export declare function isSlackConfigured(cfg: Pick<NotificationConfig, "enabled
|
|
|
196
179
|
channelId: string;
|
|
197
180
|
};
|
|
198
181
|
};
|
|
199
|
-
|
|
200
|
-
export declare function
|
|
182
|
+
export declare function resolveNotificationProvider(cfg: NotificationConfig, provider: NotificationProvider): ProviderResolution;
|
|
183
|
+
export declare function isProviderEffectivelyEnabled(cfg: NotificationConfig, provider: NotificationProvider): boolean;
|
|
184
|
+
export declare function hasAnyCompleteProvider(cfg: NotificationConfig): boolean;
|
|
185
|
+
export declare function hasAnyEffectivelyEnabledProvider(cfg: NotificationConfig): boolean;
|
|
201
186
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
* `GJC_NOTIFY=off` (also `0` / `false`, case-insensitive) suppresses the
|
|
205
|
-
* completion notification surface for this process only. `config.yml` is
|
|
206
|
-
* untouched and child processes inherit the env var, which lets non-interactive
|
|
207
|
-
* fleet runs (`gjc -p --no-session`) stay silent even when a user-level/global
|
|
208
|
-
* completion notification configuration is enabled.
|
|
187
|
+
* Resolve generic live-stream policy. This policy only governs automatic
|
|
188
|
+
* current-session frames; it never changes durable provider eligibility.
|
|
209
189
|
*/
|
|
190
|
+
export type GenericNotificationSessionSource = "hard_opt_out" | "session_local_off" | "explicit_env" | "token_env" | "configured_provider" | "session_scope" | "none";
|
|
191
|
+
export interface GenericNotificationSessionEligibility {
|
|
192
|
+
enabled: boolean;
|
|
193
|
+
source: GenericNotificationSessionSource;
|
|
194
|
+
}
|
|
195
|
+
export type GenericNotificationStreamSource = "session_not_admitted" | "env_on" | "env_off" | "durable_telegram" | "none";
|
|
196
|
+
export interface GenericNotificationStreamPolicy {
|
|
197
|
+
enabled: boolean;
|
|
198
|
+
source: GenericNotificationStreamSource;
|
|
199
|
+
}
|
|
200
|
+
export interface GenericNotificationSessionEligibilityInput {
|
|
201
|
+
cfg: NotificationConfig;
|
|
202
|
+
env: NodeJS.ProcessEnv;
|
|
203
|
+
sessionDisabled: boolean;
|
|
204
|
+
spawnedByGjc?: boolean;
|
|
205
|
+
}
|
|
206
|
+
export declare function resolveGenericNotificationSessionEligibility(input: GenericNotificationSessionEligibilityInput): GenericNotificationSessionEligibility;
|
|
207
|
+
export declare function resolveGenericNotificationStreamPolicy(input: {
|
|
208
|
+
cfg: NotificationConfig;
|
|
209
|
+
env: NodeJS.ProcessEnv;
|
|
210
|
+
genericSessionEnabled: boolean;
|
|
211
|
+
}): GenericNotificationStreamPolicy;
|
|
210
212
|
export declare function completionNotifyDisabledByEnv(env: NodeJS.ProcessEnv): boolean;
|
|
211
|
-
/** Canonical host eligibility for the dormant notification session surface. */
|
|
212
213
|
export interface NotificationHostEligibilityInput {
|
|
213
214
|
env: NodeJS.ProcessEnv;
|
|
214
|
-
/** False for host modes that cannot own a notification session endpoint. */
|
|
215
215
|
hostModeSupported?: boolean;
|
|
216
|
-
/** Task recursion depth; helper/subagent sessions must not own remote surfaces. */
|
|
217
216
|
taskDepth?: number;
|
|
218
|
-
/** Parent subagent id/prefix; present for helper/subagent sessions even when depth is omitted. */
|
|
219
217
|
parentTaskPrefix?: string;
|
|
220
|
-
/** Role-agent type/name; present for task sessions even if depth metadata is lost. */
|
|
221
218
|
currentAgentType?: string;
|
|
222
|
-
/** Canonical global session scope; absent preserves the default `all` behavior. */
|
|
223
219
|
sessionScope?: NotificationConfig["sessionScope"];
|
|
224
|
-
/** Whether this process was spawned by one of GJC's marked child spawn sites. */
|
|
225
220
|
spawnedByGjc?: boolean;
|
|
226
221
|
}
|
|
227
|
-
/**
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
* eligible unconfigured host still gets a zero-side-effect control surface.
|
|
231
|
-
*/
|
|
232
|
-
export declare function isNotificationHostEligible(input: NotificationHostEligibilityInput): boolean;
|
|
233
|
-
/**
|
|
234
|
-
* Legacy compatibility helper for callers that require both host eligibility
|
|
235
|
-
* and a currently configured or explicit notification runtime.
|
|
236
|
-
*/
|
|
237
|
-
export declare function shouldRegisterNotificationsExtension(input: {
|
|
222
|
+
/** Generic host eligibility for the dormant automatic notification surface. */
|
|
223
|
+
export declare function isGenericNotificationHostEligible(input: NotificationHostEligibilityInput): boolean;
|
|
224
|
+
export interface GenericNotificationRegistrationInput {
|
|
238
225
|
env: NodeJS.ProcessEnv;
|
|
239
226
|
cfg?: NotificationConfig;
|
|
240
|
-
/** Task recursion depth; helper/subagent sessions must not spawn remote surfaces. */
|
|
241
227
|
taskDepth?: number;
|
|
242
|
-
/** Parent subagent id/prefix; present for helper/subagent sessions even when depth is omitted. */
|
|
243
228
|
parentTaskPrefix?: string;
|
|
244
|
-
/** Role-agent type/name; present for task sessions even if depth metadata is lost. */
|
|
245
229
|
currentAgentType?: string;
|
|
246
|
-
/**
|
|
247
|
-
* True when this session was launched by one of GJC's own programmatic
|
|
248
|
-
* separate-process child spawn sites (marked via {@link SPAWN_PROVENANCE_ENV}).
|
|
249
|
-
* Under `notifications.sessionScope = "primary"` such children are suppressed
|
|
250
|
-
* unless they explicitly opt in, so an interactive parent that fans out work
|
|
251
|
-
* does not flood the paired chat with topics for children the user never
|
|
252
|
-
* asked for. User-opened sessions (CLI/tmux/headless) never carry the marker.
|
|
253
|
-
*/
|
|
254
|
-
spawnedByGjc?: boolean;
|
|
255
|
-
}): boolean;
|
|
256
|
-
/**
|
|
257
|
-
* Resolve whether THIS session should run notifications.
|
|
258
|
-
* Precedence (highest first):
|
|
259
|
-
* 1) env.GJC_NOTIFICATIONS === "0" -> false (hard opt-out)
|
|
260
|
-
* 2) sessionDisabled === true -> false (local /notify off)
|
|
261
|
-
* 3) env.GJC_NOTIFICATIONS === "1" || env.GJC_NOTIFICATIONS_TOKEN present -> true (legacy explicit)
|
|
262
|
-
* 4) spawned GJC child with `sessionScope=primary` -> false
|
|
263
|
-
* 5) isGloballyConfigured(cfg) -> true (global auto-on)
|
|
264
|
-
* 6) otherwise false
|
|
265
|
-
*/
|
|
266
|
-
export declare function isSessionNotificationsEnabled(input: {
|
|
267
|
-
cfg: NotificationConfig;
|
|
268
|
-
env: NodeJS.ProcessEnv;
|
|
269
|
-
sessionDisabled: boolean;
|
|
270
|
-
/** This process was programmatically spawned by GJC (consumed at SDK startup). */
|
|
271
230
|
spawnedByGjc?: boolean;
|
|
272
|
-
}
|
|
231
|
+
}
|
|
232
|
+
/** Generic registration admission; direct provider actions do not call this helper. */
|
|
233
|
+
export declare function shouldRegisterGenericNotificationsExtension(input: GenericNotificationRegistrationInput): boolean;
|
|
234
|
+
export declare function isGenericNotificationSessionEnabled(input: GenericNotificationSessionEligibilityInput): boolean;
|
|
273
235
|
/** Mask a bot token for display: first 4 chars + "…" + "(len N)"; "(unset)" when undefined/empty. Never reveal full token. */
|
|
274
236
|
export declare function maskToken(token: string | undefined): string;
|
|
275
237
|
/** Stable non-reversible fingerprint of a token: sha256 hex, first 12 chars. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DiscordInboundEvent, DiscordMessageComponent, DiscordProvider, DiscordThread } from "./discord-provider";
|
|
1
|
+
import type { DiscordConfigurationProbeResult, DiscordDiagnosticProvider, DiscordInboundEvent, DiscordMessageComponent, DiscordOneShotTestResult, DiscordProvider, DiscordThread } from "./discord-provider";
|
|
2
2
|
export interface DiscordGatewaySocket {
|
|
3
3
|
readonly readyState: number;
|
|
4
4
|
send(data: string): void;
|
|
@@ -21,7 +21,7 @@ export interface DiscordLiveProviderOptions {
|
|
|
21
21
|
apiBaseUrl?: string;
|
|
22
22
|
}
|
|
23
23
|
/** Discord REST/Gateway implementation. The only credential is held privately and is never emitted. */
|
|
24
|
-
export declare class DiscordLiveProvider implements DiscordProvider {
|
|
24
|
+
export declare class DiscordLiveProvider implements DiscordProvider, DiscordDiagnosticProvider {
|
|
25
25
|
#private;
|
|
26
26
|
readonly applicationId: string;
|
|
27
27
|
constructor(options: DiscordLiveProviderOptions);
|
|
@@ -64,6 +64,12 @@ export declare class DiscordLiveProvider implements DiscordProvider {
|
|
|
64
64
|
}): Promise<{
|
|
65
65
|
id: string;
|
|
66
66
|
} | null>;
|
|
67
|
+
probeConfiguration(signal?: AbortSignal): Promise<DiscordConfigurationProbeResult>;
|
|
68
|
+
sendOneShotTest(input: {
|
|
69
|
+
channelId: string;
|
|
70
|
+
message: string;
|
|
71
|
+
signal?: AbortSignal;
|
|
72
|
+
}): Promise<DiscordOneShotTestResult>;
|
|
67
73
|
start(onEvent: (event: DiscordInboundEvent) => Promise<void>): Promise<void>;
|
|
68
74
|
stop(): Promise<void>;
|
|
69
75
|
}
|
|
@@ -36,6 +36,25 @@ export interface DiscordMessageComponent {
|
|
|
36
36
|
}>;
|
|
37
37
|
}>;
|
|
38
38
|
}
|
|
39
|
+
export interface DiscordConfigurationProbeResult {
|
|
40
|
+
ok: boolean;
|
|
41
|
+
detail: string;
|
|
42
|
+
botUserId?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface DiscordOneShotTestResult {
|
|
45
|
+
ok: boolean;
|
|
46
|
+
detail: string;
|
|
47
|
+
messageId?: string;
|
|
48
|
+
uncertain?: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface DiscordDiagnosticProvider {
|
|
51
|
+
probeConfiguration(signal?: AbortSignal): Promise<DiscordConfigurationProbeResult>;
|
|
52
|
+
sendOneShotTest(input: {
|
|
53
|
+
channelId: string;
|
|
54
|
+
message: string;
|
|
55
|
+
signal?: AbortSignal;
|
|
56
|
+
}): Promise<DiscordOneShotTestResult>;
|
|
57
|
+
}
|
|
39
58
|
export interface DiscordProvider {
|
|
40
59
|
readonly applicationId: string;
|
|
41
60
|
readonly botUserId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RawSettings, SettingsAtomicPatch, SettingsAtomicReceipt } from "../../config/settings";
|
|
2
|
-
import { type NotificationSettingsReader, type TelegramActivationMarker, type TelegramActivationMarkers, type TelegramActivationReason, type TelegramActivationState, telegramActivationIdentity } from "./config";
|
|
2
|
+
import { type NotificationProvider, type NotificationSettingsReader, type ProviderSecretDisposition, type TelegramActivationMarker, type TelegramActivationMarkers, type TelegramActivationReason, type TelegramActivationState, telegramActivationIdentity } from "./config";
|
|
3
3
|
import { type EnsureTelegramDaemonDetailedResult, type TelegramDaemonFs } from "./telegram-daemon";
|
|
4
4
|
export type { TelegramActivationMarker, TelegramActivationMarkers, TelegramActivationReason, TelegramActivationState };
|
|
5
5
|
export { telegramActivationIdentity };
|
|
@@ -41,7 +41,7 @@ export interface ProposedTelegramIdentityPreflightInput {
|
|
|
41
41
|
export declare function proposedTelegramIdentity(input: ProposedTelegramIdentityPreflightInput): Promise<ProposedTelegramIdentity>;
|
|
42
42
|
export interface NotificationConfigurationWriter extends NotificationSettingsReader {
|
|
43
43
|
commitAtomicBatch(patches: readonly SettingsAtomicPatch[]): Promise<SettingsAtomicReceipt>;
|
|
44
|
-
commitAtomicBatchWithCurrent
|
|
44
|
+
commitAtomicBatchWithCurrent(buildPatches: (current: Readonly<RawSettings>) => Promise<readonly SettingsAtomicPatch[]> | readonly SettingsAtomicPatch[]): Promise<SettingsAtomicReceipt>;
|
|
45
45
|
}
|
|
46
46
|
export declare function createTelegramActivationMarker(input: {
|
|
47
47
|
botToken: string;
|
|
@@ -55,23 +55,16 @@ export declare function observedTelegramActivationMarker(settings: NotificationS
|
|
|
55
55
|
export declare function persistTelegramActivationMarker(settings: NotificationConfigurationWriter, marker: TelegramActivationMarker): Promise<SettingsAtomicReceipt>;
|
|
56
56
|
/** Clear only the exact marker that was safely reconciled. */
|
|
57
57
|
export declare function clearTelegramActivationMarker(settings: NotificationConfigurationWriter, marker: TelegramActivationMarker): Promise<void>;
|
|
58
|
-
export type CompleteNonTelegramAdapter = "discord" | "slack";
|
|
59
58
|
export type SaveTelegramInactiveAvailability = {
|
|
60
59
|
available: true;
|
|
61
60
|
};
|
|
62
|
-
/**
|
|
63
|
-
* Telegram-specific activation markers let Save inactive preserve globally
|
|
64
|
-
* enabled Discord and Slack adapters, so the action is always available.
|
|
65
|
-
*/
|
|
61
|
+
/** Telegram activation markers make Save inactive independent of sibling providers. */
|
|
66
62
|
export declare function getSaveTelegramInactiveAvailability(_settings: NotificationSettingsReader): SaveTelegramInactiveAvailability;
|
|
67
63
|
export type SaveTelegramInactiveResult = {
|
|
68
64
|
status: "saved_inactive";
|
|
69
65
|
receipt: SettingsAtomicReceipt;
|
|
70
66
|
};
|
|
71
|
-
/**
|
|
72
|
-
* Atomically persist Telegram credentials with a non-secret inactive marker.
|
|
73
|
-
* Global notifications are disabled only when Telegram is the sole complete adapter.
|
|
74
|
-
*/
|
|
67
|
+
/** Atomically persist Telegram credentials, desired-off intent, and its inactive marker. */
|
|
75
68
|
export declare function saveTelegramInactive(input: {
|
|
76
69
|
settings: NotificationConfigurationWriter;
|
|
77
70
|
botToken: string;
|
|
@@ -117,9 +110,16 @@ export interface TelegramPostCommitActivation {
|
|
|
117
110
|
}
|
|
118
111
|
export type PostCommitTelegramActivationResult = {
|
|
119
112
|
status: "activated";
|
|
120
|
-
|
|
113
|
+
receipt: SettingsAtomicReceipt;
|
|
114
|
+
reconnect: Exclude<TelegramDaemonReconnectOutcome, "blocked_identity" | "disabled">;
|
|
115
|
+
} | {
|
|
116
|
+
status: "activation_failed";
|
|
117
|
+
receipt: SettingsAtomicReceipt;
|
|
118
|
+
reconnect?: TelegramDaemonReconnectOutcome;
|
|
119
|
+
message: string;
|
|
121
120
|
} | {
|
|
122
121
|
status: "blocked_identity";
|
|
122
|
+
receipt: SettingsAtomicReceipt;
|
|
123
123
|
message: string;
|
|
124
124
|
restore(): Promise<BlockedTelegramRestoreResult>;
|
|
125
125
|
retainCommitted(): void;
|
|
@@ -135,12 +135,6 @@ export type BlockedTelegramRestoreResult = {
|
|
|
135
135
|
} | {
|
|
136
136
|
status: "still_blocked";
|
|
137
137
|
};
|
|
138
|
-
/**
|
|
139
|
-
* Complete a committed Telegram update in the required order: identity
|
|
140
|
-
* reconnect first, normal session reconciliation second. A post-commit foreign
|
|
141
|
-
* owner race stops the endpoint, durably marks only that Telegram identity
|
|
142
|
-
* inactive, then exposes an ordered CAS restore/retain choice.
|
|
143
|
-
*/
|
|
144
138
|
export declare function reconcileCommittedTelegramConfiguration(input: {
|
|
145
139
|
receipt: SettingsAtomicReceipt;
|
|
146
140
|
activation: TelegramPostCommitActivation;
|
|
@@ -169,3 +163,118 @@ export declare function saveTelegramConfiguration(input: {
|
|
|
169
163
|
preflight?: (input: Omit<ProposedTelegramIdentityPreflightInput, "settings">) => Promise<ProposedTelegramIdentity>;
|
|
170
164
|
activation?: TelegramPostCommitActivation;
|
|
171
165
|
}): Promise<SaveTelegramConfigurationResult>;
|
|
166
|
+
export type ProviderSecretMutation = {
|
|
167
|
+
action: "keep";
|
|
168
|
+
} | {
|
|
169
|
+
action: "replace";
|
|
170
|
+
value: string;
|
|
171
|
+
} | {
|
|
172
|
+
action: "remove";
|
|
173
|
+
};
|
|
174
|
+
export interface TelegramProviderConfigurationMutation {
|
|
175
|
+
provider: "telegram";
|
|
176
|
+
botToken: ProviderSecretMutation;
|
|
177
|
+
chatId?: string;
|
|
178
|
+
richEnabled?: boolean;
|
|
179
|
+
richDraftEnabled?: boolean;
|
|
180
|
+
streamingEnabled?: boolean;
|
|
181
|
+
}
|
|
182
|
+
export interface DiscordProviderConfigurationMutation {
|
|
183
|
+
provider: "discord";
|
|
184
|
+
botToken: ProviderSecretMutation;
|
|
185
|
+
applicationId?: string;
|
|
186
|
+
guildId?: string;
|
|
187
|
+
parentChannelId?: string;
|
|
188
|
+
}
|
|
189
|
+
export interface SlackProviderConfigurationMutation {
|
|
190
|
+
provider: "slack";
|
|
191
|
+
botToken: ProviderSecretMutation;
|
|
192
|
+
appToken: ProviderSecretMutation;
|
|
193
|
+
workspaceId?: string;
|
|
194
|
+
channelId?: string;
|
|
195
|
+
authorizedUserId?: string | null;
|
|
196
|
+
}
|
|
197
|
+
export type NotificationProviderConfigurationMutation = TelegramProviderConfigurationMutation | DiscordProviderConfigurationMutation | SlackProviderConfigurationMutation;
|
|
198
|
+
export interface NotificationProviderRuntimeAuthority {
|
|
199
|
+
activate(provider: NotificationProvider): Promise<void>;
|
|
200
|
+
deactivate(provider: NotificationProvider): Promise<void>;
|
|
201
|
+
}
|
|
202
|
+
export type NotificationProviderMutationResult = {
|
|
203
|
+
status: "saved";
|
|
204
|
+
receipt: SettingsAtomicReceipt;
|
|
205
|
+
observerFailed: boolean;
|
|
206
|
+
} | {
|
|
207
|
+
status: "activated";
|
|
208
|
+
receipt: SettingsAtomicReceipt;
|
|
209
|
+
observerFailed: boolean;
|
|
210
|
+
} | {
|
|
211
|
+
status: "activation_failed";
|
|
212
|
+
receipt: SettingsAtomicReceipt;
|
|
213
|
+
observerFailed: boolean;
|
|
214
|
+
} | {
|
|
215
|
+
status: "deactivation_failed";
|
|
216
|
+
receipt: SettingsAtomicReceipt;
|
|
217
|
+
observerFailed: boolean;
|
|
218
|
+
} | {
|
|
219
|
+
status: "commit_failed";
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Sole CAS-backed provider configuration authority. It commits one selected-provider
|
|
223
|
+
* batch before observer/runtime effects and never reports rollback after a durable save.
|
|
224
|
+
*/
|
|
225
|
+
export declare function mutateNotificationProvider(input: {
|
|
226
|
+
settings: NotificationConfigurationWriter;
|
|
227
|
+
mutation: NotificationProviderConfigurationMutation;
|
|
228
|
+
desiredEnabled?: boolean;
|
|
229
|
+
configureAndActivate?: boolean;
|
|
230
|
+
notifyConfigChanged?: () => Promise<void> | void;
|
|
231
|
+
redact?: boolean;
|
|
232
|
+
runtime?: NotificationProviderRuntimeAuthority;
|
|
233
|
+
signal?: AbortSignal;
|
|
234
|
+
}): Promise<NotificationProviderMutationResult>;
|
|
235
|
+
export type NotificationProviderRemovalResult = {
|
|
236
|
+
status: "removed";
|
|
237
|
+
receipt: SettingsAtomicReceipt;
|
|
238
|
+
observerFailed: boolean;
|
|
239
|
+
} | {
|
|
240
|
+
status: "deactivation_failed";
|
|
241
|
+
receipt?: SettingsAtomicReceipt;
|
|
242
|
+
observerFailed?: boolean;
|
|
243
|
+
} | {
|
|
244
|
+
status: "commit_failed_after_teardown";
|
|
245
|
+
} | {
|
|
246
|
+
status: "commit_failed";
|
|
247
|
+
};
|
|
248
|
+
/** Remove only one provider. Telegram keeps teardown-before-delete; chat providers deactivate after commit. */
|
|
249
|
+
export declare function removeNotificationProvider(input: {
|
|
250
|
+
settings: NotificationConfigurationWriter;
|
|
251
|
+
provider: NotificationProvider;
|
|
252
|
+
runtime: NotificationProviderRuntimeAuthority;
|
|
253
|
+
notifyConfigChanged?: () => Promise<void> | void;
|
|
254
|
+
}): Promise<NotificationProviderRemovalResult>;
|
|
255
|
+
export type GlobalNotificationMutationResult = {
|
|
256
|
+
status: "saved";
|
|
257
|
+
receipt: SettingsAtomicReceipt;
|
|
258
|
+
observerFailed: boolean;
|
|
259
|
+
} | {
|
|
260
|
+
status: "global_deactivation_partial";
|
|
261
|
+
receipt: SettingsAtomicReceipt;
|
|
262
|
+
failed: readonly NotificationProvider[];
|
|
263
|
+
observerFailed: boolean;
|
|
264
|
+
} | {
|
|
265
|
+
status: "global_activation_partial";
|
|
266
|
+
receipt: SettingsAtomicReceipt;
|
|
267
|
+
failed: readonly NotificationProvider[];
|
|
268
|
+
observerFailed: boolean;
|
|
269
|
+
} | {
|
|
270
|
+
status: "commit_failed";
|
|
271
|
+
};
|
|
272
|
+
/** Toggle only the global master. Provider configuration and desired intent are preserved. */
|
|
273
|
+
export declare function setGlobalNotificationsEnabled(input: {
|
|
274
|
+
settings: NotificationConfigurationWriter;
|
|
275
|
+
enabled: boolean;
|
|
276
|
+
runtime?: NotificationProviderRuntimeAuthority;
|
|
277
|
+
notifyConfigChanged?: () => Promise<void> | void;
|
|
278
|
+
}): Promise<GlobalNotificationMutationResult>;
|
|
279
|
+
/** Safe helper for UI contracts that must retain only the disposition, never replacement material. */
|
|
280
|
+
export declare function providerSecretDisposition(mutation: ProviderSecretMutation): ProviderSecretDisposition;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { WriteFileOptions } from "node:fs";
|
|
2
2
|
import type { Settings } from "../../config/settings";
|
|
3
|
+
import { type NotificationProvider, type NotificationRuntime, type ProviderResolution } from "./config";
|
|
4
|
+
import type { DiscordDiagnosticProvider } from "./discord-provider";
|
|
5
|
+
import type { SlackDiagnosticProvider } from "./slack-provider";
|
|
3
6
|
/**
|
|
4
7
|
* Strip secrets from a human-facing diagnostic string. Redacts the configured
|
|
5
8
|
* bot token (exact match) and any token-shaped substring so health/test details
|
|
@@ -53,17 +56,34 @@ export interface NotificationServiceDeps {
|
|
|
53
56
|
pidAlive?: (pid: number) => boolean;
|
|
54
57
|
fetchImpl?: typeof fetch;
|
|
55
58
|
apiBase?: string;
|
|
59
|
+
createDiscordDiagnostic?: (config: {
|
|
60
|
+
applicationId: string;
|
|
61
|
+
botToken: string;
|
|
62
|
+
}) => DiscordDiagnosticProvider;
|
|
63
|
+
createSlackDiagnostic?: (config: {
|
|
64
|
+
appToken: string;
|
|
65
|
+
botToken: string;
|
|
66
|
+
}) => SlackDiagnosticProvider;
|
|
67
|
+
providerRuntimeStatus?: (provider: NotificationProvider) => Promise<NotificationRuntime> | NotificationRuntime;
|
|
56
68
|
}
|
|
57
69
|
export interface AdapterConfigView {
|
|
58
70
|
botTokenMasked: string;
|
|
59
71
|
channel: string | undefined;
|
|
60
72
|
configured: boolean;
|
|
73
|
+
quarantined: boolean;
|
|
74
|
+
desiredEnabled: boolean;
|
|
75
|
+
desiredSource: ProviderResolution["desiredSource"];
|
|
76
|
+
effectiveEnabled: boolean;
|
|
77
|
+
issues: ProviderResolution["issues"];
|
|
78
|
+
runtime?: NotificationRuntime;
|
|
61
79
|
}
|
|
62
80
|
export interface NotificationStatusReport {
|
|
63
81
|
enabled: boolean;
|
|
64
82
|
redact: boolean;
|
|
65
83
|
verbosity: "lean" | "verbose";
|
|
66
84
|
globallyConfigured: boolean;
|
|
85
|
+
anyProviderComplete: boolean;
|
|
86
|
+
anyProviderEffective: boolean;
|
|
67
87
|
telegram: AdapterConfigView & {
|
|
68
88
|
tokenFingerprint: string | undefined;
|
|
69
89
|
};
|
|
@@ -139,6 +159,8 @@ export interface EndpointHealth {
|
|
|
139
159
|
export interface NotificationHealthReport {
|
|
140
160
|
overall: HealthLevel;
|
|
141
161
|
configured: boolean;
|
|
162
|
+
provider?: NotificationProvider;
|
|
163
|
+
resolution?: ProviderResolution;
|
|
142
164
|
checks: HealthCheck[];
|
|
143
165
|
daemon: DaemonHealth;
|
|
144
166
|
endpoints: EndpointHealth;
|
|
@@ -152,8 +174,10 @@ export interface HealthOptions {
|
|
|
152
174
|
settings: Settings;
|
|
153
175
|
stateRoot?: string;
|
|
154
176
|
deps?: NotificationServiceDeps;
|
|
155
|
-
|
|
177
|
+
provider?: NotificationProvider;
|
|
178
|
+
/** When true, use the selected provider's REST-only diagnostic path. */
|
|
156
179
|
probe?: boolean;
|
|
180
|
+
signal?: AbortSignal;
|
|
157
181
|
}
|
|
158
182
|
/** Structural (offline-by-default) health of the notification subsystem. */
|
|
159
183
|
export declare function checkNotificationHealth(opts: HealthOptions): Promise<NotificationHealthReport>;
|
|
@@ -161,16 +185,19 @@ export declare function checkNotificationHealth(opts: HealthOptions): Promise<No
|
|
|
161
185
|
export declare function formatNotificationHealthReport(report: NotificationHealthReport): string;
|
|
162
186
|
export interface NotificationTestResult {
|
|
163
187
|
ok: boolean;
|
|
164
|
-
adapter
|
|
165
|
-
|
|
188
|
+
adapter?: NotificationProvider;
|
|
189
|
+
destination?: string;
|
|
166
190
|
detail: string;
|
|
191
|
+
uncertain?: boolean;
|
|
167
192
|
}
|
|
168
193
|
export interface TestOptions {
|
|
169
194
|
settings: Settings;
|
|
170
195
|
deps?: NotificationServiceDeps;
|
|
196
|
+
provider?: NotificationProvider;
|
|
171
197
|
text?: string;
|
|
198
|
+
signal?: AbortSignal;
|
|
172
199
|
}
|
|
173
|
-
/** Send a one-off test
|
|
200
|
+
/** Send a one-off test through exactly one durable, effective provider. */
|
|
174
201
|
export declare function sendNotificationTest(opts: TestOptions): Promise<NotificationTestResult>;
|
|
175
202
|
/** Render a test result as a single human-readable line (no secrets). */
|
|
176
203
|
export declare function formatNotificationTestResult(result: NotificationTestResult): string;
|