@gajae-code/coding-agent 0.7.10 → 0.8.0
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 +58 -0
- package/README.md +2 -2
- package/dist/types/capability/mcp.d.ts +2 -0
- package/dist/types/config/keybindings.d.ts +11 -5
- package/dist/types/config/settings-schema.d.ts +25 -2
- package/dist/types/defaults/gjc-defaults.d.ts +7 -0
- package/dist/types/discovery/cursor.d.ts +4 -1
- package/dist/types/discovery/index.d.ts +0 -1
- package/dist/types/discovery/windsurf.d.ts +3 -1
- package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +3 -2
- package/dist/types/gjc-runtime/restricted-role-agent-bash.d.ts +1 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +5 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +1 -0
- package/dist/types/modes/components/custom-editor.d.ts +6 -1
- package/dist/types/modes/components/settings-selector.d.ts +1 -0
- package/dist/types/modes/components/skill-message.d.ts +1 -0
- package/dist/types/modes/components/status-line.d.ts +8 -0
- package/dist/types/modes/components/two-column-body.d.ts +9 -0
- package/dist/types/modes/components/welcome.d.ts +9 -1
- package/dist/types/modes/controllers/command-controller.d.ts +1 -0
- package/dist/types/modes/controllers/input-controller.d.ts +5 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +8 -0
- package/dist/types/modes/interactive-mode.d.ts +2 -0
- package/dist/types/modes/prompt-action-autocomplete.d.ts +2 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +1 -0
- package/dist/types/modes/slash-command-visibility.d.ts +1 -0
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/runtime-mcp/config-writer.d.ts +9 -0
- package/dist/types/runtime-mcp/config.d.ts +2 -0
- package/dist/types/runtime-mcp/loader.d.ts +2 -0
- package/dist/types/runtime-mcp/manager.d.ts +2 -0
- package/dist/types/runtime-mcp/types.d.ts +6 -0
- package/dist/types/sdk.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +8 -5
- package/dist/types/slash-commands/types.d.ts +2 -0
- package/dist/types/system-prompt.d.ts +7 -0
- package/dist/types/utils/cmux-workspace.d.ts +30 -1
- package/dist/types/web/search/index.d.ts +3 -1
- package/dist/types/web/search/provider.d.ts +9 -0
- package/dist/types/web/search/providers/utils.d.ts +42 -13
- package/dist/types/workflow/workflow-intent-diff.d.ts +19 -0
- package/package.json +10 -10
- package/src/capability/mcp.ts +2 -0
- package/src/cli/update-cli.ts +24 -0
- package/src/cli/web-search-cli.ts +2 -5
- package/src/cli.ts +1 -1
- package/src/commands/launch.ts +1 -1
- package/src/commands/ralplan.ts +1 -0
- package/src/config/keybindings.ts +14 -5
- package/src/config/mcp-schema.json +5 -1
- package/src/config/model-profiles.ts +16 -0
- package/src/config/settings-schema.ts +18 -2
- package/src/coordinator-mcp/server.ts +15 -3
- package/src/defaults/gjc/skills/ralplan/SKILL.md +16 -14
- package/src/defaults/gjc-defaults.ts +16 -0
- package/src/discovery/builtin.ts +12 -0
- package/src/discovery/cursor.ts +5 -84
- package/src/discovery/gemini.ts +3 -89
- package/src/discovery/index.ts +4 -1
- package/src/discovery/mcp-json.ts +11 -0
- package/src/discovery/opencode.ts +5 -122
- package/src/discovery/windsurf.ts +4 -82
- package/src/edit/read-file.ts +9 -1
- package/src/extensibility/extensions/runner.ts +2 -1
- package/src/gjc-runtime/launch-tmux.ts +164 -42
- package/src/gjc-runtime/ralplan-runtime.ts +22 -6
- package/src/gjc-runtime/restricted-role-agent-bash.ts +1 -0
- package/src/gjc-runtime/session-state-sidecar.ts +167 -24
- package/src/gjc-runtime/state-runtime.ts +8 -5
- package/src/gjc-runtime/state-writer.ts +5 -5
- package/src/gjc-runtime/team-runtime.ts +56 -51
- package/src/internal-urls/docs-index.generated.ts +8 -7
- package/src/main.ts +2 -2
- package/src/migrate/executor.ts +23 -6
- package/src/modes/components/agent-dashboard.ts +1 -34
- package/src/modes/components/custom-editor.ts +26 -0
- package/src/modes/components/extensions/extension-dashboard.ts +2 -48
- package/src/modes/components/model-selector.ts +64 -4
- package/src/modes/components/session-selector.ts +19 -9
- package/src/modes/components/settings-selector.ts +13 -2
- package/src/modes/components/skill-message.ts +18 -10
- package/src/modes/components/status-line.ts +215 -86
- package/src/modes/components/tree-selector.ts +28 -8
- package/src/modes/components/two-column-body.ts +36 -0
- package/src/modes/components/welcome.ts +171 -35
- package/src/modes/controllers/command-controller.ts +23 -0
- package/src/modes/controllers/event-controller.ts +4 -0
- package/src/modes/controllers/input-controller.ts +192 -39
- package/src/modes/controllers/selector-controller.ts +25 -28
- package/src/modes/interactive-mode.ts +36 -30
- package/src/modes/prompt-action-autocomplete.ts +23 -1
- package/src/modes/rpc/rpc-types.ts +1 -0
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +9 -3
- package/src/modes/shared/agent-wire/workflow-gate-schema.ts +20 -0
- package/src/modes/slash-command-visibility.ts +9 -0
- package/src/modes/types.ts +2 -0
- package/src/modes/utils/hotkeys-markdown.ts +5 -2
- package/src/modes/utils/ui-helpers.ts +76 -3
- package/src/notifications/index.ts +20 -1
- package/src/notifications/lifecycle-control-runtime.ts +12 -3
- package/src/notifications/telegram-daemon.ts +4 -4
- package/src/prompts/agents/architect.md +7 -4
- package/src/prompts/agents/critic.md +15 -6
- package/src/prompts/agents/planner.md +8 -3
- package/src/prompts/system/system-prompt.md +15 -1
- package/src/prompts/tools/bash.md +1 -1
- package/src/runtime-mcp/config-writer.ts +28 -0
- package/src/runtime-mcp/config.ts +7 -0
- package/src/runtime-mcp/loader.ts +3 -0
- package/src/runtime-mcp/manager.ts +3 -0
- package/src/runtime-mcp/types.ts +6 -0
- package/src/sdk.ts +7 -6
- package/src/session/agent-session.ts +81 -18
- package/src/session/session-manager.ts +58 -18
- package/src/slash-commands/builtin-registry.ts +30 -10
- package/src/slash-commands/types.ts +2 -0
- package/src/system-prompt.ts +8 -0
- package/src/task/executor.ts +5 -0
- package/src/tools/ast-grep.ts +10 -7
- package/src/tools/bash.ts +39 -14
- package/src/tools/index.ts +8 -1
- package/src/utils/cmux-workspace.ts +134 -7
- package/src/utils/title-generator.ts +1 -1
- package/src/web/kagi.ts +1 -1
- package/src/web/parallel.ts +2 -2
- package/src/web/search/index.ts +118 -45
- package/src/web/search/provider.ts +65 -0
- package/src/web/search/providers/anthropic.ts +1 -1
- package/src/web/search/providers/brave.ts +1 -1
- package/src/web/search/providers/codex.ts +1 -1
- package/src/web/search/providers/duckduckgo.ts +1 -1
- package/src/web/search/providers/exa.ts +1 -1
- package/src/web/search/providers/gemini.ts +7 -3
- package/src/web/search/providers/jina.ts +1 -1
- package/src/web/search/providers/kimi.ts +6 -1
- package/src/web/search/providers/openai-compatible.ts +1 -1
- package/src/web/search/providers/parallel.ts +1 -1
- package/src/web/search/providers/perplexity.ts +2 -2
- package/src/web/search/providers/searxng.ts +1 -1
- package/src/web/search/providers/synthetic.ts +1 -1
- package/src/web/search/providers/tavily.ts +1 -1
- package/src/web/search/providers/utils.ts +67 -17
- package/src/web/search/providers/xai.ts +1 -1
- package/src/web/search/providers/zai.ts +1 -1
- package/src/workflow/workflow-intent-diff.ts +199 -0
- package/dist/types/discovery/vscode.d.ts +0 -1
- package/src/discovery/vscode.ts +0 -105
|
@@ -159,7 +159,7 @@ export interface AgentSessionConfig {
|
|
|
159
159
|
agent: Agent;
|
|
160
160
|
sessionManager: SessionManager;
|
|
161
161
|
settings: Settings;
|
|
162
|
-
/** Models to cycle through with
|
|
162
|
+
/** Models to cycle through with Alt+N (from --models flag) */
|
|
163
163
|
scopedModels?: ScopedModelSelection[];
|
|
164
164
|
/** Initial session thinking selector. */
|
|
165
165
|
thinkingLevel?: ThinkingLevel;
|
|
@@ -671,7 +671,7 @@ export declare class AgentSession {
|
|
|
671
671
|
followUp: readonly string[];
|
|
672
672
|
};
|
|
673
673
|
/**
|
|
674
|
-
* Pop the
|
|
674
|
+
* Pop the newest queued message across steering and follow-up queues.
|
|
675
675
|
* Used by dequeue keybinding to restore messages to editor one at a time.
|
|
676
676
|
* Returns the popped entry's `.text`; the tag (if any) dies with the
|
|
677
677
|
* record — no orphan state can outlive the queue entry.
|
|
@@ -905,9 +905,12 @@ export declare class AgentSession {
|
|
|
905
905
|
*/
|
|
906
906
|
setAutoRetryEnabled(enabled: boolean): void;
|
|
907
907
|
/**
|
|
908
|
-
* Manually retry the last failed assistant turn
|
|
909
|
-
*
|
|
910
|
-
*
|
|
908
|
+
* Manually retry the last failed assistant turn, or resume an interrupted tail
|
|
909
|
+
* left by a non-graceful process exit after the user/custom/tool-result message
|
|
910
|
+
* was persisted but before the agent emitted a terminal assistant response.
|
|
911
|
+
* Removes failed/aborted/unresolved tool-use assistant tails before
|
|
912
|
+
* re-attempting with a fresh retry budget.
|
|
913
|
+
* @returns true if retry/resume was initiated, false if no retryable tail exists or agent is busy
|
|
911
914
|
*/
|
|
912
915
|
retry(): Promise<boolean>;
|
|
913
916
|
/**
|
|
@@ -17,6 +17,8 @@ export interface BuiltinSlashCommand {
|
|
|
17
17
|
subcommands?: SubcommandDef[];
|
|
18
18
|
/** Static inline hint when command takes a simple argument (no subcommands). */
|
|
19
19
|
inlineHint?: string;
|
|
20
|
+
/** Higher values sort earlier in TUI slash-command autocomplete. */
|
|
21
|
+
priority?: number;
|
|
20
22
|
}
|
|
21
23
|
/** Parsed slash-command text after stripping the leading "/". */
|
|
22
24
|
export interface ParsedSlashCommand {
|
|
@@ -76,6 +76,13 @@ export interface BuildSystemPromptOptions {
|
|
|
76
76
|
mcpDiscoveryMode?: boolean;
|
|
77
77
|
/** Discoverable MCP server summaries to advertise when discovery mode is active. */
|
|
78
78
|
mcpDiscoveryServerSummaries?: string[];
|
|
79
|
+
/** Whether built-in tool discovery ("all" mode) is active; enables the tool-discovery prompt block. */
|
|
80
|
+
toolDiscoveryActive?: boolean;
|
|
81
|
+
/** Hidden discoverable tools to advertise (name + one-line summary) when tool discovery is active. */
|
|
82
|
+
discoverableTools?: Array<{
|
|
83
|
+
name: string;
|
|
84
|
+
summary: string;
|
|
85
|
+
}>;
|
|
79
86
|
/** Encourage the agent to delegate via tasks unless changes are trivial. */
|
|
80
87
|
eagerTasks?: boolean;
|
|
81
88
|
/** Rules with alwaysApply=true — their full content is injected into the prompt. */
|
|
@@ -2,6 +2,13 @@ export interface CmuxWorkspaceRenameCommand {
|
|
|
2
2
|
command: string;
|
|
3
3
|
args: string[];
|
|
4
4
|
}
|
|
5
|
+
/** Current ownership state of a cmux workspace, read back from `cmux workspace list`. */
|
|
6
|
+
export interface CmuxWorkspaceOwnership {
|
|
7
|
+
/** cmux marks a workspace `has_custom_title` once an explicit title is set (by the user or by GJC). */
|
|
8
|
+
hasCustomTitle: boolean;
|
|
9
|
+
/** The workspace's current display title. */
|
|
10
|
+
title: string;
|
|
11
|
+
}
|
|
5
12
|
export interface CmuxWorkspaceRenameProcess {
|
|
6
13
|
exited: Promise<number>;
|
|
7
14
|
kill(): void;
|
|
@@ -17,7 +24,29 @@ export interface CmuxWorkspaceTitleSyncOptions {
|
|
|
17
24
|
stdout: "ignore";
|
|
18
25
|
stderr: "ignore";
|
|
19
26
|
}) => CmuxWorkspaceRenameProcess;
|
|
27
|
+
/** Reads the current ownership state of `workspaceId`. Injectable for tests. */
|
|
28
|
+
readOwnership?: (cmuxCommand: string, workspaceId: string, env: NodeJS.ProcessEnv) => Promise<CmuxWorkspaceOwnership | null>;
|
|
20
29
|
}
|
|
21
30
|
export declare function sanitizeCmuxWorkspaceTitle(title: string | undefined): string | undefined;
|
|
31
|
+
export declare function formatCmuxWorkspaceTitle(title: string | undefined): string | undefined;
|
|
22
32
|
export declare function buildCmuxWorkspaceRenameCommand(sessionName: string | undefined, env?: NodeJS.ProcessEnv): CmuxWorkspaceRenameCommand | null;
|
|
23
|
-
|
|
33
|
+
/** Parse `cmux workspace list --json --id-format both` output and return the
|
|
34
|
+
* ownership state of the workspace matching `workspaceId` (by UUID `id` or `ref`). */
|
|
35
|
+
export declare function parseCmuxWorkspaceOwnership(jsonText: string, workspaceId: string): CmuxWorkspaceOwnership | null;
|
|
36
|
+
/** Only rename when GJC owns the name:
|
|
37
|
+
* - unknown ownership (read failed) → skip (fail safe, never clobber)
|
|
38
|
+
* - already the desired title → skip (no-op)
|
|
39
|
+
* - workspace still on its default title → rename
|
|
40
|
+
* - any custom title (user- or peer-set) → skip
|
|
41
|
+
* This makes GJC name a fresh workspace once and then leave it alone, so it
|
|
42
|
+
* never overwrites a user-pinned name and multiple sessions sharing one
|
|
43
|
+
* CMUX_WORKSPACE_ID do not thrash the workspace title. */
|
|
44
|
+
export declare function shouldRenameCmuxWorkspace(ownership: CmuxWorkspaceOwnership | null, desiredTitle: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Best-effort sync of the containing cmux workspace title to the current GJC
|
|
47
|
+
* session name. Ownership-guarded: GJC reads the current workspace title and
|
|
48
|
+
* only renames a workspace that still has its default title, so it never
|
|
49
|
+
* overwrites a name the user pinned or a name a peer session (sharing the same
|
|
50
|
+
* CMUX_WORKSPACE_ID) set. Opt out with GJC_NO_CMUX_RENAME.
|
|
51
|
+
*/
|
|
52
|
+
export declare function syncCmuxWorkspaceTitle(sessionName: string | undefined, options?: CmuxWorkspaceTitleSyncOptions): Promise<void>;
|
|
@@ -44,6 +44,8 @@ export type SearchToolParams = z.infer<typeof webSearchSchema>;
|
|
|
44
44
|
export interface SearchQueryParams extends SearchToolParams {
|
|
45
45
|
provider?: SearchProviderId | "auto";
|
|
46
46
|
}
|
|
47
|
+
/** Override the hedge delay (tests). Non-finite/non-positive resets to default. */
|
|
48
|
+
export declare function setDdgHedgeDelayMs(ms: number | undefined): void;
|
|
47
49
|
/**
|
|
48
50
|
* Execute a web search query for CLI/testing workflows.
|
|
49
51
|
*
|
|
@@ -111,6 +113,6 @@ export declare class WebSearchTool implements AgentTool<typeof webSearchSchema,
|
|
|
111
113
|
export declare const webSearchCustomTool: CustomTool<typeof webSearchSchema, SearchRenderDetails>;
|
|
112
114
|
export declare function getSearchTools(): CustomTool<any, any>[];
|
|
113
115
|
export { getConfiguredSearchProviderPreference, getSearchProvider, setPreferredSearchProvider, setSearchFallbackProviders, } from "./provider";
|
|
114
|
-
export { setSearchHardTimeoutMs } from "./providers/utils";
|
|
116
|
+
export { applyConfiguredSearchTimeout, setSearchHardTimeoutMs } from "./providers/utils";
|
|
115
117
|
export type { SearchProviderId as SearchProvider, SearchResponse } from "./types";
|
|
116
118
|
export { isConfigurableSearchProviderId, isSearchProviderPreference } from "./types";
|
|
@@ -6,8 +6,17 @@ export { SearchProvider } from "./providers/base";
|
|
|
6
6
|
export declare function getSearchProviderLabel(id: SearchProviderId): string;
|
|
7
7
|
export declare function getSearchProvider(id: SearchProviderId): Promise<SearchProvider>;
|
|
8
8
|
export declare const SEARCH_PROVIDER_ORDER: SearchProviderId[];
|
|
9
|
+
/** Drop every cached resolved chain (settings changed, tests). */
|
|
10
|
+
export declare function clearResolvedChainCache(): void;
|
|
9
11
|
export declare function setPreferredSearchProvider(provider: SearchProviderId | "auto"): void;
|
|
10
12
|
export declare function setSearchFallbackProviders(ids: readonly string[]): void;
|
|
13
|
+
/**
|
|
14
|
+
* Fire-and-forget warm-up: resolve the provider chain once so the provider
|
|
15
|
+
* modules are imported and the chain cache is primed before the first
|
|
16
|
+
* user-visible search. Errors are intentionally swallowed — prewarming must
|
|
17
|
+
* never surface a failure the real search path would handle itself.
|
|
18
|
+
*/
|
|
19
|
+
export declare function prewarmSearchProviders(options: ResolveProviderChainOptions): void;
|
|
11
20
|
export interface SearchProviderPreferenceSource {
|
|
12
21
|
get(path: "providers.webSearch" | "web_search.provider"): SearchProviderId | "auto";
|
|
13
22
|
has(path: "providers.webSearch" | "web_search.provider"): boolean;
|
|
@@ -15,27 +15,53 @@ import { SearchProviderError, type SearchProviderId, type SearchSource } from ".
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function findCredential(storage: AgentStorage | null | undefined, envKey: string | null | undefined, ...storageProviders: string[]): string | null;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* Pure search APIs (brave, exa, jina, tavily, searxng, synthetic, zai)
|
|
24
|
-
* settle far faster in practice; reusing the same ceiling keeps the wiring
|
|
25
|
-
* uniform without compromising correctness.
|
|
18
|
+
* Legacy hard ceiling for a single web-search round-trip, retained as the
|
|
19
|
+
* fallback for call sites that do not declare a timeout class. 300s tolerates
|
|
20
|
+
* pathological cases while still guaranteeing the session unfreezes if Bun's
|
|
21
|
+
* `AbortSignal` fails to propagate on Windows.
|
|
26
22
|
*/
|
|
27
23
|
export declare const SEARCH_HARD_TIMEOUT_MS = 300000;
|
|
24
|
+
/**
|
|
25
|
+
* Hard ceiling for pure search APIs (brave, exa, jina, tavily, kagi,
|
|
26
|
+
* parallel, searxng, synthetic, zai, duckduckgo). These settle in ~1-3s in
|
|
27
|
+
* practice; a hung TCP/TLS connection should fall through to the next
|
|
28
|
+
* provider in seconds, not minutes. Kimi is the exception: it declares an
|
|
29
|
+
* explicit ceiling aligned with its upstream 30s request budget.
|
|
30
|
+
*/
|
|
31
|
+
export declare const SEARCH_API_TIMEOUT_MS = 15000;
|
|
32
|
+
/**
|
|
33
|
+
* Hard ceiling for LLM-mediated search providers (anthropic, codex, gemini,
|
|
34
|
+
* perplexity, xai, openai-compatible). These legitimately take tens of
|
|
35
|
+
* seconds because a model performs the search and synthesizes an answer.
|
|
36
|
+
*/
|
|
37
|
+
export declare const SEARCH_LLM_TIMEOUT_MS = 120000;
|
|
38
|
+
/** Timeout class a provider declares for its outbound round-trips. */
|
|
39
|
+
export type SearchTimeoutClass = "api" | "llm";
|
|
28
40
|
/**
|
|
29
41
|
* Override the hard timeout applied to every web-search round-trip.
|
|
30
42
|
*
|
|
31
43
|
* @param ms - Hard timeout in milliseconds. Non-finite or non-positive
|
|
32
|
-
* values
|
|
44
|
+
* values clear the override so per-class defaults apply.
|
|
33
45
|
*/
|
|
34
46
|
export declare function setSearchHardTimeoutMs(ms: number | undefined): void;
|
|
47
|
+
/** Structural settings source for {@link applyConfiguredSearchTimeout}. */
|
|
48
|
+
export interface SearchTimeoutSettingSource {
|
|
49
|
+
get(path: "web_search.timeout"): unknown;
|
|
50
|
+
has(path: "web_search.timeout"): boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Install the `web_search.timeout` override from settings — but only when the
|
|
54
|
+
* user explicitly configured it. The settings schema ships a default value
|
|
55
|
+
* (300), and consuming that default via `get()` alone would reinstall a
|
|
56
|
+
* uniform 300s ceiling on every session, silently disabling the per-class
|
|
57
|
+
* timeout defaults. `has()` distinguishes loaded/overridden settings from
|
|
58
|
+
* schema defaults; unset clears any previous override so class defaults apply.
|
|
59
|
+
*/
|
|
60
|
+
export declare function applyConfiguredSearchTimeout(settings: SearchTimeoutSettingSource): void;
|
|
35
61
|
/**
|
|
36
62
|
* Compose a caller-supplied {@link AbortSignal} with a hard timeout so an
|
|
37
|
-
* outbound `fetch()` is guaranteed to settle
|
|
38
|
-
*
|
|
63
|
+
* outbound `fetch()` is guaranteed to settle even when the runtime fails to
|
|
64
|
+
* propagate cancellation to the underlying transport.
|
|
39
65
|
*
|
|
40
66
|
* Bun's WinHTTP backend on Windows is known to ignore `AbortSignal` once a
|
|
41
67
|
* TCP/TLS connection stalls (oven-sh/bun#15275, oven-sh/bun#18536); without
|
|
@@ -43,9 +69,12 @@ export declare function setSearchHardTimeoutMs(ms: number | undefined): void;
|
|
|
43
69
|
* because the user's Esc is never delivered to the native layer.
|
|
44
70
|
*
|
|
45
71
|
* @param signal - Caller cancellation signal, if any.
|
|
46
|
-
* @param
|
|
72
|
+
* @param msOrClass - Explicit timeout in milliseconds, or a
|
|
73
|
+
* {@link SearchTimeoutClass} resolved to its class default. Omitted falls
|
|
74
|
+
* back to the legacy {@link SEARCH_HARD_TIMEOUT_MS} ceiling. A user-set
|
|
75
|
+
* `web_search.timeout` overrides class defaults (but not explicit ms).
|
|
47
76
|
*/
|
|
48
|
-
export declare function withHardTimeout(signal: AbortSignal | undefined,
|
|
77
|
+
export declare function withHardTimeout(signal: AbortSignal | undefined, msOrClass?: number | SearchTimeoutClass): AbortSignal;
|
|
49
78
|
/**
|
|
50
79
|
* Map a provider's raw source list to the unified SearchSource shape,
|
|
51
80
|
* clamped to the requested result count and annotated with ageSeconds.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const WORKFLOW_INTENT_DIFF_CUSTOM_TYPE = "workflow-intent-diff";
|
|
2
|
+
export type WorkflowIntentRoute = "direct" | "deep-interview" | "ralplan" | "ultragoal" | "team";
|
|
3
|
+
export type DirectTrackingMode = "custom-entry-only" | "not-direct";
|
|
4
|
+
export type RootCausePhaseStatus = "active" | "inactive";
|
|
5
|
+
export interface WorkflowIntentDiff {
|
|
6
|
+
readonly version: 1;
|
|
7
|
+
readonly route: WorkflowIntentRoute;
|
|
8
|
+
readonly reason: string;
|
|
9
|
+
readonly directTracking: DirectTrackingMode;
|
|
10
|
+
readonly recommendedSkill?: Exclude<WorkflowIntentRoute, "direct">;
|
|
11
|
+
readonly recommendedInvocation?: string;
|
|
12
|
+
readonly triggers: readonly string[];
|
|
13
|
+
readonly rootCausePhase: {
|
|
14
|
+
readonly status: RootCausePhaseStatus;
|
|
15
|
+
readonly triggers: readonly string[];
|
|
16
|
+
};
|
|
17
|
+
readonly promptPreview: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function buildWorkflowIntentDiff(text: string): WorkflowIntentDiff | null;
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/coding-agent",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"description": "Gajae Code CLI with read, bash, edit, write tools and session management",
|
|
6
|
-
"homepage": "https://
|
|
6
|
+
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo",
|
|
8
8
|
"contributors": [
|
|
9
9
|
"Mario Zechner"
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
|
-
"url": "git+https://github.com/
|
|
14
|
+
"url": "git+https://github.com/Yeachan-Heo/gajae-code.git",
|
|
15
15
|
"directory": "packages/coding-agent"
|
|
16
16
|
},
|
|
17
17
|
"bugs": {
|
|
18
|
-
"url": "https://github.com/
|
|
18
|
+
"url": "https://github.com/Yeachan-Heo/gajae-code/issues"
|
|
19
19
|
},
|
|
20
20
|
"keywords": [
|
|
21
21
|
"coding-agent",
|
|
@@ -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
|
-
"@gajae-code/stats": "0.
|
|
56
|
-
"@gajae-code/agent-core": "0.
|
|
57
|
-
"@gajae-code/ai": "0.
|
|
58
|
-
"@gajae-code/natives": "0.
|
|
59
|
-
"@gajae-code/tui": "0.
|
|
60
|
-
"@gajae-code/utils": "0.
|
|
55
|
+
"@gajae-code/stats": "0.8.0",
|
|
56
|
+
"@gajae-code/agent-core": "0.8.0",
|
|
57
|
+
"@gajae-code/ai": "0.8.0",
|
|
58
|
+
"@gajae-code/natives": "0.8.0",
|
|
59
|
+
"@gajae-code/tui": "0.8.0",
|
|
60
|
+
"@gajae-code/utils": "0.8.0",
|
|
61
61
|
"@puppeteer/browsers": "^2.13.0",
|
|
62
62
|
"@types/turndown": "5.0.6",
|
|
63
63
|
"@xterm/headless": "^6.0.0",
|
package/src/capability/mcp.ts
CHANGED
|
@@ -15,6 +15,8 @@ export interface MCPServer {
|
|
|
15
15
|
name: string;
|
|
16
16
|
/** Whether this server is enabled (default: true) */
|
|
17
17
|
enabled?: boolean;
|
|
18
|
+
/** Whether to connect automatically at session startup (default: true) */
|
|
19
|
+
autoload?: boolean;
|
|
18
20
|
/** Connection timeout in milliseconds */
|
|
19
21
|
timeout?: number;
|
|
20
22
|
/** Command to run (for stdio transport) */
|
package/src/cli/update-cli.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { pipeline } from "node:stream/promises";
|
|
|
10
10
|
import { $which, APP_NAME, isEnoent, VERSION } from "@gajae-code/utils";
|
|
11
11
|
import { $ } from "bun";
|
|
12
12
|
import chalk from "chalk";
|
|
13
|
+
import { installDefaultGjcDefinitions } from "../defaults/gjc-defaults";
|
|
13
14
|
import { theme } from "../modes/theme/theme";
|
|
14
15
|
|
|
15
16
|
const RELEASE_REPO = "Yeachan-Heo/gajae-code";
|
|
@@ -628,6 +629,29 @@ export async function runUpdateCommand(opts: { force: boolean; check: boolean })
|
|
|
628
629
|
console.error(chalk.red(`Update failed: ${err}`));
|
|
629
630
|
process.exit(1);
|
|
630
631
|
}
|
|
632
|
+
|
|
633
|
+
await refreshInstalledDefaultSkills();
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Refresh opted-in on-disk default workflow skill copies after a successful
|
|
638
|
+
* update. The four default skills ship embedded in the binary, so most users
|
|
639
|
+
* need nothing here. But users who ran `gjc setup defaults` have on-disk copies
|
|
640
|
+
* under the agent dir that shadow the embedded defaults; those would otherwise
|
|
641
|
+
* go stale after an update. Only rewrite files that already exist and differ —
|
|
642
|
+
* never materialize new copies for users who never opted in.
|
|
643
|
+
*/
|
|
644
|
+
async function refreshInstalledDefaultSkills(): Promise<void> {
|
|
645
|
+
try {
|
|
646
|
+
const result = await installDefaultGjcDefinitions({ refreshOnly: true });
|
|
647
|
+
if (result.written > 0) {
|
|
648
|
+
console.log(
|
|
649
|
+
chalk.dim(`Refreshed ${result.written} local default workflow skill file(s) at ${result.targetRoot}`),
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
} catch (err) {
|
|
653
|
+
console.error(chalk.yellow(`Warning: failed to refresh local default workflow skills: ${err}`));
|
|
654
|
+
}
|
|
631
655
|
}
|
|
632
656
|
|
|
633
657
|
/**
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
type SearchQueryParams,
|
|
17
17
|
} from "../web/search/index";
|
|
18
18
|
import { SEARCH_PROVIDER_ORDER, setPreferredSearchProvider, setSearchFallbackProviders } from "../web/search/provider";
|
|
19
|
-
import {
|
|
19
|
+
import { applyConfiguredSearchTimeout } from "../web/search/providers/utils";
|
|
20
20
|
import { renderSearchResult } from "../web/search/render";
|
|
21
21
|
import type { SearchProviderId } from "../web/search/types";
|
|
22
22
|
|
|
@@ -181,10 +181,7 @@ export async function runSearchCommand(cmd: SearchCommandArgs): Promise<void> {
|
|
|
181
181
|
configuredFallback.filter(value => typeof value === "string" && isConfigurableSearchProviderId(value)),
|
|
182
182
|
);
|
|
183
183
|
}
|
|
184
|
-
|
|
185
|
-
if (typeof configuredTimeout === "number" && Number.isFinite(configuredTimeout) && configuredTimeout > 0) {
|
|
186
|
-
setSearchHardTimeoutMs(configuredTimeout * 1000);
|
|
187
|
-
}
|
|
184
|
+
applyConfiguredSearchTimeout(settings);
|
|
188
185
|
|
|
189
186
|
const params: SearchQueryParams = {
|
|
190
187
|
query: cmd.query,
|
package/src/cli.ts
CHANGED
|
@@ -141,7 +141,7 @@ class RootHelpCommand extends Command {
|
|
|
141
141
|
resume: Flags.string({ char: "r", description: "Resume a session (by ID prefix, path, or picker if omitted)" }),
|
|
142
142
|
"session-dir": Flags.string({ description: "Directory for session storage and lookup" }),
|
|
143
143
|
"no-session": Flags.boolean({ description: "Don't save session (ephemeral)" }),
|
|
144
|
-
models: Flags.string({ description: "Comma-separated model patterns for
|
|
144
|
+
models: Flags.string({ description: "Comma-separated model patterns for Alt+N cycling" }),
|
|
145
145
|
"no-tools": Flags.boolean({ description: "Disable all built-in tools" }),
|
|
146
146
|
"no-lsp": Flags.boolean({ description: "Disable LSP tools, formatting, and diagnostics" }),
|
|
147
147
|
"no-pty": Flags.boolean({ description: "Disable PTY-based interactive bash execution" }),
|
package/src/commands/launch.ts
CHANGED
|
@@ -119,7 +119,7 @@ export default class Index extends Command {
|
|
|
119
119
|
description: "Don't save session (ephemeral)",
|
|
120
120
|
}),
|
|
121
121
|
models: Flags.string({
|
|
122
|
-
description: "Comma-separated model patterns for
|
|
122
|
+
description: "Comma-separated model patterns for Alt+N cycling",
|
|
123
123
|
}),
|
|
124
124
|
"no-tools": Flags.boolean({
|
|
125
125
|
description: "Disable all built-in tools",
|
package/src/commands/ralplan.ts
CHANGED
|
@@ -8,6 +8,7 @@ export default class Ralplan extends Command {
|
|
|
8
8
|
'$ gjc ralplan "<task description>"',
|
|
9
9
|
'$ gjc ralplan --interactive --deliberate "<task description>"',
|
|
10
10
|
'$ gjc ralplan --write --stage planner --stage_n 1 --artifact "<markdown or path>"',
|
|
11
|
+
"$ gjc ralplan --write --stage critic --stage_n 1 --artifact-env GJC_RALPLAN_ARTIFACT",
|
|
11
12
|
];
|
|
12
13
|
|
|
13
14
|
async run(): Promise<void> {
|
|
@@ -22,6 +22,7 @@ interface AppKeybindings {
|
|
|
22
22
|
"app.suspend": true;
|
|
23
23
|
"app.thinking.cycle": true;
|
|
24
24
|
"app.thinking.toggle": true;
|
|
25
|
+
"app.commandPalette.open": true;
|
|
25
26
|
"app.model.cycleForward": true;
|
|
26
27
|
"app.model.cycleBackward": true;
|
|
27
28
|
"app.model.select": true;
|
|
@@ -59,6 +60,10 @@ declare module "@gajae-code/tui" {
|
|
|
59
60
|
interface Keybindings extends AppKeybindings {}
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
export function defaultMessageQueueKeysForPlatform(platform: NodeJS.Platform = process.platform): KeyId {
|
|
64
|
+
return platform === "win32" ? "alt+q" : "alt+enter";
|
|
65
|
+
}
|
|
66
|
+
|
|
62
67
|
/**
|
|
63
68
|
* All keybindings definitions: TUI + app-specific.
|
|
64
69
|
*/
|
|
@@ -88,12 +93,16 @@ export const KEYBINDINGS = {
|
|
|
88
93
|
defaultKeys: "ctrl+t",
|
|
89
94
|
description: "Toggle thinking mode",
|
|
90
95
|
},
|
|
91
|
-
"app.
|
|
96
|
+
"app.commandPalette.open": {
|
|
92
97
|
defaultKeys: "ctrl+p",
|
|
98
|
+
description: "Open command palette",
|
|
99
|
+
},
|
|
100
|
+
"app.model.cycleForward": {
|
|
101
|
+
defaultKeys: "alt+n",
|
|
93
102
|
description: "Cycle to next model",
|
|
94
103
|
},
|
|
95
104
|
"app.model.cycleBackward": {
|
|
96
|
-
defaultKeys: "shift+
|
|
105
|
+
defaultKeys: "alt+shift+n",
|
|
97
106
|
description: "Cycle to previous model",
|
|
98
107
|
},
|
|
99
108
|
"app.model.select": {
|
|
@@ -121,7 +130,7 @@ export const KEYBINDINGS = {
|
|
|
121
130
|
description: "Send follow-up message (no default; Ctrl+Enter submits)",
|
|
122
131
|
},
|
|
123
132
|
"app.message.queue": {
|
|
124
|
-
defaultKeys:
|
|
133
|
+
defaultKeys: defaultMessageQueueKeysForPlatform(),
|
|
125
134
|
description: "Queue message for next turn",
|
|
126
135
|
},
|
|
127
136
|
"app.message.dequeue": {
|
|
@@ -141,8 +150,8 @@ export const KEYBINDINGS = {
|
|
|
141
150
|
description: "Copy prompt",
|
|
142
151
|
},
|
|
143
152
|
"app.session.new": {
|
|
144
|
-
defaultKeys:
|
|
145
|
-
description: "
|
|
153
|
+
defaultKeys: "ctrl+n",
|
|
154
|
+
description: "Start a new session",
|
|
146
155
|
},
|
|
147
156
|
"app.session.tree": {
|
|
148
157
|
defaultKeys: [],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://raw.githubusercontent.com/
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/Yeachan-Heo/gajae-code/main/packages/coding-agent/src/config/mcp-schema.json",
|
|
4
4
|
"title": "GJC MCP configuration",
|
|
5
5
|
"description": "Schema for mcp.json, .mcp.json, .gjc/mcp.json, and ~/.gjc/agent/mcp.json used by the GJC coding agent.",
|
|
6
6
|
"type": "object",
|
|
@@ -96,6 +96,10 @@
|
|
|
96
96
|
"type": "boolean",
|
|
97
97
|
"description": "Whether GJC should try to connect this server."
|
|
98
98
|
},
|
|
99
|
+
"autoload": {
|
|
100
|
+
"type": "boolean",
|
|
101
|
+
"description": "Whether to connect this server automatically at session startup (default: true). When false the server stays configured until connected explicitly (e.g. /mcp connect <name>)."
|
|
102
|
+
},
|
|
99
103
|
"timeout": {
|
|
100
104
|
"type": "number",
|
|
101
105
|
"exclusiveMinimum": 0,
|
|
@@ -104,6 +104,13 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
104
104
|
critic: "anthropic/claude-opus-4-8:high",
|
|
105
105
|
architect: "anthropic/claude-opus-4-8:xhigh",
|
|
106
106
|
}),
|
|
107
|
+
profile("claude-fable", ["anthropic"], {
|
|
108
|
+
default: "anthropic/claude-fable-5:xhigh",
|
|
109
|
+
executor: "anthropic/claude-sonnet-5",
|
|
110
|
+
planner: "anthropic/claude-fable-5:low",
|
|
111
|
+
critic: "anthropic/claude-fable-5:high",
|
|
112
|
+
architect: "anthropic/claude-fable-5:xhigh",
|
|
113
|
+
}),
|
|
107
114
|
profile("glm-eco", ["zai"], {
|
|
108
115
|
default: "zai/glm-5.2:low",
|
|
109
116
|
executor: "zai/glm-5.2:minimal",
|
|
@@ -261,6 +268,13 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
261
268
|
critic: "opencode-go/mimo-v2.5-pro",
|
|
262
269
|
architect: "openai-codex/gpt-5.5:xhigh",
|
|
263
270
|
}),
|
|
271
|
+
profile("fable-opus-codex", ["anthropic", "openai-codex"], {
|
|
272
|
+
default: "anthropic/claude-fable-5:high",
|
|
273
|
+
executor: "openai-codex/gpt-5.5:high",
|
|
274
|
+
planner: "anthropic/claude-opus-4-8:medium",
|
|
275
|
+
critic: "anthropic/claude-opus-4-8:high",
|
|
276
|
+
architect: "openai-codex/gpt-5.5:xhigh",
|
|
277
|
+
}),
|
|
264
278
|
];
|
|
265
279
|
|
|
266
280
|
export interface ModelProfilePresentation {
|
|
@@ -278,6 +292,7 @@ const PROFILE_PRESENTATION: Record<string, ModelProfilePresentation> = {
|
|
|
278
292
|
"codex-pro": { displayName: "Codex Pro", providerGroup: "CODEX" },
|
|
279
293
|
opencodego: { displayName: "OpenCodeGo", providerGroup: "OPENCODEGO" },
|
|
280
294
|
"claude-opus": { displayName: "Claude Opus", providerGroup: "CLAUDE" },
|
|
295
|
+
"claude-fable": { displayName: "Claude Fable", providerGroup: "CLAUDE" },
|
|
281
296
|
"glm-eco": { displayName: "GLM Eco", providerGroup: "GLM" },
|
|
282
297
|
"glm-medium": { displayName: "GLM Medium", providerGroup: "GLM" },
|
|
283
298
|
"glm-pro": { displayName: "GLM Pro", providerGroup: "GLM" },
|
|
@@ -299,6 +314,7 @@ const PROFILE_PRESENTATION: Record<string, ModelProfilePresentation> = {
|
|
|
299
314
|
"minimax-pro": { displayName: "MiniMax Pro", providerGroup: "MINIMAX" },
|
|
300
315
|
"opus-codex": { displayName: "Opus + Codex", providerGroup: "COMBOS" },
|
|
301
316
|
"codex-opencodego": { displayName: "Codex + OpenCodeGo", providerGroup: "COMBOS" },
|
|
317
|
+
"fable-opus-codex": { displayName: "Fable + Opus + Codex", providerGroup: "COMBOS" },
|
|
302
318
|
};
|
|
303
319
|
|
|
304
320
|
const PROFILE_GROUP_ORDER = [
|
|
@@ -507,6 +507,21 @@ export const SETTINGS_SCHEMA = {
|
|
|
507
507
|
description: "Use the session name color for the editor border and status line gap",
|
|
508
508
|
},
|
|
509
509
|
},
|
|
510
|
+
"statusLine.maxRows": {
|
|
511
|
+
type: "number",
|
|
512
|
+
default: 1,
|
|
513
|
+
ui: {
|
|
514
|
+
tab: "appearance",
|
|
515
|
+
label: "Status Line Rows",
|
|
516
|
+
description:
|
|
517
|
+
"Maximum rows for the status line. When greater than 1, overflowing segments wrap onto additional rows instead of being dropped.",
|
|
518
|
+
options: [
|
|
519
|
+
{ value: "1", label: "1 row", description: "Single line; overflow is truncated (default)" },
|
|
520
|
+
{ value: "2", label: "2 rows", description: "Wrap overflow onto a second row" },
|
|
521
|
+
{ value: "3", label: "3 rows", description: "Wrap overflow across up to three rows" },
|
|
522
|
+
],
|
|
523
|
+
},
|
|
524
|
+
},
|
|
510
525
|
"tools.artifactSpillThreshold": {
|
|
511
526
|
type: "number",
|
|
512
527
|
default: 50,
|
|
@@ -2478,7 +2493,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
2478
2493
|
"tools.discoveryMode": {
|
|
2479
2494
|
type: "enum",
|
|
2480
2495
|
values: ["off", "all"] as const,
|
|
2481
|
-
default: "
|
|
2496
|
+
default: "all",
|
|
2482
2497
|
ui: {
|
|
2483
2498
|
tab: "tools",
|
|
2484
2499
|
label: "Tool Discovery",
|
|
@@ -2493,7 +2508,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
2493
2508
|
tab: "tools",
|
|
2494
2509
|
label: "Essential Tools Override",
|
|
2495
2510
|
description:
|
|
2496
|
-
"Override the always-loaded built-in tools (default: read, bash, edit). Leave empty to use defaults.",
|
|
2511
|
+
"Override the always-loaded built-in tools (default: read, bash, edit, write, search, find). Leave empty to use defaults.",
|
|
2497
2512
|
},
|
|
2498
2513
|
},
|
|
2499
2514
|
|
|
@@ -3280,6 +3295,7 @@ export interface ExaSettings {
|
|
|
3280
3295
|
export interface StatusLineSettings {
|
|
3281
3296
|
preset: StatusLinePreset;
|
|
3282
3297
|
separator: StatusLineSeparatorStyle;
|
|
3298
|
+
maxRows: number;
|
|
3283
3299
|
showHookStatus: boolean;
|
|
3284
3300
|
showSkillHud: boolean;
|
|
3285
3301
|
leftSegments: StatusLineSegmentId[];
|
|
@@ -1273,9 +1273,21 @@ async function sendTmuxPromptKeys(
|
|
|
1273
1273
|
prompt: string,
|
|
1274
1274
|
runner: CommandRunner = runCommand,
|
|
1275
1275
|
): Promise<boolean> {
|
|
1276
|
-
const
|
|
1277
|
-
|
|
1278
|
-
|
|
1276
|
+
const bufferName = `gjc-coordinator-prompt-${randomUUID()}`;
|
|
1277
|
+
const buffered = await runner(["tmux", "set-buffer", "-b", bufferName, "--", prompt]);
|
|
1278
|
+
if (buffered.exitCode !== 0) return false;
|
|
1279
|
+
const pasted = await runner(["tmux", "paste-buffer", "-d", "-b", bufferName, "-t", target]);
|
|
1280
|
+
if (pasted.exitCode !== 0) {
|
|
1281
|
+
await runner(["tmux", "delete-buffer", "-b", bufferName]);
|
|
1282
|
+
return false;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
// Multiline slash-command prompts can leave the editor autocomplete menu focused
|
|
1286
|
+
// after paste. Escape clears that UI-only state so Enter submits the buffered
|
|
1287
|
+
// prompt instead of selecting the highlighted completion.
|
|
1288
|
+
const dismissedAutocomplete = await runner(["tmux", "send-keys", "-t", target, "Escape"]);
|
|
1289
|
+
if (dismissedAutocomplete.exitCode !== 0) return false;
|
|
1290
|
+
const submitted = await runner(["tmux", "send-keys", "-t", target, "Enter"]);
|
|
1279
1291
|
return submitted.exitCode === 0;
|
|
1280
1292
|
}
|
|
1281
1293
|
|