@sayknow-cli/coding-agent 0.3.0 → 0.3.2

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 (233) hide show
  1. package/bin/skc.js +4 -0
  2. package/dist/types/cli/mcp-cli.d.ts +25 -0
  3. package/dist/types/cli/notify-cli.d.ts +2 -0
  4. package/dist/types/cli/plugin-cli.d.ts +2 -0
  5. package/dist/types/cli.d.ts +6 -0
  6. package/dist/types/commands/mcp.d.ts +70 -0
  7. package/dist/types/commands/plugin.d.ts +6 -0
  8. package/dist/types/commands/session.d.ts +6 -0
  9. package/dist/types/config/keybindings.d.ts +2 -2
  10. package/dist/types/config/model-profile-activation.d.ts +8 -1
  11. package/dist/types/config/settings-schema.d.ts +39 -2
  12. package/dist/types/deep-interview/plaintext-gate-guard.d.ts +11 -0
  13. package/dist/types/defaults/skc-defaults.d.ts +2 -13
  14. package/dist/types/extensibility/shared-events.d.ts +1 -0
  15. package/dist/types/extensibility/skc-plugins/compiler.d.ts +19 -0
  16. package/dist/types/extensibility/skc-plugins/constrained-hooks.d.ts +29 -0
  17. package/dist/types/extensibility/skc-plugins/index.d.ts +9 -0
  18. package/dist/types/extensibility/skc-plugins/injection.d.ts +9 -0
  19. package/dist/types/extensibility/skc-plugins/installer.d.ts +13 -0
  20. package/dist/types/extensibility/skc-plugins/mcp-policy.d.ts +26 -0
  21. package/dist/types/extensibility/skc-plugins/observability.d.ts +27 -0
  22. package/dist/types/extensibility/skc-plugins/prompt-appendix.d.ts +16 -0
  23. package/dist/types/extensibility/skc-plugins/registry.d.ts +32 -0
  24. package/dist/types/extensibility/skc-plugins/runtime-adapters.d.ts +64 -0
  25. package/dist/types/extensibility/skc-plugins/session-validation.d.ts +42 -0
  26. package/dist/types/extensibility/skc-plugins/types.d.ts +158 -2
  27. package/dist/types/extensibility/skc-plugins/validation.d.ts +8 -1
  28. package/dist/types/lsp/types.d.ts +2 -0
  29. package/dist/types/main.d.ts +2 -0
  30. package/dist/types/modes/components/custom-editor.d.ts +1 -1
  31. package/dist/types/modes/components/model-selector.d.ts +8 -0
  32. package/dist/types/modes/components/status-line/git-utils.d.ts +6 -0
  33. package/dist/types/modes/theme/defaults/index.d.ts +99 -0
  34. package/dist/types/notifications/attachment-registry.d.ts +17 -0
  35. package/dist/types/notifications/chat-adapters.d.ts +9 -0
  36. package/dist/types/notifications/config.d.ts +9 -1
  37. package/dist/types/notifications/engine.d.ts +59 -0
  38. package/dist/types/notifications/html-format.d.ts +11 -0
  39. package/dist/types/notifications/index.d.ts +149 -1
  40. package/dist/types/notifications/lifecycle-commands.d.ts +60 -0
  41. package/dist/types/notifications/lifecycle-control-runtime.d.ts +98 -0
  42. package/dist/types/notifications/lifecycle-orchestrator.d.ts +144 -0
  43. package/dist/types/notifications/managed-daemon.d.ts +48 -0
  44. package/dist/types/notifications/operator-runtime.d.ts +52 -0
  45. package/dist/types/notifications/rate-limit-pool.d.ts +2 -0
  46. package/dist/types/notifications/recent-activity.d.ts +35 -0
  47. package/dist/types/notifications/telegram-daemon.d.ts +133 -16
  48. package/dist/types/notifications/telegram-reference.d.ts +3 -1
  49. package/dist/types/notifications/threaded-inbound.d.ts +19 -0
  50. package/dist/types/notifications/threaded-render.d.ts +6 -1
  51. package/dist/types/notifications/topic-registry.d.ts +12 -9
  52. package/dist/types/runtime-mcp/types.d.ts +7 -0
  53. package/dist/types/sdk.d.ts +2 -0
  54. package/dist/types/session/agent-session.d.ts +16 -4
  55. package/dist/types/session/blob-store.d.ts +25 -0
  56. package/dist/types/session/session-manager.d.ts +57 -0
  57. package/dist/types/skc-runtime/launch-tmux.d.ts +1 -0
  58. package/dist/types/skc-runtime/psmux-detect.d.ts +78 -0
  59. package/dist/types/skc-runtime/ralplan-runtime.d.ts +1 -1
  60. package/dist/types/skc-runtime/team-runtime.d.ts +2 -0
  61. package/dist/types/skc-runtime/tmux-common.d.ts +30 -2
  62. package/dist/types/skc-runtime/tmux-sessions.d.ts +18 -0
  63. package/dist/types/slash-commands/helpers/fast-status-report.d.ts +6 -0
  64. package/dist/types/system-prompt.d.ts +2 -0
  65. package/dist/types/task/executor.d.ts +9 -1
  66. package/dist/types/tools/composer-bash-policy.d.ts +14 -0
  67. package/dist/types/tools/fetch.d.ts +23 -0
  68. package/dist/types/tools/index.d.ts +4 -1
  69. package/dist/types/tools/telegram-send.d.ts +32 -0
  70. package/dist/types/utils/changelog.d.ts +1 -0
  71. package/dist/types/web/insane/bridge.d.ts +103 -0
  72. package/dist/types/web/insane/url-guard.d.ts +25 -0
  73. package/dist/types/web/scrapers/types.d.ts +5 -0
  74. package/dist/types/web/scrapers/utils.d.ts +7 -1
  75. package/dist/types/web/search/provider.d.ts +18 -1
  76. package/dist/types/web/search/providers/insane.d.ts +53 -0
  77. package/dist/types/web/search/providers/text-citations.d.ts +23 -0
  78. package/dist/types/web/search/types.d.ts +12 -4
  79. package/package.json +14 -10
  80. package/scripts/g004-tmux-smoke.ts +100 -0
  81. package/scripts/g005-daemon-smoke.ts +180 -0
  82. package/scripts/g011-daemon-path-smoke.ts +153 -0
  83. package/scripts/verify-insane-vendor.ts +132 -0
  84. package/src/cli/args.ts +1 -1
  85. package/src/cli/fast-help.ts +30 -2
  86. package/src/cli/mcp-cli.ts +272 -0
  87. package/src/cli/notify-cli.ts +152 -5
  88. package/src/cli/plugin-cli.ts +66 -3
  89. package/src/cli.ts +30 -12
  90. package/src/commands/mcp.ts +117 -0
  91. package/src/commands/plugin.ts +4 -0
  92. package/src/commands/session.ts +18 -0
  93. package/src/commands/team.ts +1 -1
  94. package/src/config/keybindings.ts +2 -2
  95. package/src/config/model-profile-activation.ts +55 -7
  96. package/src/config/settings-schema.ts +30 -1
  97. package/src/deep-interview/plaintext-gate-guard.ts +94 -0
  98. package/src/defaults/skc/extensions/grok-cli-vendor/biome.json +1 -1
  99. package/src/defaults/skc/skills/deep-interview/SKILL.md +7 -6
  100. package/src/defaults/skc/skills/ralplan/SKILL.md +11 -4
  101. package/src/defaults/skc/skills/team/SKILL.md +5 -3
  102. package/src/defaults/skc/skills/ultragoal/SKILL.md +41 -13
  103. package/src/defaults/skc-defaults.ts +2 -27
  104. package/src/export/html/index.ts +2 -2
  105. package/src/extensibility/extensions/runner.ts +1 -0
  106. package/src/extensibility/shared-events.ts +1 -0
  107. package/src/extensibility/skc-plugins/compiler.ts +351 -0
  108. package/src/extensibility/skc-plugins/constrained-hooks.ts +170 -0
  109. package/src/extensibility/skc-plugins/index.ts +9 -0
  110. package/src/extensibility/skc-plugins/injection.ts +109 -0
  111. package/src/extensibility/skc-plugins/installer.ts +434 -0
  112. package/src/extensibility/skc-plugins/loader.ts +3 -1
  113. package/src/extensibility/skc-plugins/mcp-policy.ts +239 -0
  114. package/src/extensibility/skc-plugins/observability.ts +84 -0
  115. package/src/extensibility/skc-plugins/paths.ts +1 -1
  116. package/src/extensibility/skc-plugins/prompt-appendix.ts +109 -0
  117. package/src/extensibility/skc-plugins/registry.ts +180 -0
  118. package/src/extensibility/skc-plugins/runtime-adapters.ts +234 -0
  119. package/src/extensibility/skc-plugins/schema.ts +250 -20
  120. package/src/extensibility/skc-plugins/session-validation.ts +147 -0
  121. package/src/extensibility/skc-plugins/types.ts +199 -3
  122. package/src/extensibility/skc-plugins/validation.ts +80 -0
  123. package/src/extensibility/skills.ts +15 -0
  124. package/src/hooks/skill-state.ts +57 -0
  125. package/src/internal-urls/docs-index.generated.ts +17 -13
  126. package/src/lsp/config.ts +16 -3
  127. package/src/lsp/defaults.json +7 -0
  128. package/src/lsp/types.ts +2 -0
  129. package/src/main.ts +14 -3
  130. package/src/modes/bridge/bridge-mode.ts +11 -0
  131. package/src/modes/components/assistant-message.ts +49 -1
  132. package/src/modes/components/custom-editor.ts +2 -0
  133. package/src/modes/components/footer.ts +2 -3
  134. package/src/modes/components/hook-editor.ts +1 -1
  135. package/src/modes/components/hook-selector.ts +67 -43
  136. package/src/modes/components/model-selector.ts +56 -11
  137. package/src/modes/components/status-line/git-utils.ts +25 -0
  138. package/src/modes/components/status-line.ts +10 -11
  139. package/src/modes/components/welcome.ts +2 -3
  140. package/src/modes/controllers/event-controller.ts +15 -0
  141. package/src/modes/controllers/extension-ui-controller.ts +0 -27
  142. package/src/modes/controllers/selector-controller.ts +53 -11
  143. package/src/modes/interactive-mode.ts +50 -3
  144. package/src/modes/shared/agent-wire/scopes.ts +1 -1
  145. package/src/modes/theme/defaults/gruvbox-dark.json +99 -0
  146. package/src/modes/theme/defaults/index.ts +2 -0
  147. package/src/modes/utils/context-usage.ts +2 -2
  148. package/src/modes/utils/hotkeys-markdown.ts +1 -1
  149. package/src/notifications/attachment-registry.ts +23 -0
  150. package/src/notifications/chat-adapters.ts +147 -0
  151. package/src/notifications/config.ts +23 -2
  152. package/src/notifications/engine.ts +100 -0
  153. package/src/notifications/html-format.ts +38 -0
  154. package/src/notifications/index.ts +417 -45
  155. package/src/notifications/lifecycle-commands.ts +238 -0
  156. package/src/notifications/lifecycle-control-runtime.ts +405 -0
  157. package/src/notifications/lifecycle-orchestrator.ts +358 -0
  158. package/src/notifications/managed-daemon.ts +163 -0
  159. package/src/notifications/operator-runtime.ts +171 -0
  160. package/src/notifications/rate-limit-pool.ts +19 -0
  161. package/src/notifications/recent-activity.ts +132 -0
  162. package/src/notifications/telegram-daemon.ts +984 -242
  163. package/src/notifications/telegram-reference.ts +25 -7
  164. package/src/notifications/threaded-inbound.ts +60 -4
  165. package/src/notifications/threaded-render.ts +20 -2
  166. package/src/notifications/topic-registry.ts +23 -9
  167. package/src/prompts/agents/executor.md +2 -2
  168. package/src/runtime-mcp/transports/stdio.ts +38 -4
  169. package/src/runtime-mcp/types.ts +7 -0
  170. package/src/sdk.ts +157 -10
  171. package/src/session/agent-session.ts +248 -125
  172. package/src/session/blob-store.ts +196 -8
  173. package/src/session/session-manager.ts +762 -12
  174. package/src/skc-runtime/launch-tmux.ts +85 -22
  175. package/src/skc-runtime/ledger-event-renderer.ts +1 -0
  176. package/src/skc-runtime/psmux-detect.ts +239 -0
  177. package/src/skc-runtime/ralplan-runtime.ts +2 -2
  178. package/src/skc-runtime/team-runtime.ts +56 -23
  179. package/src/skc-runtime/tmux-common.ts +88 -4
  180. package/src/skc-runtime/tmux-sessions.ts +111 -9
  181. package/src/skc-runtime/ultragoal-guard.ts +25 -8
  182. package/src/skc-runtime/ultragoal-runtime.ts +75 -15
  183. package/src/skc-runtime/workflow-manifest.generated.json +29 -0
  184. package/src/skc-runtime/workflow-manifest.ts +7 -2
  185. package/src/slash-commands/builtin-registry.ts +23 -3
  186. package/src/slash-commands/helpers/fast-status-report.ts +13 -3
  187. package/src/slash-commands/helpers/parse.ts +2 -1
  188. package/src/system-prompt.ts +9 -0
  189. package/src/task/executor.ts +31 -7
  190. package/src/task/index.ts +2 -0
  191. package/src/tools/ask.ts +5 -1
  192. package/src/tools/bash.ts +9 -0
  193. package/src/tools/composer-bash-policy.ts +96 -0
  194. package/src/tools/fetch.ts +94 -1
  195. package/src/tools/index.ts +6 -1
  196. package/src/tools/telegram-send.ts +137 -0
  197. package/src/utils/changelog.ts +8 -0
  198. package/src/web/insane/bridge.ts +350 -0
  199. package/src/web/insane/url-guard.ts +159 -0
  200. package/src/web/scrapers/types.ts +143 -45
  201. package/src/web/scrapers/utils.ts +70 -19
  202. package/src/web/search/provider.ts +77 -18
  203. package/src/web/search/providers/anthropic.ts +70 -3
  204. package/src/web/search/providers/codex.ts +1 -119
  205. package/src/web/search/providers/gemini.ts +99 -0
  206. package/src/web/search/providers/insane.ts +551 -0
  207. package/src/web/search/providers/openai-compatible.ts +66 -32
  208. package/src/web/search/providers/text-citations.ts +111 -0
  209. package/src/web/search/types.ts +13 -2
  210. package/vendor/insane-search/LICENSE +21 -0
  211. package/vendor/insane-search/MANIFEST.json +24 -0
  212. package/vendor/insane-search/engine/__init__.py +23 -0
  213. package/vendor/insane-search/engine/__main__.py +128 -0
  214. package/vendor/insane-search/engine/bias_check.py +183 -0
  215. package/vendor/insane-search/engine/executor.py +254 -0
  216. package/vendor/insane-search/engine/fetch_chain.py +725 -0
  217. package/vendor/insane-search/engine/learning.py +175 -0
  218. package/vendor/insane-search/engine/phase0.py +214 -0
  219. package/vendor/insane-search/engine/safety.py +91 -0
  220. package/vendor/insane-search/engine/templates/package.json +11 -0
  221. package/vendor/insane-search/engine/templates/playwright_mobile_chrome.js +188 -0
  222. package/vendor/insane-search/engine/templates/playwright_real_chrome.js +243 -0
  223. package/vendor/insane-search/engine/tests/test_hardening.py +57 -0
  224. package/vendor/insane-search/engine/tests/test_smoke.py +152 -0
  225. package/vendor/insane-search/engine/tests/test_u1.py +200 -0
  226. package/vendor/insane-search/engine/tests/test_u4.py +131 -0
  227. package/vendor/insane-search/engine/tests/test_u5.py +163 -0
  228. package/vendor/insane-search/engine/tests/test_u7.py +124 -0
  229. package/vendor/insane-search/engine/transport.py +211 -0
  230. package/vendor/insane-search/engine/url_transforms.py +98 -0
  231. package/vendor/insane-search/engine/validators.py +331 -0
  232. package/vendor/insane-search/engine/waf_detector.py +214 -0
  233. package/vendor/insane-search/engine/waf_profiles.yaml +162 -0
@@ -7,12 +7,56 @@ export declare const SKC_SUBSKILL_PARENT_AGENTS: readonly ["executor", "architec
7
7
  export type SkcSubskillParentAgent = (typeof SKC_SUBSKILL_PARENT_AGENTS)[number];
8
8
  export type SkcSubskillParent = SkcSubskillParentSkill | SkcSubskillParentAgent;
9
9
  export declare const SKC_AGENT_SUBSKILL_PHASES: Record<SkcSubskillParentAgent, string[]>;
10
+ export interface SkcPluginToolManifestEntry {
11
+ name: string;
12
+ path: string;
13
+ description?: string;
14
+ sha256?: string;
15
+ /**
16
+ * "always-on" object entries are activated for the whole session; legacy
17
+ * string shorthand stays "subskill"-scoped and is only attached to subskill
18
+ * bindings (never registered as an always-on tool surface).
19
+ */
20
+ surface: "subskill" | "always-on";
21
+ }
22
+ export interface SkcPluginHookManifestEntry {
23
+ name: string;
24
+ event: string;
25
+ target?: string;
26
+ phase?: "before" | "after";
27
+ path: string;
28
+ sha256?: string;
29
+ }
30
+ export type SkcPluginMcpTransport = "stdio" | "http" | "sse";
31
+ export interface SkcPluginMcpManifestEntry {
32
+ name: string;
33
+ transport: SkcPluginMcpTransport;
34
+ command?: string;
35
+ args?: string[];
36
+ cwd?: string;
37
+ url?: string;
38
+ headers?: Record<string, string>;
39
+ sha256?: string;
40
+ }
41
+ export interface SkcPluginAppendixManifestEntry {
42
+ name: string;
43
+ path?: string;
44
+ content?: string;
45
+ sha256?: string;
46
+ }
47
+ export interface SkcPluginAgentAppendixManifestEntry extends SkcPluginAppendixManifestEntry {
48
+ agent: SkcSubskillParentAgent;
49
+ }
10
50
  export interface SkcPluginManifest {
11
51
  name: string;
12
52
  version: string;
13
53
  kind: "sayknow-cli-plugin";
14
54
  subskills: string[];
15
- tools: string[];
55
+ tools: SkcPluginToolManifestEntry[];
56
+ hooks: SkcPluginHookManifestEntry[];
57
+ mcps: SkcPluginMcpManifestEntry[];
58
+ systemAppendix: SkcPluginAppendixManifestEntry[];
59
+ agentAppendix: SkcPluginAgentAppendixManifestEntry[];
16
60
  }
17
61
  export interface SubskillFrontmatter {
18
62
  name: string;
@@ -57,8 +101,120 @@ export interface LoadedSkcPlugin {
57
101
  bindings: LoadedSubskillBinding[];
58
102
  toolBindings: PhaseScopedToolBinding[];
59
103
  }
60
- export type SkcPluginLoadErrorCode = "forbidden_surface" | "invalid_manifest" | "invalid_frontmatter" | "invalid_parent" | "invalid_phase" | "duplicate_arg" | "duplicate_parent_phase" | "missing_file" | "invalid_kind";
104
+ export type SkcPluginLoadErrorCode = "forbidden_surface" | "invalid_manifest" | "invalid_kind" | "unsupported_surface" | "invalid_frontmatter" | "invalid_parent" | "invalid_phase" | "missing_file" | "hash_mismatch" | "invalid_appendix" | "invalid_hook" | "invalid_mcp" | "duplicate_arg" | "duplicate_parent_phase" | "duplicate_tool" | "duplicate_hook" | "duplicate_mcp" | "duplicate_appendix" | "security_policy" | "install_conflict" | "session_collision" | "runtime_mismatch" | "quarantined_surface";
61
105
  export declare class SkcPluginLoadError extends Error {
62
106
  readonly code: SkcPluginLoadErrorCode;
63
107
  constructor(code: SkcPluginLoadErrorCode, message: string, options?: ErrorOptions);
64
108
  }
109
+ export type SkcPluginScope = "user" | "project";
110
+ export type SkcPluginSourceKind = "path" | "git" | "tarball";
111
+ export interface SkcPluginCopiedFile {
112
+ relativePath: string;
113
+ sha256: string;
114
+ bytes: number;
115
+ }
116
+ export interface NormalizedSubskillSurface {
117
+ extensionId: string;
118
+ name: string;
119
+ description: string;
120
+ parent: string;
121
+ phase: string;
122
+ activationArg: string;
123
+ relativePath: string;
124
+ sha256: string;
125
+ }
126
+ export interface NormalizedToolSurface {
127
+ extensionId: string;
128
+ name: string;
129
+ relativePath: string;
130
+ sha256: string;
131
+ description?: string;
132
+ }
133
+ export interface NormalizedHookSurface {
134
+ extensionId: string;
135
+ name: string;
136
+ event: string;
137
+ target?: string;
138
+ phase?: "before" | "after";
139
+ relativePath: string;
140
+ sha256: string;
141
+ }
142
+ export interface NormalizedMcpSurface {
143
+ extensionId: string;
144
+ name: string;
145
+ transport: SkcPluginMcpTransport;
146
+ configHash: string;
147
+ config: SkcPluginMcpManifestEntry;
148
+ }
149
+ export interface NormalizedAppendixSurface {
150
+ extensionId: string;
151
+ name: string;
152
+ relativePath?: string;
153
+ /** Inline appendix body (when the manifest used `content` instead of `path`). */
154
+ content?: string;
155
+ contentHash: string;
156
+ bytes: number;
157
+ }
158
+ export interface NormalizedAgentAppendixSurface extends NormalizedAppendixSurface {
159
+ agent: SkcSubskillParentAgent;
160
+ }
161
+ export interface NormalizedSkcPluginSurfaces {
162
+ subskills: NormalizedSubskillSurface[];
163
+ tools: NormalizedToolSurface[];
164
+ hooks: NormalizedHookSurface[];
165
+ mcps: NormalizedMcpSurface[];
166
+ systemAppendices: NormalizedAppendixSurface[];
167
+ agentAppendices: NormalizedAgentAppendixSurface[];
168
+ }
169
+ /**
170
+ * Result of the pure compile step. Computed from manifest, frontmatter, and
171
+ * declared files read as bytes only — never by importing plugin code.
172
+ */
173
+ export interface NormalizedSkcPluginBundle {
174
+ name: string;
175
+ version: string;
176
+ root: string;
177
+ manifestPath: string;
178
+ manifestHash: string;
179
+ surfaces: NormalizedSkcPluginSurfaces;
180
+ files: SkcPluginCopiedFile[];
181
+ }
182
+ export interface SkcPluginQuarantineEntry {
183
+ surfaceId: string;
184
+ code: SkcPluginLoadErrorCode;
185
+ message: string;
186
+ detectedAt: string;
187
+ }
188
+ export interface SkcPluginRegistrySource {
189
+ kind: SkcPluginSourceKind;
190
+ uri: string;
191
+ ref?: string;
192
+ sha?: string;
193
+ resolvedAt: string;
194
+ }
195
+ export interface SkcPluginRegistryEntry {
196
+ name: string;
197
+ version: string;
198
+ scope: SkcPluginScope;
199
+ enabled: boolean;
200
+ pluginRoot: string;
201
+ manifestPath: string;
202
+ manifestHash: string;
203
+ source: SkcPluginRegistrySource;
204
+ installedAt: string;
205
+ updatedAt: string;
206
+ copiedFiles: SkcPluginCopiedFile[];
207
+ surfaces: NormalizedSkcPluginSurfaces;
208
+ disabledSurfaceIds: string[];
209
+ quarantine?: SkcPluginQuarantineEntry[];
210
+ }
211
+ export interface SkcPluginRegistry {
212
+ version: 1;
213
+ scope: SkcPluginScope;
214
+ plugins: SkcPluginRegistryEntry[];
215
+ }
216
+ /**
217
+ * Stable identifiers for plugin-contributed surfaces used by observability,
218
+ * disabledSurfaceIds, and quarantine bookkeeping.
219
+ */
220
+ export type SkcPluginSurfaceExtensionId = string;
@@ -1,4 +1,11 @@
1
- import { type LoadedSubskillBinding, type SubskillFrontmatter } from "./types";
1
+ import { type LoadedSubskillBinding, type NormalizedSkcPluginBundle, type SkcPluginRegistryEntry, type SubskillFrontmatter } from "./types";
2
2
  export declare function validateBinding(fm: SubskillFrontmatter): void;
3
3
  export declare function buildParentArgMap(bindings: readonly LoadedSubskillBinding[]): Map<string, Map<string, LoadedSubskillBinding>>;
4
4
  export declare function buildParentPhaseSet(bindings: readonly LoadedSubskillBinding[]): Set<string>;
5
+ /**
6
+ * Hard install-time collision + security validation for a compiled bundle
7
+ * against the effective installed registry (other plugins in the target scope
8
+ * universe). Collisions are hard errors; the registry is the collision
9
+ * authority, never capability first-wins.
10
+ */
11
+ export declare function validateInstallPlan(bundle: NormalizedSkcPluginBundle, effectiveEntries: readonly SkcPluginRegistryEntry[]): void;
@@ -224,6 +224,8 @@ export interface ServerConfig {
224
224
  /** Per-server warmup timeout in milliseconds. Overrides the global WARMUP_TIMEOUT_MS for this server during startup. */
225
225
  warmupTimeoutMs?: number;
226
226
  capabilities?: ServerCapabilities;
227
+ /** Names of lower-precedence servers to drop when this server is available. */
228
+ supersedes?: string[];
227
229
  /** If true, this is a linter/formatter server (e.g., Biome) - used only for diagnostics/actions, not type intelligence */
228
230
  isLinter?: boolean;
229
231
  /** Resolved absolute path to the command binary (set during config loading) */
@@ -12,6 +12,7 @@ import type { SubmittedUserInput } from "./modes/types";
12
12
  import { type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession, discoverAuthStorage } from "./sdk";
13
13
  import type { AgentSession } from "./session/agent-session";
14
14
  import type { AuthStorage } from "./session/auth-storage";
15
+ import { SessionManager } from "./session/session-manager";
15
16
  export interface InteractiveModeNotify {
16
17
  kind: "warn" | "error" | "info";
17
18
  message: string;
@@ -48,6 +49,7 @@ export declare function applyStartupModelProfilesOrExit(args: Parameters<typeof
48
49
  * tool registry and shadow the client-supplied servers (issue #1234).
49
50
  */
50
51
  export declare function createAcpSessionFactory(args: AcpSessionFactoryOptions): AcpSessionFactory;
52
+ export declare function createSessionManager(parsed: Args, cwd: string, activeSettings?: Settings): Promise<SessionManager | undefined>;
51
53
  /**
52
54
  * Research-mode (RLM) preset hook. Lets `skc rlm` augment the session options
53
55
  * (system prompt, restricted toolset, custom python tool) and assert the tool
@@ -1,6 +1,6 @@
1
1
  import { Editor, type KeyId } from "@sayknow-cli/tui";
2
2
  import { type AppKeybinding } from "../../config/keybindings";
3
- type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.expand" | "app.thinking.toggle" | "app.editor.external" | "app.history.search" | "app.message.dequeue" | "app.message.queue" | "app.clipboard.pasteImage" | "app.clipboard.copyPrompt">;
3
+ type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.expand" | "app.thinking.toggle" | "app.editor.external" | "app.history.search" | "app.message.dequeue" | "app.message.followUp" | "app.message.queue" | "app.clipboard.pasteImage" | "app.clipboard.copyPrompt">;
4
4
  type PastePendingClearReason = "timeout" | "queue-limit";
5
5
  /**
6
6
  * Custom editor that handles configurable app-level shortcuts for coding-agent.
@@ -38,7 +38,15 @@ export declare class ModelSelectorComponent extends Container {
38
38
  sessionId?: string;
39
39
  isFastForProvider?: (provider?: string) => boolean;
40
40
  isFastForSubagentProvider?: (provider?: string) => boolean;
41
+ isCurrentModelFastModeActive?: () => boolean;
42
+ currentThinkingLevel?: ThinkingLevel;
43
+ activeModelProfile?: string;
41
44
  });
45
+ refreshRoleAssignments(options?: {
46
+ currentModel?: Model;
47
+ currentThinkingLevel?: ThinkingLevel;
48
+ activeModelProfile?: string;
49
+ }): void;
42
50
  handleInput(keyData: string): void;
43
51
  getSearchInput(): Input;
44
52
  __testSelectProfile(profileName: string, setDefault: boolean): Promise<void>;
@@ -1,3 +1,4 @@
1
+ import type { GitHeadState } from "../../../utils/git";
1
2
  /**
2
3
  * Extract "owner/repo" from a GitHub remote URL.
3
4
  * Handles HTTPS, SSH (scp-style), and git:// protocols.
@@ -20,3 +21,8 @@ export declare function canReuseCachedPr(cachedPr: {
20
21
  number: number;
21
22
  url: string;
22
23
  } | null | undefined, cachedContext: PrCacheContext | undefined, currentContext: PrCacheContext | null): boolean;
24
+ export interface CurrentBranchState {
25
+ readonly branch: string | null;
26
+ readonly repoId: string | null;
27
+ }
28
+ export declare function resolveCurrentBranch(cwd: string, resolveHead?: (cwd: string) => GitHeadState | null): CurrentBranchState;
@@ -325,6 +325,105 @@ export declare const defaultThemes: {
325
325
  "preset": string;
326
326
  };
327
327
  };
328
+ "gruvbox-dark": {
329
+ $schema: string;
330
+ name: string;
331
+ vars: {
332
+ "bgHard": string;
333
+ "surface": string;
334
+ "surfaceBright": string;
335
+ "borderNeutral": string;
336
+ "borderSubtle": string;
337
+ "fg": string;
338
+ "muted": string;
339
+ "dim": string;
340
+ "gray": string;
341
+ "red": string;
342
+ "green": string;
343
+ "yellow": string;
344
+ "blue": string;
345
+ "purple": string;
346
+ "aqua": string;
347
+ "orange": string;
348
+ "diffRemovalRed": string;
349
+ };
350
+ colors: {
351
+ "accent": string;
352
+ "border": string;
353
+ "borderAccent": string;
354
+ "borderMuted": string;
355
+ "success": string;
356
+ "error": string;
357
+ "warning": string;
358
+ "muted": string;
359
+ "dim": string;
360
+ "text": string;
361
+ "thinkingText": string;
362
+ "selectedBg": string;
363
+ "userMessageBg": string;
364
+ "userMessageText": string;
365
+ "customMessageBg": string;
366
+ "customMessageText": string;
367
+ "customMessageLabel": string;
368
+ "toolPendingBg": string;
369
+ "toolSuccessBg": string;
370
+ "toolErrorBg": string;
371
+ "toolTitle": string;
372
+ "toolOutput": string;
373
+ "mdHeading": string;
374
+ "mdLink": string;
375
+ "mdLinkUrl": string;
376
+ "mdCode": string;
377
+ "mdCodeBlock": string;
378
+ "mdCodeBlockBorder": string;
379
+ "mdQuote": string;
380
+ "mdQuoteBorder": string;
381
+ "mdHr": string;
382
+ "mdListBullet": string;
383
+ "toolDiffAdded": string;
384
+ "toolDiffRemoved": string;
385
+ "toolDiffContext": string;
386
+ "syntaxComment": string;
387
+ "syntaxKeyword": string;
388
+ "syntaxFunction": string;
389
+ "syntaxVariable": string;
390
+ "syntaxString": string;
391
+ "syntaxNumber": string;
392
+ "syntaxType": string;
393
+ "syntaxOperator": string;
394
+ "syntaxPunctuation": string;
395
+ "thinkingOff": string;
396
+ "thinkingMinimal": string;
397
+ "thinkingLow": string;
398
+ "thinkingMedium": string;
399
+ "thinkingHigh": string;
400
+ "thinkingXhigh": string;
401
+ "bashMode": string;
402
+ "pythonMode": string;
403
+ "statusLineBg": string;
404
+ "statusLineSep": string;
405
+ "statusLineModel": string;
406
+ "statusLinePath": string;
407
+ "statusLineGitClean": string;
408
+ "statusLineGitDirty": string;
409
+ "statusLineContext": string;
410
+ "statusLineSpend": string;
411
+ "statusLineStaged": string;
412
+ "statusLineDirty": string;
413
+ "statusLineUntracked": string;
414
+ "statusLineOutput": string;
415
+ "statusLineCost": string;
416
+ "statusLineSubagents": string;
417
+ };
418
+ export: {
419
+ "pageBg": string;
420
+ "cardBg": string;
421
+ "infoBg": string;
422
+ };
423
+ symbols: {
424
+ "preset": string;
425
+ };
426
+ };
328
427
  opencode: {
329
428
  $schema: string;
330
429
  name: string;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Process-wide registry mapping a session id to a sink that delivers a local
3
+ * file to the session's connected Telegram chat as a document. Registered by
4
+ * the notifications extension; consumed by the telegram_send tool.
5
+ */
6
+ /** Delivers a local file to the session's Telegram chat. */
7
+ export type TelegramFileSink = (file: {
8
+ path: string;
9
+ caption?: string;
10
+ }) => Promise<{
11
+ ok: boolean;
12
+ error?: string;
13
+ }>;
14
+ /** Register `sink` for `sessionId`. Returns a disposer that clears it. */
15
+ export declare function registerTelegramFileSink(sessionId: string, sink: TelegramFileSink): () => void;
16
+ /** The Telegram file sink for `sessionId`, if one is registered. */
17
+ export declare function getTelegramFileSink(sessionId: string): TelegramFileSink | undefined;
@@ -0,0 +1,9 @@
1
+ import type { NotificationPresentationAdapter } from "./engine";
2
+ type AdapterKind = "discord" | "slack";
3
+ interface ChatAdapterOptions {
4
+ kind: AdapterKind;
5
+ channelId?: string;
6
+ }
7
+ export declare function createDiscordAdapter(opts?: Omit<ChatAdapterOptions, "kind">): NotificationPresentationAdapter;
8
+ export declare function createSlackAdapter(opts?: Omit<ChatAdapterOptions, "kind">): NotificationPresentationAdapter;
9
+ export {};
@@ -3,13 +3,21 @@ export interface NotificationConfig {
3
3
  enabled: boolean;
4
4
  botToken?: string;
5
5
  chatId?: string;
6
+ discord: {
7
+ botToken?: string;
8
+ channelId?: string;
9
+ };
10
+ slack: {
11
+ botToken?: string;
12
+ channelId?: string;
13
+ };
6
14
  redact: boolean;
7
15
  verbosity: "lean" | "verbose";
8
16
  idleTimeoutMs: number;
9
17
  }
10
18
  /** Read typed config from Settings. */
11
19
  export declare function getNotificationConfig(settings: Settings): NotificationConfig;
12
- /** Is global config sufficient for auto-on (enabled + botToken + chatId all present)? */
20
+ /** Is global config sufficient for auto-on (enabled + at least one configured adapter)? */
13
21
  export declare function isGloballyConfigured(cfg: NotificationConfig): boolean;
14
22
  /** Resolve whether the notifications extension should be registered at SDK startup. */
15
23
  export declare function shouldRegisterNotificationsExtension(input: {
@@ -0,0 +1,59 @@
1
+ import { type RedactableAction } from "./config";
2
+ export type NotificationEvent = ({
3
+ type: "action_needed";
4
+ } & RedactableAction) | {
5
+ type: "action_resolved";
6
+ id: string;
7
+ sessionId: string;
8
+ resolvedBy?: string;
9
+ } | {
10
+ type: "frame";
11
+ sessionId: string;
12
+ frame: Record<string, unknown>;
13
+ };
14
+ export interface NotificationReplyRoute {
15
+ sessionId: string;
16
+ actionId: string;
17
+ answer: number | string | {
18
+ selected?: Array<number | string>;
19
+ custom?: string;
20
+ };
21
+ }
22
+ export interface NotificationAdapterPayload {
23
+ adapter: string;
24
+ channelKey?: string;
25
+ body: unknown;
26
+ route?: Omit<NotificationReplyRoute, "answer">;
27
+ }
28
+ export interface NotificationPresentationAdapter {
29
+ readonly kind: "telegram" | "discord" | "slack";
30
+ render(event: NotificationEvent): NotificationAdapterPayload[];
31
+ mapInbound(input: unknown): NotificationReplyRoute | undefined;
32
+ }
33
+ export interface EngineSessionSink {
34
+ sendReply(route: NotificationReplyRoute): void;
35
+ }
36
+ export interface NotificationEngineOptions {
37
+ redact: boolean;
38
+ sessionTag: (sessionId: string) => string;
39
+ }
40
+ /**
41
+ * Shared presentation engine for managed notification clients.
42
+ *
43
+ * It owns fanout, redaction boundaries, pending-action routing, and reply
44
+ * delivery into session sinks. Transport adapters stay pure: render an internal
45
+ * event into a public-safe payload and map an inbound transport interaction
46
+ * back into a session/action answer.
47
+ */
48
+ export declare class NotificationPresentationEngine {
49
+ private readonly opts;
50
+ readonly adapters: readonly NotificationPresentationAdapter[];
51
+ private readonly sessions;
52
+ private readonly pending;
53
+ constructor(adapters: readonly NotificationPresentationAdapter[], opts: NotificationEngineOptions);
54
+ connectSession(sessionId: string, sink: EngineSessionSink): void;
55
+ dropSession(sessionId: string): void;
56
+ fanout(event: NotificationEvent): NotificationAdapterPayload[];
57
+ routeInbound(adapterKind: NotificationPresentationAdapter["kind"], input: unknown): boolean;
58
+ private redactEvent;
59
+ }
@@ -49,10 +49,21 @@ export declare function finalizeTelegramHtml(message?: string): string | undefin
49
49
  * `1. 1. …` and keeps the displayed number aligned with the button's real index.
50
50
  */
51
51
  export declare function buttonLabel(label: string, index: number): string;
52
+ /** Numbered, escaped option list for the Telegram message body. */
53
+ export declare function numberedOptionList(labels: string[]): string;
54
+ /** Compact numeric button label; full option text belongs in the message body. */
55
+ export declare function choiceButtonLabel(index: number): string;
52
56
  export interface InlineButton {
53
57
  text: string;
54
58
  callback_data: string;
55
59
  }
60
+ /**
61
+ * Lay out option callbacks as compact numeric buttons. Telegram mobile clients
62
+ * ellipsize long inline-keyboard labels and tall keyboards can be obscured by
63
+ * the composer, so the full choice text is rendered in the message body while
64
+ * the keyboard keeps only stable one-based tap targets.
65
+ */
66
+ export declare function buildCompactChoiceGrid(labels: string[], callbackForIndex: (index: number) => string): InlineButton[][];
56
67
  /**
57
68
  * Lay out option labels as a numbered button grid. Long buttons take a
58
69
  * full-width row; runs of short buttons are packed into rows of up to 3. The
@@ -12,12 +12,160 @@
12
12
  * - `ask` (unattended/RPC): observes emitted workflow gates and resolves the real
13
13
  * gate on a remote reply via `ctx.workflowGate`.
14
14
  * - `turn_end` -> `action_needed` (kind `idle`, deduped per turn).
15
- * - `session_shutdown` -> stop the server + deregister the answer source.
15
+ * - `session_shutdown` -> `session_closed` frame, stop server, deregister answer source.
16
16
  *
17
17
  * Enable with Settings notifications config, `SKC_NOTIFICATIONS=1` (a token is
18
18
  * generated), or `SKC_NOTIFICATIONS_TOKEN`.
19
19
  */
20
20
  import type { ExtensionFactory } from "../extensibility/extensions";
21
+ /** Where a `session_create` should run. Discriminated by `kind`. */
22
+ export type SessionCreateTarget = {
23
+ kind: "existing_path";
24
+ path: string;
25
+ } | {
26
+ kind: "worktree";
27
+ repo: string;
28
+ branch: string;
29
+ } | {
30
+ kind: "plain_dir";
31
+ path: string;
32
+ };
33
+ /** Identifies the session a `session_close` targets. */
34
+ export interface SessionCloseTarget {
35
+ sessionId: string;
36
+ /** Expected SKC-managed tmux session name (defense-in-depth match). */
37
+ tmuxSession?: string;
38
+ /** Expected `@skc-session-state-file` tag (defense-in-depth match). */
39
+ sessionStateFile?: string;
40
+ }
41
+ /** Identifies the session a `session_resume` targets. */
42
+ export interface SessionResumeTarget {
43
+ sessionIdOrPrefix: string;
44
+ /** Optional repo/working-dir hint to disambiguate matches. */
45
+ path?: string;
46
+ }
47
+ /** Create a new session. */
48
+ export interface SessionCreateFrame {
49
+ type: "session_create";
50
+ requestId: string;
51
+ /** Deterministic lifecycle marker preallocated by the daemon before spawn. */
52
+ lifecycleRequestId: string;
53
+ /** Session id the daemon preallocated and propagates to the child. */
54
+ intendedSessionId: string;
55
+ /** Telegram update id (idempotency key on the daemon side). */
56
+ updateId: number;
57
+ chatId: string;
58
+ /** Control-endpoint token authorizing this frame. */
59
+ token: string;
60
+ target: SessionCreateTarget;
61
+ /** Reference to the daemon-written, once-consumed startup-prompt file. */
62
+ startupPromptRef?: string;
63
+ }
64
+ /** Close (hard-kill, history preserved) a session. */
65
+ export interface SessionCloseFrame {
66
+ type: "session_close";
67
+ requestId: string;
68
+ updateId: number;
69
+ chatId: string;
70
+ token: string;
71
+ target: SessionCloseTarget;
72
+ /** Hard-kill even if a live pane is attached (SKC-managed only). */
73
+ force?: boolean;
74
+ }
75
+ /** Resume a session (reattach if alive, else cold-restart from history). */
76
+ export interface SessionResumeFrame {
77
+ type: "session_resume";
78
+ requestId: string;
79
+ updateId: number;
80
+ chatId: string;
81
+ token: string;
82
+ target: SessionResumeTarget;
83
+ startupPromptRef?: string;
84
+ }
85
+ /** Any client -> ingress lifecycle request frame. */
86
+ export type SessionLifecycleRequest = SessionCreateFrame | SessionCloseFrame | SessionResumeFrame;
87
+ /** Terminal status of a lifecycle request. */
88
+ export type LifecycleStatus = "ok" | "error";
89
+ /** A connected session's per-session endpoint, returned to the control client. */
90
+ export interface LifecycleEndpoint {
91
+ url: string;
92
+ token: string;
93
+ }
94
+ /** The Telegram topic/thread a session is surfaced in. */
95
+ export interface LifecycleTopic {
96
+ chatId: string;
97
+ threadId: string;
98
+ }
99
+ /** How a create request was correlated to its spawned session. */
100
+ export type MatchedBy = "spawn_marker" | "session_ready";
101
+ /** Response to a successful `session_create`. */
102
+ export interface SessionCreateResponseFrame {
103
+ type: "session_create_response";
104
+ requestId: string;
105
+ status: LifecycleStatus;
106
+ lifecycleRequestId: string;
107
+ sessionId: string;
108
+ matchedBy: MatchedBy;
109
+ endpoint: LifecycleEndpoint;
110
+ topic: LifecycleTopic;
111
+ target: SessionCreateTarget;
112
+ }
113
+ /** Response to a successful `session_close`. */
114
+ export interface SessionCloseResponseFrame {
115
+ type: "session_close_response";
116
+ requestId: string;
117
+ status: LifecycleStatus;
118
+ sessionId: string;
119
+ processGone: boolean;
120
+ historyPreserved: boolean;
121
+ endpointStale: boolean;
122
+ }
123
+ /** Whether a resume reattached to a live session or cold-restarted a dead one. */
124
+ export type ResumeMode = "reattached" | "cold_restarted";
125
+ /** Response to a successful `session_resume`. */
126
+ export interface SessionResumeResponseFrame {
127
+ type: "session_resume_response";
128
+ requestId: string;
129
+ status: LifecycleStatus;
130
+ sessionId: string;
131
+ mode: ResumeMode;
132
+ endpoint: LifecycleEndpoint;
133
+ topic: LifecycleTopic;
134
+ }
135
+ /** Machine-readable reason a lifecycle request failed. */
136
+ export type LifecycleErrorReason = "unauthorized" | "rate_limited" | "duplicate_conflict" | "invalid_target" | "ambiguous_target" | "spawn_failed" | "discovery_timeout" | "readiness_timeout" | "close_refused" | "not_found" | "terminal_uncertain";
137
+ /** A candidate returned with an `ambiguous_target` resume error. */
138
+ export interface ResumeCandidate {
139
+ sessionId: string;
140
+ path?: string;
141
+ /** Last-activity epoch-millis (session history file mtime), if known. */
142
+ mtimeMs?: number;
143
+ }
144
+ /** A structured lifecycle error frame. */
145
+ export interface SessionLifecycleErrorFrame {
146
+ type: "session_lifecycle_error";
147
+ requestId: string;
148
+ status: LifecycleStatus;
149
+ reason: LifecycleErrorReason;
150
+ message: string;
151
+ candidates?: ResumeCandidate[];
152
+ }
153
+ /** Any ingress -> client lifecycle response frame. */
154
+ export type SessionLifecycleResponse = SessionCreateResponseFrame | SessionCloseResponseFrame | SessionResumeResponseFrame | SessionLifecycleErrorFrame;
155
+ /**
156
+ * Replayable per-session readiness signal (mirror of the Rust `session_ready`
157
+ * frame). Buffered and replayed to late clients so WS-open alone never implies
158
+ * the session is live and surfaced.
159
+ */
160
+ export interface SessionReadyFrame {
161
+ type: "session_ready";
162
+ sessionId: string;
163
+ lifecycleRequestId?: string;
164
+ startupPromptRef?: string;
165
+ repo?: string;
166
+ branch?: string;
167
+ title?: string;
168
+ }
21
169
  /**
22
170
  * Best-effort real repository name (no git spawn): resolves the main worktree
23
171
  * root directory so linked worktrees report the repo (e.g. `sayknow-cli`)