@gajae-code/coding-agent 0.7.2 → 0.7.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 (154) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/bin/gjc.js +4 -0
  3. package/dist/types/cli/mcp-cli.d.ts +25 -0
  4. package/dist/types/cli/plugin-cli.d.ts +2 -0
  5. package/dist/types/cli.d.ts +6 -0
  6. package/dist/types/commands/mcp.d.ts +70 -0
  7. package/dist/types/commands/plugin.d.ts +6 -0
  8. package/dist/types/commands/session.d.ts +6 -0
  9. package/dist/types/config/keybindings.d.ts +2 -2
  10. package/dist/types/config/model-profile-activation.d.ts +8 -1
  11. package/dist/types/deep-interview/plaintext-gate-guard.d.ts +11 -0
  12. package/dist/types/extensibility/gjc-plugins/compiler.d.ts +19 -0
  13. package/dist/types/extensibility/gjc-plugins/constrained-hooks.d.ts +29 -0
  14. package/dist/types/extensibility/gjc-plugins/index.d.ts +9 -0
  15. package/dist/types/extensibility/gjc-plugins/injection.d.ts +9 -0
  16. package/dist/types/extensibility/gjc-plugins/installer.d.ts +13 -0
  17. package/dist/types/extensibility/gjc-plugins/mcp-policy.d.ts +26 -0
  18. package/dist/types/extensibility/gjc-plugins/observability.d.ts +27 -0
  19. package/dist/types/extensibility/gjc-plugins/prompt-appendix.d.ts +16 -0
  20. package/dist/types/extensibility/gjc-plugins/registry.d.ts +32 -0
  21. package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +64 -0
  22. package/dist/types/extensibility/gjc-plugins/session-validation.d.ts +42 -0
  23. package/dist/types/extensibility/gjc-plugins/types.d.ts +158 -2
  24. package/dist/types/extensibility/gjc-plugins/validation.d.ts +8 -1
  25. package/dist/types/gjc-runtime/launch-tmux.d.ts +1 -0
  26. package/dist/types/gjc-runtime/psmux-detect.d.ts +78 -0
  27. package/dist/types/gjc-runtime/team-runtime.d.ts +2 -0
  28. package/dist/types/gjc-runtime/tmux-common.d.ts +20 -1
  29. package/dist/types/gjc-runtime/tmux-sessions.d.ts +18 -0
  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/status-line/git-utils.d.ts +6 -0
  34. package/dist/types/modes/theme/defaults/index.d.ts +99 -0
  35. package/dist/types/notifications/html-format.d.ts +11 -0
  36. package/dist/types/notifications/index.d.ts +149 -1
  37. package/dist/types/notifications/lifecycle-commands.d.ts +72 -0
  38. package/dist/types/notifications/lifecycle-control-runtime.d.ts +98 -0
  39. package/dist/types/notifications/lifecycle-orchestrator.d.ts +144 -0
  40. package/dist/types/notifications/operator-runtime.d.ts +52 -0
  41. package/dist/types/notifications/rate-limit-pool.d.ts +2 -0
  42. package/dist/types/notifications/recent-activity.d.ts +35 -0
  43. package/dist/types/notifications/telegram-daemon.d.ts +114 -16
  44. package/dist/types/notifications/telegram-reference.d.ts +3 -1
  45. package/dist/types/notifications/topic-registry.d.ts +12 -9
  46. package/dist/types/runtime-mcp/types.d.ts +7 -0
  47. package/dist/types/sdk.d.ts +2 -0
  48. package/dist/types/session/agent-session.d.ts +14 -4
  49. package/dist/types/session/blob-store.d.ts +25 -0
  50. package/dist/types/session/session-manager.d.ts +57 -0
  51. package/dist/types/slash-commands/helpers/fast-status-report.d.ts +6 -0
  52. package/dist/types/system-prompt.d.ts +2 -0
  53. package/dist/types/task/executor.d.ts +9 -1
  54. package/dist/types/tools/composer-bash-policy.d.ts +14 -0
  55. package/dist/types/tools/index.d.ts +3 -1
  56. package/dist/types/utils/changelog.d.ts +1 -0
  57. package/dist/types/web/insane/url-guard.d.ts +6 -3
  58. package/dist/types/web/scrapers/types.d.ts +5 -0
  59. package/dist/types/web/scrapers/utils.d.ts +7 -1
  60. package/package.json +11 -9
  61. package/scripts/g004-tmux-smoke.ts +100 -0
  62. package/scripts/g005-daemon-smoke.ts +181 -0
  63. package/scripts/g011-daemon-path-smoke.ts +153 -0
  64. package/src/cli/mcp-cli.ts +272 -0
  65. package/src/cli/plugin-cli.ts +66 -3
  66. package/src/cli.ts +27 -6
  67. package/src/commands/mcp.ts +117 -0
  68. package/src/commands/plugin.ts +4 -0
  69. package/src/commands/session.ts +18 -0
  70. package/src/config/keybindings.ts +2 -2
  71. package/src/config/model-profile-activation.ts +55 -7
  72. package/src/deep-interview/plaintext-gate-guard.ts +94 -0
  73. package/src/defaults/gjc/extensions/grok-cli-vendor/biome.json +1 -1
  74. package/src/defaults/gjc/skills/deep-interview/SKILL.md +7 -6
  75. package/src/defaults/gjc/skills/team/SKILL.md +5 -3
  76. package/src/defaults/gjc/skills/ultragoal/SKILL.md +41 -13
  77. package/src/export/html/index.ts +2 -2
  78. package/src/extensibility/extensions/runner.ts +1 -0
  79. package/src/extensibility/gjc-plugins/compiler.ts +351 -0
  80. package/src/extensibility/gjc-plugins/constrained-hooks.ts +170 -0
  81. package/src/extensibility/gjc-plugins/index.ts +9 -0
  82. package/src/extensibility/gjc-plugins/injection.ts +109 -0
  83. package/src/extensibility/gjc-plugins/installer.ts +434 -0
  84. package/src/extensibility/gjc-plugins/loader.ts +3 -1
  85. package/src/extensibility/gjc-plugins/mcp-policy.ts +239 -0
  86. package/src/extensibility/gjc-plugins/observability.ts +84 -0
  87. package/src/extensibility/gjc-plugins/paths.ts +1 -1
  88. package/src/extensibility/gjc-plugins/prompt-appendix.ts +109 -0
  89. package/src/extensibility/gjc-plugins/registry.ts +180 -0
  90. package/src/extensibility/gjc-plugins/runtime-adapters.ts +234 -0
  91. package/src/extensibility/gjc-plugins/schema.ts +250 -20
  92. package/src/extensibility/gjc-plugins/session-validation.ts +147 -0
  93. package/src/extensibility/gjc-plugins/types.ts +199 -3
  94. package/src/extensibility/gjc-plugins/validation.ts +80 -0
  95. package/src/extensibility/skills.ts +15 -0
  96. package/src/gjc-runtime/launch-tmux.ts +61 -7
  97. package/src/gjc-runtime/psmux-detect.ts +239 -0
  98. package/src/gjc-runtime/team-runtime.ts +56 -23
  99. package/src/gjc-runtime/tmux-common.ts +30 -3
  100. package/src/gjc-runtime/tmux-sessions.ts +51 -1
  101. package/src/gjc-runtime/ultragoal-guard.ts +25 -8
  102. package/src/gjc-runtime/ultragoal-runtime.ts +75 -15
  103. package/src/hooks/skill-state.ts +57 -0
  104. package/src/internal-urls/docs-index.generated.ts +12 -8
  105. package/src/main.ts +14 -3
  106. package/src/modes/bridge/bridge-mode.ts +11 -0
  107. package/src/modes/components/custom-editor.ts +2 -0
  108. package/src/modes/components/footer.ts +2 -3
  109. package/src/modes/components/hook-editor.ts +1 -1
  110. package/src/modes/components/hook-selector.ts +67 -43
  111. package/src/modes/components/model-selector.ts +56 -11
  112. package/src/modes/components/status-line/git-utils.ts +25 -0
  113. package/src/modes/components/status-line.ts +10 -11
  114. package/src/modes/components/welcome.ts +2 -3
  115. package/src/modes/controllers/extension-ui-controller.ts +0 -27
  116. package/src/modes/controllers/selector-controller.ts +53 -11
  117. package/src/modes/interactive-mode.ts +4 -1
  118. package/src/modes/shared/agent-wire/scopes.ts +1 -1
  119. package/src/modes/theme/defaults/gruvbox-dark.json +99 -0
  120. package/src/modes/theme/defaults/index.ts +2 -0
  121. package/src/modes/utils/hotkeys-markdown.ts +1 -1
  122. package/src/notifications/html-format.ts +38 -0
  123. package/src/notifications/index.ts +242 -12
  124. package/src/notifications/lifecycle-commands.ts +228 -0
  125. package/src/notifications/lifecycle-control-runtime.ts +400 -0
  126. package/src/notifications/lifecycle-orchestrator.ts +358 -0
  127. package/src/notifications/operator-runtime.ts +171 -0
  128. package/src/notifications/rate-limit-pool.ts +19 -0
  129. package/src/notifications/recent-activity.ts +132 -0
  130. package/src/notifications/telegram-daemon.ts +778 -257
  131. package/src/notifications/telegram-reference.ts +25 -7
  132. package/src/notifications/topic-registry.ts +23 -9
  133. package/src/prompts/agents/executor.md +2 -2
  134. package/src/runtime-mcp/transports/stdio.ts +38 -4
  135. package/src/runtime-mcp/types.ts +7 -0
  136. package/src/sdk.ts +157 -10
  137. package/src/session/agent-session.ts +166 -74
  138. package/src/session/blob-store.ts +196 -8
  139. package/src/session/session-manager.ts +678 -7
  140. package/src/slash-commands/builtin-registry.ts +23 -3
  141. package/src/slash-commands/helpers/fast-status-report.ts +13 -3
  142. package/src/slash-commands/helpers/parse.ts +2 -1
  143. package/src/system-prompt.ts +9 -0
  144. package/src/task/executor.ts +31 -7
  145. package/src/task/index.ts +2 -0
  146. package/src/tools/ask.ts +5 -1
  147. package/src/tools/bash.ts +9 -0
  148. package/src/tools/composer-bash-policy.ts +96 -0
  149. package/src/tools/fetch.ts +18 -2
  150. package/src/tools/index.ts +3 -1
  151. package/src/utils/changelog.ts +8 -0
  152. package/src/web/insane/url-guard.ts +18 -14
  153. package/src/web/scrapers/types.ts +143 -45
  154. package/src/web/scrapers/utils.ts +70 -19
@@ -7,12 +7,56 @@ export declare const GJC_SUBSKILL_PARENT_AGENTS: readonly ["executor", "architec
7
7
  export type GjcSubskillParentAgent = (typeof GJC_SUBSKILL_PARENT_AGENTS)[number];
8
8
  export type GjcSubskillParent = GjcSubskillParentSkill | GjcSubskillParentAgent;
9
9
  export declare const GJC_AGENT_SUBSKILL_PHASES: Record<GjcSubskillParentAgent, string[]>;
10
+ export interface GjcPluginToolManifestEntry {
11
+ name: string;
12
+ path: string;
13
+ description?: string;
14
+ sha256?: string;
15
+ /**
16
+ * "always-on" object entries are activated for the whole session; legacy
17
+ * string shorthand stays "subskill"-scoped and is only attached to subskill
18
+ * bindings (never registered as an always-on tool surface).
19
+ */
20
+ surface: "subskill" | "always-on";
21
+ }
22
+ export interface GjcPluginHookManifestEntry {
23
+ name: string;
24
+ event: string;
25
+ target?: string;
26
+ phase?: "before" | "after";
27
+ path: string;
28
+ sha256?: string;
29
+ }
30
+ export type GjcPluginMcpTransport = "stdio" | "http" | "sse";
31
+ export interface GjcPluginMcpManifestEntry {
32
+ name: string;
33
+ transport: GjcPluginMcpTransport;
34
+ command?: string;
35
+ args?: string[];
36
+ cwd?: string;
37
+ url?: string;
38
+ headers?: Record<string, string>;
39
+ sha256?: string;
40
+ }
41
+ export interface GjcPluginAppendixManifestEntry {
42
+ name: string;
43
+ path?: string;
44
+ content?: string;
45
+ sha256?: string;
46
+ }
47
+ export interface GjcPluginAgentAppendixManifestEntry extends GjcPluginAppendixManifestEntry {
48
+ agent: GjcSubskillParentAgent;
49
+ }
10
50
  export interface GjcPluginManifest {
11
51
  name: string;
12
52
  version: string;
13
53
  kind: "gajae-code-plugin";
14
54
  subskills: string[];
15
- tools: string[];
55
+ tools: GjcPluginToolManifestEntry[];
56
+ hooks: GjcPluginHookManifestEntry[];
57
+ mcps: GjcPluginMcpManifestEntry[];
58
+ systemAppendix: GjcPluginAppendixManifestEntry[];
59
+ agentAppendix: GjcPluginAgentAppendixManifestEntry[];
16
60
  }
17
61
  export interface SubskillFrontmatter {
18
62
  name: string;
@@ -57,8 +101,120 @@ export interface LoadedGjcPlugin {
57
101
  bindings: LoadedSubskillBinding[];
58
102
  toolBindings: PhaseScopedToolBinding[];
59
103
  }
60
- export type GjcPluginLoadErrorCode = "forbidden_surface" | "invalid_manifest" | "invalid_frontmatter" | "invalid_parent" | "invalid_phase" | "duplicate_arg" | "duplicate_parent_phase" | "missing_file" | "invalid_kind";
104
+ export type GjcPluginLoadErrorCode = "forbidden_surface" | "invalid_manifest" | "invalid_kind" | "unsupported_surface" | "invalid_frontmatter" | "invalid_parent" | "invalid_phase" | "missing_file" | "hash_mismatch" | "invalid_appendix" | "invalid_hook" | "invalid_mcp" | "duplicate_arg" | "duplicate_parent_phase" | "duplicate_tool" | "duplicate_hook" | "duplicate_mcp" | "duplicate_appendix" | "security_policy" | "install_conflict" | "session_collision" | "runtime_mismatch" | "quarantined_surface";
61
105
  export declare class GjcPluginLoadError extends Error {
62
106
  readonly code: GjcPluginLoadErrorCode;
63
107
  constructor(code: GjcPluginLoadErrorCode, message: string, options?: ErrorOptions);
64
108
  }
109
+ export type GjcPluginScope = "user" | "project";
110
+ export type GjcPluginSourceKind = "path" | "git" | "tarball";
111
+ export interface GjcPluginCopiedFile {
112
+ relativePath: string;
113
+ sha256: string;
114
+ bytes: number;
115
+ }
116
+ export interface NormalizedSubskillSurface {
117
+ extensionId: string;
118
+ name: string;
119
+ description: string;
120
+ parent: string;
121
+ phase: string;
122
+ activationArg: string;
123
+ relativePath: string;
124
+ sha256: string;
125
+ }
126
+ export interface NormalizedToolSurface {
127
+ extensionId: string;
128
+ name: string;
129
+ relativePath: string;
130
+ sha256: string;
131
+ description?: string;
132
+ }
133
+ export interface NormalizedHookSurface {
134
+ extensionId: string;
135
+ name: string;
136
+ event: string;
137
+ target?: string;
138
+ phase?: "before" | "after";
139
+ relativePath: string;
140
+ sha256: string;
141
+ }
142
+ export interface NormalizedMcpSurface {
143
+ extensionId: string;
144
+ name: string;
145
+ transport: GjcPluginMcpTransport;
146
+ configHash: string;
147
+ config: GjcPluginMcpManifestEntry;
148
+ }
149
+ export interface NormalizedAppendixSurface {
150
+ extensionId: string;
151
+ name: string;
152
+ relativePath?: string;
153
+ /** Inline appendix body (when the manifest used `content` instead of `path`). */
154
+ content?: string;
155
+ contentHash: string;
156
+ bytes: number;
157
+ }
158
+ export interface NormalizedAgentAppendixSurface extends NormalizedAppendixSurface {
159
+ agent: GjcSubskillParentAgent;
160
+ }
161
+ export interface NormalizedGjcPluginSurfaces {
162
+ subskills: NormalizedSubskillSurface[];
163
+ tools: NormalizedToolSurface[];
164
+ hooks: NormalizedHookSurface[];
165
+ mcps: NormalizedMcpSurface[];
166
+ systemAppendices: NormalizedAppendixSurface[];
167
+ agentAppendices: NormalizedAgentAppendixSurface[];
168
+ }
169
+ /**
170
+ * Result of the pure compile step. Computed from manifest, frontmatter, and
171
+ * declared files read as bytes only — never by importing plugin code.
172
+ */
173
+ export interface NormalizedGjcPluginBundle {
174
+ name: string;
175
+ version: string;
176
+ root: string;
177
+ manifestPath: string;
178
+ manifestHash: string;
179
+ surfaces: NormalizedGjcPluginSurfaces;
180
+ files: GjcPluginCopiedFile[];
181
+ }
182
+ export interface GjcPluginQuarantineEntry {
183
+ surfaceId: string;
184
+ code: GjcPluginLoadErrorCode;
185
+ message: string;
186
+ detectedAt: string;
187
+ }
188
+ export interface GjcPluginRegistrySource {
189
+ kind: GjcPluginSourceKind;
190
+ uri: string;
191
+ ref?: string;
192
+ sha?: string;
193
+ resolvedAt: string;
194
+ }
195
+ export interface GjcPluginRegistryEntry {
196
+ name: string;
197
+ version: string;
198
+ scope: GjcPluginScope;
199
+ enabled: boolean;
200
+ pluginRoot: string;
201
+ manifestPath: string;
202
+ manifestHash: string;
203
+ source: GjcPluginRegistrySource;
204
+ installedAt: string;
205
+ updatedAt: string;
206
+ copiedFiles: GjcPluginCopiedFile[];
207
+ surfaces: NormalizedGjcPluginSurfaces;
208
+ disabledSurfaceIds: string[];
209
+ quarantine?: GjcPluginQuarantineEntry[];
210
+ }
211
+ export interface GjcPluginRegistry {
212
+ version: 1;
213
+ scope: GjcPluginScope;
214
+ plugins: GjcPluginRegistryEntry[];
215
+ }
216
+ /**
217
+ * Stable identifiers for plugin-contributed surfaces used by observability,
218
+ * disabledSurfaceIds, and quarantine bookkeeping.
219
+ */
220
+ export type GjcPluginSurfaceExtensionId = string;
@@ -1,4 +1,11 @@
1
- import { type LoadedSubskillBinding, type SubskillFrontmatter } from "./types";
1
+ import { type GjcPluginRegistryEntry, type LoadedSubskillBinding, type NormalizedGjcPluginBundle, type SubskillFrontmatter } from "./types";
2
2
  export declare function validateBinding(fm: SubskillFrontmatter): void;
3
3
  export declare function buildParentArgMap(bindings: readonly LoadedSubskillBinding[]): Map<string, Map<string, LoadedSubskillBinding>>;
4
4
  export declare function buildParentPhaseSet(bindings: readonly LoadedSubskillBinding[]): Set<string>;
5
+ /**
6
+ * Hard install-time collision + security validation for a compiled bundle
7
+ * against the effective installed registry (other plugins in the target scope
8
+ * universe). Collisions are hard errors; the registry is the collision
9
+ * authority, never capability first-wins.
10
+ */
11
+ export declare function validateInstallPlan(bundle: NormalizedGjcPluginBundle, effectiveEntries: readonly GjcPluginRegistryEntry[]): void;
@@ -4,6 +4,7 @@ export { buildGjcTmuxProfileCommands, GJC_DEFAULT_TMUX_SESSION, GJC_TMUX_COMMAND
4
4
  export declare const GJC_TMUX_LAUNCHED_ENV = "GJC_TMUX_LAUNCHED";
5
5
  export declare const GJC_LAUNCH_POLICY_ENV = "GJC_LAUNCH_POLICY";
6
6
  export declare const GJC_TMUX_WINDOW_LABEL_MAX_WIDTH = 48;
7
+ export declare const GJC_PSMUX_PROFILE_FORCE_ENV = "GJC_PSMUX_PROFILE_FORCE";
7
8
  interface TtyState {
8
9
  stdin: boolean;
9
10
  stdout: boolean;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Windows psmux detection and tmux-binary resolution.
3
+ *
4
+ * Recent psmux releases (see docs/compatibility.md in the psmux repo) close
5
+ * the round-trip gap for set-option / show-options user options and the
6
+ * set-window-option profile values gjc emits, which is what unblocks the
7
+ * native Windows gjc --tmux path. This module detects that capability so gjc
8
+ * can pick psmux when tmux is missing on Windows, and so callers can decide
9
+ * whether to treat a given tmux binary as psmux (affecting e.g. the untagged
10
+ * diagnostic wording and namespace handling).
11
+ *
12
+ * The probe is intentionally lightweight: it runs a single tmux -V (or
13
+ * --version) once per process and caches the verdict. Cache invalidation
14
+ * knobs:
15
+ * - force: true re-probes on every call (used by tests).
16
+ * - GJC_PSMUX_FORCE_DETECT=1 re-probes each call.
17
+ * - GJC_PSMUX_DETECTION=off skips probing entirely.
18
+ */
19
+ export declare const GJC_PSMUX_COMMAND_ENV = "GJC_PSMUX_COMMAND";
20
+ export declare const GJC_PSMUX_DETECTION_ENV = "GJC_PSMUX_DETECTION";
21
+ export declare const GJC_PSMUX_FORCE_DETECT_ENV = "GJC_PSMUX_FORCE_DETECT";
22
+ /** Names that psmux installs as the canonical executable / alias. */
23
+ export declare const PSMUX_BINARY_NAMES: readonly ["psmux", "pmux", "tmux"];
24
+ export type PsmuxSpawnRunner = (command: string, args: string[]) => {
25
+ exitCode: number | null;
26
+ stdout?: string;
27
+ stderr?: string;
28
+ };
29
+ /**
30
+ * Resolves a tmux-class binary name (e.g. "psmux", "tmux") to an absolute
31
+ * filesystem path or returns null when the binary cannot be located. The
32
+ * default implementation uses `Bun.which`; production callers leave it
33
+ * alone and unit tests inject a stub via `__setBinaryResolverForTests`
34
+ * so the version-banner probe can be exercised hermetically.
35
+ */
36
+ export type BinaryResolver = (candidate: string) => string | null;
37
+ /** @internal Test-only seam; production code never calls this. */
38
+ export declare function __setBinaryResolverForTests(resolver: BinaryResolver | null): void;
39
+ export declare function envDisabled(value: string | undefined): boolean;
40
+ /**
41
+ * Decide whether command resolves to a psmux binary by probing its version
42
+ * output. The result is cached per process unless force is set or
43
+ * GJC_PSMUX_FORCE_DETECT=1.
44
+ */
45
+ export declare function detectPsmux(command: string, options?: {
46
+ force?: boolean;
47
+ env?: NodeJS.ProcessEnv;
48
+ runner?: PsmuxSpawnRunner;
49
+ }): boolean;
50
+ export interface ResolveGjcTmuxBinaryOptions {
51
+ platform?: NodeJS.Platform;
52
+ env?: NodeJS.ProcessEnv;
53
+ runner?: PsmuxSpawnRunner;
54
+ }
55
+ export interface ResolvedTmuxBinary {
56
+ command: string;
57
+ isPsmux: boolean;
58
+ viaExplicitOverride: boolean;
59
+ }
60
+ /**
61
+ * Resolve the tmux command GJC should invoke. Honors the existing
62
+ * GJC_TMUX_COMMAND / GJC_TEAM_TMUX_COMMAND overrides; on Windows when no
63
+ * override is set, psmux (installed as psmux, pmux, or tmux) is picked
64
+ * automatically so the default gjc --tmux flow lands on a real multiplexer.
65
+ */
66
+ export declare function resolveGjcTmuxBinary(options?: ResolveGjcTmuxBinaryOptions): ResolvedTmuxBinary;
67
+ /** Test-only helper: drop the in-process detection cache. */
68
+ export declare function clearPsmuxDetectionCache(): void;
69
+ export interface PsmuxProbe {
70
+ command: string;
71
+ versionOutput: string;
72
+ isPsmux: boolean;
73
+ }
74
+ export declare function probePsmux(command: string, options?: {
75
+ env?: NodeJS.ProcessEnv;
76
+ runner?: PsmuxSpawnRunner;
77
+ force?: boolean;
78
+ }): PsmuxProbe;
@@ -281,6 +281,8 @@ export declare function persistGjcTeamModeStateSummary(snapshot: GjcTeamSnapshot
281
281
  export declare function recoverGjcTeamStaleClaims(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamLivenessRecoveryResult>;
282
282
  type GjcTeamTaskMetadataInput = Partial<Pick<GjcTeamTask, "owner" | "lane" | "required_role" | "allowed_roles" | "depends_on" | "blocked_by">>;
283
283
  export declare function resolveGjcWorkerCommand(cwd?: string, env?: NodeJS.ProcessEnv): string;
284
+ /** @internal Exported for unit tests. */
285
+ export declare function buildWorkerCommand(config: GjcTeamConfig, worker: GjcTeamWorker, platform?: NodeJS.Platform): string;
284
286
  export type GjcWorkerCheckpointClassification = {
285
287
  kind: "clean";
286
288
  files: string[];
@@ -23,7 +23,26 @@ export interface TmuxCommandResult {
23
23
  }
24
24
  export type TmuxCommandRunner = (args: string[]) => TmuxCommandResult;
25
25
  export declare function envDisabled(value: string | undefined): boolean;
26
- export declare function resolveGjcTmuxCommand(env?: NodeJS.ProcessEnv): string;
26
+ /**
27
+ * Resolve the tmux (or tmux-compatible multiplexer) command GJC should invoke.
28
+ *
29
+ * This is the shared entry point used by every GJC code path that needs to talk
30
+ * to a multiplexer: `gjc --tmux` planning, `gjc session ...`, `gjc team ...`,
31
+ * the lifecycle controller, and the harness resident owner. Routing all of
32
+ * them through the same resolver means a single `GJC_TMUX_COMMAND` override or
33
+ * a single Windows psmux / pmux detection wins for the whole process — the
34
+ * failure mode where `gjc --tmux` creates a psmux-backed session and then
35
+ * `gjc session status` fails because it queries literal `tmux` is closed off.
36
+ *
37
+ * Explicit `GJC_TMUX_COMMAND` / `GJC_TEAM_TMUX_COMMAND` overrides are honored on
38
+ * every platform. On native Windows without an override the resolver walks
39
+ * `psmux`, then `pmux`, then `tmux` and uses the first binary present on PATH.
40
+ * On POSIX the resolver returns `tmux` (the historical default) and only
41
+ * falls through to the platform-aware walker if the caller opts in.
42
+ */
43
+ export declare function resolveGjcTmuxCommand(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string;
44
+ export type { PsmuxProbe, ResolvedTmuxBinary, ResolveGjcTmuxBinaryOptions } from "./psmux-detect";
45
+ export { clearPsmuxDetectionCache, detectPsmux, probePsmux, resolveGjcTmuxBinary } from "./psmux-detect";
27
46
  /**
28
47
  * Build the exact-session target for tmux *option* commands
29
48
  * (`show-options` / `set-option`) and `display-message -t`.
@@ -41,4 +41,22 @@ export declare function createGjcTmuxSession(env?: NodeJS.ProcessEnv): GjcTmuxSe
41
41
  /** @internal */
42
42
  export declare function readTmuxSessionTagsForGc(sessionName: string, env?: NodeJS.ProcessEnv): GjcTmuxSessionTagsForGc;
43
43
  export declare function removeGjcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv): GjcTmuxSessionStatus;
44
+ /**
45
+ * Force-close a GJC-managed tmux session, even if a live pane is attached.
46
+ *
47
+ * This is the lifecycle-control counterpart to {@link removeGjcTmuxSession}: 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
+ * GJC-managed session:
51
+ * - re-reads the exact tmux profile immediately before kill (never a non-GJC
52
+ * session, even one that collides by name);
53
+ * - when `expectedSessionId` is given, requires the `@gjc-session-id` tag match;
54
+ * - when `expectedStateFile` is given, requires the `@gjc-session-state-file`
55
+ * tag match.
56
+ *
57
+ * Returns the prior status (for audit). Throws a tagged error otherwise:
58
+ * `gjc_tmux_session_not_found`, `gjc_tmux_session_not_managed`,
59
+ * `gjc_tmux_session_id_mismatch`, or `gjc_tmux_session_state_file_mismatch`.
60
+ */
61
+ export declare function forceCloseGjcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv, expectedSessionId?: string, expectedStateFile?: string): GjcTmuxSessionStatus;
44
62
  export declare function attachGjcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv): never;
@@ -12,6 +12,7 @@ import type { SubmittedUserInput } from "./modes/types";
12
12
  import { type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession, discoverAuthStorage } from "./sdk";
13
13
  import type { AgentSession } from "./session/agent-session";
14
14
  import type { AuthStorage } from "./session/auth-storage";
15
+ import { SessionManager } from "./session/session-manager";
15
16
  export interface InteractiveModeNotify {
16
17
  kind: "warn" | "error" | "info";
17
18
  message: string;
@@ -48,6 +49,7 @@ export declare function applyStartupModelProfilesOrExit(args: Parameters<typeof
48
49
  * tool registry and shadow the client-supplied servers (issue #1234).
49
50
  */
50
51
  export declare function createAcpSessionFactory(args: AcpSessionFactoryOptions): AcpSessionFactory;
52
+ export declare function createSessionManager(parsed: Args, cwd: string, activeSettings?: Settings): Promise<SessionManager | undefined>;
51
53
  /**
52
54
  * Research-mode (RLM) preset hook. Lets `gjc rlm` augment the session options
53
55
  * (system prompt, restricted toolset, custom python tool) and assert the tool
@@ -1,6 +1,6 @@
1
1
  import { Editor, type KeyId } from "@gajae-code/tui";
2
2
  import { type AppKeybinding } from "../../config/keybindings";
3
- type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.expand" | "app.thinking.toggle" | "app.editor.external" | "app.history.search" | "app.message.dequeue" | "app.message.queue" | "app.clipboard.pasteImage" | "app.clipboard.copyPrompt">;
3
+ type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.expand" | "app.thinking.toggle" | "app.editor.external" | "app.history.search" | "app.message.dequeue" | "app.message.followUp" | "app.message.queue" | "app.clipboard.pasteImage" | "app.clipboard.copyPrompt">;
4
4
  type PastePendingClearReason = "timeout" | "queue-limit";
5
5
  /**
6
6
  * Custom editor that handles configurable app-level shortcuts for coding-agent.
@@ -35,7 +35,15 @@ export declare class ModelSelectorComponent extends Container {
35
35
  sessionId?: string;
36
36
  isFastForProvider?: (provider?: string) => boolean;
37
37
  isFastForSubagentProvider?: (provider?: string) => boolean;
38
+ isCurrentModelFastModeActive?: () => boolean;
39
+ currentThinkingLevel?: ThinkingLevel;
40
+ activeModelProfile?: string;
38
41
  });
42
+ refreshRoleAssignments(options?: {
43
+ currentModel?: Model;
44
+ currentThinkingLevel?: ThinkingLevel;
45
+ activeModelProfile?: string;
46
+ }): void;
39
47
  handleInput(keyData: string): void;
40
48
  getSearchInput(): Input;
41
49
  __testSelectProfile(profileName: string, setDefault: boolean): Promise<void>;
@@ -1,3 +1,4 @@
1
+ import type { GitHeadState } from "../../../utils/git";
1
2
  /**
2
3
  * Extract "owner/repo" from a GitHub remote URL.
3
4
  * Handles HTTPS, SSH (scp-style), and git:// protocols.
@@ -20,3 +21,8 @@ export declare function canReuseCachedPr(cachedPr: {
20
21
  number: number;
21
22
  url: string;
22
23
  } | null | undefined, cachedContext: PrCacheContext | undefined, currentContext: PrCacheContext | null): boolean;
24
+ export interface CurrentBranchState {
25
+ readonly branch: string | null;
26
+ readonly repoId: string | null;
27
+ }
28
+ export declare function resolveCurrentBranch(cwd: string, resolveHead?: (cwd: string) => GitHeadState | null): CurrentBranchState;
@@ -325,6 +325,105 @@ export declare const defaultThemes: {
325
325
  "preset": string;
326
326
  };
327
327
  };
328
+ "gruvbox-dark": {
329
+ $schema: string;
330
+ name: string;
331
+ vars: {
332
+ "bgHard": string;
333
+ "surface": string;
334
+ "surfaceBright": string;
335
+ "borderNeutral": string;
336
+ "borderSubtle": string;
337
+ "fg": string;
338
+ "muted": string;
339
+ "dim": string;
340
+ "gray": string;
341
+ "red": string;
342
+ "green": string;
343
+ "yellow": string;
344
+ "blue": string;
345
+ "purple": string;
346
+ "aqua": string;
347
+ "orange": string;
348
+ "diffRemovalRed": string;
349
+ };
350
+ colors: {
351
+ "accent": string;
352
+ "border": string;
353
+ "borderAccent": string;
354
+ "borderMuted": string;
355
+ "success": string;
356
+ "error": string;
357
+ "warning": string;
358
+ "muted": string;
359
+ "dim": string;
360
+ "text": string;
361
+ "thinkingText": string;
362
+ "selectedBg": string;
363
+ "userMessageBg": string;
364
+ "userMessageText": string;
365
+ "customMessageBg": string;
366
+ "customMessageText": string;
367
+ "customMessageLabel": string;
368
+ "toolPendingBg": string;
369
+ "toolSuccessBg": string;
370
+ "toolErrorBg": string;
371
+ "toolTitle": string;
372
+ "toolOutput": string;
373
+ "mdHeading": string;
374
+ "mdLink": string;
375
+ "mdLinkUrl": string;
376
+ "mdCode": string;
377
+ "mdCodeBlock": string;
378
+ "mdCodeBlockBorder": string;
379
+ "mdQuote": string;
380
+ "mdQuoteBorder": string;
381
+ "mdHr": string;
382
+ "mdListBullet": string;
383
+ "toolDiffAdded": string;
384
+ "toolDiffRemoved": string;
385
+ "toolDiffContext": string;
386
+ "syntaxComment": string;
387
+ "syntaxKeyword": string;
388
+ "syntaxFunction": string;
389
+ "syntaxVariable": string;
390
+ "syntaxString": string;
391
+ "syntaxNumber": string;
392
+ "syntaxType": string;
393
+ "syntaxOperator": string;
394
+ "syntaxPunctuation": string;
395
+ "thinkingOff": string;
396
+ "thinkingMinimal": string;
397
+ "thinkingLow": string;
398
+ "thinkingMedium": string;
399
+ "thinkingHigh": string;
400
+ "thinkingXhigh": string;
401
+ "bashMode": string;
402
+ "pythonMode": string;
403
+ "statusLineBg": string;
404
+ "statusLineSep": string;
405
+ "statusLineModel": string;
406
+ "statusLinePath": string;
407
+ "statusLineGitClean": string;
408
+ "statusLineGitDirty": string;
409
+ "statusLineContext": string;
410
+ "statusLineSpend": string;
411
+ "statusLineStaged": string;
412
+ "statusLineDirty": string;
413
+ "statusLineUntracked": string;
414
+ "statusLineOutput": string;
415
+ "statusLineCost": string;
416
+ "statusLineSubagents": string;
417
+ };
418
+ export: {
419
+ "pageBg": string;
420
+ "cardBg": string;
421
+ "infoBg": string;
422
+ };
423
+ symbols: {
424
+ "preset": string;
425
+ };
426
+ };
328
427
  opencode: {
329
428
  $schema: string;
330
429
  name: string;
@@ -49,10 +49,21 @@ export declare function finalizeTelegramHtml(message?: string): string | undefin
49
49
  * `1. 1. …` and keeps the displayed number aligned with the button's real index.
50
50
  */
51
51
  export declare function buttonLabel(label: string, index: number): string;
52
+ /** Numbered, escaped option list for the Telegram message body. */
53
+ export declare function numberedOptionList(labels: string[]): string;
54
+ /** Compact numeric button label; full option text belongs in the message body. */
55
+ export declare function choiceButtonLabel(index: number): string;
52
56
  export interface InlineButton {
53
57
  text: string;
54
58
  callback_data: string;
55
59
  }
60
+ /**
61
+ * Lay out option callbacks as compact numeric buttons. Telegram mobile clients
62
+ * ellipsize long inline-keyboard labels and tall keyboards can be obscured by
63
+ * the composer, so the full choice text is rendered in the message body while
64
+ * the keyboard keeps only stable one-based tap targets.
65
+ */
66
+ export declare function buildCompactChoiceGrid(labels: string[], callbackForIndex: (index: number) => string): InlineButton[][];
56
67
  /**
57
68
  * Lay out option labels as a numbered button grid. Long buttons take a
58
69
  * full-width row; runs of short buttons are packed into rows of up to 3. The