@sayknow-cli/coding-agent 0.3.1 → 0.3.4

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/bin/skc.js +4 -0
  2. package/dist/types/cli/mcp-cli.d.ts +25 -0
  3. package/dist/types/cli/plugin-cli.d.ts +2 -0
  4. package/dist/types/cli.d.ts +6 -0
  5. package/dist/types/commands/mcp.d.ts +70 -0
  6. package/dist/types/commands/plugin.d.ts +6 -0
  7. package/dist/types/commands/session.d.ts +6 -0
  8. package/dist/types/config/keybindings.d.ts +2 -2
  9. package/dist/types/config/model-profile-activation.d.ts +8 -1
  10. package/dist/types/config/model-profiles.d.ts +2 -2
  11. package/dist/types/config/model-registry.d.ts +3 -3
  12. package/dist/types/config/models-config-schema.d.ts +0 -5
  13. package/dist/types/config/settings-schema.d.ts +79 -68
  14. package/dist/types/deep-interview/plaintext-gate-guard.d.ts +11 -0
  15. package/dist/types/export/html/template.generated.d.ts +1 -1
  16. package/dist/types/extensibility/skc-plugins/compiler.d.ts +19 -0
  17. package/dist/types/extensibility/skc-plugins/constrained-hooks.d.ts +29 -0
  18. package/dist/types/extensibility/skc-plugins/index.d.ts +9 -0
  19. package/dist/types/extensibility/skc-plugins/injection.d.ts +9 -0
  20. package/dist/types/extensibility/skc-plugins/installer.d.ts +13 -0
  21. package/dist/types/extensibility/skc-plugins/mcp-policy.d.ts +26 -0
  22. package/dist/types/extensibility/skc-plugins/observability.d.ts +27 -0
  23. package/dist/types/extensibility/skc-plugins/prompt-appendix.d.ts +16 -0
  24. package/dist/types/extensibility/skc-plugins/registry.d.ts +32 -0
  25. package/dist/types/extensibility/skc-plugins/runtime-adapters.d.ts +64 -0
  26. package/dist/types/extensibility/skc-plugins/session-validation.d.ts +42 -0
  27. package/dist/types/extensibility/skc-plugins/types.d.ts +158 -2
  28. package/dist/types/extensibility/skc-plugins/validation.d.ts +8 -1
  29. package/dist/types/i18n/messages/en.d.ts +0 -1
  30. package/dist/types/main.d.ts +2 -0
  31. package/dist/types/modes/components/custom-editor.d.ts +1 -1
  32. package/dist/types/modes/components/model-selector.d.ts +8 -0
  33. package/dist/types/modes/components/settings-defs.d.ts +0 -1
  34. package/dist/types/modes/components/status-line/git-utils.d.ts +6 -0
  35. package/dist/types/modes/theme/defaults/index.d.ts +99 -0
  36. package/dist/types/modes/theme/theme.d.ts +1 -1
  37. package/dist/types/notifications/html-format.d.ts +11 -0
  38. package/dist/types/notifications/index.d.ts +149 -1
  39. package/dist/types/notifications/lifecycle-commands.d.ts +60 -0
  40. package/dist/types/notifications/lifecycle-control-runtime.d.ts +98 -0
  41. package/dist/types/notifications/lifecycle-orchestrator.d.ts +144 -0
  42. package/dist/types/notifications/operator-runtime.d.ts +52 -0
  43. package/dist/types/notifications/rate-limit-pool.d.ts +2 -0
  44. package/dist/types/notifications/recent-activity.d.ts +35 -0
  45. package/dist/types/notifications/telegram-daemon.d.ts +114 -16
  46. package/dist/types/notifications/telegram-reference.d.ts +3 -1
  47. package/dist/types/notifications/topic-registry.d.ts +12 -9
  48. package/dist/types/runtime-mcp/types.d.ts +7 -0
  49. package/dist/types/sdk.d.ts +2 -0
  50. package/dist/types/session/agent-session.d.ts +14 -4
  51. package/dist/types/session/blob-store.d.ts +25 -0
  52. package/dist/types/session/session-manager.d.ts +57 -0
  53. package/dist/types/skc-runtime/launch-tmux.d.ts +1 -0
  54. package/dist/types/skc-runtime/psmux-detect.d.ts +78 -0
  55. package/dist/types/skc-runtime/state-renderer.d.ts +5 -0
  56. package/dist/types/skc-runtime/team-runtime.d.ts +2 -0
  57. package/dist/types/skc-runtime/tmux-common.d.ts +30 -2
  58. package/dist/types/skc-runtime/tmux-sessions.d.ts +18 -0
  59. package/dist/types/skc-runtime/ultragoal-guard.d.ts +37 -1
  60. package/dist/types/skc-runtime/ultragoal-runtime.d.ts +80 -0
  61. package/dist/types/slash-commands/helpers/fast-status-report.d.ts +6 -0
  62. package/dist/types/system-prompt.d.ts +2 -0
  63. package/dist/types/task/executor.d.ts +9 -1
  64. package/dist/types/tools/browser/tab-supervisor.d.ts +31 -0
  65. package/dist/types/tools/composer-bash-policy.d.ts +14 -0
  66. package/dist/types/tools/computer-gc.d.ts +23 -0
  67. package/dist/types/tools/cron.d.ts +36 -61
  68. package/dist/types/tools/index.d.ts +3 -2
  69. package/dist/types/tools/resource-gc.d.ts +54 -0
  70. package/dist/types/utils/changelog.d.ts +1 -0
  71. package/dist/types/web/insane/url-guard.d.ts +6 -3
  72. package/dist/types/web/scrapers/types.d.ts +5 -0
  73. package/dist/types/web/scrapers/utils.d.ts +7 -1
  74. package/dist/types/web/search/index.d.ts +1 -0
  75. package/dist/types/web/search/providers/utils.d.ts +11 -4
  76. package/package.json +11 -9
  77. package/scripts/g004-tmux-smoke.ts +100 -0
  78. package/scripts/g005-daemon-smoke.ts +180 -0
  79. package/scripts/g011-daemon-path-smoke.ts +153 -0
  80. package/src/cli/args.ts +0 -1
  81. package/src/cli/fast-help.ts +29 -2
  82. package/src/cli/mcp-cli.ts +272 -0
  83. package/src/cli/plugin-cli.ts +66 -3
  84. package/src/cli/web-search-cli.ts +5 -0
  85. package/src/cli.ts +30 -12
  86. package/src/commands/mcp.ts +117 -0
  87. package/src/commands/plugin.ts +4 -0
  88. package/src/commands/session.ts +18 -0
  89. package/src/config/keybindings.ts +2 -2
  90. package/src/config/model-profile-activation.ts +62 -8
  91. package/src/config/model-profiles.ts +3 -4
  92. package/src/config/model-registry.ts +3 -6
  93. package/src/config/models-config-schema.ts +1 -1
  94. package/src/config/settings-schema.ts +88 -103
  95. package/src/deep-interview/plaintext-gate-guard.ts +94 -0
  96. package/src/defaults/skc/extensions/grok-cli-vendor/biome.json +1 -1
  97. package/src/defaults/skc/skills/deep-interview/SKILL.md +7 -6
  98. package/src/defaults/skc/skills/team/SKILL.md +5 -3
  99. package/src/defaults/skc/skills/ultragoal/SKILL.md +41 -13
  100. package/src/export/html/index.ts +2 -2
  101. package/src/export/html/template.generated.ts +1 -1
  102. package/src/export/html/template.js +0 -12
  103. package/src/extensibility/extensions/runner.ts +1 -0
  104. package/src/extensibility/skc-plugins/compiler.ts +351 -0
  105. package/src/extensibility/skc-plugins/constrained-hooks.ts +170 -0
  106. package/src/extensibility/skc-plugins/index.ts +9 -0
  107. package/src/extensibility/skc-plugins/injection.ts +109 -0
  108. package/src/extensibility/skc-plugins/installer.ts +434 -0
  109. package/src/extensibility/skc-plugins/loader.ts +3 -1
  110. package/src/extensibility/skc-plugins/mcp-policy.ts +239 -0
  111. package/src/extensibility/skc-plugins/observability.ts +84 -0
  112. package/src/extensibility/skc-plugins/paths.ts +1 -1
  113. package/src/extensibility/skc-plugins/prompt-appendix.ts +109 -0
  114. package/src/extensibility/skc-plugins/registry.ts +180 -0
  115. package/src/extensibility/skc-plugins/runtime-adapters.ts +234 -0
  116. package/src/extensibility/skc-plugins/schema.ts +250 -20
  117. package/src/extensibility/skc-plugins/session-validation.ts +147 -0
  118. package/src/extensibility/skc-plugins/types.ts +199 -3
  119. package/src/extensibility/skc-plugins/validation.ts +80 -0
  120. package/src/extensibility/skills.ts +15 -0
  121. package/src/goals/tools/goal-tool.ts +14 -1
  122. package/src/hooks/skill-state.ts +57 -0
  123. package/src/i18n/messages/de.ts +0 -1
  124. package/src/i18n/messages/en.ts +0 -1
  125. package/src/i18n/messages/es.ts +0 -1
  126. package/src/i18n/messages/fr.ts +0 -1
  127. package/src/i18n/messages/ja.ts +0 -1
  128. package/src/i18n/messages/ko.ts +0 -1
  129. package/src/i18n/messages/zh.ts +0 -1
  130. package/src/internal-urls/docs-index.generated.ts +14 -11
  131. package/src/main.ts +14 -3
  132. package/src/modes/bridge/bridge-mode.ts +11 -0
  133. package/src/modes/components/assistant-message.ts +49 -1
  134. package/src/modes/components/custom-editor.ts +2 -0
  135. package/src/modes/components/footer.ts +2 -3
  136. package/src/modes/components/hook-editor.ts +1 -1
  137. package/src/modes/components/hook-selector.ts +67 -43
  138. package/src/modes/components/model-selector.ts +65 -12
  139. package/src/modes/components/settings-defs.ts +1 -2
  140. package/src/modes/components/settings-selector.ts +2 -7
  141. package/src/modes/components/status-line/git-utils.ts +25 -0
  142. package/src/modes/components/status-line.ts +10 -11
  143. package/src/modes/components/welcome.ts +2 -3
  144. package/src/modes/controllers/extension-ui-controller.ts +0 -27
  145. package/src/modes/controllers/selector-controller.ts +59 -11
  146. package/src/modes/interactive-mode.ts +4 -1
  147. package/src/modes/shared/agent-wire/scopes.ts +1 -1
  148. package/src/modes/theme/defaults/gruvbox-dark.json +99 -0
  149. package/src/modes/theme/defaults/index.ts +2 -0
  150. package/src/modes/theme/theme.ts +0 -4
  151. package/src/modes/utils/hotkeys-markdown.ts +1 -1
  152. package/src/notifications/html-format.ts +38 -0
  153. package/src/notifications/index.ts +242 -12
  154. package/src/notifications/lifecycle-commands.ts +238 -0
  155. package/src/notifications/lifecycle-control-runtime.ts +405 -0
  156. package/src/notifications/lifecycle-orchestrator.ts +358 -0
  157. package/src/notifications/operator-runtime.ts +171 -0
  158. package/src/notifications/rate-limit-pool.ts +19 -0
  159. package/src/notifications/recent-activity.ts +132 -0
  160. package/src/notifications/telegram-daemon.ts +778 -257
  161. package/src/notifications/telegram-reference.ts +25 -7
  162. package/src/notifications/topic-registry.ts +23 -9
  163. package/src/prompts/agents/executor.md +2 -2
  164. package/src/prompts/system/system-prompt.md +2 -2
  165. package/src/prompts/tools/cron.md +5 -3
  166. package/src/prompts/tools/read.md +1 -1
  167. package/src/runtime-mcp/transports/stdio.ts +38 -4
  168. package/src/runtime-mcp/types.ts +7 -0
  169. package/src/sdk.ts +162 -10
  170. package/src/session/agent-session.ts +210 -74
  171. package/src/session/blob-store.ts +196 -8
  172. package/src/session/session-manager.ts +762 -12
  173. package/src/skc-runtime/launch-tmux.ts +68 -19
  174. package/src/skc-runtime/psmux-detect.ts +239 -0
  175. package/src/skc-runtime/state-renderer.ts +13 -0
  176. package/src/skc-runtime/team-runtime.ts +56 -23
  177. package/src/skc-runtime/tmux-common.ts +88 -4
  178. package/src/skc-runtime/tmux-sessions.ts +111 -9
  179. package/src/skc-runtime/ultragoal-guard.ts +192 -8
  180. package/src/skc-runtime/ultragoal-runtime.ts +296 -16
  181. package/src/slash-commands/builtin-registry.ts +23 -3
  182. package/src/slash-commands/helpers/fast-status-report.ts +13 -3
  183. package/src/slash-commands/helpers/parse.ts +2 -1
  184. package/src/system-prompt.ts +9 -0
  185. package/src/task/executor.ts +31 -7
  186. package/src/task/index.ts +2 -0
  187. package/src/tools/ask.ts +5 -1
  188. package/src/tools/bash.ts +9 -0
  189. package/src/tools/browser/tab-supervisor.ts +86 -2
  190. package/src/tools/composer-bash-policy.ts +96 -0
  191. package/src/tools/computer-gc.ts +66 -0
  192. package/src/tools/computer.ts +2 -0
  193. package/src/tools/cron.ts +75 -112
  194. package/src/tools/fetch.ts +18 -2
  195. package/src/tools/index.ts +5 -9
  196. package/src/tools/read.ts +25 -55
  197. package/src/tools/renderers.ts +0 -2
  198. package/src/tools/resource-gc.ts +291 -0
  199. package/src/tools/ultragoal-ask-guard.ts +7 -1
  200. package/src/utils/changelog.ts +8 -0
  201. package/src/web/insane/url-guard.ts +18 -14
  202. package/src/web/scrapers/types.ts +143 -45
  203. package/src/web/scrapers/utils.ts +70 -19
  204. package/src/web/search/index.ts +1 -0
  205. package/src/web/search/providers/utils.ts +22 -5
  206. package/vendor/insane-search/MANIFEST.json +3 -1
  207. package/vendor/insane-search/engine/__init__.py +14 -0
  208. package/vendor/insane-search/engine/content_safety.py +151 -0
  209. package/vendor/insane-search/engine/fetch_chain.py +32 -0
  210. package/vendor/insane-search/engine/tests/test_u8.py +216 -0
  211. package/dist/types/tools/inspect-image-renderer.d.ts +0 -26
  212. package/dist/types/tools/inspect-image.d.ts +0 -31
  213. package/src/prompts/tools/inspect-image-system.md +0 -20
  214. package/src/prompts/tools/inspect-image.md +0 -32
  215. package/src/tools/inspect-image-renderer.ts +0 -103
  216. package/src/tools/inspect-image.ts +0 -172
@@ -0,0 +1,19 @@
1
+ import { type NormalizedSkcPluginBundle } from "./types";
2
+ /**
3
+ * Stable surface extension-id builders. Kept here so install, runtime, and
4
+ * observability all derive identical ids.
5
+ */
6
+ export declare const surfaceIds: {
7
+ readonly tool: (name: string) => string;
8
+ readonly hook: (event: string, phase: string | undefined, target: string | undefined, name: string) => string;
9
+ readonly mcp: (name: string) => string;
10
+ readonly systemAppendix: (plugin: string, name: string) => string;
11
+ readonly agentAppendix: (agent: string, plugin: string, name: string) => string;
12
+ readonly subskill: (parent: string, phase: string, activationArg: string) => string;
13
+ };
14
+ /**
15
+ * Pure compile step: reads only the manifest, subskill frontmatter, and
16
+ * declared files (as bytes for hashing/existence). It NEVER imports or executes
17
+ * plugin tool/hook code.
18
+ */
19
+ export declare function compileSkcPluginBundle(root: string): Promise<NormalizedSkcPluginBundle>;
@@ -0,0 +1,29 @@
1
+ import { type SessionQuarantine } from "./session-validation";
2
+ /**
3
+ * Constrained plugin-hook loader.
4
+ *
5
+ * Third-party plugin hooks are NOT given the broad first-party HookAPI. They
6
+ * receive a restricted API that can only register a handler for their declared
7
+ * event; every session-mutation / command / shell capability throws
8
+ * security_policy. After the factory runs we verify it registered exactly the
9
+ * declared event (and nothing else), or the hook is quarantined.
10
+ */
11
+ export interface ConstrainedPluginHook {
12
+ plugin: string;
13
+ event: string;
14
+ target?: string;
15
+ phase?: "before" | "after";
16
+ handler: (...args: any[]) => unknown;
17
+ }
18
+ export interface ConstrainedHookLoadResult {
19
+ hooks: ConstrainedPluginHook[];
20
+ quarantine: SessionQuarantine[];
21
+ }
22
+ /**
23
+ * Load all always-on constrained plugin hooks for the effective registry at
24
+ * `cwd`, applying hash-drift + collision quarantine first. Returns empty when
25
+ * no plugins are installed.
26
+ */
27
+ export declare function loadConstrainedPluginHooks(input: {
28
+ cwd: string;
29
+ }): Promise<ConstrainedHookLoadResult>;
@@ -1,8 +1,17 @@
1
1
  export * from "./activation";
2
+ export * from "./compiler";
3
+ export * from "./constrained-hooks";
2
4
  export * from "./injection";
5
+ export * from "./installer";
3
6
  export * from "./loader";
7
+ export * from "./mcp-policy";
8
+ export * from "./observability";
4
9
  export * from "./paths";
10
+ export * from "./prompt-appendix";
11
+ export * from "./registry";
12
+ export * from "./runtime-adapters";
5
13
  export * from "./schema";
14
+ export * from "./session-validation";
6
15
  export * from "./state";
7
16
  export * from "./tools";
8
17
  export * from "./types";
@@ -29,3 +29,12 @@ export declare function buildAgentSubskillInjection(input: {
29
29
  sessionId?: string;
30
30
  agentName: string;
31
31
  }): Promise<string>;
32
+ import type { SkcPluginRegistryEntry } from "./types";
33
+ /**
34
+ * Tier-1 advertisement for a workflow parent skill: bounded, metadata-only list
35
+ * of installed sub-skills bound to `parent`, rendered ONLY in that parent's
36
+ * prompt (never the global public-workflow-surface). No body content.
37
+ */
38
+ export declare function buildSubskillAdvertisement(entries: readonly SkcPluginRegistryEntry[], parent: string, phase?: string): string;
39
+ /** Tier-1 advertisement for a role-agent parent. */
40
+ export declare function buildAgentSubskillAdvertisement(entries: readonly SkcPluginRegistryEntry[], agentName: string): string;
@@ -0,0 +1,13 @@
1
+ import { type SkcPluginRegistryEntry, type SkcPluginScope } from "./types";
2
+ export interface InstallSkcPluginOptions {
3
+ scope: SkcPluginScope;
4
+ cwd: string;
5
+ force?: boolean;
6
+ }
7
+ export interface InstallSkcPluginResult {
8
+ status: "installed" | "updated" | "unchanged";
9
+ entry: SkcPluginRegistryEntry;
10
+ }
11
+ export declare function installSkcPluginBundle(source: string, options: InstallSkcPluginOptions): Promise<InstallSkcPluginResult>;
12
+ /** True only when the source actually resolves to a SKC plugin bundle (root sayknow-plugin.json). */
13
+ export declare function isSkcPluginBundleSource(source: string): Promise<boolean>;
@@ -0,0 +1,26 @@
1
+ import { type SkcPluginMcpManifestEntry } from "./types";
2
+ export declare function isDeniedIpv4(host: string): boolean;
3
+ export declare function isDeniedIpv6(host: string): boolean;
4
+ /**
5
+ * Synchronous URL policy (scheme, credentials, host literal ranges). Used for
6
+ * the primary endpoint and any redirect/token/discovery URL.
7
+ */
8
+ export declare function assertUrlAllowed(rawUrl: string, label?: string): URL;
9
+ /** Reject headers with control characters / CRLF injection. */
10
+ export declare function assertHeadersAllowed(headers: Record<string, string> | undefined): void;
11
+ /**
12
+ * Runtime DNS check: resolve the host and ensure no resolved address falls in a
13
+ * denied range (covers DNS rebinding when re-run before each connect).
14
+ */
15
+ export declare function assertDnsResolvesPublic(hostname: string, label?: string): Promise<void>;
16
+ export interface StdioPolicyContext {
17
+ pluginRoot: string;
18
+ }
19
+ /** stdio launcher/path confinement policy. */
20
+ export declare function assertStdioAllowed(entry: SkcPluginMcpManifestEntry, ctx: StdioPolicyContext): void;
21
+ /**
22
+ * Install-time MCP policy (no network required). Validates scheme/host literals
23
+ * and stdio confinement. Runtime connect additionally calls
24
+ * assertDnsResolvesPublic and re-validates redirect/token URLs.
25
+ */
26
+ export declare function assertMcpInstallPolicy(entry: SkcPluginMcpManifestEntry, ctx: StdioPolicyContext): void;
@@ -0,0 +1,27 @@
1
+ import type { SkcPluginRegistryEntry, SkcPluginScope } from "./types";
2
+ /**
3
+ * Observability for SKC plugin bundle surfaces, consumable by the extension
4
+ * dashboard / state manager. Each surface row carries its stable extension id,
5
+ * owning plugin, scope, source kind, enabled/disabled/quarantined status, and a
6
+ * content hash. MCP auth/header values are NEVER included.
7
+ */
8
+ export type PluginSurfaceStatus = "enabled" | "disabled" | "quarantined";
9
+ export interface PluginSurfaceRow {
10
+ extensionId: string;
11
+ kind: "tool" | "hook" | "mcp" | "system-appendix" | "agent-appendix" | "subskill";
12
+ plugin: string;
13
+ scope: SkcPluginScope;
14
+ sourceKind: SkcPluginRegistryEntry["source"]["kind"];
15
+ status: PluginSurfaceStatus;
16
+ hash: string;
17
+ quarantineCode?: string;
18
+ }
19
+ export interface PluginObservabilitySummary {
20
+ plugins: number;
21
+ surfaces: PluginSurfaceRow[];
22
+ }
23
+ /**
24
+ * Build the observability summary for the effective registry at `cwd`, including
25
+ * hash-drift and session-collision quarantine status.
26
+ */
27
+ export declare function summarizeSkcPluginObservability(cwd: string): Promise<PluginObservabilitySummary>;
@@ -0,0 +1,16 @@
1
+ import type { SkcPluginRegistryEntry, SkcSubskillParentAgent } from "./types";
2
+ export interface RenderedPluginAppendices {
3
+ /** Combined system-appendix block text (empty if none). */
4
+ system: string;
5
+ /** Per-agent appendix block text. */
6
+ byAgent: Map<SkcSubskillParentAgent, string>;
7
+ /** Stable digest of all rendered appendix content + identities (for cache/refresh). */
8
+ digest: string;
9
+ }
10
+ /**
11
+ * Build appendix blocks from the active, enabled registry entries in their
12
+ * deterministic order. Per-appendix and total size caps are enforced
13
+ * fail-closed (oversize content is dropped with a marker, never silently
14
+ * truncated into the prompt as authoritative text).
15
+ */
16
+ export declare function renderPluginAppendices(entries: readonly SkcPluginRegistryEntry[]): Promise<RenderedPluginAppendices>;
@@ -0,0 +1,32 @@
1
+ import { type SkcPluginRegistry, type SkcPluginRegistryEntry, type SkcPluginScope } from "./types";
2
+ export declare function registryRootForScope(scope: SkcPluginScope, cwd: string): string;
3
+ export declare function registryPathForScope(scope: SkcPluginScope, cwd: string): string;
4
+ /**
5
+ * Deterministic ordering: scope (user before project) -> normalized name ->
6
+ * resolved plugin root. Collisions are errors elsewhere; order only controls
7
+ * stable hook/appendix sequencing.
8
+ */
9
+ export declare function sortRegistryEntries(entries: SkcPluginRegistryEntry[]): SkcPluginRegistryEntry[];
10
+ export declare function readRegistry(scope: SkcPluginScope, cwd: string): Promise<SkcPluginRegistry>;
11
+ export declare function withRegistryLock<T>(scope: SkcPluginScope, cwd: string, fn: () => Promise<T>): Promise<T>;
12
+ /**
13
+ * Lock-free atomic write (temp+fsync+rename). Only call while already holding
14
+ * the per-scope registry lock via withRegistryLock.
15
+ */
16
+ export declare function writeRegistryUnlocked(registry: SkcPluginRegistry, cwd: string): Promise<void>;
17
+ /**
18
+ * Atomic registry write: write to a temp sibling, fsync, then rename. Guarded
19
+ * by an interprocess lockfile so concurrent installs cannot clobber each other.
20
+ */
21
+ export declare function writeRegistry(registry: SkcPluginRegistry, cwd: string): Promise<void>;
22
+ /**
23
+ * Mutate a scope's registry as a single locked read-modify-write transaction so
24
+ * concurrent installs cannot lose each other's updates. The mutator receives a
25
+ * sorted copy and returns the next entry list.
26
+ */
27
+ export declare function updateRegistry(scope: SkcPluginScope, cwd: string, mutator: (entries: SkcPluginRegistryEntry[]) => SkcPluginRegistryEntry[]): Promise<SkcPluginRegistry>;
28
+ /**
29
+ * Effective registry for a cwd: user + project entries in deterministic order.
30
+ */
31
+ export declare function loadEffectiveSkcPluginRegistry(cwd: string): Promise<SkcPluginRegistryEntry[]>;
32
+ export declare function registryEntryFingerprint(entry: SkcPluginRegistryEntry): string;
@@ -0,0 +1,64 @@
1
+ import type { CustomTool } from "../custom-tools/types";
2
+ import { type SessionQuarantine } from "./session-validation";
3
+ export interface AlwaysOnPluginTools {
4
+ tools: CustomTool[];
5
+ quarantine: SessionQuarantine[];
6
+ }
7
+ /**
8
+ * Load the always-on plugin tool surfaces for the effective registry at `cwd`.
9
+ *
10
+ * Safety properties:
11
+ * - Hash drift quarantines the plugin (runtime_mismatch) before any import.
12
+ * - Session-start collisions vs reserved/built-in names quarantine fail-closed.
13
+ * - Manifest-declared tool names are authoritative: a factory that returns a
14
+ * different/extra/missing name is rejected with runtime_mismatch and skipped.
15
+ * - Reserved tool names are never overwritten.
16
+ *
17
+ * Returns an empty result when no plugins are installed, so callers that always
18
+ * call this in `createAgentSession` incur no behavior change without plugins.
19
+ */
20
+ export declare function loadAlwaysOnPluginTools(input: {
21
+ cwd: string;
22
+ reservedToolNames: string[];
23
+ }): Promise<AlwaysOnPluginTools>;
24
+ /**
25
+ * Render the always-on system-appendix blocks for the effective registry at
26
+ * `cwd`, applying hash-drift + collision quarantine first. Returns "" when no
27
+ * plugins are installed/enabled. Safe to call unconditionally at session start.
28
+ */
29
+ export declare function renderAlwaysOnSystemAppendices(input: {
30
+ cwd: string;
31
+ }): Promise<string>;
32
+ /**
33
+ * Render the agent-appendix block and Tier-1 sub-skill advertisement for a role
34
+ * agent at session/spawn time. Hash-drift + collision quarantine applied first.
35
+ * Returns empty strings when nothing applies.
36
+ */
37
+ export declare function renderAgentPromptAdditions(input: {
38
+ cwd: string;
39
+ agentName: string;
40
+ }): Promise<{
41
+ appendix: string;
42
+ advertisement: string;
43
+ }>;
44
+ /**
45
+ * Render the Tier-1 sub-skill advertisement for a workflow parent skill.
46
+ * Returns "" when nothing applies. Quarantine applied first.
47
+ */
48
+ export declare function renderSkillAdvertisement(input: {
49
+ cwd: string;
50
+ skillName: string;
51
+ phase?: string;
52
+ }): Promise<string>;
53
+ /**
54
+ * Convert active plugin-bundle MCP surfaces into runtime MCPServerConfig entries,
55
+ * applying install + runtime MCP policy (URL scheme/private-range deny, DNS
56
+ * re-resolution for http/sse, stdio root-confinement) before connection. Servers
57
+ * failing policy are quarantined and excluded. Returns {} when none.
58
+ */
59
+ export declare function buildPluginMcpConfigs(input: {
60
+ cwd: string;
61
+ }): Promise<{
62
+ configs: Record<string, any>;
63
+ quarantine: SessionQuarantine[];
64
+ }>;
@@ -0,0 +1,42 @@
1
+ import type { SkcPluginLoadErrorCode, SkcPluginRegistryEntry } from "./types";
2
+ /**
3
+ * Session-start validation: the registry is the collision authority. Capability
4
+ * provider output is supplied as EVIDENCE only; plugin surfaces are never
5
+ * resolved by capability first-wins. Offending surfaces are quarantined
6
+ * fail-closed with a stable error code rather than silently shadowed.
7
+ */
8
+ export interface SessionCapabilityEvidence {
9
+ /** Built-in + provider tool names already present before plugin insertion. */
10
+ toolNames?: Iterable<string>;
11
+ /** Non-plugin MCP server names from providers/built-ins. */
12
+ mcpNames?: Iterable<string>;
13
+ /** Non-plugin hook keys (event:phase:target:name) from providers/built-ins. */
14
+ hookKeys?: Iterable<string>;
15
+ /** Existing appendix extension ids already present. */
16
+ appendixIds?: Iterable<string>;
17
+ }
18
+ export interface SessionQuarantine {
19
+ plugin: string;
20
+ surfaceId: string;
21
+ code: SkcPluginLoadErrorCode;
22
+ message: string;
23
+ }
24
+ export interface SessionValidationResult {
25
+ /** Registry entries (enabled, non-quarantined) whose surfaces may activate. */
26
+ active: SkcPluginRegistryEntry[];
27
+ /** Per-surface quarantine records (fail-closed). */
28
+ quarantine: SessionQuarantine[];
29
+ }
30
+ /**
31
+ * Re-verify that the installed files still match the registry's recorded hashes.
32
+ * Drift (manual edits, partial writes) quarantines the whole plugin with
33
+ * runtime_mismatch.
34
+ */
35
+ export declare function verifyEntryHashes(entry: SkcPluginRegistryEntry): Promise<SessionQuarantine | null>;
36
+ /**
37
+ * Validate the effective installed registry against the current capability
38
+ * universe (evidence) and across plugins. Returns the entries that may activate
39
+ * plus per-surface quarantine records. Disabled entries/surfaces are skipped
40
+ * (not an error).
41
+ */
42
+ export declare function validateSessionBundles(entries: readonly SkcPluginRegistryEntry[], evidence?: SessionCapabilityEvidence, preQuarantined?: readonly SessionQuarantine[]): SessionValidationResult;
@@ -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;
@@ -30,7 +30,6 @@ export declare const en: {
30
30
  readonly "settings.tab.appearance": "Appearance";
31
31
  readonly "settings.tab.model": "Model";
32
32
  readonly "settings.tab.interaction": "Interaction";
33
- readonly "settings.tab.notifications": "Notifications";
34
33
  readonly "settings.tab.context": "Context";
35
34
  readonly "settings.tab.memory": "Memory";
36
35
  readonly "settings.tab.editing": "Editing";
@@ -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>;
@@ -37,7 +37,6 @@ export interface SubmenuSettingDef extends BaseSettingDef {
37
37
  }
38
38
  export interface TextInputSettingDef extends BaseSettingDef {
39
39
  type: "text";
40
- secret?: boolean;
41
40
  }
42
41
  export type SettingDef = BooleanSettingDef | EnumSettingDef | SubmenuSettingDef | TextInputSettingDef;
43
42
  /** Get all setting definitions with UI */
@@ -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;