@gajae-code/coding-agent 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/types/modes/components/gajae-pet-widget.d.ts +1 -0
- package/dist/types/modes/components/pet-capability.d.ts +37 -0
- package/dist/types/modes/components/pet-selector.d.ts +1 -1
- package/dist/types/modes/components/settings-selector.d.ts +9 -0
- package/dist/types/modes/interactive-mode.d.ts +2 -1
- package/dist/types/modes/types.d.ts +11 -1
- package/package.json +7 -7
- package/src/config/model-profiles.ts +19 -19
- package/src/extensibility/slash-commands.ts +3 -3
- package/src/gjc-runtime/tmux-owner-isolation.ts +4 -1
- package/src/internal-urls/docs-index.generated.ts +3 -3
- package/src/modes/components/custom-editor.ts +1 -0
- package/src/modes/components/gajae-pet-widget.ts +169 -20
- package/src/modes/components/pet-capability.ts +115 -0
- package/src/modes/components/pet-selector.ts +4 -6
- package/src/modes/components/settings-selector.ts +28 -2
- package/src/modes/controllers/extension-ui-controller.ts +9 -8
- package/src/modes/controllers/input-controller.ts +43 -13
- package/src/modes/controllers/selector-controller.ts +7 -18
- package/src/modes/interactive-mode.ts +49 -4
- package/src/modes/types.ts +11 -1
- package/src/session/agent-session.ts +52 -7
- package/src/session/session-manager.ts +9 -2
- package/src/slash-commands/builtin-registry.ts +31 -29
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.10.2] - 2026-07-14
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Gajae Pet selection is now terminal-capability aware: unsupported terminals show an actionable warning (with multiplexer-specific guidance for tmux/screen/zellij, including the `PI_FORCE_IMAGE_PROTOCOL=sixel` expert opt-in), `/pet` and Settings disable the unavailable `RedGajae`/`BlueGajae` choices while `off` stays selectable, a saved-but-unavailable choice is identified as `(saved)`, and the public command names are consistent across execution, completion, and inline hints (`/pet RedGajae`, `/pet BlueGajae`, `/pet off`, case-insensitive).
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Documented the current GPT-5.6 Codex and combo profile mappings as product judgments, including the durable `opus-codex` `anthropic/claude-sonnet-5` planner override and `fable-opus-codex` `anthropic/claude-opus-4-8:medium` planner.
|
|
14
|
+
- RPC clients can now durably select the machine-global default model and effective thinking level for subsequent messages, while project policy and resumed session history retain precedence; a late live-apply failure now restores the prior runtime model and thinking level without masking the original error.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Gajae Pet overlays no longer leak images or stale pixels across lifecycle changes: each widget owns a randomized Kitty image ID (deleted on disable, replace, switch, and dispose), the previous Sixel footprint is tracked and erased on movement, resize, and narrow-terminal fallback, replaced pet widgets are disposed before their successors install, and a saved pet preference survives editor replacement while graphics are still unavailable (so a delayed Sixel capability probe can still activate it). Teardown is exception-safe and idempotent: a failed or unavailable terminal write never aborts logical disposal or steals a successor widget's overlay slot, and Sixel/Kitty cleanup authority is retained until the erase is actually delivered so a later mode switch or dispose retries it.
|
|
19
|
+
- Gajae Pet cleanup that fails during final widget disposal is now retained by the TUI for retry, and Kitty image IDs remain reserved until their exact-ID delete is delivered.
|
|
20
|
+
- Fixed `gjc --tmux` startup from GNOME and other VTE terminals by recognizing `vte-spawn-*.scope` only when cgroup metadata proves matching user-manager ancestry (#2159).
|
|
21
|
+
|
|
5
22
|
## [0.10.1] - 2026-07-13
|
|
6
23
|
|
|
7
24
|
### Added
|
|
@@ -12,8 +29,11 @@
|
|
|
12
29
|
### Fixed
|
|
13
30
|
|
|
14
31
|
- IRC deliveries now accept their exchange batch in the recipient's volatile current-session queue before recipient/main UI observations or sender success. Awaited deliveries generate the reply first, then accept the ordered incoming + auto-reply pair and commit the IRC roster claim before observation; provider failures and sender aborts before acceptance leave no ghost exchange, while observer failures after acceptance are isolated. This is not a durability guarantee: durable history injection remains a later flush and no fsync, recovery, persistent IDs, or deduplication was added.
|
|
32
|
+
- `/model` role-agent assignments now replace active model-profile overrides immediately, so changing architect, critic, planner, or executor models and reasoning levels takes effect in the current session and remains persisted afterward.
|
|
15
33
|
- Print mode now records terminal text-mode errors as exit status 1 (or 78 for context overflow) without bypassing output quiescence or session disposal. It retains JSON event delivery through disposal and suppresses `EPIPE` from its owned stdout; `ERR_STREAM_DESTROYED` is suppressed only after that `EPIPE` has latched, while other output failures remain errors.
|
|
16
34
|
- Extension contexts now receive a defensive copy from `getSystemPrompt()` instead of the live mutable system-prompt array, so an in-place mutation by an in-process extension can no longer bypass context-revision tracking and serve stale display-only context-usage estimates.
|
|
35
|
+
- Preserved clipboard image attachments when the interactive editor clears the composer before dispatching the submit callback, so Alt+V image placeholders still send their image blocks instead of placeholder-only text (#2126).
|
|
36
|
+
- Completed bracketed-paste input now returns a manually paged transcript to live output before the paste is dispatched, including asynchronous consumed and unconsumed paste paths.
|
|
17
37
|
|
|
18
38
|
## [0.10.0] - 2026-07-12
|
|
19
39
|
|
|
@@ -53,6 +53,7 @@ export declare class GajaePetWidget {
|
|
|
53
53
|
* eye-roll it fires the signature burst once (RedGajae flex, BlueGajae para-para
|
|
54
54
|
* then sob) so the selector demos the animation instead of waiting the random gap. */
|
|
55
55
|
previewMode(mode: PetMode): void;
|
|
56
|
+
commitPreviewMode(mode: PetMode): void;
|
|
56
57
|
dispose(): void;
|
|
57
58
|
/** Re-mount the composer editor (framed when a skin is active) after an overlay. */
|
|
58
59
|
remountComposer(): void;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type SelectItem } from "@gajae-code/tui";
|
|
2
|
+
export type PetPixelProtocol = "sixel" | "kitty";
|
|
3
|
+
export declare const PET_UNAVAILABLE_DESCRIPTION = "Unavailable: requires compatible Kitty or Sixel overlay rendering";
|
|
4
|
+
export declare const PET_SAVED_UNAVAILABLE_DESCRIPTION = "Saved, unavailable \u2014 requires compatible Kitty or Sixel overlay rendering";
|
|
5
|
+
export declare const PET_UNAVAILABLE_WARNING = "\u26A0 Pets aren\u2019t available in this terminal. Its image support isn\u2019t compatible with Gajae Pet\u2019s overlay rendering yet. Try Kitty, Ghostty, WezTerm, or a terminal with compatible Sixel support.";
|
|
6
|
+
export declare function getPetUnavailableWarning(env?: NodeJS.ProcessEnv): string;
|
|
7
|
+
export declare function getPetPixelProtocol(): PetPixelProtocol | null;
|
|
8
|
+
export declare function isPetAvailable(): boolean;
|
|
9
|
+
export declare function createPetSelectItems(options: ReadonlyArray<SelectItem>, currentValue: string, available: boolean): SelectItem[];
|
|
10
|
+
/**
|
|
11
|
+
* Grace period before declaring the terminal pet-incapable at startup. The
|
|
12
|
+
* asynchronous Sixel capability probe starts inside `TUI.start()` and answers
|
|
13
|
+
* within its own 250 ms deadline; this margin covers probe scheduling so a
|
|
14
|
+
* supported terminal is never told it is incompatible while the probe is
|
|
15
|
+
* still in flight.
|
|
16
|
+
*/
|
|
17
|
+
export declare const PET_CAPABILITY_SETTLE_MS = 1000;
|
|
18
|
+
/**
|
|
19
|
+
* Whether the asynchronous startup Sixel capability probe may still enable
|
|
20
|
+
* graphics for this session, meaning current unavailability is not final.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isPetCapabilityProbePending(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Deliver the pet-unavailable startup warning only once the capability
|
|
25
|
+
* question is settled. With no probe pending, unavailability is final and
|
|
26
|
+
* `onUnavailable` fires immediately. While a probe may still enable
|
|
27
|
+
* graphics, the warning is deferred: a protocol-change event cancels it (the
|
|
28
|
+
* saved pet re-applies through the existing subscription), and only the
|
|
29
|
+
* settle deadline passing with the terminal still unavailable emits it.
|
|
30
|
+
* Returns a disposer that cancels the pending decision.
|
|
31
|
+
*/
|
|
32
|
+
export declare function warnWhenPetCapabilitySettled(options: {
|
|
33
|
+
probePending: boolean;
|
|
34
|
+
isAvailable?: () => boolean;
|
|
35
|
+
onUnavailable: () => void;
|
|
36
|
+
settleMs?: number;
|
|
37
|
+
}): () => void;
|
|
@@ -6,6 +6,6 @@ import type { PetMode } from "./gajae-pet-widget";
|
|
|
6
6
|
*/
|
|
7
7
|
export declare class PetSelectorComponent extends Container {
|
|
8
8
|
#private;
|
|
9
|
-
constructor(current: PetMode, onSelect: (mode: PetMode) => void, onCancel: () => void, onPreview: (mode: PetMode) => void);
|
|
9
|
+
constructor(current: PetMode, onSelect: (mode: PetMode) => void, onCancel: () => void, onPreview: (mode: PetMode) => void, available: boolean);
|
|
10
10
|
getSelectList(): SelectList;
|
|
11
11
|
}
|
|
@@ -20,6 +20,8 @@ export interface SettingsRuntimeContext {
|
|
|
20
20
|
availableModelProfiles: string[];
|
|
21
21
|
/** Working directory for plugins tab */
|
|
22
22
|
cwd: string;
|
|
23
|
+
/** Whether this terminal can render the pet overlay. */
|
|
24
|
+
petAvailable?: boolean;
|
|
23
25
|
}
|
|
24
26
|
/** Status line settings subset for preview */
|
|
25
27
|
export interface StatusLinePreviewSettings {
|
|
@@ -41,6 +43,13 @@ export interface SettingsCallbacks {
|
|
|
41
43
|
onThemePreviewCancel?: (theme: string) => void | Promise<void>;
|
|
42
44
|
/** Called to live-preview the gajae pet skin while browsing the pet setting. */
|
|
43
45
|
onPetPreview?: (mode: string) => void;
|
|
46
|
+
/**
|
|
47
|
+
* Commit a pet mode through the shared result-returning policy. The policy
|
|
48
|
+
* rechecks capability immediately before mutation and owns persistence, so
|
|
49
|
+
* the settings surface never persists `pet.mode` ahead of acceptance.
|
|
50
|
+
* Returns whether the commit was accepted.
|
|
51
|
+
*/
|
|
52
|
+
onPetCommit?: (mode: string) => boolean;
|
|
44
53
|
/** Called for status line preview while configuring */
|
|
45
54
|
onStatusLinePreview?: (settings: StatusLinePreviewSettings) => void;
|
|
46
55
|
/** Get current rendered status line for inline preview */
|
|
@@ -139,8 +139,9 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
139
139
|
updateEditorChrome(): void;
|
|
140
140
|
updateEditorBorderColor(): void;
|
|
141
141
|
updateEditorTopBorder(): void;
|
|
142
|
-
setPetMode(mode: PetMode):
|
|
142
|
+
setPetMode(mode: PetMode): boolean;
|
|
143
143
|
previewPetMode(mode: PetMode): void;
|
|
144
|
+
commitPetPreviewMode(mode: PetMode): boolean;
|
|
144
145
|
restoreComposer(): void;
|
|
145
146
|
rebuildChatFromMessages(policy: TranscriptRebuildPolicy): void;
|
|
146
147
|
/** Apply any deferred model switch after the current stream ends. */
|
|
@@ -153,9 +153,19 @@ export interface InteractiveModeContext {
|
|
|
153
153
|
setWorkingMessage(message?: string): void;
|
|
154
154
|
applyPendingWorkingMessage(): void;
|
|
155
155
|
ensureLoadingAnimation(): void;
|
|
156
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Commit a pet mode through the shared result-returning policy: capability
|
|
158
|
+
* is rechecked immediately before mutation and the preference persists only
|
|
159
|
+
* on acceptance. Returns whether the commit was accepted.
|
|
160
|
+
*/
|
|
161
|
+
setPetMode(mode: PetMode): boolean;
|
|
157
162
|
/** Live-preview a pet skin during a selector without persisting. */
|
|
158
163
|
previewPetMode(mode: PetMode): void;
|
|
164
|
+
/**
|
|
165
|
+
* Commit a settings-overlay pet change without re-mounting the composer.
|
|
166
|
+
* Same shared commit policy and result semantics as `setPetMode`.
|
|
167
|
+
*/
|
|
168
|
+
commitPetPreviewMode(mode: PetMode): boolean;
|
|
159
169
|
/** Re-mount the composer (pet-aware) after an overlay/selector closes. */
|
|
160
170
|
restoreComposer(): void;
|
|
161
171
|
startPendingSubmission(input: {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/coding-agent",
|
|
4
|
-
"version": "0.10.
|
|
4
|
+
"version": "0.10.2",
|
|
5
5
|
"description": "Gajae Code CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo and Gajae Code Contributors",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"@agentclientprotocol/sdk": "1.2.1",
|
|
50
50
|
"@babel/parser": "^7.29.3",
|
|
51
51
|
"@mozilla/readability": "^0.6.0",
|
|
52
|
-
"@gajae-code/stats": "0.10.
|
|
53
|
-
"@gajae-code/agent-core": "0.10.
|
|
54
|
-
"@gajae-code/ai": "0.10.
|
|
55
|
-
"@gajae-code/natives": "0.10.
|
|
56
|
-
"@gajae-code/tui": "0.10.
|
|
57
|
-
"@gajae-code/utils": "0.10.
|
|
52
|
+
"@gajae-code/stats": "0.10.2",
|
|
53
|
+
"@gajae-code/agent-core": "0.10.2",
|
|
54
|
+
"@gajae-code/ai": "0.10.2",
|
|
55
|
+
"@gajae-code/natives": "0.10.2",
|
|
56
|
+
"@gajae-code/tui": "0.10.2",
|
|
57
|
+
"@gajae-code/utils": "0.10.2",
|
|
58
58
|
"@puppeteer/browsers": "^2.13.0",
|
|
59
59
|
"@types/turndown": "5.0.6",
|
|
60
60
|
"@xterm/headless": "^6.0.0",
|
|
@@ -70,25 +70,25 @@ const profile = (
|
|
|
70
70
|
|
|
71
71
|
export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
72
72
|
profile("codex-eco", ["openai-codex"], {
|
|
73
|
-
default: "openai-codex/gpt-5.6-terra:
|
|
74
|
-
executor: "openai-codex/gpt-5.6-luna:
|
|
75
|
-
planner: "openai-codex/gpt-5.6-
|
|
76
|
-
critic: "openai-codex/gpt-5.6-terra:
|
|
77
|
-
architect: "openai-codex/gpt-5.6-
|
|
73
|
+
default: "openai-codex/gpt-5.6-terra:low",
|
|
74
|
+
executor: "openai-codex/gpt-5.6-luna:low",
|
|
75
|
+
planner: "openai-codex/gpt-5.6-luna:high",
|
|
76
|
+
critic: "openai-codex/gpt-5.6-terra:xhigh",
|
|
77
|
+
architect: "openai-codex/gpt-5.6-terra:high",
|
|
78
78
|
}),
|
|
79
79
|
profile("codex-medium", ["openai-codex"], {
|
|
80
|
-
default: "openai-codex/gpt-5.6-sol:
|
|
81
|
-
executor: "openai-codex/gpt-5.6-terra:
|
|
80
|
+
default: "openai-codex/gpt-5.6-sol:low",
|
|
81
|
+
executor: "openai-codex/gpt-5.6-terra:low",
|
|
82
82
|
planner: "openai-codex/gpt-5.6-terra:high",
|
|
83
|
-
critic: "openai-codex/gpt-5.6-
|
|
83
|
+
critic: "openai-codex/gpt-5.6-sol:xhigh",
|
|
84
84
|
architect: "openai-codex/gpt-5.6-sol:high",
|
|
85
85
|
}),
|
|
86
86
|
profile("codex-pro", ["openai-codex"], {
|
|
87
|
-
default: "openai-codex/gpt-5.6-sol:
|
|
88
|
-
executor: "openai-codex/gpt-5.6-terra:
|
|
87
|
+
default: "openai-codex/gpt-5.6-sol:medium",
|
|
88
|
+
executor: "openai-codex/gpt-5.6-terra:medium",
|
|
89
89
|
planner: "openai-codex/gpt-5.6-sol:high",
|
|
90
|
-
critic: "openai-codex/gpt-5.6-sol:
|
|
91
|
-
architect: "openai-codex/gpt-5.6-sol:
|
|
90
|
+
critic: "openai-codex/gpt-5.6-sol:max",
|
|
91
|
+
architect: "openai-codex/gpt-5.6-sol:xhigh",
|
|
92
92
|
}),
|
|
93
93
|
profile("opencodego", ["opencode-go"], {
|
|
94
94
|
default: "opencode-go/kimi-k2.6",
|
|
@@ -256,21 +256,21 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
256
256
|
}),
|
|
257
257
|
profile("opus-codex", ["anthropic", "openai-codex"], {
|
|
258
258
|
default: "anthropic/claude-opus-4-8:xhigh",
|
|
259
|
-
executor: "openai-codex/gpt-5.6-terra:
|
|
260
|
-
planner: "
|
|
261
|
-
critic: "openai-codex/gpt-5.6-
|
|
262
|
-
architect: "openai-codex/gpt-5.6-sol:
|
|
259
|
+
executor: "openai-codex/gpt-5.6-terra:low",
|
|
260
|
+
planner: "anthropic/claude-sonnet-5",
|
|
261
|
+
critic: "openai-codex/gpt-5.6-sol:xhigh",
|
|
262
|
+
architect: "openai-codex/gpt-5.6-sol:high",
|
|
263
263
|
}),
|
|
264
264
|
profile("codex-opencodego", ["openai-codex", "opencode-go"], {
|
|
265
|
-
default: "openai-codex/gpt-5.6-
|
|
265
|
+
default: "openai-codex/gpt-5.6-sol:low",
|
|
266
266
|
executor: "opencode-go/deepseek-v4-pro",
|
|
267
267
|
planner: "opencode-go/kimi-k2.6",
|
|
268
268
|
critic: "opencode-go/mimo-v2.5-pro",
|
|
269
|
-
architect: "openai-codex/gpt-5.6-sol:
|
|
269
|
+
architect: "openai-codex/gpt-5.6-sol:high",
|
|
270
270
|
}),
|
|
271
271
|
profile("fable-opus-codex", ["anthropic", "openai-codex"], {
|
|
272
272
|
default: "anthropic/claude-fable-5:high",
|
|
273
|
-
executor: "openai-codex/gpt-5.6-terra:
|
|
273
|
+
executor: "openai-codex/gpt-5.6-terra:medium",
|
|
274
274
|
planner: "anthropic/claude-opus-4-8:medium",
|
|
275
275
|
critic: "anthropic/claude-opus-4-8:high",
|
|
276
276
|
architect: "openai-codex/gpt-5.6-sol:xhigh",
|
|
@@ -35,7 +35,7 @@ function buildArgumentCompletions(subcommands: SubcommandDef[]): (prefix: string
|
|
|
35
35
|
if (argumentPrefix.includes(" ")) return null; // past the subcommand
|
|
36
36
|
const lower = argumentPrefix.toLowerCase();
|
|
37
37
|
const matches = subcommands
|
|
38
|
-
.filter(s => s.name.startsWith(lower))
|
|
38
|
+
.filter(s => s.name.toLowerCase().startsWith(lower))
|
|
39
39
|
.map(s => ({
|
|
40
40
|
value: `${s.name} `,
|
|
41
41
|
label: s.name,
|
|
@@ -59,7 +59,7 @@ function buildSubcommandInlineHint(subcommands: SubcommandDef[]): (argumentText:
|
|
|
59
59
|
// Still typing subcommand name — show remaining chars + usage
|
|
60
60
|
const prefix = trimmed.toLowerCase();
|
|
61
61
|
if (prefix.length === 0) return null;
|
|
62
|
-
const match = subcommands.find(s => s.name.startsWith(prefix));
|
|
62
|
+
const match = subcommands.find(s => s.name.toLowerCase().startsWith(prefix));
|
|
63
63
|
if (!match) return null;
|
|
64
64
|
const remaining = match.name.slice(prefix.length);
|
|
65
65
|
return remaining + (match.usage ? ` ${match.usage}` : "");
|
|
@@ -68,7 +68,7 @@ function buildSubcommandInlineHint(subcommands: SubcommandDef[]): (argumentText:
|
|
|
68
68
|
// Subcommand typed — show remaining usage params
|
|
69
69
|
const subName = trimmed.slice(0, spaceIndex).toLowerCase();
|
|
70
70
|
const afterSub = trimmed.slice(spaceIndex + 1);
|
|
71
|
-
const sub = subcommands.find(s => s.name === subName);
|
|
71
|
+
const sub = subcommands.find(s => s.name.toLowerCase() === subName);
|
|
72
72
|
if (!sub?.usage) return null;
|
|
73
73
|
|
|
74
74
|
if (afterSub.length > 0) {
|
|
@@ -86,7 +86,10 @@ export function classifyCgroup(input: { platform: NodeJS.Platform; cgroupText?:
|
|
|
86
86
|
diagnostic: "service_cgroup_inheritance",
|
|
87
87
|
};
|
|
88
88
|
const scope = paths.find(value => /(?:^|\/)(?:user|session|app|init|gjc)[^/]*\.scope(?:\/|$)/.test(value));
|
|
89
|
-
|
|
89
|
+
const vteScope = paths.find(value =>
|
|
90
|
+
/^\/user\.slice\/user-(\d+)\.slice\/user@\1\.service(?:\/[^/]+)*\/vte-spawn-[A-Za-z0-9_.-]+\.scope$/.test(value),
|
|
91
|
+
);
|
|
92
|
+
if (scope || vteScope) return { classification: "safe", scope: scope ?? vteScope };
|
|
90
93
|
if (paths.every(value => value === "/")) return { classification: "safe", scope: "/" };
|
|
91
94
|
return {
|
|
92
95
|
classification: "unverifiable",
|