@gajae-code/coding-agent 0.8.2 → 0.9.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.
Files changed (179) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/types/append-only-mode.d.ts +31 -0
  3. package/dist/types/capability/rule.d.ts +8 -0
  4. package/dist/types/cli/fixture-report.d.ts +20 -0
  5. package/dist/types/cli/fixture-report.test.d.ts +1 -0
  6. package/dist/types/cli/nofile-limit.d.ts +11 -0
  7. package/dist/types/cli/update-cli.d.ts +22 -0
  8. package/dist/types/config/settings-schema.d.ts +105 -1
  9. package/dist/types/discovery/index.d.ts +1 -0
  10. package/dist/types/export/html/template.generated.d.ts +1 -1
  11. package/dist/types/export/ttsr.d.ts +14 -3
  12. package/dist/types/gjc-runtime/deep-interview-state.d.ts +5 -2
  13. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +7 -0
  14. package/dist/types/gjc-runtime/state-writer.d.ts +3 -0
  15. package/dist/types/gjc-runtime/team-runtime.d.ts +26 -0
  16. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +42 -0
  17. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +119 -13
  18. package/dist/types/goals/runtime.d.ts +1 -0
  19. package/dist/types/hooks/native-skill-hook.d.ts +12 -0
  20. package/dist/types/modes/components/assistant-message.d.ts +5 -1
  21. package/dist/types/modes/components/status-line.d.ts +9 -0
  22. package/dist/types/modes/controllers/command-controller.d.ts +1 -0
  23. package/dist/types/modes/controllers/event-controller.d.ts +5 -0
  24. package/dist/types/modes/interactive-mode.d.ts +2 -0
  25. package/dist/types/modes/rpc/rpc-types.d.ts +14 -0
  26. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +19 -0
  27. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +23 -1
  28. package/dist/types/modes/types.d.ts +1 -0
  29. package/dist/types/modes/utils/ui-helpers.d.ts +1 -0
  30. package/dist/types/notifications/config.d.ts +6 -0
  31. package/dist/types/notifications/telegram-daemon.d.ts +8 -0
  32. package/dist/types/notifications/threaded-render.d.ts +6 -0
  33. package/dist/types/sdk.d.ts +3 -0
  34. package/dist/types/session/agent-session.d.ts +43 -1
  35. package/dist/types/session/file-mention-pruning.d.ts +8 -0
  36. package/dist/types/session/messages.d.ts +4 -0
  37. package/dist/types/session/session-manager.d.ts +17 -1
  38. package/dist/types/skill-state/active-state.d.ts +18 -1
  39. package/dist/types/system-prompt.d.ts +18 -2
  40. package/dist/types/task/executor.d.ts +1 -0
  41. package/dist/types/task/fork-context-budget.d.ts +7 -0
  42. package/dist/types/task/token-log.d.ts +30 -0
  43. package/dist/types/task/token-log.test.d.ts +1 -0
  44. package/dist/types/tools/bisect.d.ts +81 -0
  45. package/dist/types/tools/index.d.ts +1 -0
  46. package/dist/types/tools/search.d.ts +2 -2
  47. package/dist/types/utils/file-mentions.d.ts +14 -0
  48. package/dist/types/utils/git.d.ts +32 -0
  49. package/dist/types/web/scrapers/youtube.d.ts +8 -0
  50. package/package.json +7 -7
  51. package/src/append-only-mode.ts +58 -0
  52. package/src/autoresearch/prompt.md +1 -1
  53. package/src/autoresearch/tools/log-experiment.ts +1 -1
  54. package/src/capability/rule.ts +9 -0
  55. package/src/cli/config-cli.ts +27 -3
  56. package/src/cli/fixture-report.test.ts +230 -0
  57. package/src/cli/fixture-report.ts +171 -0
  58. package/src/cli/nofile-limit.ts +48 -0
  59. package/src/cli/update-cli.ts +85 -9
  60. package/src/cli.ts +26 -0
  61. package/src/commands/contribution-prep.ts +1 -1
  62. package/src/config/settings-schema.ts +68 -1
  63. package/src/defaults/gjc/skills/deep-interview/SKILL.md +12 -13
  64. package/src/defaults/gjc/skills/ralplan/SKILL.md +30 -93
  65. package/src/defaults/gjc/skills/team/SKILL.md +16 -13
  66. package/src/defaults/gjc/skills/ultragoal/SKILL.md +59 -4
  67. package/src/defaults/gjc/skills/ultragoal/pipeline-validation-contracts.md +30 -0
  68. package/src/defaults/gjc-defaults.ts +9 -0
  69. package/src/discovery/helpers.ts +10 -0
  70. package/src/discovery/index.ts +1 -0
  71. package/src/export/html/template.generated.ts +1 -1
  72. package/src/export/html/template.js +60 -2
  73. package/src/export/ttsr.ts +96 -18
  74. package/src/extensibility/extensions/runner.ts +181 -219
  75. package/src/extensibility/gjc-plugins/runtime-adapters.ts +156 -44
  76. package/src/gjc-runtime/deep-interview-state.ts +31 -2
  77. package/src/gjc-runtime/session-state-sidecar.ts +208 -13
  78. package/src/gjc-runtime/state-writer.ts +15 -0
  79. package/src/gjc-runtime/team-runtime.ts +164 -15
  80. package/src/gjc-runtime/ultragoal-guard.ts +55 -66
  81. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +315 -0
  82. package/src/gjc-runtime/ultragoal-runtime.ts +1593 -143
  83. package/src/gjc-runtime/workflow-manifest.generated.json +113 -2
  84. package/src/gjc-runtime/workflow-manifest.ts +74 -1
  85. package/src/goals/runtime.ts +10 -2
  86. package/src/hindsight/backend.ts +1 -3
  87. package/src/hooks/native-skill-hook.ts +95 -4
  88. package/src/internal-urls/docs-index.generated.ts +14 -5
  89. package/src/main.ts +43 -2
  90. package/src/memories/index.ts +12 -1
  91. package/src/modes/components/assistant-message.ts +241 -82
  92. package/src/modes/components/custom-editor.ts +1 -0
  93. package/src/modes/components/status-line.ts +167 -54
  94. package/src/modes/components/tool-execution.ts +44 -19
  95. package/src/modes/controllers/command-controller.ts +39 -2
  96. package/src/modes/controllers/event-controller.ts +66 -47
  97. package/src/modes/controllers/input-controller.ts +1 -1
  98. package/src/modes/interactive-mode.ts +9 -1
  99. package/src/modes/rpc/rpc-mode.ts +29 -3
  100. package/src/modes/rpc/rpc-types.ts +9 -0
  101. package/src/modes/shared/agent-wire/command-validation.ts +4 -0
  102. package/src/modes/shared/agent-wire/event-contract.ts +22 -0
  103. package/src/modes/shared/agent-wire/event-envelope.ts +82 -0
  104. package/src/modes/shared/agent-wire/scopes.ts +1 -0
  105. package/src/modes/types.ts +1 -0
  106. package/src/modes/utils/ui-helpers.ts +17 -4
  107. package/src/notifications/config.ts +16 -4
  108. package/src/notifications/index.ts +78 -5
  109. package/src/notifications/telegram-daemon-cli.ts +2 -2
  110. package/src/notifications/telegram-daemon-control.ts +2 -2
  111. package/src/notifications/telegram-daemon.ts +85 -8
  112. package/src/notifications/threaded-render.ts +17 -1
  113. package/src/prompts/agents/architect.md +19 -10
  114. package/src/prompts/agents/critic.md +16 -18
  115. package/src/prompts/agents/executor.md +14 -11
  116. package/src/prompts/agents/planner.md +18 -13
  117. package/src/prompts/ci-green-request.md +3 -8
  118. package/src/prompts/goals/goal-continuation.md +0 -5
  119. package/src/prompts/goals/goal-mode-active.md +0 -5
  120. package/src/prompts/system/agent-creation-architect.md +2 -2
  121. package/src/prompts/system/plan-mode-active.md +1 -1
  122. package/src/prompts/system/plan-mode-subagent.md +3 -3
  123. package/src/prompts/system/project-prompt.md +0 -13
  124. package/src/prompts/system/subagent-system-prompt.md +3 -2
  125. package/src/prompts/system/system-prompt.md +26 -19
  126. package/src/prompts/system/volatile-project-context.md +10 -0
  127. package/src/prompts/system/web-search.md +4 -7
  128. package/src/prompts/tools/apply-patch.md +6 -0
  129. package/src/prompts/tools/ast-edit.md +1 -0
  130. package/src/prompts/tools/bash.md +1 -1
  131. package/src/prompts/tools/bisect.md +22 -0
  132. package/src/prompts/tools/browser.md +1 -1
  133. package/src/prompts/tools/cron.md +0 -2
  134. package/src/prompts/tools/eval.md +2 -2
  135. package/src/prompts/tools/find.md +1 -1
  136. package/src/prompts/tools/github.md +6 -6
  137. package/src/prompts/tools/goal.md +1 -3
  138. package/src/prompts/tools/image-gen.md +12 -5
  139. package/src/prompts/tools/irc.md +5 -4
  140. package/src/prompts/tools/job.md +2 -2
  141. package/src/prompts/tools/lsp.md +1 -1
  142. package/src/prompts/tools/monitor.md +2 -2
  143. package/src/prompts/tools/patch.md +2 -2
  144. package/src/prompts/tools/replace.md +2 -21
  145. package/src/prompts/tools/rewind.md +1 -1
  146. package/src/prompts/tools/search-tool-bm25.md +1 -11
  147. package/src/prompts/tools/search.md +1 -1
  148. package/src/prompts/tools/skill.md +3 -2
  149. package/src/prompts/tools/ssh.md +2 -1
  150. package/src/prompts/tools/subagent.md +2 -2
  151. package/src/prompts/tools/task.md +4 -5
  152. package/src/prompts/tools/todo-write.md +1 -1
  153. package/src/prompts/tools/vim.md +1 -0
  154. package/src/prompts/tools/web-search.md +2 -0
  155. package/src/prompts/tools/write.md +8 -2
  156. package/src/sdk.ts +32 -22
  157. package/src/session/agent-session.ts +732 -107
  158. package/src/session/file-mention-pruning.ts +64 -0
  159. package/src/session/messages.ts +4 -0
  160. package/src/session/session-manager.ts +59 -2
  161. package/src/skill-state/active-state.ts +141 -5
  162. package/src/skill-state/deep-interview-mutation-guard.ts +67 -3
  163. package/src/slash-commands/builtin-registry.ts +65 -0
  164. package/src/system-prompt.ts +57 -16
  165. package/src/task/executor.ts +125 -20
  166. package/src/task/fork-context-advisory.ts +2 -7
  167. package/src/task/fork-context-budget.ts +9 -0
  168. package/src/task/index.ts +4 -3
  169. package/src/task/output-manager.ts +4 -2
  170. package/src/task/token-log.test.ts +188 -0
  171. package/src/task/token-log.ts +179 -0
  172. package/src/tools/bisect.ts +367 -0
  173. package/src/tools/index.ts +3 -0
  174. package/src/tools/output-meta.ts +116 -4
  175. package/src/tools/search.ts +8 -2
  176. package/src/tools/skill.ts +15 -0
  177. package/src/utils/file-mentions.ts +39 -7
  178. package/src/utils/git.ts +73 -0
  179. package/src/web/scrapers/youtube.ts +24 -12
@@ -1,5 +1,6 @@
1
1
  import { type AgentTelemetryConfig, type ThinkingLevel } from "@gajae-code/agent-core";
2
2
  import { type Model, type ProviderSessionState } from "@gajae-code/ai";
3
+ import { createAppendOnlyContextManager, providerSupportsAppendOnlyAuto, resolveAppendOnlyMode } from "./append-only-mode";
3
4
  import { type Rule } from "./capability/rule";
4
5
  import { ModelRegistry } from "./config/model-registry";
5
6
  import { type ScopedModelSelection } from "./config/model-resolver";
@@ -241,5 +242,7 @@ export interface BuildSystemPromptOptions {
241
242
  * as separate entries so providers can cache prompt prefixes without concatenating blocks.
242
243
  */
243
244
  export declare function buildSystemPrompt(options?: BuildSystemPromptOptions): Promise<BuildSystemPromptResult>;
245
+ export { createAppendOnlyContextManager, providerSupportsAppendOnlyAuto, resolveAppendOnlyMode };
244
246
  export declare function createPluginHooksExtension(hooks: ConstrainedPluginHook[]): ExtensionFactory;
247
+ export declare function resolveIntentTracingEnabled(intentTracingSetting: boolean | undefined, hasUI: boolean): boolean;
245
248
  export declare function createAgentSession(options?: CreateAgentSessionOptions): Promise<CreateAgentSessionResult>;
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { type Agent, type AgentEvent, type AgentMessage, type AgentState, type AgentTool, type StablePrefixSnapshot, ThinkingLevel } from "@gajae-code/agent-core";
16
16
  import { type CompactionResult, type EmergencyCompactionSample } from "@gajae-code/agent-core/compaction";
17
- import type { AssistantMessage, Effort, ImageContent, Message, MessageAttribution, Model, ProviderSessionState, ServiceTier, SimpleStreamOptions, TextContent, ToolChoice, UsageReport } from "@gajae-code/ai";
17
+ import type { AssistantMessage, Effort, ImageContent, Message, MessageAttribution, Model, ProviderSessionState, ServiceTier, SimpleStreamOptions, TextContent, ToolCall, ToolChoice, UsageReport } from "@gajae-code/ai";
18
18
  export interface ForkContextSeedMetadata {
19
19
  sourceSessionId: string;
20
20
  parentMessageCount: number;
@@ -75,6 +75,7 @@ import { type DiscoverableTool, type DiscoverableToolSearchIndex } from "../tool
75
75
  import type { AskAnswerSource, ToolSession } from "../tools";
76
76
  import type { CheckpointState } from "../tools/checkpoint";
77
77
  import { type TodoItem, type TodoPhase } from "../tools/todo-write";
78
+ import { type WorkspaceTree } from "../workspace-tree";
78
79
  import type { ClientBridge } from "./client-bridge";
79
80
  import { type ContributionPrepOptions, type ContributionPrepResult } from "./contribution-prep";
80
81
  import { type CustomMessage } from "./messages";
@@ -200,6 +201,8 @@ export interface AgentSessionConfig {
200
201
  rebuildSystemPrompt?: (toolNames: string[], tools: Map<string, AgentTool>) => Promise<{
201
202
  systemPrompt: string[];
202
203
  }>;
204
+ /** Initial workspace tree snapshot used for the first volatile per-turn context message. */
205
+ workspaceTree?: WorkspaceTree;
203
206
  /** Rebuild the SSH tool from current capability discovery results. */
204
207
  reloadSshTool?: () => Promise<AgentTool | null>;
205
208
  requestedToolNames?: ReadonlySet<string>;
@@ -336,6 +339,33 @@ export type BeforeAgentStartContributor = (event: {
336
339
  images?: ImageContent[];
337
340
  sessionId: string | undefined;
338
341
  }) => Promise<BeforeAgentStartInternalMessage | undefined>;
342
+ export declare class WorkerIntegrationRequestScheduler {
343
+ #private;
344
+ readonly request: () => Promise<void>;
345
+ constructor(request: () => Promise<void>);
346
+ enqueue(): void;
347
+ flush(): Promise<void>;
348
+ }
349
+ export type StreamingEditParsedToolCall = {
350
+ toolCall: ToolCall;
351
+ path: string;
352
+ resolvedPath: string;
353
+ diff?: string;
354
+ op?: string;
355
+ rename?: string;
356
+ };
357
+ export type StreamingEditParsedCacheEntry = {
358
+ version: string;
359
+ parsed: StreamingEditParsedToolCall | undefined;
360
+ };
361
+ export declare function getStreamingEditToolCallForEvent(event: AgentEvent, cache: Map<string, StreamingEditParsedCacheEntry>, resolvePath: (filePath: string) => string | undefined): StreamingEditParsedToolCall | undefined;
362
+ /** Test-only counters for AgentSession event fan-out hot-path assertions. */
363
+ export declare const __agentSessionPerfCounters: {
364
+ listenerSnapshotRebuilds: number;
365
+ messageUpdateExtensionQueues: number;
366
+ reset(): void;
367
+ };
368
+ export declare function buildContextInjectionSignature(kind: string, parts: readonly string[]): string;
339
369
  export declare class AgentSession {
340
370
  #private;
341
371
  readonly agent: Agent;
@@ -344,6 +374,13 @@ export declare class AgentSession {
344
374
  readonly taskDepth: number;
345
375
  readonly yieldQueue: YieldQueue;
346
376
  readonly configWarnings: string[];
377
+ readonly streamingEditDebugCounters: {
378
+ guardRuns: number;
379
+ processedChars: number;
380
+ checkedRemovedLines: number;
381
+ fullChecks: number;
382
+ nonEditDeterminations: number;
383
+ };
347
384
  readonly rawSseDebugBuffer: RawSseDebugBuffer;
348
385
  constructor(config: AgentSessionConfig);
349
386
  /** Model registry for API key resolution and model discovery */
@@ -716,6 +753,11 @@ export declare class AgentSession {
716
753
  * @returns true if completed, false if cancelled by hook
717
754
  */
718
755
  newSession(options?: NewSessionOptions): Promise<boolean>;
756
+ /**
757
+ * Clear active conversational/model context while preserving the current
758
+ * session identity and durable history trail.
759
+ */
760
+ clearContext(): Promise<boolean>;
719
761
  /**
720
762
  * Set a display name for the current session.
721
763
  */
@@ -0,0 +1,8 @@
1
+ import type { SessionEntry, SessionMessageEntry } from "./session-manager";
2
+ export interface FileMentionPruneResult {
3
+ changed: SessionMessageEntry[];
4
+ bytesSaved: number;
5
+ }
6
+ /** Notice injected in place of a superseded file-mention body. */
7
+ export declare function stalefileMentionNotice(path: string): string;
8
+ export declare function pruneStaleFileMentions(entries: readonly SessionEntry[], resolveAbs: (path: string) => string): FileMentionPruneResult;
@@ -129,6 +129,10 @@ export interface FileMentionMessage {
129
129
  /** Why the file contents were omitted from auto-read. */
130
130
  skippedReason?: "tooLarge";
131
131
  image?: ImageContent;
132
+ /** Set when this mention duplicated a recently shown path (compact note, no full body). */
133
+ duplicate?: boolean;
134
+ /** Set when a stale entry was pruned to a digest notice (never silently deleted). */
135
+ pruned?: boolean;
132
136
  }>;
133
137
  timestamp: number;
134
138
  }
@@ -1,5 +1,6 @@
1
1
  import type { AgentMessage } from "@gajae-code/agent-core";
2
2
  import type { ImageContent, Message, MessageAttribution, ServiceTier, TextContent } from "@gajae-code/ai";
3
+ import type { TtsrInjectionRecord } from "../export/ttsr";
3
4
  import { ArtifactManager } from "./artifacts";
4
5
  import { type BlobPutResult, BlobStore } from "./blob-store";
5
6
  import { type BashExecutionMessage, type CustomMessage, type FileMentionMessage, type HookMessage, type PythonExecutionMessage } from "./messages";
@@ -141,6 +142,10 @@ export interface TtsrInjectionEntry extends SessionEntryBase {
141
142
  type: "ttsr_injection";
142
143
  /** Names of rules that were injected */
143
144
  injectedRules: string[];
145
+ /** Rich rule injection records with repeat state. */
146
+ injectedRuleRecords?: TtsrInjectionRecord[];
147
+ /** TTSR manager message count when this injection was recorded. */
148
+ ttsrMessageCount?: number;
144
149
  }
145
150
  /** Persisted MCP discovery selection state for a session branch. */
146
151
  export interface MCPToolSelectionEntry extends SessionEntryBase {
@@ -212,6 +217,10 @@ export interface SessionContext {
212
217
  models: Record<string, string>;
213
218
  /** Names of TTSR rules that have been injected this session */
214
219
  injectedTtsrRules: string[];
220
+ /** Rich TTSR rule injection records for repeat resume. */
221
+ injectedTtsrRuleRecords?: TtsrInjectionRecord[];
222
+ /** TTSR manager message count for repeat resume. */
223
+ ttsrMessageCount?: number;
215
224
  /** MCP tool names selected through discovery for this session branch. */
216
225
  selectedMCPToolNames: string[];
217
226
  /** Whether this branch contains an explicit persisted MCP selection entry. */
@@ -477,6 +486,13 @@ export declare class SessionManager {
477
486
  appendCompaction<T = unknown>(summary: string, shortSummary: string | undefined, firstKeptEntryId: string, tokensBefore: number, details?: T, fromExtension?: boolean, preserveData?: Record<string, unknown>): string;
478
487
  /** Append a custom entry (for extensions) as child of current leaf, then advance leaf. Returns entry id. */
479
488
  appendCustomEntry(customType: string, data?: unknown): string;
489
+ /**
490
+ * Append a root marker that starts a fresh active branch without changing the
491
+ * session id or deleting earlier durable entries. Subsequent messages descend
492
+ * from this marker, so provider context is clear while history remains
493
+ * available for diagnostics/export.
494
+ */
495
+ appendContextClearEntry(data?: Record<string, unknown>): string;
480
496
  /**
481
497
  * Write mutated message entries back into the canonical entry store by id.
482
498
  *
@@ -511,7 +527,7 @@ export declare class SessionManager {
511
527
  * @param ruleNames Names of rules that were injected
512
528
  * @returns Entry id
513
529
  */
514
- appendTtsrInjection(ruleNames: string[]): string;
530
+ appendTtsrInjection(ruleNames: string[], records?: TtsrInjectionRecord[], ttsrMessageCount?: number): string;
515
531
  /**
516
532
  * Get all unique TTSR rule names that have been injected in the current branch.
517
533
  * Scans from root to current leaf for ttsr_injection entries.
@@ -92,7 +92,24 @@ export declare function listActiveSkills(raw: unknown): SkillActiveEntry[];
92
92
  export declare function normalizeSkillActiveState(raw: unknown): SkillActiveState | null;
93
93
  export declare function getSkillActiveStatePaths(cwd: string, sessionId?: string): SkillActiveStatePaths;
94
94
  export declare function collapsePlanningPipeline(entries: readonly SkillActiveEntry[]): SkillActiveEntry[];
95
- export declare function readVisibleSkillActiveState(cwd: string, sessionId?: string): Promise<SkillActiveState | null>;
95
+ export type VisibleSkillActiveStateCacheTier = "security" | "hud";
96
+ export interface ReadVisibleSkillActiveStateOptions {
97
+ tier?: VisibleSkillActiveStateCacheTier;
98
+ }
99
+ interface ActiveStateStatSignature {
100
+ path: string;
101
+ mtimeMs: number;
102
+ size: number;
103
+ }
104
+ interface ActiveStateSignature {
105
+ sessionPath: ActiveStateStatSignature | null;
106
+ activeDir: ActiveStateStatSignature | null;
107
+ activeEntries: ActiveStateStatSignature[];
108
+ ralplanModeState: ActiveStateStatSignature | null;
109
+ }
110
+ export declare function computeActiveStateSignature(cwd: string, sessionId: string): Promise<ActiveStateSignature>;
111
+ export declare function invalidateVisibleSkillActiveStateCache(cwd?: string, sessionId?: string): void;
112
+ export declare function readVisibleSkillActiveState(cwd: string, sessionId?: string, opts?: ReadVisibleSkillActiveStateOptions): Promise<SkillActiveState | null>;
96
113
  export declare function syncSkillActiveState(options: SyncSkillActiveStateOptions): Promise<void>;
97
114
  export interface ApplyHandoffOptions {
98
115
  cwd: string;
@@ -17,9 +17,12 @@ export interface LoadContextFilesOptions {
17
17
  cwd?: string;
18
18
  }
19
19
  /**
20
- * Load all project context files using the capability API.
20
+ * Load all context files using the capability API.
21
21
  * Returns {path, content, depth} entries for all discovered context files.
22
- * Files are sorted by depth (descending) so files closer to cwd appear last/more prominent.
22
+ * Native user-global files (`~/.gjc/agent/AGENTS.md`) come first, then project
23
+ * files sorted by depth (descending) so files closer to cwd appear last/more
24
+ * prominent. User-home files from foreign providers (`~/.claude/CLAUDE.md`,
25
+ * `~/.codex/AGENTS.md`, …) stay excluded — only gjc's own user config applies.
23
26
  */
24
27
  export declare function loadProjectContextFiles(options?: LoadContextFilesOptions): Promise<Array<{
25
28
  path: string;
@@ -91,12 +94,25 @@ export interface BuildSystemPromptOptions {
91
94
  secretsEnabled?: boolean;
92
95
  /** Pre-loaded workspace tree (skips discovery if provided). May be a Promise to allow early kick-off. */
93
96
  workspaceTree?: WorkspaceTree | Promise<WorkspaceTree>;
97
+ /**
98
+ * Render a trimmed role-agent base prompt for subagent sessions: omits the
99
+ * workflow-surface/routing/self-awareness (`<gjc-runtime>`) and `<soul>` blocks
100
+ * that only apply to the top-level interactive/print agent. Tool safety, repo
101
+ * safety, and the completion contract are retained. Default: false.
102
+ */
103
+ subagent?: boolean;
94
104
  }
95
105
  /** Result of building provider-facing system prompt messages. */
96
106
  export interface BuildSystemPromptResult {
97
107
  /** Ordered system prompt blocks. Providers should preserve entries as distinct messages/blocks. */
98
108
  systemPrompt: string[];
99
109
  }
110
+ export interface BuildVolatileProjectContextOptions {
111
+ cwd?: string;
112
+ date?: string;
113
+ workspaceTree?: WorkspaceTree;
114
+ }
115
+ export declare function buildVolatileProjectContext(options?: BuildVolatileProjectContextOptions): string;
100
116
  /** Build the system prompt with tools, guidelines, and context */
101
117
  export declare function buildSystemPrompt(options?: BuildSystemPromptOptions): Promise<BuildSystemPromptResult>;
102
118
  export {};
@@ -114,6 +114,7 @@ interface FinalizeSubprocessOutputResult {
114
114
  }
115
115
  export declare const SUBAGENT_WARNING_NULL_YIELD = "SYSTEM WARNING: Subagent called yield with null data.";
116
116
  export declare const SUBAGENT_WARNING_MISSING_YIELD = "SYSTEM WARNING: Subagent exited without calling yield tool after 3 reminders.";
117
+ export declare const SUBAGENT_WARNING_PLACEHOLDER_YIELD = "SYSTEM WARNING: Subagent yield data contains a placeholder instead of the actual result.";
117
118
  export declare function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): FinalizeSubprocessOutputResult;
118
119
  export declare function createSubagentSettings(baseSettings: Settings, inheritedServiceTier?: ServiceTier): Settings;
119
120
  /**
@@ -0,0 +1,7 @@
1
+ export declare const FORK_CONTEXT_TOKEN_BUDGET_BY_MODE: {
2
+ readonly none: 0;
3
+ readonly receipt: 2000;
4
+ readonly "last-turn": 4000;
5
+ readonly bounded: 8000;
6
+ readonly full: 15000;
7
+ };
@@ -0,0 +1,30 @@
1
+ import type { ChatUsageSnapshot, CostEstimate } from "@gajae-code/agent-core";
2
+ import type { TaskTokenLog, TaskTokenMetrics } from "./types";
3
+ export interface TaskTokenLogChatBuckets {
4
+ readonly inputTokens: number;
5
+ readonly outputTokens: number;
6
+ readonly cachedInputTokens: number;
7
+ readonly cacheWriteTokens: number;
8
+ readonly costUsd?: number;
9
+ }
10
+ export interface TaskTokenLogSessionManager {
11
+ getSessionId(): string;
12
+ }
13
+ export interface TaskTokenLogContext {
14
+ readonly subagentId: string;
15
+ readonly agent?: string;
16
+ readonly turn: number;
17
+ readonly at: string;
18
+ readonly model?: string;
19
+ }
20
+ export declare function taskTokenLogFromChat(chat: TaskTokenLogChatBuckets, ctx: TaskTokenLogContext): TaskTokenLog;
21
+ export declare function taskTokenLogFromUsage(usage: ChatUsageSnapshot, ctx: TaskTokenLogContext & {
22
+ readonly cost?: CostEstimate;
23
+ }): TaskTokenLog;
24
+ export declare function resolveTaskTokenLogDir(cwd: string, sessionManager: TaskTokenLogSessionManager | undefined, envSessionId?: string | undefined): Promise<string | undefined>;
25
+ export declare function persistTaskTokenLog(entry: TaskTokenLog, opts: {
26
+ dir: string;
27
+ }): Promise<void>;
28
+ export declare function readTaskTokenLogs(dir: string): Promise<TaskTokenLog[]>;
29
+ export declare function computeTaskTokenMetrics(logs: readonly TaskTokenLog[]): TaskTokenMetrics;
30
+ export declare function computeCacheHitRate(input: number, cacheRead: number): number;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,81 @@
1
+ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@gajae-code/agent-core";
2
+ import * as z from "zod/v4";
3
+ import type { ToolSession } from ".";
4
+ import type { OutputMeta } from "./output-meta";
5
+ declare const bisectSchema: z.ZodObject<{
6
+ good: z.ZodString;
7
+ bad: z.ZodDefault<z.ZodString>;
8
+ run: z.ZodString;
9
+ invert: z.ZodDefault<z.ZodBoolean>;
10
+ maxSteps: z.ZodDefault<z.ZodNumber>;
11
+ stepTimeoutMs: z.ZodDefault<z.ZodNumber>;
12
+ }, z.core.$strip>;
13
+ type BisectParams = z.infer<typeof bisectSchema>;
14
+ export type BisectVerdict = "good" | "bad" | "skip";
15
+ export interface BisectStep {
16
+ rev: string;
17
+ verdict: BisectVerdict;
18
+ }
19
+ export interface BisectMarkResult {
20
+ exitCode: number;
21
+ output: string;
22
+ }
23
+ export interface BisectControllerDeps {
24
+ maxSteps: number;
25
+ /** SHA of the revision git currently has checked out. */
26
+ currentRev: () => Promise<string>;
27
+ /** Evaluate the predicate at the checked-out revision. */
28
+ evaluate: (rev: string) => Promise<BisectVerdict>;
29
+ /** Apply the verdict via `git bisect good|bad|skip` and return the raw result. */
30
+ mark: (verdict: BisectVerdict) => Promise<BisectMarkResult>;
31
+ }
32
+ export interface BisectOutcome {
33
+ culprit: string | null;
34
+ steps: BisectStep[];
35
+ concluded: boolean;
36
+ reason?: string;
37
+ }
38
+ export interface BisectToolDetails {
39
+ meta?: OutputMeta;
40
+ culprit: string | null;
41
+ invert: boolean;
42
+ concluded: boolean;
43
+ steps: BisectStep[];
44
+ author?: string;
45
+ date?: string;
46
+ subject?: string;
47
+ reason?: string;
48
+ }
49
+ /** Parse the culprit SHA from `git bisect good|bad` output, or null when not yet converged. */
50
+ export declare function parseFirstBadCommit(output: string): string | null;
51
+ /**
52
+ * Map a predicate exit code to a bisect verdict. `invert` swaps the good/bad
53
+ * mapping (to hunt for a fixing commit) but never reinterprets a skip.
54
+ */
55
+ export declare function classifyExit(exitCode: number, invert: boolean): BisectVerdict;
56
+ /**
57
+ * Drive the bisect loop. Pure orchestration — every git/predicate effect is
58
+ * injected — so it can be exercised deterministically without a real repo.
59
+ */
60
+ export declare function runBisectController(deps: BisectControllerDeps, signal?: AbortSignal): Promise<BisectOutcome>;
61
+ export declare class BisectTool implements AgentTool<typeof bisectSchema, BisectToolDetails> {
62
+ private readonly session;
63
+ readonly name = "bisect";
64
+ readonly label = "Bisect";
65
+ readonly summary = "Find the commit that introduced a regression by driving git bisect with a shell predicate";
66
+ readonly description: string;
67
+ readonly parameters: z.ZodObject<{
68
+ good: z.ZodString;
69
+ bad: z.ZodDefault<z.ZodString>;
70
+ run: z.ZodString;
71
+ invert: z.ZodDefault<z.ZodBoolean>;
72
+ maxSteps: z.ZodDefault<z.ZodNumber>;
73
+ stepTimeoutMs: z.ZodDefault<z.ZodNumber>;
74
+ }, z.core.$strip>;
75
+ readonly strict = true;
76
+ readonly loadMode = "discoverable";
77
+ readonly intent: (args: Partial<BisectParams>) => string;
78
+ constructor(session: ToolSession);
79
+ execute(_toolCallId: string, params: BisectParams, signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<BisectToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<BisectToolDetails>>;
80
+ }
81
+ export {};
@@ -31,6 +31,7 @@ export * from "./ask";
31
31
  export * from "./ast-edit";
32
32
  export * from "./ast-grep";
33
33
  export * from "./bash";
34
+ export * from "./bisect";
34
35
  export * from "./browser";
35
36
  export * from "./calculator";
36
37
  export * from "./checkpoint";
@@ -8,7 +8,7 @@ import type { ToolSession } from ".";
8
8
  import { type OutputMeta } from "./output-meta";
9
9
  declare const searchSchema: z.ZodObject<{
10
10
  pattern: z.ZodString;
11
- paths: z.ZodArray<z.ZodString>;
11
+ paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
12
12
  i: z.ZodOptional<z.ZodBoolean>;
13
13
  gitignore: z.ZodOptional<z.ZodBoolean>;
14
14
  skip: z.ZodOptional<z.ZodNumber>;
@@ -61,7 +61,7 @@ export declare class SearchTool implements AgentTool<typeof searchSchema, Search
61
61
  readonly description: string;
62
62
  readonly parameters: z.ZodObject<{
63
63
  pattern: z.ZodString;
64
- paths: z.ZodArray<z.ZodString>;
64
+ paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
65
65
  i: z.ZodOptional<z.ZodBoolean>;
66
66
  gitignore: z.ZodOptional<z.ZodBoolean>;
67
67
  skip: z.ZodOptional<z.ZodNumber>;
@@ -1,4 +1,10 @@
1
1
  import type { AgentMessage } from "@gajae-code/agent-core";
2
+ /**
3
+ * Default inline cap for auto-read file mentions, deliberately below the
4
+ * read-tool cap (`DEFAULT_MAX_BYTES`, 50KB) so an incidental `@path` mention
5
+ * injects a smaller snippet than an explicit `read`. Overridable per call.
6
+ */
7
+ export declare const DEFAULT_FILE_MENTION_INLINE_BYTES: number;
2
8
  /** Extract all @filepath mentions from text */
3
9
  export declare function extractFileMentions(text: string): string[];
4
10
  /**
@@ -8,4 +14,12 @@ export declare function extractFileMentions(text: string): string[];
8
14
  export declare function generateFileMentionMessages(filePaths: string[], cwd: string, options?: {
9
15
  autoResizeImages?: boolean;
10
16
  useHashLines?: boolean;
17
+ /** Inline byte cap for auto-read text. Default: DEFAULT_FILE_MENTION_INLINE_BYTES. */
18
+ maxInlineBytes?: number;
19
+ /**
20
+ * Resolved paths already shown (read or mentioned) recently in the
21
+ * conversation. A mention of one of these emits a compact duplicate note
22
+ * instead of re-injecting the full body.
23
+ */
24
+ recentlyShownPaths?: ReadonlySet<string>;
11
25
  }): Promise<AgentMessage[]>;
@@ -307,6 +307,38 @@ export declare function clean(cwd: string, options?: {
307
307
  paths?: readonly string[];
308
308
  signal?: AbortSignal;
309
309
  }): Promise<void>;
310
+ export interface BisectCommitInfo {
311
+ sha: string;
312
+ author: string;
313
+ date: string;
314
+ subject: string;
315
+ stat: string;
316
+ }
317
+ /**
318
+ * Thin wrappers over `git bisect`. The marking commands (`good`/`bad`/`skip`)
319
+ * return the raw {@link GitCommandResult} without throwing so callers can both
320
+ * detect a genuine failure (non-zero exit) and scan the output for the
321
+ * "<sha> is the first bad commit" conclusion. `reset` is best-effort and never
322
+ * throws so it is safe to call from a `finally` block to restore the worktree.
323
+ */
324
+ export declare const bisect: {
325
+ /** Begin a bisect session (does not seed good/bad endpoints). */
326
+ start(cwd: string, signal?: AbortSignal): Promise<void>;
327
+ /** Mark a revision (or current HEAD when omitted) good. Returns raw output. */
328
+ good(cwd: string, ref?: string, signal?: AbortSignal): Promise<GitCommandResult>;
329
+ /** Mark a revision (or current HEAD when omitted) bad. Returns raw output. */
330
+ bad(cwd: string, ref?: string, signal?: AbortSignal): Promise<GitCommandResult>;
331
+ /** Skip the current (untestable) revision. Returns raw output. */
332
+ skip(cwd: string, signal?: AbortSignal): Promise<GitCommandResult>;
333
+ /** Read the replayable bisect log for the current session. */
334
+ log(cwd: string, signal?: AbortSignal): Promise<string>;
335
+ /** End the bisect session, restoring the original HEAD. Never throws. */
336
+ reset(cwd: string, signal?: AbortSignal): Promise<void>;
337
+ /** True when `ancestor` is a first-parent-or-merge ancestor of `descendant`. */
338
+ isAncestor(cwd: string, ancestor: string, descendant: string, signal?: AbortSignal): Promise<boolean>;
339
+ /** Resolve author/date/subject and a diffstat for a commit (for the receipt). */
340
+ describe(cwd: string, sha: string, signal?: AbortSignal): Promise<BisectCommitInfo>;
341
+ };
310
342
  export declare const ls: {
311
343
  /** List files tracked or untracked by git. */
312
344
  files(cwd: string, options?: {
@@ -1,4 +1,12 @@
1
1
  import type { SpecialHandler } from "./types";
2
+ export interface YouTubeUrl {
3
+ videoId: string;
4
+ playlistId?: string;
5
+ }
6
+ /**
7
+ * Parse YouTube URL into components
8
+ */
9
+ export declare function parseYouTubeUrl(url: string): YouTubeUrl | null;
2
10
  /**
3
11
  * Handle YouTube URLs - fetch metadata and transcript
4
12
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@gajae-code/coding-agent",
4
- "version": "0.8.2",
4
+ "version": "0.9.0",
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",
@@ -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.8.2",
56
- "@gajae-code/agent-core": "0.8.2",
57
- "@gajae-code/ai": "0.8.2",
58
- "@gajae-code/natives": "0.8.2",
59
- "@gajae-code/tui": "0.8.2",
60
- "@gajae-code/utils": "0.8.2",
55
+ "@gajae-code/stats": "0.9.0",
56
+ "@gajae-code/agent-core": "0.9.0",
57
+ "@gajae-code/ai": "0.9.0",
58
+ "@gajae-code/natives": "0.9.0",
59
+ "@gajae-code/tui": "0.9.0",
60
+ "@gajae-code/utils": "0.9.0",
61
61
  "@puppeteer/browsers": "^2.13.0",
62
62
  "@types/turndown": "5.0.6",
63
63
  "@xterm/headless": "^6.0.0",
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Single source of truth for append-only context-mode resolution and manager
3
+ * construction. Both the initial session build (`sdk.ts`) and the runtime
4
+ * model/setting-change path (`agent-session.ts`), plus the status UI, resolve
5
+ * through here so the auto allowlist and prefix-reset diagnostics never drift.
6
+ */
7
+
8
+ import { AppendOnlyContextManager } from "@gajae-code/agent-core";
9
+ import { logger } from "@gajae-code/utils";
10
+
11
+ /**
12
+ * Providers for which append-only context auto-enables. Exact provider-string
13
+ * match only: `anthropic` reached via a gateway/aggregator provider string
14
+ * (e.g. `openrouter`, a custom gateway) does NOT match and stays opt-in via
15
+ * `provider.appendOnlyContext: "on"`, because those transports can rewrite or
16
+ * renormalize the request in ways that have not been validated for append-only
17
+ * prefix stability.
18
+ */
19
+ export function providerSupportsAppendOnlyAuto(provider: string): boolean {
20
+ return provider === "deepseek" || provider === "anthropic";
21
+ }
22
+
23
+ /**
24
+ * Resolve whether to enable append-only context mode based on the setting and provider.
25
+ *
26
+ * - `"on"` → always enable
27
+ * - `"off"` → never enable
28
+ * - `"auto"` → enable for providers with strong prompt-prefix caching that this
29
+ * harness has validated (see {@link providerSupportsAppendOnlyAuto})
30
+ */
31
+ export function resolveAppendOnlyMode(setting: "auto" | "on" | "off" | undefined, provider: string): boolean {
32
+ switch (setting ?? "auto") {
33
+ case "on":
34
+ return true;
35
+ case "off":
36
+ return false;
37
+ default:
38
+ return providerSupportsAppendOnlyAuto(provider);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Construct an {@link AppendOnlyContextManager} wired to emit per-session
44
+ * stable-prefix reset diagnostics. Use this at every creation site so the
45
+ * telemetry is uniform.
46
+ */
47
+ export function createAppendOnlyContextManager(provider: string | undefined): AppendOnlyContextManager {
48
+ return new AppendOnlyContextManager({
49
+ onPrefixChange: info =>
50
+ logger.debug("append-only stable prefix changed (cache prefix reset)", {
51
+ provider,
52
+ from: info.from,
53
+ to: info.to,
54
+ version: info.version,
55
+ reason: info.from === "<unbuilt>" ? "initial-build" : "prefix-mutation",
56
+ }),
57
+ });
58
+ }
@@ -22,7 +22,7 @@ You are running an autonomous experiment loop. Keep iterating until the user int
22
22
  ### Available tools
23
23
  - `init_experiment` — open or reconfigure the session. Pass `new_segment: true` to start a fresh baseline within the current session.
24
24
  - `run_experiment` — run the benchmark (`bash autoresearch.sh`). Output is captured automatically and `METRIC name=value` / `ASI key=value` lines printed by the harness are parsed back to you. The command is fixed; if you need a different workload, edit `autoresearch.sh` and bump segment via `init_experiment new_segment: true`.
25
- - `log_experiment` — record the result. On `keep`, modified files are committed for you; on `discard`/`crash`/`checks_failed`, the worktree is reverted. Pass `flag_runs` to mark earlier runs as suspect; flagged runs are excluded from baseline and best-metric math.
25
+ - `log_experiment` — record the result. On `keep`, changes are committed only on a dedicated `autoresearch/*` branch; otherwise the tool warns and leaves files in the worktree. On `discard`/`crash`/`checks_failed`, the worktree is reverted. Pass `flag_runs` to mark earlier runs as suspect; flagged runs are excluded from baseline and best-metric math.
26
26
  - `update_notes` — replace the durable session playbook (`body`) or append to the ideas backlog (`append_idea`). The notes are injected into your system prompt every iteration.
27
27
 
28
28
  ### Operating protocol
@@ -62,7 +62,7 @@ export function createLogExperimentTool(
62
62
  name: "log_experiment",
63
63
  label: "Log Experiment",
64
64
  description:
65
- "Log the result of the latest run_experiment. Records the metric, optional ASI metadata, modified paths, and scope deviations. On `keep`, modified files are committed; on `discard`/`crash`/`checks_failed`, the worktree is reverted. Pass `flag_runs` to mark earlier runs as suspect; flagged runs are excluded from baseline and best-metric math.",
65
+ "Log the result of the latest run_experiment. Records the metric, optional ASI metadata, modified paths, and scope deviations. On `keep`, modified files are committed only on a dedicated `autoresearch/*` branch; otherwise the tool warns and leaves them in the worktree. On `discard`/`crash`/`checks_failed`, the worktree is reverted. Pass `flag_runs` to mark earlier runs as suspect; flagged runs are excluded from baseline and best-metric math.",
66
66
  parameters: logExperimentSchema,
67
67
  defaultInactive: true,
68
68
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
@@ -22,6 +22,11 @@ export interface RuleFrontmatter {
22
22
  scope?: string | string[];
23
23
  /** Per-rule TTSR interrupt mode override. */
24
24
  interruptMode?: "never" | "prose-only" | "tool-only" | "always";
25
+ /** Per-rule TTSR repeat mode override. */
26
+ repeatMode?: "once" | "after-gap";
27
+ /** Per-rule TTSR repeat gap override. */
28
+ repeatGap?: number;
29
+
25
30
  [key: string]: unknown;
26
31
  }
27
32
 
@@ -47,6 +52,10 @@ export interface Rule {
47
52
  scope?: string[];
48
53
  /** Per-rule TTSR interrupt mode override (falls back to global ttsr.interruptMode). */
49
54
  interruptMode?: "never" | "prose-only" | "tool-only" | "always";
55
+ /** Per-rule TTSR repeat mode override (falls back to global ttsr.repeatMode). */
56
+ repeatMode?: "once" | "after-gap";
57
+ /** Per-rule TTSR repeat gap override (falls back to global ttsr.repeatGap). */
58
+ repeatGap?: number;
50
59
  /** Source metadata */
51
60
  _source: SourceMeta;
52
61
  }