@sayknow-cli/coding-agent 0.3.9 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/cli/notify-cli.d.ts +5 -0
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/config/model-profile-activation.d.ts +7 -7
- package/dist/types/config/model-registry.d.ts +11 -3
- package/dist/types/config/model-resolver.d.ts +2 -2
- package/dist/types/config/settings-schema.d.ts +1 -1
- package/dist/types/config/settings.d.ts +7 -0
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +20 -0
- package/dist/types/modes/components/settings-selector.d.ts +2 -2
- package/dist/types/modes/components/thinking-selector.d.ts +6 -1
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/notifications/config-commands.d.ts +29 -0
- package/dist/types/notifications/index.d.ts +12 -1
- package/dist/types/notifications/threaded-render.d.ts +2 -0
- package/dist/types/notifications/topic-registry.d.ts +4 -5
- package/dist/types/runtime-credential-selector.d.ts +7 -0
- package/dist/types/sdk.d.ts +7 -1
- package/dist/types/session/agent-session.d.ts +6 -3
- package/dist/types/tools/index.d.ts +1 -0
- package/dist/types/tools/skill-discovery.d.ts +40 -0
- package/package.json +7 -7
- package/src/cli/args.ts +8 -0
- package/src/cli/notify-cli.ts +27 -1
- package/src/cli/update-cli.ts +24 -63
- package/src/cli.ts +5 -0
- package/src/commands/launch.ts +5 -0
- package/src/commands/notify.ts +2 -2
- package/src/config/model-profile-activation.ts +23 -7
- package/src/config/model-registry.ts +107 -11
- package/src/config/model-resolver.ts +5 -16
- package/src/config/settings-schema.ts +3 -2
- package/src/config/settings.ts +24 -1
- package/src/extensibility/runtime-skill-discovery.ts +229 -0
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/main.ts +26 -3
- package/src/modes/components/settings-selector.ts +3 -3
- package/src/modes/components/thinking-selector.ts +79 -18
- package/src/modes/controllers/input-controller.ts +50 -9
- package/src/modes/controllers/selector-controller.ts +7 -5
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +48 -15
- package/src/notifications/config-commands.ts +70 -0
- package/src/notifications/index.ts +156 -9
- package/src/notifications/rich-render.ts +1 -0
- package/src/notifications/telegram-daemon.ts +87 -4
- package/src/notifications/threaded-render.ts +14 -0
- package/src/notifications/topic-registry.ts +9 -8
- package/src/prompts/tools/skill-discovery.md +13 -0
- package/src/runtime-credential-selector.ts +35 -0
- package/src/sdk.ts +68 -5
- package/src/session/agent-session.ts +42 -18
- package/src/skc-runtime/psmux-detect.ts +17 -2
- package/src/system-prompt.ts +4 -6
- package/src/tools/index.ts +4 -0
- package/src/tools/skill-discovery.ts +73 -0
- package/src/tools/skill.ts +15 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ Sayknow-CLI is a rebranded fork of [gajae-code](https://github.com/Yeachan-Heo/g
|
|
|
4
4
|
This file tracks the **fork's own releases**; upstream's full feature history lives
|
|
5
5
|
in that project. Each release notes the upstream version it is built on.
|
|
6
6
|
|
|
7
|
+
## [0.3.11] — 2026-07-09
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Restored npm source-install native loading by probing the platform optional
|
|
12
|
+
package (`@sayknow-cli/natives-<platform>`) when the stable native loader package
|
|
13
|
+
no longer carries `.node` binaries directly.
|
|
14
|
+
|
|
15
|
+
## [0.3.10] — 2026-07-09
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Synced onto upstream **gajae-code v0.9.2**, carrying the 0.9.2 patch set into
|
|
20
|
+
Sayknow-CLI while preserving the SKC fork layer and release surface.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Updated the release version surfaces so `skc --version`, package metadata,
|
|
25
|
+
native sentinel exports, plugin metadata, schemas, and public sync checks report
|
|
26
|
+
**0.3.10** consistently.
|
|
27
|
+
|
|
7
28
|
## [0.3.0] — 2026-06-23
|
|
8
29
|
|
|
9
30
|
### Changed
|
package/dist/types/cli/args.d.ts
CHANGED
|
@@ -19,12 +19,17 @@ export interface NotifyCommandDeps {
|
|
|
19
19
|
setupRedact?: boolean;
|
|
20
20
|
setupInteractive?: boolean;
|
|
21
21
|
threadedModePrompt?: (message: string) => Promise<string>;
|
|
22
|
+
tokenPrompt?: () => Promise<string>;
|
|
23
|
+
setExitCode?: (code: number) => void;
|
|
24
|
+
exitProcess?: (code: number) => void;
|
|
22
25
|
}
|
|
23
26
|
export declare function parseNotifyArgs(args: string[]): NotifyCommandArgs | undefined;
|
|
24
27
|
export declare function runNotifyCommand(cmd: NotifyCommandArgs, deps?: NotifyCommandDeps): Promise<void>;
|
|
28
|
+
export declare function runNotifyCliCommand(cmd: NotifyCommandArgs, deps?: NotifyCommandDeps): Promise<void>;
|
|
25
29
|
type TokenPromptInput = NodeJS.ReadStream & {
|
|
26
30
|
isRaw?: boolean;
|
|
27
31
|
setRawMode?: (mode: boolean) => unknown;
|
|
32
|
+
pause?: () => unknown;
|
|
28
33
|
};
|
|
29
34
|
type TokenPromptOutput = Pick<NodeJS.WriteStream, "write">;
|
|
30
35
|
export declare function promptForToken(input?: TokenPromptInput, output?: TokenPromptOutput): Promise<string>;
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -40,6 +40,9 @@ export declare class RootHelpCommand extends Command {
|
|
|
40
40
|
"api-key": import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
|
|
41
41
|
description: string;
|
|
42
42
|
};
|
|
43
|
+
credential: import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
|
|
44
|
+
description: string;
|
|
45
|
+
};
|
|
43
46
|
"system-prompt": import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
|
|
44
47
|
description: string;
|
|
45
48
|
};
|
|
@@ -37,6 +37,9 @@ export default class Index extends Command {
|
|
|
37
37
|
"api-key": import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
|
|
38
38
|
description: string;
|
|
39
39
|
};
|
|
40
|
+
credential: import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
|
|
41
|
+
description: string;
|
|
42
|
+
};
|
|
40
43
|
"system-prompt": import("@sayknow-cli/utils/cli").FlagDescriptor<"string"> & {
|
|
41
44
|
description: string;
|
|
42
45
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ThinkingLevel } from "@sayknow-cli/agent-core";
|
|
2
2
|
import type { Api, Model } from "@sayknow-cli/ai";
|
|
3
3
|
import type { AgentSession } from "../session/agent-session";
|
|
4
4
|
import { type ModelRegistry, type SkcModelAssignmentTargetId } from "./model-registry";
|
|
@@ -16,6 +16,10 @@ export interface PrepareModelProfileActivationOptions {
|
|
|
16
16
|
settings: Pick<Settings, "get">;
|
|
17
17
|
profileName: string;
|
|
18
18
|
}
|
|
19
|
+
export interface ApplyModelProfileActivationOptions {
|
|
20
|
+
persistDefault?: boolean;
|
|
21
|
+
thinkingLevelOverride?: ThinkingLevel;
|
|
22
|
+
}
|
|
19
23
|
export interface PreparedModelProfileActivation {
|
|
20
24
|
profileName: string;
|
|
21
25
|
session: ModelProfileActivationSession & {
|
|
@@ -55,10 +59,6 @@ export declare function materializeActiveModelProfileAssignment(options: Materia
|
|
|
55
59
|
export declare function materializeActiveModelProfileAssignments(options: MaterializeModelProfileAssignmentsOptions): boolean;
|
|
56
60
|
export declare function formatModelProfileCredentialError(profileName: string, providers: readonly string[]): string;
|
|
57
61
|
export declare function prepareModelProfileActivation(options: PrepareModelProfileActivationOptions): Promise<PreparedModelProfileActivation>;
|
|
58
|
-
export declare function applyPreparedModelProfileActivation(prepared: PreparedModelProfileActivation, options?:
|
|
59
|
-
|
|
60
|
-
}): Promise<void>;
|
|
61
|
-
export declare function activateModelProfile(options: PrepareModelProfileActivationOptions, applyOptions?: {
|
|
62
|
-
persistDefault?: boolean;
|
|
63
|
-
}): Promise<void>;
|
|
62
|
+
export declare function applyPreparedModelProfileActivation(prepared: PreparedModelProfileActivation, options?: ApplyModelProfileActivationOptions): Promise<void>;
|
|
63
|
+
export declare function activateModelProfile(options: PrepareModelProfileActivationOptions, applyOptions?: ApplyModelProfileActivationOptions): Promise<void>;
|
|
64
64
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Api, type AssistantMessageEventStream, type CacheRetention, type Context, type Model, type ModelRefreshStrategy, type ModelRequestTransform, type SimpleStreamOptions, type ThinkingConfig } from "@sayknow-cli/ai";
|
|
1
|
+
import { type Api, type AssistantMessageEventStream, type AuthCredentialSelector, type CacheRetention, type Context, type Model, type ModelRefreshStrategy, type ModelRequestTransform, type SimpleStreamOptions, type ThinkingConfig } from "@sayknow-cli/ai";
|
|
2
2
|
import type { OAuthCredentials, OAuthLoginCallbacks } from "@sayknow-cli/ai/utils/oauth/types";
|
|
3
3
|
import { type ThemeColor } from "../modes/theme/theme";
|
|
4
4
|
import type { AuthStorage } from "../session/auth-storage";
|
|
@@ -19,6 +19,8 @@ export interface ModelRoleInfo {
|
|
|
19
19
|
}
|
|
20
20
|
export declare const MODEL_ROLES: Record<ModelRole, ModelRoleInfo>;
|
|
21
21
|
export declare const MODEL_ROLE_IDS: ModelRole[];
|
|
22
|
+
export declare const MODEL_PROFILE_NAME_PATTERN: RegExp;
|
|
23
|
+
export declare const MODEL_PROFILE_NAME_PATTERN_DESCRIPTION = "lowercase letters, numbers, dots, underscores, or hyphens";
|
|
22
24
|
export type SkcModelAssignmentTargetId = "default" | "executor" | "architect" | "planner" | "critic";
|
|
23
25
|
export interface SkcModelAssignmentTargetInfo extends ModelRoleInfo {
|
|
24
26
|
id: SkcModelAssignmentTargetId;
|
|
@@ -342,6 +344,8 @@ export declare class ModelRegistry {
|
|
|
342
344
|
getModelProfile(name: string): ModelProfileDefinition | undefined;
|
|
343
345
|
getAvailableModelProfileNames(): string[];
|
|
344
346
|
saveCustomModelProfile(name: string, definition: ModelProfileConfig): Promise<ModelProfileDefinition>;
|
|
347
|
+
renameCustomModelProfile(name: string, displayName: string): Promise<ModelProfileDefinition>;
|
|
348
|
+
deleteCustomModelProfile(name: string): Promise<ModelProfileConfig>;
|
|
345
349
|
applyConfiguredModelBindings(targetSettings: Settings): void;
|
|
346
350
|
/**
|
|
347
351
|
* Get all models (built-in + custom).
|
|
@@ -382,11 +386,15 @@ export declare class ModelRegistry {
|
|
|
382
386
|
/**
|
|
383
387
|
* Get API key for a model.
|
|
384
388
|
*/
|
|
385
|
-
getApiKey(model: Model<Api>, sessionId?: string
|
|
389
|
+
getApiKey(model: Model<Api>, sessionId?: string, options?: {
|
|
390
|
+
credentialSelector?: AuthCredentialSelector;
|
|
391
|
+
}): Promise<string | undefined>;
|
|
386
392
|
/**
|
|
387
393
|
* Get API key for a provider (e.g., "openai").
|
|
388
394
|
*/
|
|
389
|
-
getApiKeyForProvider(provider: string, sessionId?: string, baseUrl?: string
|
|
395
|
+
getApiKeyForProvider(provider: string, sessionId?: string, baseUrl?: string, options?: {
|
|
396
|
+
credentialSelector?: AuthCredentialSelector;
|
|
397
|
+
}): Promise<string | undefined>;
|
|
390
398
|
/**
|
|
391
399
|
* Check if a model is using OAuth credentials (subscription).
|
|
392
400
|
*/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Model resolution, scoping, and initial selection
|
|
3
3
|
*/
|
|
4
4
|
import { ThinkingLevel } from "@sayknow-cli/agent-core";
|
|
5
|
-
import { type Api, type
|
|
5
|
+
import { type Api, type KnownProvider, type Model } from "@sayknow-cli/ai";
|
|
6
6
|
import { type ModelRegistry, type ModelRole } from "./model-registry";
|
|
7
7
|
import type { Settings } from "./settings";
|
|
8
8
|
/** Default model IDs for each known provider */
|
|
@@ -204,7 +204,7 @@ export declare function findInitialModel(options: {
|
|
|
204
204
|
isContinuing: boolean;
|
|
205
205
|
defaultProvider?: string;
|
|
206
206
|
defaultModelId?: string;
|
|
207
|
-
defaultThinkingSelector?:
|
|
207
|
+
defaultThinkingSelector?: ThinkingLevel;
|
|
208
208
|
modelRegistry: InitialModelRegistry;
|
|
209
209
|
}): Promise<InitialModelResult>;
|
|
210
210
|
/**
|
|
@@ -950,7 +950,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
950
950
|
};
|
|
951
951
|
readonly defaultThinkingLevel: {
|
|
952
952
|
readonly type: "enum";
|
|
953
|
-
readonly values: readonly Effort[];
|
|
953
|
+
readonly values: readonly ["off", ...Effort[]];
|
|
954
954
|
readonly default: Effort;
|
|
955
955
|
readonly ui: {
|
|
956
956
|
readonly tab: "model";
|
|
@@ -82,6 +82,13 @@ export declare class Settings {
|
|
|
82
82
|
* Call before exit to ensure all changes are persisted.
|
|
83
83
|
*/
|
|
84
84
|
flush(): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Like {@link flush}, but rejects if the durable save fails instead of
|
|
87
|
+
* swallowing the error. Use where the caller must confirm persistence before
|
|
88
|
+
* reporting success (e.g. the Telegram `/rich` toggle). In-memory instances
|
|
89
|
+
* ({@link isolated}) short-circuit in {@link #saveNow} and never throw.
|
|
90
|
+
*/
|
|
91
|
+
flushOrThrow(): Promise<void>;
|
|
85
92
|
cloneForCwd(cwd: string): Promise<Settings>;
|
|
86
93
|
getStorage(): AgentStorage | null;
|
|
87
94
|
getCwd(): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SkillsSettings } from "../config/settings-schema";
|
|
2
|
+
import type { Skill } from "./skills";
|
|
3
|
+
export type RuntimeSkillDiscoverySource = "project" | "user";
|
|
4
|
+
export interface RuntimeSkillDiscoveryCandidate {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
source: RuntimeSkillDiscoverySource;
|
|
8
|
+
path: string;
|
|
9
|
+
useWhen?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface DiscoverRuntimeSkillsOptions {
|
|
12
|
+
cwd: string;
|
|
13
|
+
home?: string;
|
|
14
|
+
query?: string;
|
|
15
|
+
limit?: number;
|
|
16
|
+
source?: RuntimeSkillDiscoverySource | "all";
|
|
17
|
+
policy?: SkillsSettings;
|
|
18
|
+
}
|
|
19
|
+
export declare function discoverRuntimeSkills(options: DiscoverRuntimeSkillsOptions): Promise<RuntimeSkillDiscoveryCandidate[]>;
|
|
20
|
+
export declare function findRuntimeSkillByName(cwd: string, name: string, policy?: SkillsSettings, home?: string): Promise<Skill | undefined>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ThinkingLevel as ThinkingLevelValue } from "@sayknow-cli/agent-core";
|
|
2
2
|
import type { Effort } from "@sayknow-cli/ai";
|
|
3
3
|
import { Container, SettingsList } from "@sayknow-cli/tui";
|
|
4
4
|
import { type SettingPath } from "../../config/settings";
|
|
@@ -13,7 +13,7 @@ export interface SettingsRuntimeContext {
|
|
|
13
13
|
/** Available thinking levels (from session) */
|
|
14
14
|
availableThinkingLevels: Effort[];
|
|
15
15
|
/** Current thinking level (from session) */
|
|
16
|
-
thinkingLevel:
|
|
16
|
+
thinkingLevel: ThinkingLevelValue | undefined;
|
|
17
17
|
/** Available themes */
|
|
18
18
|
availableThemes: string[];
|
|
19
19
|
/** Available model profile names (from the model registry) */
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { type ThinkingLevel as ThinkingLevelValue } from "@sayknow-cli/agent-core";
|
|
2
2
|
import { Container, SelectList } from "@sayknow-cli/tui";
|
|
3
|
+
export interface ThinkingSelectorSelection {
|
|
4
|
+
level: ThinkingLevelValue;
|
|
5
|
+
persistDefault: boolean;
|
|
6
|
+
}
|
|
3
7
|
/**
|
|
4
8
|
* Component that renders a thinking level selector with borders
|
|
5
9
|
*/
|
|
6
10
|
export declare class ThinkingSelectorComponent extends Container {
|
|
7
11
|
#private;
|
|
8
|
-
constructor(currentLevel: ThinkingLevelValue | undefined, availableLevels: ThinkingLevelValue[], onSelect: (
|
|
12
|
+
constructor(currentLevel: ThinkingLevelValue | undefined, availableLevels: ThinkingLevelValue[], onSelect: (selection: ThinkingSelectorSelection) => void, onCancel: () => void);
|
|
13
|
+
handleInput(data: string): void;
|
|
9
14
|
getSelectList(): SelectList;
|
|
10
15
|
}
|
|
@@ -18,6 +18,35 @@ export interface ConfigCommandChange {
|
|
|
18
18
|
verbosity?: "lean" | "verbose";
|
|
19
19
|
redact?: boolean;
|
|
20
20
|
}
|
|
21
|
+
export type TelegramControlCommandName = "reasoning" | "usage" | "context" | "compact";
|
|
22
|
+
export type TelegramControlCommand = {
|
|
23
|
+
name: "reasoning";
|
|
24
|
+
action: "cycle" | "status" | "set";
|
|
25
|
+
level?: string;
|
|
26
|
+
} | {
|
|
27
|
+
name: "usage";
|
|
28
|
+
} | {
|
|
29
|
+
name: "context";
|
|
30
|
+
} | {
|
|
31
|
+
name: "compact";
|
|
32
|
+
instructions?: string;
|
|
33
|
+
};
|
|
34
|
+
export type TelegramControlCommandParseResult = {
|
|
35
|
+
kind: "none";
|
|
36
|
+
} | {
|
|
37
|
+
kind: "ignored";
|
|
38
|
+
commandName: TelegramControlCommandName;
|
|
39
|
+
} | {
|
|
40
|
+
kind: "command";
|
|
41
|
+
command: TelegramControlCommand;
|
|
42
|
+
} | {
|
|
43
|
+
kind: "invalid";
|
|
44
|
+
commandName: TelegramControlCommandName;
|
|
45
|
+
usage: string;
|
|
46
|
+
};
|
|
47
|
+
export declare function telegramControlCommandUsage(commandName: TelegramControlCommandName): string;
|
|
48
|
+
/** Parse deterministic Telegram session-control commands. Recognised roots fail closed. */
|
|
49
|
+
export declare function parseTelegramControlCommand(text: string, botUsername?: string): TelegramControlCommandParseResult;
|
|
21
50
|
/**
|
|
22
51
|
* Parse an in-thread config command. Returns the requested change, or
|
|
23
52
|
* `undefined` when the text is not a recognised config command (so the daemon
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* generated), or `SKC_NOTIFICATIONS_TOKEN`.
|
|
19
19
|
*/
|
|
20
20
|
import { Settings } from "../config/settings";
|
|
21
|
-
import type { ExtensionAPI } from "../extensibility/extensions";
|
|
21
|
+
import type { ExtensionAPI, ExtensionContext } from "../extensibility/extensions";
|
|
22
22
|
/** Where a `session_create` should run. Discriminated by `kind`. */
|
|
23
23
|
export type SessionCreateTarget = {
|
|
24
24
|
kind: "existing_path";
|
|
@@ -176,6 +176,17 @@ export interface SessionReadyFrame {
|
|
|
176
176
|
*/
|
|
177
177
|
export declare function readGitRepoName(cwd: string): string | undefined;
|
|
178
178
|
export declare function notificationsEnabled(): boolean;
|
|
179
|
+
interface NotificationControlCommandPayload {
|
|
180
|
+
name?: unknown;
|
|
181
|
+
action?: unknown;
|
|
182
|
+
level?: unknown;
|
|
183
|
+
instructions?: unknown;
|
|
184
|
+
}
|
|
185
|
+
export declare function executeNotificationControlCommand(command: NotificationControlCommandPayload | undefined, ctx: ExtensionContext, api: ExtensionAPI): Promise<{
|
|
186
|
+
status: "ok" | "error" | "unavailable";
|
|
187
|
+
message: string;
|
|
188
|
+
}>;
|
|
179
189
|
export declare function createNotificationsExtension(api: ExtensionAPI, options?: {
|
|
180
190
|
settings?: Settings;
|
|
181
191
|
}): void;
|
|
192
|
+
export {};
|
|
@@ -58,11 +58,10 @@ export declare class TopicRegistry {
|
|
|
58
58
|
markIdentitySent(sessionId: string): void;
|
|
59
59
|
/** Whether the identity header still needs sending for this session. */
|
|
60
60
|
needsIdentity(sessionId: string): boolean;
|
|
61
|
-
/**
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
applyName(sessionId: string, name: string): boolean;
|
|
61
|
+
/** Whether a known session topic's applied title differs from `name`. */
|
|
62
|
+
needsRename(sessionId: string, name: string): boolean;
|
|
63
|
+
/** Commit a successfully-applied Telegram topic title. */
|
|
64
|
+
markNameApplied(sessionId: string, name: string): void;
|
|
66
65
|
/** Remove a session topic record after Telegram deletes the topic. */
|
|
67
66
|
delete(sessionId: string): boolean;
|
|
68
67
|
/** Serialise for atomic persistence beside the daemon state. */
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AuthCredentialSelector } from "@sayknow-cli/ai";
|
|
2
|
+
export interface CliCredentialSelector {
|
|
3
|
+
provider?: string;
|
|
4
|
+
selector: AuthCredentialSelector;
|
|
5
|
+
raw: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseCliCredentialSelector(raw: string): CliCredentialSelector;
|
package/dist/types/sdk.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AgentTelemetryConfig, type ThinkingLevel } from "@sayknow-cli/agent-core";
|
|
2
|
-
import { type Model, type ProviderSessionState } from "@sayknow-cli/ai";
|
|
2
|
+
import { type AuthCredentialSelector, type Model, type ProviderSessionState } from "@sayknow-cli/ai";
|
|
3
3
|
import { createAppendOnlyContextManager, providerSupportsAppendOnlyAuto, resolveAppendOnlyMode } from "./append-only-mode";
|
|
4
4
|
import { type Rule } from "./capability/rule";
|
|
5
5
|
import { ModelRegistry } from "./config/model-registry";
|
|
@@ -55,6 +55,12 @@ export interface CreateAgentSessionOptions {
|
|
|
55
55
|
/** Optional provider-facing session identifier for prompt caches and sticky auth selection.
|
|
56
56
|
* Keeps persisted session files isolated while reusing provider-side caches. */
|
|
57
57
|
providerSessionId?: string;
|
|
58
|
+
/** Runtime credential selector for multi-account auth pools. */
|
|
59
|
+
credentialSelector?: {
|
|
60
|
+
provider?: string;
|
|
61
|
+
selector: AuthCredentialSelector;
|
|
62
|
+
raw: string;
|
|
63
|
+
};
|
|
58
64
|
/** Custom tools to register (in addition to built-in tools). Accepts both CustomTool and ToolDefinition. */
|
|
59
65
|
customTools?: (CustomTool | ToolDefinition)[];
|
|
60
66
|
/** Explicit parent/phase used to load active SKC sub-skill tools for this session. */
|
|
@@ -270,6 +270,8 @@ export interface PromptOptions {
|
|
|
270
270
|
images?: ImageContent[];
|
|
271
271
|
/** When streaming, how to queue the message: "steer" (interrupt) or "followUp" (wait). */
|
|
272
272
|
streamingBehavior?: "steer" | "followUp";
|
|
273
|
+
/** When set to "sequential", this follow-up is delivered one prompt at a time even if followUpMode is "all". */
|
|
274
|
+
followUpQueuePolicy?: "respect-mode" | "sequential";
|
|
273
275
|
/** Optional tool choice override for the next LLM call. */
|
|
274
276
|
toolChoice?: ToolChoice;
|
|
275
277
|
/** Send as developer/system message instead of user. Providers that support it use the developer role; others fall back to user. */
|
|
@@ -657,7 +659,7 @@ export declare class AgentSession {
|
|
|
657
659
|
* @throws Error if no model selected or no API key available (when not streaming)
|
|
658
660
|
*/
|
|
659
661
|
prompt(text: string, options?: PromptOptions): Promise<void>;
|
|
660
|
-
promptCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: Pick<PromptOptions, "streamingBehavior" | "toolChoice">): Promise<void>;
|
|
662
|
+
promptCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: Pick<PromptOptions, "streamingBehavior" | "toolChoice" | "followUpQueuePolicy">): Promise<void>;
|
|
661
663
|
/**
|
|
662
664
|
* Queue a steering message to interrupt the agent mid-run.
|
|
663
665
|
*/
|
|
@@ -665,7 +667,7 @@ export declare class AgentSession {
|
|
|
665
667
|
/**
|
|
666
668
|
* Queue a follow-up message to process after the agent would otherwise stop.
|
|
667
669
|
*/
|
|
668
|
-
followUp(text: string, images?: ImageContent[]): Promise<void>;
|
|
670
|
+
followUp(text: string, images?: ImageContent[], options?: Pick<PromptOptions, "followUpQueuePolicy">): Promise<void>;
|
|
669
671
|
queueDeferredMessage(message: CustomMessage): void;
|
|
670
672
|
queueDeferredMessageForTests(message: CustomMessage, triggerTurn?: boolean): void;
|
|
671
673
|
/**
|
|
@@ -679,6 +681,7 @@ export declare class AgentSession {
|
|
|
679
681
|
sendCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: {
|
|
680
682
|
triggerTurn?: boolean;
|
|
681
683
|
deliverAs?: "steer" | "followUp" | "nextTurn";
|
|
684
|
+
followUpQueuePolicy?: "respect-mode" | "sequential";
|
|
682
685
|
}): Promise<void>;
|
|
683
686
|
/** Remove undelivered queued custom messages matching `predicate` from executable queues and tagged display mirrors. */
|
|
684
687
|
purgeQueuedCustomMessages(predicate: (message: CustomMessage) => boolean): PurgeQueuedCustomMessagesResult;
|
|
@@ -834,7 +837,7 @@ export declare class AgentSession {
|
|
|
834
837
|
getAvailableModels(): Model[];
|
|
835
838
|
/**
|
|
836
839
|
* Set thinking level.
|
|
837
|
-
* Saves the effective metadata-clamped level to session and settings
|
|
840
|
+
* Saves the effective metadata-clamped level to the session, and to settings when requested.
|
|
838
841
|
*/
|
|
839
842
|
setThinkingLevel(level: ThinkingLevel | undefined, persist?: boolean): void;
|
|
840
843
|
/**
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { AgentTool, AgentToolResult } from "@sayknow-cli/agent-core";
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
|
+
import { type RuntimeSkillDiscoveryCandidate } from "../extensibility/runtime-skill-discovery";
|
|
4
|
+
import type { ToolSession } from ".";
|
|
5
|
+
declare const skillDiscoverySchema: z.ZodObject<{
|
|
6
|
+
query: z.ZodOptional<z.ZodString>;
|
|
7
|
+
source: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
8
|
+
all: "all";
|
|
9
|
+
project: "project";
|
|
10
|
+
user: "user";
|
|
11
|
+
}>>>;
|
|
12
|
+
limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
13
|
+
}, z.core.$strict>;
|
|
14
|
+
export type SkillDiscoveryToolInput = z.infer<typeof skillDiscoverySchema>;
|
|
15
|
+
export interface SkillDiscoveryToolDetails {
|
|
16
|
+
candidates: RuntimeSkillDiscoveryCandidate[];
|
|
17
|
+
count: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class SkillDiscoveryTool implements AgentTool<typeof skillDiscoverySchema, SkillDiscoveryToolDetails> {
|
|
20
|
+
#private;
|
|
21
|
+
readonly name = "skill_discovery";
|
|
22
|
+
readonly label = "SkillDiscovery";
|
|
23
|
+
readonly summary = "Discover project and user runtime skills by thin metadata";
|
|
24
|
+
readonly loadMode = "essential";
|
|
25
|
+
readonly description: string;
|
|
26
|
+
readonly parameters: z.ZodObject<{
|
|
27
|
+
query: z.ZodOptional<z.ZodString>;
|
|
28
|
+
source: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
29
|
+
all: "all";
|
|
30
|
+
project: "project";
|
|
31
|
+
user: "user";
|
|
32
|
+
}>>>;
|
|
33
|
+
limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
34
|
+
}, z.core.$strict>;
|
|
35
|
+
readonly strict = true;
|
|
36
|
+
constructor(session: ToolSession);
|
|
37
|
+
static createIf(session: ToolSession): SkillDiscoveryTool | null;
|
|
38
|
+
execute(_toolCallId: string, input: SkillDiscoveryToolInput, signal?: AbortSignal): Promise<AgentToolResult<SkillDiscoveryToolDetails>>;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@sayknow-cli/coding-agent",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.11",
|
|
5
5
|
"description": "Sayknow-CLI CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://sayknow-cli.com",
|
|
7
7
|
"author": "jaybeyond",
|
|
@@ -52,12 +52,12 @@
|
|
|
52
52
|
"@agentclientprotocol/sdk": "0.21.0",
|
|
53
53
|
"@babel/parser": "^7.29.3",
|
|
54
54
|
"@mozilla/readability": "^0.6.0",
|
|
55
|
-
"@sayknow-cli/stats": "0.3.
|
|
56
|
-
"@sayknow-cli/agent-core": "0.3.
|
|
57
|
-
"@sayknow-cli/ai": "0.3.
|
|
58
|
-
"@sayknow-cli/natives": "0.3.
|
|
59
|
-
"@sayknow-cli/tui": "0.3.
|
|
60
|
-
"@sayknow-cli/utils": "0.3.
|
|
55
|
+
"@sayknow-cli/stats": "0.3.11",
|
|
56
|
+
"@sayknow-cli/agent-core": "0.3.11",
|
|
57
|
+
"@sayknow-cli/ai": "0.3.11",
|
|
58
|
+
"@sayknow-cli/natives": "0.3.11",
|
|
59
|
+
"@sayknow-cli/tui": "0.3.11",
|
|
60
|
+
"@sayknow-cli/utils": "0.3.11",
|
|
61
61
|
"@puppeteer/browsers": "^2.13.0",
|
|
62
62
|
"@types/turndown": "5.0.6",
|
|
63
63
|
"@xterm/headless": "^6.0.0",
|
package/src/cli/args.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { type Effort, THINKING_EFFORTS } from "@sayknow-cli/ai";
|
|
5
5
|
import { APP_NAME, CONFIG_DIR_NAME, logger } from "@sayknow-cli/utils";
|
|
6
|
+
import { CliParseError } from "@sayknow-cli/utils/cli";
|
|
6
7
|
import chalk from "chalk";
|
|
7
8
|
import { parseEffort } from "../thinking";
|
|
8
9
|
import { BUILTIN_TOOLS } from "../tools";
|
|
@@ -20,6 +21,7 @@ export interface Args {
|
|
|
20
21
|
mpreset?: string;
|
|
21
22
|
default?: boolean;
|
|
22
23
|
apiKey?: string;
|
|
24
|
+
credential?: string;
|
|
23
25
|
systemPrompt?: string;
|
|
24
26
|
appendSystemPrompt?: string;
|
|
25
27
|
thinking?: Effort;
|
|
@@ -136,6 +138,12 @@ export function parseArgs(args: string[]): Args {
|
|
|
136
138
|
result.default = true;
|
|
137
139
|
} else if (arg === "--api-key" && i + 1 < args.length) {
|
|
138
140
|
result.apiKey = args[++i];
|
|
141
|
+
} else if (arg === "--credential") {
|
|
142
|
+
const next = args[i + 1];
|
|
143
|
+
if (!next || next.startsWith("-")) {
|
|
144
|
+
throw new CliParseError("--credential requires <selector>");
|
|
145
|
+
}
|
|
146
|
+
result.credential = args[++i];
|
|
139
147
|
} else if (arg === "--system-prompt" && i + 1 < args.length) {
|
|
140
148
|
result.systemPrompt = args[++i];
|
|
141
149
|
} else if (arg === "--append-system-prompt" && i + 1 < args.length) {
|
package/src/cli/notify-cli.ts
CHANGED
|
@@ -31,6 +31,9 @@ export interface NotifyCommandDeps {
|
|
|
31
31
|
setupRedact?: boolean;
|
|
32
32
|
setupInteractive?: boolean;
|
|
33
33
|
threadedModePrompt?: (message: string) => Promise<string>;
|
|
34
|
+
tokenPrompt?: () => Promise<string>;
|
|
35
|
+
setExitCode?: (code: number) => void;
|
|
36
|
+
exitProcess?: (code: number) => void;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
interface TelegramApiResponse<T> {
|
|
@@ -126,6 +129,27 @@ export async function runNotifyCommand(cmd: NotifyCommandArgs, deps: NotifyComma
|
|
|
126
129
|
}
|
|
127
130
|
}
|
|
128
131
|
|
|
132
|
+
export async function runNotifyCliCommand(cmd: NotifyCommandArgs, deps: NotifyCommandDeps = {}): Promise<void> {
|
|
133
|
+
try {
|
|
134
|
+
await runNotifyCommand(cmd, deps);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
if (cmd.action !== "setup" || !(error instanceof Error)) {
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const cancelled = error.message === "Telegram bot token prompt cancelled.";
|
|
141
|
+
process.stderr.write(cancelled ? "Telegram notify setup cancelled.\n" : `Error: ${error.message}\n`);
|
|
142
|
+
const code = cancelled ? 130 : 1;
|
|
143
|
+
if (deps.setExitCode) {
|
|
144
|
+
deps.setExitCode(code);
|
|
145
|
+
} else {
|
|
146
|
+
process.exitCode = code;
|
|
147
|
+
}
|
|
148
|
+
const exitProcess = deps.exitProcess ?? (deps.setExitCode ? undefined : process.exit);
|
|
149
|
+
exitProcess?.(code);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
129
153
|
async function getSettings(deps: NotifyCommandDeps): Promise<Settings> {
|
|
130
154
|
if (deps.settings) return deps.settings;
|
|
131
155
|
const { Settings } = await import("../config/settings");
|
|
@@ -136,7 +160,7 @@ async function runSetup(deps: NotifyCommandDeps): Promise<void> {
|
|
|
136
160
|
const settings = await getSettings(deps);
|
|
137
161
|
const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
|
|
138
162
|
const apiBase = deps.apiBase ?? DEFAULT_API_BASE;
|
|
139
|
-
const token = deps.setupToken ?? (await promptForToken());
|
|
163
|
+
const token = deps.setupToken ?? (await (deps.tokenPrompt ?? promptForToken)());
|
|
140
164
|
if (!token.trim()) {
|
|
141
165
|
throw new Error("Telegram bot token is required.");
|
|
142
166
|
}
|
|
@@ -179,6 +203,7 @@ async function runSetup(deps: NotifyCommandDeps): Promise<void> {
|
|
|
179
203
|
type TokenPromptInput = NodeJS.ReadStream & {
|
|
180
204
|
isRaw?: boolean;
|
|
181
205
|
setRawMode?: (mode: boolean) => unknown;
|
|
206
|
+
pause?: () => unknown;
|
|
182
207
|
};
|
|
183
208
|
|
|
184
209
|
type TokenPromptOutput = Pick<NodeJS.WriteStream, "write">;
|
|
@@ -206,6 +231,7 @@ export async function promptForToken(
|
|
|
206
231
|
input.off("data", onData);
|
|
207
232
|
input.off("error", onError);
|
|
208
233
|
input.setRawMode?.(wasRaw);
|
|
234
|
+
input.pause?.();
|
|
209
235
|
output.write("\n");
|
|
210
236
|
};
|
|
211
237
|
|