@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
@@ -1,3 +1,4 @@
1
+ import type { ResolvedTmuxBinary } from "./psmux-detect";
1
2
  export declare const SKC_DEFAULT_TMUX_SESSION = "sayknow_cli";
2
3
  export declare const SKC_TMUX_SESSION_PREFIX = "sayknow_cli_";
3
4
  export declare const SKC_TMUX_COMMAND_ENV = "SKC_TMUX_COMMAND";
@@ -11,6 +12,7 @@ export declare const SKC_TMUX_PROJECT_OPTION = "@skc-project";
11
12
  export declare const SKC_TMUX_SESSION_ID_OPTION = "@skc-session-id";
12
13
  export declare const SKC_TMUX_SESSION_STATE_FILE_OPTION = "@skc-session-state-file";
13
14
  export declare const SKC_TMUX_VERSION_OPTION = "@skc-version";
15
+ export declare const SKC_PSMUX_PROFILE_FORCE_ENV = "SKC_PSMUX_PROFILE_FORCE";
14
16
  export interface SkcTmuxProfileCommand {
15
17
  description: string;
16
18
  args: string[];
@@ -23,7 +25,26 @@ export interface TmuxCommandResult {
23
25
  }
24
26
  export type TmuxCommandRunner = (args: string[]) => TmuxCommandResult;
25
27
  export declare function envDisabled(value: string | undefined): boolean;
26
- export declare function resolveSkcTmuxCommand(env?: NodeJS.ProcessEnv): string;
28
+ /**
29
+ * Resolve the tmux (or tmux-compatible multiplexer) command SKC should invoke.
30
+ *
31
+ * This is the shared entry point used by every SKC code path that needs to talk
32
+ * to a multiplexer: `skc --tmux` planning, `skc session ...`, `skc team ...`,
33
+ * the lifecycle controller, and the harness resident owner. Routing all of
34
+ * them through the same resolver means a single `SKC_TMUX_COMMAND` override or
35
+ * a single Windows psmux / pmux detection wins for the whole process — the
36
+ * failure mode where `skc --tmux` creates a psmux-backed session and then
37
+ * `skc session status` fails because it queries literal `tmux` is closed off.
38
+ *
39
+ * Explicit `SKC_TMUX_COMMAND` / `SKC_TEAM_TMUX_COMMAND` overrides are honored on
40
+ * every platform. On native Windows without an override the resolver walks
41
+ * `psmux`, then `pmux`, then `tmux` and uses the first binary present on PATH.
42
+ * On POSIX the resolver returns `tmux` (the historical default) and only
43
+ * falls through to the platform-aware walker if the caller opts in.
44
+ */
45
+ export declare function resolveSkcTmuxCommand(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string;
46
+ export type { PsmuxProbe, ResolvedTmuxBinary, ResolveSkcTmuxBinaryOptions } from "./psmux-detect";
47
+ export { clearPsmuxDetectionCache, detectPsmux, probePsmux, resolveSkcTmuxBinary } from "./psmux-detect";
27
48
  /**
28
49
  * Build the exact-session target for tmux *option* commands
29
50
  * (`show-options` / `set-option`) and `display-message -t`.
@@ -34,7 +55,11 @@ export declare function resolveSkcTmuxCommand(env?: NodeJS.ProcessEnv): string;
34
55
  * keeps the exact-session match while giving tmux the window-qualified target
35
56
  * those commands require. See sayknow-cli#580.
36
57
  */
37
- export declare function buildSkcTmuxExactOptionTarget(sessionName: string): string;
58
+ export declare function buildSkcTmuxExactOptionTarget(sessionName: string, opts?: {
59
+ env?: NodeJS.ProcessEnv;
60
+ platform?: NodeJS.Platform;
61
+ binary?: ResolvedTmuxBinary;
62
+ }): string;
38
63
  export declare const SKC_TMUX_UNTAGGED_REASON = "skc_tmux_session_untagged";
39
64
  export declare function buildSkcTmuxUntaggedSessionHint(tmuxCommand: string): string;
40
65
  export declare function buildSkcTmuxUntaggedSessionError(sessionName: string, tmuxCommand: string): string;
@@ -60,5 +85,8 @@ export declare function buildSkcTmuxProfileCommands(target: string, env?: NodeJS
60
85
  sessionId?: string | null;
61
86
  sessionStateFile?: string | null;
62
87
  version?: string | null;
88
+ }, opts?: {
89
+ platform?: NodeJS.Platform;
90
+ tmuxCommand?: string;
63
91
  }): SkcTmuxProfileCommand[];
64
92
  export declare function normalizeTmuxCreatedAt(raw: string): string;
@@ -41,4 +41,22 @@ export declare function createSkcTmuxSession(env?: NodeJS.ProcessEnv): SkcTmuxSe
41
41
  /** @internal */
42
42
  export declare function readTmuxSessionTagsForGc(sessionName: string, env?: NodeJS.ProcessEnv): SkcTmuxSessionTagsForGc;
43
43
  export declare function removeSkcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv): SkcTmuxSessionStatus;
44
+ /**
45
+ * Force-close a SKC-managed tmux session, even if a live pane is attached.
46
+ *
47
+ * This is the lifecycle-control counterpart to {@link removeSkcTmuxSession}: it
48
+ * intentionally does NOT refuse live/attached panes (hard-kill is the contract),
49
+ * but it keeps every safety check so it can only ever kill a genuinely
50
+ * SKC-managed session:
51
+ * - re-reads the exact tmux profile immediately before kill (never a non-SKC
52
+ * session, even one that collides by name);
53
+ * - when `expectedSessionId` is given, requires the `@skc-session-id` tag match;
54
+ * - when `expectedStateFile` is given, requires the `@skc-session-state-file`
55
+ * tag match.
56
+ *
57
+ * Returns the prior status (for audit). Throws a tagged error otherwise:
58
+ * `skc_tmux_session_not_found`, `skc_tmux_session_not_managed`,
59
+ * `skc_tmux_session_id_mismatch`, or `skc_tmux_session_state_file_mismatch`.
60
+ */
61
+ export declare function forceCloseSkcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv, expectedSessionId?: string, expectedStateFile?: string): SkcTmuxSessionStatus;
44
62
  export declare function attachSkcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv): never;
@@ -1,4 +1,4 @@
1
- import { type UltragoalGoal, type UltragoalLedgerEvent, type UltragoalPlan, type UltragoalReceiptKind } from "./ultragoal-runtime";
1
+ import { type UltragoalGoal, type UltragoalLedgerEvent, type UltragoalNudgeSurface, type UltragoalPlan, type UltragoalReceiptKind } from "./ultragoal-runtime";
2
2
  export type UltragoalGuardState = "inactive" | "unrelated_goal" | "active_verified_complete" | "active_missing_receipt" | "active_stale_receipt" | "active_missing_final_receipt" | "active_dirty_quality_gate" | "active_review_blocked_unrecorded" | "active_review_blocked_recorded" | "unreadable_fail_closed";
3
3
  export interface UltragoalGuardDiagnostic {
4
4
  state: UltragoalGuardState;
@@ -30,6 +30,29 @@ export declare function readUltragoalVerificationState(input: {
30
30
  sessionId?: string | null;
31
31
  }): Promise<UltragoalGuardDiagnostic>;
32
32
  export declare function isUltragoalAskBlocked(cwd: string): Promise<UltragoalAskBlockDiagnostic>;
33
+ /**
34
+ * Escalating per-attempt refusal text. Deliberately avoids every
35
+ * `isUltragoalBypassPrompt` trigger: no `update_goal(`, no "skip/weaken verification",
36
+ * no "mark ... complete", no "--status complete", and the word "complete" never
37
+ * appears (so the `goal` ... `complete` proximity rule cannot match).
38
+ */
39
+ export declare function formatUltragoalNudgeMessage(input: {
40
+ surface: UltragoalNudgeSurface;
41
+ attempt: number;
42
+ budget: number;
43
+ goalId: string;
44
+ }): string;
45
+ /**
46
+ * Assert-path entry for the `ask` surface (the ask guard lives in another module).
47
+ * Resolves the active (leader) Ultragoal session so subagent/headless asks consume
48
+ * the leader run's budget rather than a fresh child ledger.
49
+ */
50
+ export declare function consumeUltragoalAskNudge(cwd: string, sessionId?: string | null): Promise<{
51
+ nudged: true;
52
+ message: string;
53
+ } | {
54
+ nudged: false;
55
+ }>;
33
56
  export declare function assertCanCompleteCurrentGoal(input: {
34
57
  cwd: string;
35
58
  currentGoal?: CurrentGoalLike | null;
@@ -49,3 +72,16 @@ export interface UltragoalPauseBlockDiagnostic {
49
72
  */
50
73
  export declare function isUltragoalPauseBlocked(cwd: string): Promise<UltragoalPauseBlockDiagnostic>;
51
74
  export declare function assertUltragoalPauseAllowed(cwd: string): Promise<void>;
75
+ /**
76
+ * Guard `goal({"op":"drop"})` during an active Ultragoal run. A *real give-up* (an
77
+ * aggregate run still mid-flight with incomplete required stories) is nudged while
78
+ * budget remains; once exhausted it falls through to today's drop behavior. Legitimate
79
+ * aggregate-reset drops — no durable run, unrelated goal, an already dropped/stale
80
+ * aggregate, or an all-stories-complete run — are never nudged. If durable state
81
+ * exists but cannot be read to classify the drop, fail closed.
82
+ */
83
+ export declare function assertUltragoalDropAllowed(input: {
84
+ cwd: string;
85
+ currentGoal?: CurrentGoalLike | null;
86
+ sessionId?: string | null;
87
+ }): Promise<void>;
@@ -53,6 +53,41 @@ export interface UltragoalLedgerEvent extends JsonObject {
53
53
  goalId?: string;
54
54
  timestamp?: string;
55
55
  }
56
+ export type UltragoalNudgeSurface = "pause" | "drop" | "ask" | "premature_complete";
57
+ export type UltragoalNudgeTargetKind = "story" | "final_aggregate_receipt";
58
+ export interface UltragoalNudgeLedgerEvent extends UltragoalLedgerEvent {
59
+ event: "nudge";
60
+ goalId: string;
61
+ targetKind: UltragoalNudgeTargetKind;
62
+ surface: UltragoalNudgeSurface;
63
+ attempt: number;
64
+ budget: number;
65
+ reason: string;
66
+ currentGoalObjective?: string;
67
+ }
68
+ export interface UltragoalNudgeTarget {
69
+ goalId: string;
70
+ targetKind: UltragoalNudgeTargetKind;
71
+ }
72
+ export type UltragoalNudgeOutcome = {
73
+ nudged: true;
74
+ attempt: number;
75
+ budget: number;
76
+ goalId: string;
77
+ targetKind: UltragoalNudgeTargetKind;
78
+ event: UltragoalNudgeLedgerEvent;
79
+ } | {
80
+ nudged: false;
81
+ exhausted: true;
82
+ count: number;
83
+ budget: number;
84
+ goalId: string;
85
+ targetKind: UltragoalNudgeTargetKind;
86
+ } | {
87
+ nudged: false;
88
+ inactive: true;
89
+ reason: string;
90
+ };
56
91
  export interface UltragoalPaths {
57
92
  dir: string;
58
93
  briefPath: string;
@@ -67,6 +102,11 @@ export interface UltragoalStatusSummary {
67
102
  currentGoal?: UltragoalGoal;
68
103
  counts: Record<UltragoalGoalStatus, number>;
69
104
  goals: UltragoalGoal[];
105
+ nudgeBudget?: number;
106
+ nudgeCount?: number;
107
+ nudgeRemaining?: number;
108
+ nudgeGoalId?: string;
109
+ nudgeTargetKind?: UltragoalNudgeTargetKind;
70
110
  }
71
111
  export interface UltragoalCommandResult {
72
112
  reviewBlockerGoalIds?: string[];
@@ -82,6 +122,46 @@ interface JsonObject {
82
122
  export declare function hashStructuredValue(value: unknown): string;
83
123
  export declare function getUltragoalPaths(cwd: string, sessionId?: string | null): UltragoalPaths;
84
124
  export declare function readUltragoalLedger(cwd: string, sessionId?: string | null): Promise<UltragoalLedgerEvent[]>;
125
+ export declare const DEFAULT_ULTRAGOAL_NUDGE_BUDGET = 10;
126
+ /** Pure: count ledger `nudge` rows for an exact goalId. */
127
+ export declare function countUltragoalNudges(ledger: readonly UltragoalLedgerEvent[], goalId: string): number;
128
+ /**
129
+ * Resolve the per-story nudge budget. Project `./.skc/settings.json` overrides the
130
+ * user settings (`$SKC_CONFIG_DIR/settings.json` or `~/.skc/settings.json`), else the
131
+ * default. Mirrors the `skc.deepInterview.ambiguityThreshold` user+project precedence.
132
+ */
133
+ export declare function resolveUltragoalNudgeBudget(cwd: string): Promise<{
134
+ budget: number;
135
+ source: string;
136
+ }>;
137
+ /**
138
+ * Pure canonical selector shared by guards and status so `nudgeGoalId` can never
139
+ * diverge between what a guard consumes and what status displays. Prefers the active
140
+ * current-goal objective, then active > pending > failed (matching `chooseNextGoal`),
141
+ * then the aggregate final-receipt target when all stories are complete but the
142
+ * aggregate run still needs a final receipt. Returns null for verified-complete or
143
+ * absent/unrelated plans.
144
+ */
145
+ export declare function selectUltragoalNudgeTarget(plan: UltragoalPlan, options?: {
146
+ currentGoalObjective?: string;
147
+ retryFailed?: boolean;
148
+ }): UltragoalNudgeTarget | null;
149
+ /**
150
+ * Atomic consuming writer. Locks the ledger path, rereads + counts nudge rows for the
151
+ * target story, and appends exactly one `nudge` row inside the same critical section
152
+ * only while budget remains. Reuses the lockless `appendLedger` inside the lock (it
153
+ * does not acquire a conflicting lock), so concurrent guarded attempts cannot both
154
+ * observe `count = budget - 1` and overshoot the budget.
155
+ */
156
+ export declare function recordUltragoalNudgeIfBudgetRemaining(input: {
157
+ cwd: string;
158
+ sessionId?: string | null;
159
+ target: UltragoalNudgeTarget;
160
+ surface: UltragoalNudgeSurface;
161
+ budget: number;
162
+ reason: string;
163
+ currentGoalObjective?: string;
164
+ }): Promise<UltragoalNudgeOutcome>;
85
165
  export declare function computeUltragoalPlanGeneration(input: {
86
166
  plan: UltragoalPlan;
87
167
  ledger: readonly UltragoalLedgerEvent[];
@@ -37,6 +37,12 @@ export interface FastStatusSessionLike {
37
37
  readonly model?: Model;
38
38
  /** Fast predicate against the main session tier (current model + `modelRoles`). */
39
39
  isFastForProvider(provider?: string): boolean;
40
+ /**
41
+ * Current-model EFFECTIVE fast state (intent minus any provider auto-disable).
42
+ * Used for the current-model row so it matches what the next request does.
43
+ * Optional so lightweight fakes can omit it; falls back to `isFastForProvider`.
44
+ */
45
+ isFastModeActive?(): boolean;
40
46
  /** Fast predicate against the effective subagent tier (`task.agentModelOverrides` roles). */
41
47
  isFastForSubagentProvider(provider?: string): boolean;
42
48
  resolveRoleModelWithThinking(role: string): {
@@ -47,6 +47,8 @@ export interface BuildSystemPromptOptions {
47
47
  toolNames?: string[];
48
48
  /** Text to append to system prompt. */
49
49
  appendSystemPrompt?: string;
50
+ /** Rendered SKC plugin system-appendix blocks (lower-authority, appended last). */
51
+ pluginAppendices?: string;
50
52
  /** Repeat full tool descriptions in system prompt. Default: false */
51
53
  repeatToolDescriptions?: boolean;
52
54
  /** Skills settings for discovery. */
@@ -4,6 +4,7 @@
4
4
  * Runs each subagent on the main thread and forwards AgentEvents for progress tracking.
5
5
  */
6
6
  import type { AgentTelemetryConfig, ThinkingLevel } from "@sayknow-cli/agent-core";
7
+ import type { ServiceTier } from "@sayknow-cli/ai";
7
8
  import { ModelRegistry } from "../config/model-registry";
8
9
  import type { PromptTemplate } from "../config/prompt-templates";
9
10
  import { Settings } from "../config/settings";
@@ -58,6 +59,13 @@ export interface ExecutorOptions {
58
59
  authStorage?: AuthStorage;
59
60
  modelRegistry?: ModelRegistry;
60
61
  settings?: Settings;
62
+ /**
63
+ * Live service-tier intent of the parent session (`AgentSession.serviceTier`),
64
+ * used as the inherited tier when `task.serviceTier === "inherit"`. Passing the
65
+ * live value (not the stale settings snapshot) lets a runtime `/fast on` reach
66
+ * subagents, and a main-model fast-mode auto-disable does not clobber it.
67
+ */
68
+ inheritedServiceTier?: ServiceTier;
61
69
  /** Override local:// protocol options so subagent shares parent's local:// root */
62
70
  localProtocolOptions?: LocalProtocolOptions;
63
71
  /**
@@ -105,7 +113,7 @@ interface FinalizeSubprocessOutputResult {
105
113
  export declare const SUBAGENT_WARNING_NULL_YIELD = "SYSTEM WARNING: Subagent called yield with null data.";
106
114
  export declare const SUBAGENT_WARNING_MISSING_YIELD = "SYSTEM WARNING: Subagent exited without calling yield tool after 3 reminders.";
107
115
  export declare function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): FinalizeSubprocessOutputResult;
108
- export declare function createSubagentSettings(baseSettings: Settings): Settings;
116
+ export declare function createSubagentSettings(baseSettings: Settings, inheritedServiceTier?: ServiceTier): Settings;
109
117
  /**
110
118
  * Run a single agent in-process.
111
119
  */
@@ -28,6 +28,10 @@ export interface TabSession {
28
28
  kindTag: BrowserKindTag;
29
29
  /** Session that acquired this tab; used for session-scoped teardown (F13). */
30
30
  ownerId?: string;
31
+ /** Unix-ms timestamp of the last acquire/run activity; drives GC idle + LRU ordering. */
32
+ lastUsedAt: number;
33
+ /** Set synchronously by the shared begin-release guard so concurrent release is a no-op. */
34
+ releasing?: boolean;
31
35
  }
32
36
  export interface AcquireTabOptions {
33
37
  url?: string;
@@ -58,6 +62,33 @@ export interface ReleaseTabOptions {
58
62
  kill?: boolean;
59
63
  }
60
64
  export declare function getTab(name: string): TabSession | undefined;
65
+ /** Read-only, GC-facing projection of a live tab. Never exposes the mutable `tabs` map. */
66
+ export interface TabGcSnapshot {
67
+ name: string;
68
+ ownerId?: string;
69
+ state: TabSession["state"];
70
+ pendingCount: number;
71
+ kindTag: BrowserKindTag;
72
+ lastUsedAt: number;
73
+ browserRefCount: number;
74
+ }
75
+ export interface BrowserGcEligibilityPolicy {
76
+ now: () => number;
77
+ idleMs: number;
78
+ }
79
+ /** Snapshot every live tab for GC ordering/diagnostics. */
80
+ export declare function listTabsForGc(): TabGcSnapshot[];
81
+ /**
82
+ * Evict a tab only if it is still GC-eligible against the LIVE supervisor state. The full
83
+ * predicate is checked synchronously and `releaseTab` is invoked with no intervening await,
84
+ * so a tab that became busy after a GC snapshot cannot be closed (its run rejected). Returns
85
+ * true only when the tab was actually released.
86
+ */
87
+ export declare function releaseTabIfGcEligible(name: string, policy: BrowserGcEligibilityPolicy): Promise<boolean>;
88
+ /** Test-only: install a fabricated tab session. */
89
+ export declare function setTabForTest(tab: TabSession): void;
90
+ /** Test-only: clear the tab registry between cases. */
91
+ export declare function clearTabsForTest(): void;
61
92
  export declare function acquireTab(name: string, browser: BrowserHandle, opts: AcquireTabOptions): Promise<AcquireTabResult>;
62
93
  export declare function runInTab(name: string, opts: RunInTabOptions): Promise<RunResultOk>;
63
94
  export declare function releaseTab(name: string, opts?: ReleaseTabOptions): Promise<boolean>;
@@ -0,0 +1,14 @@
1
+ export declare const COMPOSER_BASH_POLICY_ERROR = "Composer bash policy blocked repository file I/O. Use find, search, read, and edit tools for file discovery, file inspection, and file mutation.";
2
+ type ComposerBashPolicyResult = {
3
+ allowed: true;
4
+ } | {
5
+ allowed: false;
6
+ reason: string;
7
+ message: string;
8
+ };
9
+ export declare function isComposerBashPolicyModel(modelId: string | undefined): boolean;
10
+ export declare function checkComposerBashPolicy(input: {
11
+ modelId?: string;
12
+ commands: readonly string[];
13
+ }): ComposerBashPolicyResult;
14
+ export {};
@@ -0,0 +1,23 @@
1
+ /** Prefix of every computer-use screenshot fallback directory created under the OS temp dir. */
2
+ export declare const SCREENSHOT_FALLBACK_DIR_PREFIX = "skc-computer-screenshots-";
3
+ /** Lazy-arm marker: called when the first screenshot fallback dir is created this process. */
4
+ export declare function markScreenshotFallbackDirCreatedForGc(): void;
5
+ /** Whether any screenshot fallback dir has been created this process (GC lazy-arm gate). */
6
+ export declare function hasCreatedScreenshotFallbackDir(): boolean;
7
+ /** Test-only: reset the lazy-arm marker between cases. */
8
+ export declare function resetScreenshotFallbackGcForTest(): void;
9
+ export interface ScreenshotGcOptions {
10
+ now: () => number;
11
+ staleMs: number;
12
+ /** Base dir to scan; defaults to os.tmpdir(). Injectable for tests. */
13
+ tmpDir?: string;
14
+ }
15
+ /**
16
+ * Disk-only GC for stale computer-use screenshot fallback directories. Scans the temp dir for
17
+ * `skc-computer-screenshots-*` directories and removes those whose mtime is older than `staleMs`.
18
+ * Never throws on a per-directory failure; the whole sweep is best-effort.
19
+ */
20
+ export declare function cleanupStaleScreenshotFallbackDirs(options: ScreenshotGcOptions): Promise<{
21
+ scanned: number;
22
+ removed: number;
23
+ }>;
@@ -5,18 +5,18 @@ import type { ToolSession } from "./index";
5
5
  export declare const MAX_CRON_TASKS_PER_OWNER = 50;
6
6
  /** Recurring tasks auto-expire 7 days after creation (mirrors upstream). */
7
7
  export declare const CRON_RECURRING_MAX_AGE_MS: number;
8
- declare const cronCreateSchema: z.ZodObject<{
9
- cron_expression: z.ZodString;
10
- prompt: z.ZodString;
11
- recurring: z.ZodDefault<z.ZodBoolean>;
12
- }, z.core.$strip>;
13
- export type CronCreateParams = z.infer<typeof cronCreateSchema>;
14
- declare const cronListSchema: z.ZodObject<{}, z.core.$strip>;
15
- export type CronListParams = z.infer<typeof cronListSchema>;
16
- declare const cronDeleteSchema: z.ZodObject<{
17
- id: z.ZodString;
18
- }, z.core.$strip>;
19
- export type CronDeleteParams = z.infer<typeof cronDeleteSchema>;
8
+ declare const cronSchema: z.ZodObject<{
9
+ op: z.ZodEnum<{
10
+ create: "create";
11
+ delete: "delete";
12
+ list: "list";
13
+ }>;
14
+ cron_expression: z.ZodOptional<z.ZodString>;
15
+ prompt: z.ZodOptional<z.ZodString>;
16
+ recurring: z.ZodOptional<z.ZodBoolean>;
17
+ id: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$strict>;
19
+ export type CronParams = z.infer<typeof cronSchema>;
20
20
  export interface CronJobSnapshot {
21
21
  id: string;
22
22
  cron_expression: string;
@@ -35,18 +35,14 @@ export interface CronListJobDetails {
35
35
  prompt: string;
36
36
  humanSchedule: string;
37
37
  }
38
- export interface CronCreateToolDetails {
39
- id: string;
40
- cron_expression: string;
41
- recurring: boolean;
38
+ export interface CronToolDetails {
39
+ op: "create" | "list" | "delete";
40
+ id?: string;
41
+ cron_expression?: string;
42
+ recurring?: boolean;
42
43
  nextFireAt?: number;
43
- }
44
- export interface CronListToolDetails {
45
- jobs: CronListJobDetails[];
46
- }
47
- export interface CronDeleteToolDetails {
48
- id: string;
49
- deleted: boolean;
44
+ jobs?: CronListJobDetails[];
45
+ deleted?: boolean;
50
46
  }
51
47
  /** Clear every schedule for an owner. Exported for tests + lifecycle teardown. */
52
48
  export declare function clearOwnerSchedules(ownerId: string | undefined): void;
@@ -68,49 +64,28 @@ export declare function calculateCronFireTimeMs(params: {
68
64
  nowMs: number;
69
65
  expiresAt?: number;
70
66
  }): number;
71
- export declare class CronCreateTool implements AgentTool<typeof cronCreateSchema, CronCreateToolDetails> {
72
- private readonly session;
73
- readonly name = "CronCreate";
74
- readonly label = "CronCreate";
75
- readonly summary = "Schedule a prompt on a 5-field cron expression";
76
- readonly description: string;
77
- readonly parameters: z.ZodObject<{
78
- cron_expression: z.ZodString;
79
- prompt: z.ZodString;
80
- recurring: z.ZodDefault<z.ZodBoolean>;
81
- }, z.core.$strip>;
82
- readonly strict = true;
83
- readonly loadMode = "discoverable";
84
- constructor(session: ToolSession);
85
- static createIf(session: ToolSession): CronCreateTool | null;
86
- execute(_toolCallId: string, params: CronCreateParams, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<CronCreateToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<CronCreateToolDetails>>;
87
- }
88
- export declare class CronListTool implements AgentTool<typeof cronListSchema, CronListToolDetails> {
89
- private readonly session;
90
- readonly name = "CronList";
91
- readonly label = "CronList";
92
- readonly summary = "List scheduled cron jobs";
93
- readonly description: string;
94
- readonly parameters: z.ZodObject<{}, z.core.$strip>;
95
- readonly strict = true;
96
- readonly loadMode = "discoverable";
97
- constructor(session: ToolSession);
98
- static createIf(session: ToolSession): CronListTool | null;
99
- execute(_toolCallId: string, _params: CronListParams, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<CronListToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<CronListToolDetails>>;
100
- }
101
- export declare class CronDeleteTool implements AgentTool<typeof cronDeleteSchema, CronDeleteToolDetails> {
67
+ export declare class CronTool implements AgentTool<typeof cronSchema, CronToolDetails> {
68
+ #private;
102
69
  private readonly session;
103
- readonly name = "CronDelete";
104
- readonly label = "CronDelete";
105
- readonly summary = "Cancel a scheduled cron job by ID";
70
+ readonly name = "cron";
71
+ readonly label = "Cron";
72
+ readonly summary = "Schedule, list, and cancel cron-style prompts (op: create | list | delete)";
106
73
  readonly description: string;
107
74
  readonly parameters: z.ZodObject<{
108
- id: z.ZodString;
109
- }, z.core.$strip>;
75
+ op: z.ZodEnum<{
76
+ create: "create";
77
+ delete: "delete";
78
+ list: "list";
79
+ }>;
80
+ cron_expression: z.ZodOptional<z.ZodString>;
81
+ prompt: z.ZodOptional<z.ZodString>;
82
+ recurring: z.ZodOptional<z.ZodBoolean>;
83
+ id: z.ZodOptional<z.ZodString>;
84
+ }, z.core.$strict>;
110
85
  readonly strict = true;
111
86
  readonly loadMode = "discoverable";
112
87
  constructor(session: ToolSession);
113
- static createIf(session: ToolSession): CronDeleteTool | null;
114
- execute(_toolCallId: string, params: CronDeleteParams, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<CronDeleteToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<CronDeleteToolDetails>>;
88
+ static createIf(session: ToolSession): CronTool | null;
89
+ execute(_toolCallId: string, params: CronParams, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<CronToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<CronToolDetails>>;
115
90
  }
116
91
  export {};
@@ -1,5 +1,5 @@
1
1
  import type { AgentTelemetryConfig, AgentTool } from "@sayknow-cli/agent-core";
2
- import type { Model, ToolChoice } from "@sayknow-cli/ai";
2
+ import type { Model, ServiceTier, ToolChoice } from "@sayknow-cli/ai";
3
3
  import type { PromptTemplate } from "../config/prompt-templates";
4
4
  import type { Settings } from "../config/settings";
5
5
  import type { Skill } from "../extensibility/skills";
@@ -41,7 +41,6 @@ export * from "./eval";
41
41
  export * from "./find";
42
42
  export * from "./gh";
43
43
  export * from "./image-gen";
44
- export * from "./inspect-image";
45
44
  export * from "./irc";
46
45
  export * from "./job";
47
46
  export * from "./monitor";
@@ -173,6 +172,8 @@ export interface ToolSession {
173
172
  agentOutputManager?: AgentOutputManager;
174
173
  /** Settings instance for passing to subagents */
175
174
  settings: Settings;
175
+ /** Live service-tier intent of the parent session, inherited by `inherit` subagents. */
176
+ serviceTier?: ServiceTier;
176
177
  /** Plan mode state (if active) */
177
178
  getPlanModeState?: () => PlanModeState | undefined;
178
179
  /** Goal mode state (if active or paused) */
@@ -0,0 +1,54 @@
1
+ import type { Settings } from "../config/settings";
2
+ import { type TabGcSnapshot } from "./browser/tab-supervisor";
3
+ export interface BrowserGcPolicy {
4
+ enabled: boolean;
5
+ idleMs: number;
6
+ rssLimitBytes: number;
7
+ }
8
+ export interface ComputerGcPolicy {
9
+ enabled: boolean;
10
+ staleMs: number;
11
+ scanIntervalMs: number;
12
+ }
13
+ export declare function resolveBrowserGcPolicy(settings: Settings): BrowserGcPolicy;
14
+ export declare function resolveComputerGcPolicy(settings: Settings): ComputerGcPolicy;
15
+ export declare function resolveSweepIntervalMs(settings: Settings): number;
16
+ /** Injectable seams so the controller is fully testable without real browsers/filesystem/RSS. */
17
+ export interface ResourceGcDeps {
18
+ now: () => number;
19
+ rssBytes: () => number;
20
+ logWarn: (msg: string, meta?: Record<string, unknown>) => void;
21
+ listTabs: () => TabGcSnapshot[];
22
+ releaseTab: (name: string, policy: {
23
+ now: () => number;
24
+ idleMs: number;
25
+ }) => Promise<boolean>;
26
+ cleanupScreenshots: (opts: {
27
+ now: () => number;
28
+ staleMs: number;
29
+ }) => Promise<{
30
+ scanned: number;
31
+ removed: number;
32
+ }>;
33
+ screenshotArmed: () => boolean;
34
+ }
35
+ export interface ResourceGcRegistration {
36
+ sessionId: string;
37
+ settings: Settings;
38
+ }
39
+ /**
40
+ * Register a session with the resource GC. Starts the single shared timer on the first
41
+ * registration. Returns an idempotent unregister function; the timer stops only when the last
42
+ * session unregisters.
43
+ */
44
+ export declare function registerResourceGcSession(reg: ResourceGcRegistration): () => void;
45
+ export declare function sweepOnce(d?: ResourceGcDeps): Promise<void>;
46
+ export declare function __setResourceGcDepsForTest(overrides: Partial<ResourceGcDeps>): void;
47
+ export declare function __runResourceGcTickForTest(): Promise<void>;
48
+ export declare function __getResourceGcStateForTest(): {
49
+ timerActive: boolean;
50
+ sessionCount: number;
51
+ rssWarningActive: boolean;
52
+ inProgress: boolean;
53
+ };
54
+ export declare function __resetResourceGcForTest(): void;
@@ -25,6 +25,7 @@ export declare function parseChangelog(changelogPath: string): Promise<Changelog
25
25
  * binary-identity changelog).
26
26
  */
27
27
  export declare function getDisplayChangelogEntries(): ChangelogEntry[];
28
+ export declare function getInstalledVersionChangelogEntry(entries: readonly ChangelogEntry[], installedVersion: string): ChangelogEntry | undefined;
28
29
  /**
29
30
  * Compare versions. Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
30
31
  */
@@ -13,10 +13,13 @@ export type AddressResolver = (hostname: string) => Promise<string[]>;
13
13
  /** True for any address that is not a routable public unicast address. */
14
14
  export declare function isPrivateOrSpecialAddress(address: string): boolean;
15
15
  /**
16
- * Validate that `rawUrl` is a public http/https target safe to hand to the
17
- * insane-search engine. Resolves DNS names and rejects any that map to a
18
- * private/special address. Never throws; returns a discriminated result.
16
+ * Validate that `rawUrl` is a public http/https target. Resolves DNS names and
17
+ * rejects any that map to a private/special address. Never throws; returns a
18
+ * discriminated result.
19
19
  */
20
+ export declare function validatePublicHttpUrl(rawUrl: string, options?: {
21
+ resolver?: AddressResolver;
22
+ }): Promise<PublicUrlResult>;
20
23
  export declare function validatePublicHttpUrlForInsane(rawUrl: string, options?: {
21
24
  resolver?: AddressResolver;
22
25
  }): Promise<PublicUrlResult>;
@@ -1,4 +1,5 @@
1
1
  import type { AgentStorage } from "../../session/agent-storage";
2
+ import type { AddressResolver } from "../insane/url-guard";
2
3
  export { formatNumber } from "@sayknow-cli/utils";
3
4
  export interface RenderResult {
4
5
  url: string;
@@ -27,6 +28,9 @@ export interface LoadPageOptions {
27
28
  body?: string;
28
29
  maxBytes?: number;
29
30
  signal?: AbortSignal;
31
+ publicUrlGuard?: boolean;
32
+ resolver?: AddressResolver;
33
+ maxRedirects?: number;
30
34
  }
31
35
  export interface LoadPageResult {
32
36
  content: string;
@@ -34,6 +38,7 @@ export interface LoadPageResult {
34
38
  finalUrl: string;
35
39
  ok: boolean;
36
40
  status?: number;
41
+ error?: string;
37
42
  }
38
43
  /**
39
44
  * Fetch a page with timeout and size limit
@@ -1,5 +1,6 @@
1
1
  import { isRecord } from "@sayknow-cli/utils";
2
2
  export { isRecord };
3
+ import type { AddressResolver } from "../insane/url-guard";
3
4
  export declare function asRecord(value: unknown): Record<string, unknown> | null;
4
5
  export declare function asString(value: unknown): string | null;
5
6
  export declare function asNumber(value: unknown): number | null;
@@ -12,10 +13,15 @@ export type BinaryFetchResult = BinaryFetchSuccess | {
12
13
  ok: false;
13
14
  error?: string;
14
15
  };
16
+ export interface FetchBinaryOptions {
17
+ publicUrlGuard?: boolean;
18
+ resolver?: AddressResolver;
19
+ maxRedirects?: number;
20
+ }
15
21
  /**
16
22
  * Fetch binary content from a URL
17
23
  */
18
- export declare function fetchBinary(url: string, timeout?: number, signal?: AbortSignal): Promise<BinaryFetchResult>;
24
+ export declare function fetchBinary(url: string, timeout?: number, signal?: AbortSignal, options?: FetchBinaryOptions): Promise<BinaryFetchResult>;
19
25
  /**
20
26
  * Convert binary content to markdown using markit.
21
27
  */