@sayknow-cli/coding-agent 0.2.7 → 0.3.1

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.
Files changed (216) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/types/async/job-manager.d.ts +3 -1
  3. package/dist/types/cli/daemon-cli.d.ts +25 -0
  4. package/dist/types/cli/notify-cli.d.ts +25 -0
  5. package/dist/types/cli/setup-cli.d.ts +20 -1
  6. package/dist/types/commands/daemon.d.ts +41 -0
  7. package/dist/types/commands/notify.d.ts +41 -0
  8. package/dist/types/config/model-profile-activation.d.ts +12 -0
  9. package/dist/types/config/model-profiles.d.ts +2 -1
  10. package/dist/types/config/model-registry.d.ts +3 -3
  11. package/dist/types/config/models-config-schema.d.ts +5 -0
  12. package/dist/types/config/settings-schema.d.ts +136 -3
  13. package/dist/types/coordinator/contract.d.ts +1 -1
  14. package/dist/types/daemon/builtin.d.ts +20 -0
  15. package/dist/types/daemon/control-types.d.ts +57 -0
  16. package/dist/types/daemon/runtime.d.ts +25 -0
  17. package/dist/types/extensibility/extensions/types.d.ts +8 -0
  18. package/dist/types/extensibility/shared-events.d.ts +1 -0
  19. package/dist/types/i18n/messages/en.d.ts +1 -0
  20. package/dist/types/lsp/types.d.ts +2 -0
  21. package/dist/types/modes/components/oauth-selector.d.ts +2 -0
  22. package/dist/types/modes/components/settings-defs.d.ts +1 -0
  23. package/dist/types/modes/controllers/selector-controller.d.ts +2 -2
  24. package/dist/types/modes/interactive-mode.d.ts +1 -1
  25. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +10 -0
  26. package/dist/types/modes/theme/theme.d.ts +1 -1
  27. package/dist/types/modes/types.d.ts +7 -1
  28. package/dist/types/notifications/attachment-registry.d.ts +17 -0
  29. package/dist/types/notifications/chat-adapters.d.ts +9 -0
  30. package/dist/types/notifications/config-commands.d.ts +26 -0
  31. package/dist/types/notifications/config.d.ts +69 -0
  32. package/dist/types/notifications/engine.d.ts +59 -0
  33. package/dist/types/notifications/helpers.d.ts +55 -0
  34. package/dist/types/notifications/html-format.d.ts +62 -0
  35. package/dist/types/notifications/index.d.ts +28 -0
  36. package/dist/types/notifications/managed-daemon.d.ts +48 -0
  37. package/dist/types/notifications/rate-limit-pool.d.ts +93 -0
  38. package/dist/types/notifications/telegram-cli.d.ts +19 -0
  39. package/dist/types/notifications/telegram-daemon-cli.d.ts +11 -0
  40. package/dist/types/notifications/telegram-daemon-control.d.ts +56 -0
  41. package/dist/types/notifications/telegram-daemon.d.ts +295 -0
  42. package/dist/types/notifications/telegram-reference.d.ts +111 -0
  43. package/dist/types/notifications/threaded-inbound.d.ts +77 -0
  44. package/dist/types/notifications/threaded-render.d.ts +71 -0
  45. package/dist/types/notifications/topic-registry.d.ts +67 -0
  46. package/dist/types/rlm/index.d.ts +12 -0
  47. package/dist/types/session/agent-session.d.ts +41 -2
  48. package/dist/types/session/auth-storage.d.ts +1 -1
  49. package/dist/types/setup/credential-auto-import.d.ts +63 -0
  50. package/dist/types/setup/credential-import.d.ts +3 -0
  51. package/dist/types/setup/host-plugin-setup.d.ts +39 -0
  52. package/dist/types/skc-runtime/launch-tmux.d.ts +1 -0
  53. package/dist/types/skc-runtime/ralplan-runtime.d.ts +1 -1
  54. package/dist/types/skc-runtime/state-writer.d.ts +2 -0
  55. package/dist/types/skc-runtime/tmux-common.d.ts +3 -0
  56. package/dist/types/skc-runtime/tmux-sessions.d.ts +2 -0
  57. package/dist/types/skc-runtime/ultragoal-guard.d.ts +15 -0
  58. package/dist/types/skc-runtime/ultragoal-runtime.d.ts +14 -0
  59. package/dist/types/tools/ask-answer-registry.d.ts +13 -0
  60. package/dist/types/tools/fetch.d.ts +23 -0
  61. package/dist/types/tools/index.d.ts +19 -0
  62. package/dist/types/tools/subagent.d.ts +3 -0
  63. package/dist/types/tools/telegram-send.d.ts +32 -0
  64. package/dist/types/web/insane/bridge.d.ts +103 -0
  65. package/dist/types/web/insane/url-guard.d.ts +22 -0
  66. package/dist/types/web/search/provider.d.ts +18 -1
  67. package/dist/types/web/search/providers/insane.d.ts +53 -0
  68. package/dist/types/web/search/providers/text-citations.d.ts +23 -0
  69. package/dist/types/web/search/types.d.ts +12 -4
  70. package/package.json +10 -8
  71. package/scripts/build-binary.ts +3 -0
  72. package/scripts/verify-insane-vendor.ts +132 -0
  73. package/src/async/job-manager.ts +5 -1
  74. package/src/cli/args.ts +1 -1
  75. package/src/cli/daemon-cli.ts +122 -0
  76. package/src/cli/fast-help.ts +1 -1
  77. package/src/cli/notify-cli.ts +421 -0
  78. package/src/cli/setup-cli.ts +173 -84
  79. package/src/cli.ts +3 -3
  80. package/src/commands/daemon.ts +47 -0
  81. package/src/commands/notify.ts +61 -0
  82. package/src/commands/setup.ts +11 -1
  83. package/src/commands/team.ts +1 -1
  84. package/src/config/model-profile-activation.ts +74 -5
  85. package/src/config/model-profiles.ts +7 -4
  86. package/src/config/model-registry.ts +6 -3
  87. package/src/config/models-config-schema.ts +1 -1
  88. package/src/config/settings-schema.ts +143 -0
  89. package/src/coordinator/contract.ts +3 -0
  90. package/src/coordinator-mcp/server.ts +270 -1
  91. package/src/daemon/builtin.ts +46 -0
  92. package/src/daemon/control-types.ts +65 -0
  93. package/src/daemon/runtime.ts +51 -0
  94. package/src/defaults/skc/rules/ponytail.md +68 -0
  95. package/src/defaults/skc/skills/ralplan/SKILL.md +11 -4
  96. package/src/defaults/skc/skills/ultragoal/SKILL.md +16 -0
  97. package/src/edit/modes/replace.ts +1 -1
  98. package/src/extensibility/extensions/runner.ts +4 -0
  99. package/src/extensibility/extensions/types.ts +8 -0
  100. package/src/extensibility/shared-events.ts +1 -0
  101. package/src/goals/tools/goal-tool.ts +11 -2
  102. package/src/hashline/hash.ts +1 -1
  103. package/src/i18n/messages/de.ts +1 -0
  104. package/src/i18n/messages/en.ts +1 -0
  105. package/src/i18n/messages/es.ts +1 -0
  106. package/src/i18n/messages/fr.ts +1 -0
  107. package/src/i18n/messages/ja.ts +1 -0
  108. package/src/i18n/messages/ko.ts +1 -0
  109. package/src/i18n/messages/zh.ts +1 -0
  110. package/src/internal-urls/docs-index.generated.ts +12 -10
  111. package/src/lsp/config.ts +16 -3
  112. package/src/lsp/defaults.json +7 -0
  113. package/src/lsp/types.ts +2 -0
  114. package/src/main.ts +30 -0
  115. package/src/modes/acp/acp-event-mapper.ts +1 -0
  116. package/src/modes/components/hook-editor.ts +7 -2
  117. package/src/modes/components/oauth-selector.ts +19 -0
  118. package/src/modes/components/settings-defs.ts +2 -1
  119. package/src/modes/components/settings-selector.ts +7 -2
  120. package/src/modes/controllers/event-controller.ts +35 -0
  121. package/src/modes/controllers/selector-controller.ts +80 -17
  122. package/src/modes/interactive-mode.ts +52 -4
  123. package/src/modes/runtime-init.ts +1 -0
  124. package/src/modes/shared/agent-wire/event-contract.ts +1 -0
  125. package/src/modes/shared/agent-wire/event-envelope.ts +1 -0
  126. package/src/modes/shared/agent-wire/event-observation.ts +16 -0
  127. package/src/modes/shared/agent-wire/unattended-session.ts +22 -0
  128. package/src/modes/theme/theme.ts +4 -0
  129. package/src/modes/types.ts +7 -1
  130. package/src/modes/utils/context-usage.ts +2 -2
  131. package/src/modes/utils/ui-helpers.ts +23 -0
  132. package/src/notifications/attachment-registry.ts +23 -0
  133. package/src/notifications/chat-adapters.ts +147 -0
  134. package/src/notifications/config-commands.ts +50 -0
  135. package/src/notifications/config.ts +128 -0
  136. package/src/notifications/engine.ts +100 -0
  137. package/src/notifications/helpers.ts +135 -0
  138. package/src/notifications/html-format.ts +389 -0
  139. package/src/notifications/index.ts +842 -0
  140. package/src/notifications/managed-daemon.ts +163 -0
  141. package/src/notifications/rate-limit-pool.ts +179 -0
  142. package/src/notifications/telegram-cli.ts +194 -0
  143. package/src/notifications/telegram-daemon-cli.ts +74 -0
  144. package/src/notifications/telegram-daemon-control.ts +370 -0
  145. package/src/notifications/telegram-daemon.ts +1591 -0
  146. package/src/notifications/telegram-reference.ts +335 -0
  147. package/src/notifications/threaded-inbound.ts +136 -0
  148. package/src/notifications/threaded-render.ts +173 -0
  149. package/src/notifications/topic-registry.ts +133 -0
  150. package/src/rlm/index.ts +19 -0
  151. package/src/sdk.ts +16 -0
  152. package/src/session/agent-session.ts +195 -54
  153. package/src/session/auth-storage.ts +3 -0
  154. package/src/session/session-dump-format.ts +43 -2
  155. package/src/session/session-manager.ts +39 -5
  156. package/src/setup/credential-auto-import.ts +258 -0
  157. package/src/setup/credential-import.ts +17 -0
  158. package/src/setup/hermes/templates/operator-instructions.v1.md +10 -0
  159. package/src/setup/host-plugin-setup.ts +142 -0
  160. package/src/skc-runtime/deep-interview-recorder.ts +2 -2
  161. package/src/skc-runtime/launch-tmux.ts +27 -5
  162. package/src/skc-runtime/ledger-event-renderer.ts +1 -0
  163. package/src/skc-runtime/ralplan-runtime.ts +2 -2
  164. package/src/skc-runtime/state-runtime.ts +18 -10
  165. package/src/skc-runtime/state-writer.ts +8 -8
  166. package/src/skc-runtime/tmux-common.ts +8 -0
  167. package/src/skc-runtime/tmux-sessions.ts +8 -1
  168. package/src/skc-runtime/ultragoal-guard.ts +57 -2
  169. package/src/skc-runtime/ultragoal-runtime.ts +105 -19
  170. package/src/skc-runtime/workflow-manifest.generated.json +56 -2
  171. package/src/skc-runtime/workflow-manifest.ts +18 -3
  172. package/src/slash-commands/builtin-registry.ts +4 -1
  173. package/src/task/executor.ts +5 -1
  174. package/src/tools/ask-answer-registry.ts +25 -0
  175. package/src/tools/ask.ts +77 -6
  176. package/src/tools/fetch.ts +78 -1
  177. package/src/tools/image-gen.ts +5 -8
  178. package/src/tools/index.ts +22 -0
  179. package/src/tools/inspect-image.ts +16 -11
  180. package/src/tools/subagent-render.ts +7 -0
  181. package/src/tools/subagent.ts +38 -7
  182. package/src/tools/telegram-send.ts +137 -0
  183. package/src/web/insane/bridge.ts +350 -0
  184. package/src/web/insane/url-guard.ts +155 -0
  185. package/src/web/search/provider.ts +77 -18
  186. package/src/web/search/providers/anthropic.ts +70 -3
  187. package/src/web/search/providers/codex.ts +1 -119
  188. package/src/web/search/providers/gemini.ts +99 -0
  189. package/src/web/search/providers/insane.ts +551 -0
  190. package/src/web/search/providers/openai-compatible.ts +66 -32
  191. package/src/web/search/providers/text-citations.ts +111 -0
  192. package/src/web/search/types.ts +13 -2
  193. package/vendor/insane-search/LICENSE +21 -0
  194. package/vendor/insane-search/MANIFEST.json +24 -0
  195. package/vendor/insane-search/engine/__init__.py +23 -0
  196. package/vendor/insane-search/engine/__main__.py +128 -0
  197. package/vendor/insane-search/engine/bias_check.py +183 -0
  198. package/vendor/insane-search/engine/executor.py +254 -0
  199. package/vendor/insane-search/engine/fetch_chain.py +725 -0
  200. package/vendor/insane-search/engine/learning.py +175 -0
  201. package/vendor/insane-search/engine/phase0.py +214 -0
  202. package/vendor/insane-search/engine/safety.py +91 -0
  203. package/vendor/insane-search/engine/templates/package.json +11 -0
  204. package/vendor/insane-search/engine/templates/playwright_mobile_chrome.js +188 -0
  205. package/vendor/insane-search/engine/templates/playwright_real_chrome.js +243 -0
  206. package/vendor/insane-search/engine/tests/test_hardening.py +57 -0
  207. package/vendor/insane-search/engine/tests/test_smoke.py +152 -0
  208. package/vendor/insane-search/engine/tests/test_u1.py +200 -0
  209. package/vendor/insane-search/engine/tests/test_u4.py +131 -0
  210. package/vendor/insane-search/engine/tests/test_u5.py +163 -0
  211. package/vendor/insane-search/engine/tests/test_u7.py +124 -0
  212. package/vendor/insane-search/engine/transport.py +211 -0
  213. package/vendor/insane-search/engine/url_transforms.py +98 -0
  214. package/vendor/insane-search/engine/validators.py +331 -0
  215. package/vendor/insane-search/engine/waf_detector.py +214 -0
  216. package/vendor/insane-search/engine/waf_profiles.yaml +162 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,26 @@ Sayknow-CLI is a rebranded fork of [gajae-code](https://github.com/Yeachan-Heo/g
4
4
  This file tracks the **fork's own releases**; upstream's full feature history lives
5
5
  in that project. Each release notes the upstream version it is built on.
6
6
 
7
+ ## [0.3.0] — 2026-06-23
8
+
9
+ ### Changed
10
+
11
+ - Synced onto upstream **gajae-code v0.7.1** (from v0.6.5), bringing 0.7.0's mobile
12
+ notifications SDK + managed Telegram daemon and 0.7.1's fixes (assistant
13
+ notification lead-in, stale tmux session reuse, packaged native imports, and the
14
+ glm-zcode Z.AI provider) while preserving the Sayknow-CLI brand.
15
+
16
+ ### Added
17
+
18
+ - **Decepticon red-team integration.** Vendored [Decepticon](https://github.com/PurpleAILAB/Decepticon)
19
+ as a git submodule (`vendor/decepticon`) plus `python/decepticon-bridge` — an
20
+ `skc-rpc` host-tool bridge that exposes Decepticon's red-team agents to skc
21
+ (`decepticon_run_agent` / `decepticon_list_agents`).
22
+ - **Ponytail default rule.** Bundled the ponytail "lazy senior dev" ruleset as an
23
+ always-on default rule: pick the simplest working solution first (YAGNI, reuse,
24
+ stdlib/native first) without ever cutting validation, error handling, security,
25
+ or accessibility. Adapted from [ponytail](https://github.com/DietrichGebert/ponytail) (MIT).
26
+
7
27
  ## [0.2.7] — 2026-06-23
8
28
 
9
29
  ### Added
@@ -68,7 +68,9 @@ export interface SubagentLiveHandle {
68
68
  /** Request a cooperative safe-boundary pause (never aborts the in-flight tool). */
69
69
  requestPause(): void;
70
70
  /** Inject a steering message into the live session. */
71
- injectMessage(content: string, deliverAs: "steer" | "followUp" | "nextTurn"): Promise<void>;
71
+ injectMessage(content: string, deliverAs: "steer" | "followUp" | "nextTurn", opts?: {
72
+ fromAgentId?: string;
73
+ }): Promise<void>;
72
74
  }
73
75
  /**
74
76
  * Canonical, stable-id-keyed record for a subagent. Survives `AsyncJob`
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `skc daemon` command handler.
3
+ *
4
+ * Generic over the static built-in daemon controller map: lists/inspects
5
+ * daemons and drives cooperative stop/reload. Telegram is the only kind today.
6
+ */
7
+ import { Settings } from "../config/settings";
8
+ import type { BuiltInDaemonController, DaemonKind } from "../daemon/control-types";
9
+ export type DaemonCliAction = "list" | "status" | "stop" | "reload";
10
+ export interface DaemonCommandArgs {
11
+ action: DaemonCliAction;
12
+ kinds: DaemonKind[];
13
+ all: boolean;
14
+ json: boolean;
15
+ force: boolean;
16
+ gracefulTimeoutMs?: number;
17
+ killTimeoutMs?: number;
18
+ spawnIfStopped?: boolean;
19
+ }
20
+ export interface DaemonCommandDeps {
21
+ settings?: Settings;
22
+ controllers?: BuiltInDaemonController[];
23
+ }
24
+ export declare function parseDaemonArgs(argv: string[]): DaemonCommandArgs | undefined;
25
+ export declare function runDaemonCommand(cmd: DaemonCommandArgs, deps?: DaemonCommandDeps): Promise<void>;
@@ -0,0 +1,25 @@
1
+ import { Settings } from "../config/settings";
2
+ export type NotifyAction = "setup" | "status" | "daemon-internal";
3
+ export interface NotifyCommandArgs {
4
+ action: NotifyAction;
5
+ smoke?: boolean;
6
+ rawArgs: string[];
7
+ token?: string;
8
+ chatId?: string;
9
+ redact?: boolean;
10
+ }
11
+ export interface NotifyCommandDeps {
12
+ fetchImpl?: typeof fetch;
13
+ apiBase?: string;
14
+ settings?: Settings;
15
+ setupToken?: string;
16
+ pollTimeoutMs?: number;
17
+ pollIntervalMs?: number;
18
+ setupChatId?: string;
19
+ setupRedact?: boolean;
20
+ setupInteractive?: boolean;
21
+ threadedModePrompt?: (message: string) => Promise<string>;
22
+ }
23
+ export declare function parseNotifyArgs(args: string[]): NotifyCommandArgs | undefined;
24
+ export declare function runNotifyCommand(cmd: NotifyCommandArgs, deps?: NotifyCommandDeps): Promise<void>;
25
+ export declare function printNotifyHelp(): void;
@@ -3,7 +3,9 @@
3
3
  *
4
4
  * Handles `skc setup [component]` to install the normal defaults or optional feature dependencies.
5
5
  */
6
- export type SetupComponent = "credentials" | "defaults" | "hermes" | "hooks" | "provider" | "python" | "stt";
6
+ import { AuthStorage, SqliteAuthCredentialStore } from "@sayknow-cli/ai";
7
+ import { runExternalCredentialAutoImport } from "../setup/credential-auto-import";
8
+ export type SetupComponent = "claude" | "codex" | "credentials" | "defaults" | "hermes" | "hooks" | "provider" | "python" | "stt";
7
9
  export interface SetupCommandArgs {
8
10
  component: SetupComponent;
9
11
  flags: {
@@ -34,6 +36,7 @@ export interface SetupCommandArgs {
34
36
  profileDir?: string;
35
37
  yes?: boolean;
36
38
  dryRun?: boolean;
39
+ keychain?: boolean;
37
40
  };
38
41
  }
39
42
  /**
@@ -48,6 +51,22 @@ export declare function parseSetupArgs(args: string[]): SetupCommandArgs | undef
48
51
  * Run the setup command.
49
52
  */
50
53
  export declare function runSetupCommand(cmd: SetupCommandArgs): Promise<void>;
54
+ /**
55
+ * Discover existing Claude Code / Codex CLI credentials and import them into the
56
+ * skc credential store after a redacted preview + confirmation. Falls back to
57
+ * manual-setup guidance when nothing importable is found.
58
+ */
59
+ export interface CredentialsSetupDependencies {
60
+ openStore?: typeof SqliteAuthCredentialStore.open;
61
+ createAuthStorage?: (store: Awaited<ReturnType<typeof SqliteAuthCredentialStore.open>>) => AuthStorage;
62
+ discover?: Parameters<typeof runExternalCredentialAutoImport>[0]["discover"];
63
+ }
64
+ export declare function handleCredentialsSetup(flags: {
65
+ json?: boolean;
66
+ yes?: boolean;
67
+ dryRun?: boolean;
68
+ keychain?: boolean;
69
+ }, deps?: CredentialsSetupDependencies): Promise<void>;
51
70
  /**
52
71
  * Print setup command help.
53
72
  */
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Manage SKC background daemons (status/list/stop/reload).
3
+ */
4
+ import { Command } from "@sayknow-cli/utils/cli";
5
+ import { type DaemonCliAction } from "../cli/daemon-cli";
6
+ export default class Daemon extends Command {
7
+ static description: string;
8
+ static args: {
9
+ action: import("@sayknow-cli/utils/cli").ArgDescriptor & {
10
+ description: string;
11
+ required: false;
12
+ options: DaemonCliAction[];
13
+ };
14
+ kind: import("@sayknow-cli/utils/cli").ArgDescriptor & {
15
+ description: string;
16
+ required: false;
17
+ multiple: true;
18
+ };
19
+ };
20
+ static flags: {
21
+ all: import("@sayknow-cli/utils/cli").FlagDescriptor<"boolean"> & {
22
+ description: string;
23
+ };
24
+ json: import("@sayknow-cli/utils/cli").FlagDescriptor<"boolean"> & {
25
+ description: string;
26
+ };
27
+ force: import("@sayknow-cli/utils/cli").FlagDescriptor<"boolean"> & {
28
+ description: string;
29
+ };
30
+ "graceful-timeout-ms": import("@sayknow-cli/utils/cli").FlagDescriptor<"integer"> & {
31
+ description: string;
32
+ };
33
+ "kill-timeout-ms": import("@sayknow-cli/utils/cli").FlagDescriptor<"integer"> & {
34
+ description: string;
35
+ };
36
+ "spawn-if-stopped": import("@sayknow-cli/utils/cli").FlagDescriptor<"boolean"> & {
37
+ description: string;
38
+ };
39
+ };
40
+ run(): Promise<void>;
41
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Configure Telegram notifications.
3
+ */
4
+ import { Command } from "@sayknow-cli/utils/cli";
5
+ import { type NotifyAction } from "../cli/notify-cli";
6
+ export default class Notify extends Command {
7
+ static description: string;
8
+ static args: {
9
+ action: import("@sayknow-cli/utils/cli").ArgDescriptor & {
10
+ description: string;
11
+ required: false;
12
+ options: NotifyAction[];
13
+ };
14
+ extra: import("@sayknow-cli/utils/cli").ArgDescriptor & {
15
+ description: string;
16
+ required: false;
17
+ multiple: true;
18
+ };
19
+ };
20
+ static flags: {
21
+ smoke: import("@sayknow-cli/utils/cli").FlagDescriptor<"boolean"> & {
22
+ description: string;
23
+ };
24
+ token: import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
25
+ description: string;
26
+ };
27
+ "chat-id": import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
28
+ description: string;
29
+ };
30
+ redact: import("@sayknow-cli/utils/cli").FlagDescriptor<"boolean"> & {
31
+ description: string;
32
+ };
33
+ "owner-id": import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
34
+ description: string;
35
+ };
36
+ "agent-dir": import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
37
+ description: string;
38
+ };
39
+ };
40
+ run(): Promise<void>;
41
+ }
@@ -7,6 +7,8 @@ type ModelProfileActivationSession = Pick<AgentSession, "model" | "thinkingLevel
7
7
  setModelTemporary?: AgentSession["setModelTemporary"];
8
8
  setActiveModelProfile?: (name: string | undefined) => void;
9
9
  getActiveModelProfile?: () => string | undefined;
10
+ getSessionDefaultModelSelector?: () => string | undefined;
11
+ recordResumeDefaultModel?: (selector: string) => void;
10
12
  };
11
13
  export interface PrepareModelProfileActivationOptions {
12
14
  session: ModelProfileActivationSession;
@@ -23,10 +25,20 @@ export interface PreparedModelProfileActivation {
23
25
  previousModel: Model<Api> | undefined;
24
26
  previousThinkingLevel: ThinkingLevel | undefined;
25
27
  previousAgentModelOverrides: Record<string, string>;
28
+ previousModelRoles: Record<string, string>;
26
29
  defaultModel: Model<Api> | undefined;
27
30
  defaultThinkingLevel: ThinkingLevel | undefined;
31
+ modelRoles: Record<string, string>;
28
32
  agentModelOverrides: Record<string, string>;
29
33
  previousActiveModelProfile: string | undefined;
34
+ /**
35
+ * The session resume default ("provider/id") captured BEFORE activation —
36
+ * the model resume would restore prior to this profile. Snapshotted
37
+ * separately from `previousModel` (the live runtime model, which may be a
38
+ * transient switch) so a failed-activation rollback restores the correct
39
+ * resume default without promoting a transient model to it.
40
+ */
41
+ previousSessionDefaultModel: string | undefined;
30
42
  }
31
43
  export declare function formatModelProfileCredentialError(profileName: string, providers: readonly string[]): string;
32
44
  export declare function prepareModelProfileActivation(options: PrepareModelProfileActivationOptions): Promise<PreparedModelProfileActivation>;
@@ -20,7 +20,8 @@ export interface ModelProfileDefinition {
20
20
  }
21
21
  export interface ResolvedProfileBinding {
22
22
  defaultSelector?: string;
23
- agentModelOverrides: Partial<Record<Exclude<ModelProfileRole, "default">, string>>;
23
+ modelRoles: Partial<Record<"vision", string>>;
24
+ agentModelOverrides: Partial<Record<Exclude<ModelProfileRole, "default" | "vision">, string>>;
24
25
  }
25
26
  export declare function deriveModelProfileMappedProviders(definition: Pick<ModelProfileDefinition, "modelMapping">): string[];
26
27
  export declare function aggregateModelProfileRequiredProviders(requiredProviders: readonly string[], definition: Pick<ModelProfileDefinition, "modelMapping">): string[];
@@ -11,7 +11,7 @@ import { type Settings } from "./settings";
11
11
  export type { CanonicalModelIndex, CanonicalModelRecord, CanonicalModelVariant, ModelEquivalenceConfig };
12
12
  export declare const kNoAuth = "N/A";
13
13
  export declare function isAuthenticated(apiKey: string | undefined | null): apiKey is string;
14
- export type ModelRole = "default";
14
+ export type ModelRole = "default" | "vision";
15
15
  export interface ModelRoleInfo {
16
16
  tag?: string;
17
17
  name: string;
@@ -19,7 +19,7 @@ export interface ModelRoleInfo {
19
19
  }
20
20
  export declare const MODEL_ROLES: Record<ModelRole, ModelRoleInfo>;
21
21
  export declare const MODEL_ROLE_IDS: ModelRole[];
22
- export type SkcModelAssignmentTargetId = "default" | "executor" | "architect" | "planner" | "critic";
22
+ export type SkcModelAssignmentTargetId = "default" | "vision" | "executor" | "architect" | "planner" | "critic";
23
23
  export interface SkcModelAssignmentTargetInfo extends ModelRoleInfo {
24
24
  id: SkcModelAssignmentTargetId;
25
25
  settingsPath: "modelRoles" | "task.agentModelOverrides";
@@ -268,7 +268,7 @@ export declare const ModelsConfigFile: ConfigFile<{
268
268
  profiles?: Record<string, {
269
269
  required_providers: string[];
270
270
  display_name?: string | undefined;
271
- model_mapping: Partial<Record<"architect" | "critic" | "default" | "executor" | "planner", string>>;
271
+ model_mapping: Partial<Record<"architect" | "critic" | "default" | "executor" | "planner" | "vision", string>>;
272
272
  }> | undefined;
273
273
  }>;
274
274
  /** Provider override config (baseUrl, headers, apiKey, compat, transport) without custom models */
@@ -68,6 +68,7 @@ export declare const ProfileRoleSchema: z.ZodEnum<{
68
68
  default: "default";
69
69
  executor: "executor";
70
70
  planner: "planner";
71
+ vision: "vision";
71
72
  }>;
72
73
  export declare const ProfileModelSelectorSchema: z.ZodString;
73
74
  export declare const ProfileModelMappingSchema: z.ZodRecord<z.ZodEnum<{
@@ -76,6 +77,7 @@ export declare const ProfileModelMappingSchema: z.ZodRecord<z.ZodEnum<{
76
77
  default: "default";
77
78
  executor: "executor";
78
79
  planner: "planner";
80
+ vision: "vision";
79
81
  }> & z.core.$partial, z.ZodString>;
80
82
  export declare const ProfileDefinitionSchema: z.ZodObject<{
81
83
  required_providers: z.ZodArray<z.ZodString>;
@@ -86,6 +88,7 @@ export declare const ProfileDefinitionSchema: z.ZodObject<{
86
88
  default: "default";
87
89
  executor: "executor";
88
90
  planner: "planner";
91
+ vision: "vision";
89
92
  }> & z.core.$partial, z.ZodString>;
90
93
  }, z.core.$strict>;
91
94
  export declare const ProfilesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -97,6 +100,7 @@ export declare const ProfilesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
97
100
  default: "default";
98
101
  executor: "executor";
99
102
  planner: "planner";
103
+ vision: "vision";
100
104
  }> & z.core.$partial, z.ZodString>;
101
105
  }, z.core.$strict>>;
102
106
  export declare const ModelOverrideSchema: z.ZodObject<{
@@ -687,6 +691,7 @@ export declare const ModelsConfigSchema: z.ZodObject<{
687
691
  default: "default";
688
692
  executor: "executor";
689
693
  planner: "planner";
694
+ vision: "vision";
690
695
  }> & z.core.$partial, z.ZodString>;
691
696
  }, z.core.$strict>>>;
692
697
  }, z.core.$strict>;
@@ -10,7 +10,7 @@ import { type SkillDiscoverySettings } from "./skill-settings-defaults";
10
10
  * settings.get("compaction.enabled") // => boolean
11
11
  * settings.set("theme.dark", "red-octopus") // sync, saves in background
12
12
  */
13
- export type SettingTab = "appearance" | "model" | "interaction" | "context" | "memory" | "editing" | "tools" | "tasks" | "providers";
13
+ export type SettingTab = "appearance" | "model" | "interaction" | "notifications" | "context" | "memory" | "editing" | "tools" | "tasks" | "providers";
14
14
  /** Tab display metadata - icon is resolved via theme.symbol() */
15
15
  export type TabMetadata = {
16
16
  label: string;
@@ -56,10 +56,13 @@ interface UiString extends UiBase {
56
56
  * - Omitted → renders as a free text input.
57
57
  */
58
58
  options?: ReadonlyArray<SubmenuOption> | "runtime";
59
+ /** When true, the value is masked in the settings list display but edited in full. */
60
+ secret?: boolean;
59
61
  }
60
62
  /** Wide ui shape exposed to consumers that walk the schema generically. */
61
63
  export type AnyUiMetadata = UiBase & {
62
64
  options?: ReadonlyArray<SubmenuOption> | "runtime";
65
+ secret?: boolean;
63
66
  };
64
67
  interface BooleanDef {
65
68
  type: "boolean";
@@ -118,6 +121,103 @@ export declare const SETTINGS_SCHEMA: {
118
121
  readonly type: "string";
119
122
  readonly default: undefined;
120
123
  };
124
+ readonly "notifications.enabled": {
125
+ readonly type: "boolean";
126
+ readonly default: false;
127
+ readonly ui: {
128
+ readonly tab: "notifications";
129
+ readonly label: "Enabled";
130
+ readonly description: "Master switch for notifications. Requires at least one adapter (Telegram/Discord/Slack) configured with a token and a chat/channel to actually deliver.";
131
+ };
132
+ };
133
+ readonly "notifications.telegram.botToken": {
134
+ readonly type: "string";
135
+ readonly default: undefined;
136
+ readonly ui: {
137
+ readonly tab: "notifications";
138
+ readonly label: "Telegram bot token";
139
+ readonly description: "Telegram BotFather HTTP API token. Stored locally; shown masked.";
140
+ readonly secret: true;
141
+ };
142
+ };
143
+ readonly "notifications.telegram.chatId": {
144
+ readonly type: "string";
145
+ readonly default: undefined;
146
+ readonly ui: {
147
+ readonly tab: "notifications";
148
+ readonly label: "Telegram chat ID";
149
+ readonly description: "Target chat. For end-to-end per-session delivery this must be a forum-enabled supergroup the bot can manage; a private chat id is only enough for setup/status.";
150
+ };
151
+ };
152
+ readonly "notifications.discord.botToken": {
153
+ readonly type: "string";
154
+ readonly default: undefined;
155
+ readonly ui: {
156
+ readonly tab: "notifications";
157
+ readonly label: "Discord bot token";
158
+ readonly description: "Discord bot token for the notifications adapter. Stored locally; shown masked.";
159
+ readonly secret: true;
160
+ };
161
+ };
162
+ readonly "notifications.discord.channelId": {
163
+ readonly type: "string";
164
+ readonly default: undefined;
165
+ readonly ui: {
166
+ readonly tab: "notifications";
167
+ readonly label: "Discord channel ID";
168
+ readonly description: "Discord channel that receives notifications and routes replies back.";
169
+ };
170
+ };
171
+ readonly "notifications.slack.botToken": {
172
+ readonly type: "string";
173
+ readonly default: undefined;
174
+ readonly ui: {
175
+ readonly tab: "notifications";
176
+ readonly label: "Slack bot token";
177
+ readonly description: "Slack bot token for the notifications adapter. Stored locally; shown masked.";
178
+ readonly secret: true;
179
+ };
180
+ };
181
+ readonly "notifications.slack.channelId": {
182
+ readonly type: "string";
183
+ readonly default: undefined;
184
+ readonly ui: {
185
+ readonly tab: "notifications";
186
+ readonly label: "Slack channel ID";
187
+ readonly description: "Slack channel that receives notifications and routes replies back.";
188
+ };
189
+ };
190
+ readonly "notifications.redact": {
191
+ readonly type: "boolean";
192
+ readonly default: false;
193
+ readonly ui: {
194
+ readonly tab: "notifications";
195
+ readonly label: "Redact";
196
+ readonly description: "Strip idle summaries and streamed content before remote delivery. Ask prompts are always sent so they remain answerable.";
197
+ };
198
+ };
199
+ readonly "notifications.verbosity": {
200
+ readonly type: "string";
201
+ readonly default: "lean";
202
+ readonly validate: (value: string) => value is "lean" | "verbose";
203
+ readonly ui: {
204
+ readonly tab: "notifications";
205
+ readonly label: "Verbosity";
206
+ readonly description: "How much session context to stream to Telegram.";
207
+ readonly options: readonly [{
208
+ readonly value: "lean";
209
+ readonly label: "Lean";
210
+ }, {
211
+ readonly value: "verbose";
212
+ readonly label: "Verbose";
213
+ }];
214
+ };
215
+ };
216
+ readonly "notifications.daemon.idleTimeoutMs": {
217
+ readonly type: "number";
218
+ readonly default: 60000;
219
+ readonly validate: (value: number) => boolean;
220
+ };
121
221
  readonly autoResume: {
122
222
  readonly type: "boolean";
123
223
  readonly default: false;
@@ -2486,6 +2586,15 @@ export declare const SETTINGS_SCHEMA: {
2486
2586
  readonly description: "Allow the read tool to fetch and process URLs";
2487
2587
  };
2488
2588
  };
2589
+ readonly "web.insaneFallback": {
2590
+ readonly type: "boolean";
2591
+ readonly default: false;
2592
+ readonly ui: {
2593
+ readonly tab: "tools";
2594
+ readonly label: "Insane Search Fallback";
2595
+ readonly description: "Opt in to the vendored insane-search escalation for blocked public URL reads (403/WAF/JS-gated). Off by default. Requires preinstalled python3 + curl_cffi (and node + playwright/stealth for the browser phase); changes network posture by enabling TLS/browser impersonation for public pages.";
2596
+ };
2597
+ };
2489
2598
  readonly "github.enabled": {
2490
2599
  readonly type: "boolean";
2491
2600
  readonly default: false;
@@ -2535,7 +2644,7 @@ export declare const SETTINGS_SCHEMA: {
2535
2644
  readonly type: "array";
2536
2645
  readonly default: string[];
2537
2646
  readonly items: {
2538
- readonly enum: readonly ["duckduckgo", "exa", "brave", "jina", "kimi", "zai", "anthropic", "perplexity", "gemini", "codex", "xai", "tavily", "parallel", "kagi", "synthetic", "searxng"];
2647
+ readonly enum: readonly ["duckduckgo", "insane", "exa", "brave", "jina", "kimi", "zai", "anthropic", "perplexity", "gemini", "codex", "xai", "tavily", "parallel", "kagi", "synthetic", "searxng"];
2539
2648
  };
2540
2649
  readonly ui: {
2541
2650
  readonly tab: "tools";
@@ -3138,7 +3247,7 @@ export declare const SETTINGS_SCHEMA: {
3138
3247
  };
3139
3248
  readonly "providers.webSearch": {
3140
3249
  readonly type: "enum";
3141
- readonly values: readonly ["auto", "duckduckgo", "exa", "brave", "jina", "kimi", "zai", "perplexity", "anthropic", "gemini", "codex", "xai", "tavily", "kagi", "synthetic", "parallel", "searxng"];
3250
+ readonly values: readonly ["auto", "duckduckgo", "insane", "exa", "brave", "jina", "kimi", "zai", "perplexity", "anthropic", "gemini", "codex", "xai", "tavily", "kagi", "synthetic", "parallel", "searxng"];
3142
3251
  readonly default: "auto";
3143
3252
  readonly ui: {
3144
3253
  readonly tab: "providers";
@@ -3152,6 +3261,10 @@ export declare const SETTINGS_SCHEMA: {
3152
3261
  readonly value: "duckduckgo";
3153
3262
  readonly label: "DuckDuckGo";
3154
3263
  readonly description: "Keyless default \u2014 no API key or OAuth required";
3264
+ }, {
3265
+ readonly value: "insane";
3266
+ readonly label: "Insane";
3267
+ readonly description: "Keyless safe public-route fallback inspired by upstream insane-search";
3155
3268
  }, {
3156
3269
  readonly value: "exa";
3157
3270
  readonly label: "Exa";
@@ -3618,6 +3731,25 @@ export interface ShellMinimizerSettings {
3618
3731
  except: string[];
3619
3732
  maxCaptureBytes: number;
3620
3733
  }
3734
+ export interface NotificationsSettings {
3735
+ enabled: boolean;
3736
+ telegram: {
3737
+ botToken: string | undefined;
3738
+ chatId: string | undefined;
3739
+ };
3740
+ discord: {
3741
+ botToken: string | undefined;
3742
+ channelId: string | undefined;
3743
+ };
3744
+ slack: {
3745
+ botToken: string | undefined;
3746
+ channelId: string | undefined;
3747
+ };
3748
+ redact: boolean;
3749
+ daemon: {
3750
+ idleTimeoutMs: number;
3751
+ };
3752
+ }
3621
3753
  /** Map group prefix -> typed settings interface */
3622
3754
  export interface GroupTypeMap {
3623
3755
  compaction: CompactionSettings;
@@ -3636,6 +3768,7 @@ export interface GroupTypeMap {
3636
3768
  modelTags: ModelTagsSettings;
3637
3769
  cycleOrder: string[];
3638
3770
  shellMinimizer: ShellMinimizerSettings;
3771
+ notifications: NotificationsSettings;
3639
3772
  }
3640
3773
  export type GroupPrefix = keyof GroupTypeMap;
3641
3774
  export {};
@@ -1,4 +1,4 @@
1
1
  export declare const COORDINATOR_MCP_PROTOCOL_VERSION = "2024-11-05";
2
2
  export declare const COORDINATOR_MCP_SERVER_NAME = "skc-coordinator-mcp";
3
- export declare const COORDINATOR_MCP_TOOL_NAMES: readonly ["skc_coordinator_list_sessions", "skc_coordinator_read_status", "skc_coordinator_read_tail", "skc_coordinator_list_questions", "skc_coordinator_list_artifacts", "skc_coordinator_read_artifact", "skc_coordinator_read_coordination_status", "skc_coordinator_watch_events", "skc_coordinator_register_session", "skc_coordinator_start_session", "skc_coordinator_send_prompt", "skc_coordinator_submit_question_answer", "skc_coordinator_read_turn", "skc_coordinator_await_turn", "skc_coordinator_report_status"];
3
+ export declare const COORDINATOR_MCP_TOOL_NAMES: readonly ["skc_coordinator_list_sessions", "skc_coordinator_read_status", "skc_coordinator_read_tail", "skc_coordinator_list_questions", "skc_coordinator_list_artifacts", "skc_coordinator_read_artifact", "skc_coordinator_read_coordination_status", "skc_coordinator_watch_events", "skc_coordinator_register_session", "skc_coordinator_start_session", "skc_coordinator_send_prompt", "skc_coordinator_submit_question_answer", "skc_coordinator_read_turn", "skc_coordinator_await_turn", "skc_coordinator_report_status", "skc_delegate_plan", "skc_delegate_execute", "skc_delegate_team"];
4
4
  export type CoordinatorToolName = (typeof COORDINATOR_MCP_TOOL_NAMES)[number];
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Static built-in daemon controller map.
3
+ *
4
+ * Intentionally a static map keyed by daemon kind rather than a mutable plugin
5
+ * registry: there is exactly one kind today (`telegram`). Promote to a richer
6
+ * registry only when a second daemon kind exists.
7
+ */
8
+ import type { Settings } from "../config/settings";
9
+ import { type TelegramDaemonControlDeps } from "../notifications/telegram-daemon-control";
10
+ import type { BuiltInDaemonController, DaemonKind } from "./control-types";
11
+ export declare const BUILT_IN_DAEMON_KINDS: readonly ["telegram"];
12
+ export interface BuiltInDaemonControllerDeps {
13
+ telegram?: TelegramDaemonControlDeps;
14
+ }
15
+ export declare function createBuiltInDaemonControllers(settings: Settings, deps?: BuiltInDaemonControllerDeps): Record<DaemonKind, BuiltInDaemonController>;
16
+ /**
17
+ * Resolve the controllers a command should act on. `--all` selects every
18
+ * built-in kind; otherwise the explicit `kinds` (defaulting to `telegram`).
19
+ */
20
+ export declare function selectDaemonControllers(settings: Settings, kinds: DaemonKind[] | undefined, all: boolean, deps?: BuiltInDaemonControllerDeps): BuiltInDaemonController[];
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Public types for the `skc daemon` control plane.
3
+ *
4
+ * Deliberately compact: a small result/status surface plus a built-in
5
+ * controller contract. There is exactly one daemon kind today (`telegram`);
6
+ * a richer registry is intentionally deferred until a second kind exists.
7
+ */
8
+ export type DaemonKind = "telegram";
9
+ export type DaemonAction = "list" | "status" | "stop" | "reload";
10
+ export type DaemonHealth = "not_configured" | "stopped" | "running" | "stale" | "stopping" | "error";
11
+ export interface DaemonRuntimeInfo {
12
+ /** `source` when respawn goes through bun/node + the entry script; `compiled` for a single-file binary. */
13
+ mode: "source" | "compiled";
14
+ execPath: string;
15
+ /** True only in source/dev mode, where a respawn loads amended TypeScript directly. */
16
+ reloadPicksUpSourceEdits: boolean;
17
+ /** Present when the runtime mode constrains what reload can achieve (e.g. compiled binary). */
18
+ warning?: string;
19
+ }
20
+ export interface DaemonStatus {
21
+ kind: DaemonKind;
22
+ configured: boolean;
23
+ health: DaemonHealth;
24
+ pid?: number;
25
+ ownerId?: string;
26
+ startedAt?: number;
27
+ heartbeatAt?: number;
28
+ roots?: string[];
29
+ rootCount?: number;
30
+ runtime: DaemonRuntimeInfo;
31
+ detail?: string;
32
+ }
33
+ export interface DaemonOperationOptions {
34
+ /** How long to wait for cooperative release before escalating. */
35
+ gracefulTimeoutMs?: number;
36
+ /** How long to wait for the old pid to die after SIGKILL. */
37
+ killTimeoutMs?: number;
38
+ /** Allow hard-kill escalation / acting on a still-live owner. */
39
+ force?: boolean;
40
+ /** For reload: spawn a fresh owner even when none is currently running. */
41
+ spawnIfStopped?: boolean;
42
+ }
43
+ export interface DaemonOperationResult {
44
+ kind: DaemonKind;
45
+ action: Exclude<DaemonAction, "list">;
46
+ ok: boolean;
47
+ before?: DaemonStatus;
48
+ after?: DaemonStatus;
49
+ warnings: string[];
50
+ message: string;
51
+ }
52
+ export interface BuiltInDaemonController {
53
+ readonly kind: DaemonKind;
54
+ status(): Promise<DaemonStatus>;
55
+ stop(opts?: DaemonOperationOptions): Promise<DaemonOperationResult>;
56
+ reload(opts?: DaemonOperationOptions): Promise<DaemonOperationResult>;
57
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shared source-vs-compiled runtime detection for daemon spawning.
3
+ *
4
+ * Centralizes the logic previously embedded in `ensureTelegramDaemonRunning`
5
+ * so session autostart, reload, and status reporting agree on how a daemon
6
+ * process is launched and whether a reload can pick up amended source.
7
+ */
8
+ export interface SkcRuntimeSpawnInfo {
9
+ execPath: string;
10
+ mode: "source" | "compiled";
11
+ /** Prefix prepended before the skc subcommand args; `[Bun.main]` in source mode, otherwise `[]`. */
12
+ argsPrefix: string[];
13
+ /** True only when respawn loads edited TypeScript directly (source/dev mode). */
14
+ reloadPicksUpSourceEdits: boolean;
15
+ /** Set in compiled mode to explain that a rebuild is required before reload picks up source edits. */
16
+ warning?: string;
17
+ }
18
+ /**
19
+ * Resolve how to spawn a detached skc subcommand for the current runtime.
20
+ *
21
+ * Source/dev mode (bun/node) prepends the entry script (`Bun.main`) so the
22
+ * respawn loads edited source. A compiled single-file binary self-spawns its
23
+ * own subcommand directly and cannot pick up workspace source edits.
24
+ */
25
+ export declare function resolveSkcRuntimeSpawnInfo(execPath?: string): SkcRuntimeSpawnInfo;