@gajae-code/coding-agent 0.18.8 → 0.18.9
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 +98 -0
- package/dist/types/async/endpoint-id.d.ts +16 -0
- package/dist/types/async/support.d.ts +0 -14
- package/dist/types/commands/mcp-serve.d.ts +4 -0
- package/dist/types/discovery/mcp-json.d.ts +1 -0
- package/dist/types/eval/py/kernel.d.ts +18 -0
- package/dist/types/export/html/html-export-destination.d.ts +2 -0
- package/dist/types/extensibility/extensions/function-hooks-internal.d.ts +5 -0
- package/dist/types/extensibility/skill-management.d.ts +1 -0
- package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -3
- package/dist/types/gjc-runtime/sidecar-bootstrap-env.d.ts +6 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +3 -0
- package/dist/types/gjc-runtime/tmux-common.d.ts +8 -5
- package/dist/types/lsp/config.d.ts +8 -5
- package/dist/types/runtime-mcp/manager.d.ts +2 -1
- package/dist/types/runtime-mcp/mcp-redirect.d.ts +9 -0
- package/dist/types/runtime-mcp/oauth-public-url.d.ts +3 -1
- package/dist/types/runtime-mcp/project-host-values.d.ts +27 -0
- package/dist/types/sdk/broker/broker.d.ts +6 -1
- package/dist/types/sdk/broker/doctor-restart.d.ts +5 -0
- package/dist/types/sdk/broker/ensure.d.ts +14 -1
- package/dist/types/session/session-storage.d.ts +7 -0
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +3 -0
- package/dist/types/task/isolation-dir.d.ts +26 -0
- package/dist/types/tools/ast-edit-write-path.d.ts +13 -0
- package/dist/types/tools/browser/cdp-url.d.ts +2 -0
- package/dist/types/tools/github-side-effect.d.ts +22 -0
- package/dist/types/tools/monitor-mutation.d.ts +9 -0
- package/package.json +7 -7
- package/src/async/endpoint-id.ts +26 -0
- package/src/async/job-manager.ts +19 -10
- package/src/async/support.ts +0 -25
- package/src/capability/index.ts +14 -16
- package/src/cli/doctor/repairs.ts +4 -1
- package/src/cli/doctor-supervisor.ts +3 -0
- package/src/cli/public-command-registry.ts +28 -6
- package/src/commands/mcp-serve.ts +7 -0
- package/src/commands/sdk.ts +453 -415
- package/src/config/file-lock.ts +9 -11
- package/src/config/model-profile-activation.ts +5 -5
- package/src/coordinator-mcp/server.ts +2 -0
- package/src/customization/inventory.ts +1 -13
- package/src/dap/config.ts +2 -2
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +10 -6
- package/src/discovery/builtin.ts +3 -1
- package/src/discovery/helpers.ts +12 -9
- package/src/discovery/mcp-json.ts +20 -12
- package/src/eval/py/executor.ts +459 -77
- package/src/eval/py/kernel.ts +79 -13
- package/src/eval/py/tool-bridge.ts +4 -0
- package/src/export/html/html-export-destination.ts +16 -0
- package/src/export/html/index.ts +2 -6
- package/src/extensibility/extensions/function-hooks-internal.ts +27 -0
- package/src/extensibility/extensions/runner.ts +11 -1
- package/src/extensibility/gjc-plugins/mcp-policy.ts +2 -1
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +27 -15
- package/src/extensibility/skill-management.ts +3 -0
- package/src/gjc-runtime/launch-worktree.ts +56 -5
- package/src/gjc-runtime/psmux-detect.ts +28 -4
- package/src/gjc-runtime/session-state-sidecar.ts +3 -2
- package/src/gjc-runtime/sidecar-bootstrap-env.ts +19 -0
- package/src/gjc-runtime/state-writer.ts +22 -8
- package/src/gjc-runtime/tmux-common.ts +8 -5
- package/src/internal-urls/docs-index.generated.ts +7 -7
- package/src/lsp/config.ts +12 -63
- package/src/memories/index.ts +88 -7
- package/src/modes/components/hook-editor.ts +1 -1
- package/src/modes/components/hook-selector.ts +1 -1
- package/src/modes/controllers/input-controller.ts +2 -2
- package/src/modes/controllers/runtime-mcp-command-controller.ts +21 -13
- package/src/modes/controllers/selector-controller.ts +3 -7
- package/src/modes/controllers/todo-command-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +1 -1
- package/src/runtime-mcp/client.ts +4 -2
- package/src/runtime-mcp/json-rpc.ts +2 -1
- package/src/runtime-mcp/manager.ts +29 -11
- package/src/runtime-mcp/mcp-redirect.ts +73 -0
- package/src/runtime-mcp/oauth-flow.ts +11 -4
- package/src/runtime-mcp/oauth-public-url.ts +8 -2
- package/src/runtime-mcp/pool.ts +6 -0
- package/src/runtime-mcp/project-host-values.ts +46 -0
- package/src/runtime-mcp/transports/http.ts +2 -1
- package/src/sdk/acp/adapter.ts +2 -0
- package/src/sdk/broker/broker.ts +6 -0
- package/src/sdk/broker/doctor-restart.ts +4 -0
- package/src/sdk/broker/ensure.ts +29 -2
- package/src/sdk/host/session-runtime.test.ts +58 -9
- package/src/sdk/host/session-runtime.ts +65 -35
- package/src/sdk/router/session-router.ts +7 -6
- package/src/sdk/session.ts +2 -7
- package/src/session/agent-session.ts +59 -17
- package/src/session/artifacts.ts +3 -2
- package/src/session/internal/managed-session-scope.ts +403 -81
- package/src/session/internal/managed-session-storage.ts +125 -17
- package/src/session/session-manager.ts +12 -0
- package/src/session/session-storage.ts +30 -1
- package/src/skill-state/active-state.ts +13 -0
- package/src/skill-state/workflow-mutation-guard.ts +102 -10
- package/src/slash-commands/builtin-registry.ts +1 -1
- package/src/slash-commands/helpers/mcp.ts +8 -4
- package/src/task/isolation-dir.ts +143 -0
- package/src/task/worktree.ts +16 -7
- package/src/tools/ast-edit-write-path.ts +68 -0
- package/src/tools/ast-edit.ts +7 -2
- package/src/tools/browser/cdp-url.ts +18 -0
- package/src/tools/browser.ts +8 -1
- package/src/tools/gh.ts +10 -0
- package/src/tools/github-side-effect.ts +112 -0
- package/src/tools/monitor-mutation.ts +27 -0
- package/src/tools/monitor.ts +7 -0
- package/src/tools/python.ts +7 -6
- package/src/utils/external-editor.ts +3 -2
- package/src/web/insane/url-guard.ts +2 -1
|
@@ -215,12 +215,12 @@ import {
|
|
|
215
215
|
type AsyncJob,
|
|
216
216
|
type AsyncJobDeliveryState,
|
|
217
217
|
AsyncJobManager,
|
|
218
|
-
asyncJobEndpointId as deriveAsyncJobEndpointId,
|
|
219
218
|
type FoldReason,
|
|
220
219
|
type JobFoldEvent,
|
|
221
220
|
type OwnerSubagentShutdownLease,
|
|
222
221
|
type SubagentLifecycle,
|
|
223
222
|
} from "../async";
|
|
223
|
+
import { asyncJobEndpointId as deriveAsyncJobEndpointId } from "../async/endpoint-id";
|
|
224
224
|
import { reset as resetCapabilities } from "../capability";
|
|
225
225
|
import type { Rule } from "../capability/rule";
|
|
226
226
|
import type { CasReceipt } from "../config/atomic-yaml-patch";
|
|
@@ -238,11 +238,8 @@ import {
|
|
|
238
238
|
} from "../config/model-profile-contract";
|
|
239
239
|
import {
|
|
240
240
|
commitDurableModelProfileOwnership,
|
|
241
|
-
type DurableModelProfileOwnership,
|
|
242
241
|
InvalidModelProfileOwnershipError,
|
|
243
242
|
ModelProfileOwnershipConflictError,
|
|
244
|
-
type ModelProfileOwnershipMarker,
|
|
245
|
-
modelProfileOwnershipMarkersEqual,
|
|
246
243
|
readDurableModelProfileOwnership,
|
|
247
244
|
} from "../config/model-profile-ownership";
|
|
248
245
|
import { resolveProfileBindings } from "../config/model-profiles";
|
|
@@ -427,7 +424,7 @@ import {
|
|
|
427
424
|
readVisibleSkillActiveState,
|
|
428
425
|
syncSkillActiveState,
|
|
429
426
|
} from "../skill-state/active-state";
|
|
430
|
-
import { assertWorkflowMutationAllowed } from "../skill-state/workflow-mutation-guard";
|
|
427
|
+
import { assertWorkflowMutationAllowed, isWorkflowMutationTool } from "../skill-state/workflow-mutation-guard";
|
|
431
428
|
import { invalidateHostMetadata } from "../ssh/connection-manager";
|
|
432
429
|
import { buildVolatileProjectContext } from "../system-prompt";
|
|
433
430
|
import { DelegationHintController } from "../task/delegation-hint";
|
|
@@ -452,6 +449,7 @@ import {
|
|
|
452
449
|
import { assertEditableFile } from "../tools/auto-generated-guard";
|
|
453
450
|
import { releaseTabsForOwner } from "../tools/browser/tab-supervisor";
|
|
454
451
|
import type { CheckpointState } from "../tools/checkpoint";
|
|
452
|
+
import { githubPermissionIntent } from "../tools/github-side-effect";
|
|
455
453
|
import { outputMeta, wrapToolWithMetaNotice } from "../tools/output-meta";
|
|
456
454
|
import { normalizeLocalScheme, resolveReadPath, resolveToCwd } from "../tools/path-utils";
|
|
457
455
|
import { registerResourceGcSession } from "../tools/resource-gc";
|
|
@@ -922,6 +920,28 @@ export interface QueuedInputSubmission {
|
|
|
922
920
|
|
|
923
921
|
/** Listener function for agent session events */
|
|
924
922
|
export type AgentSessionEventListener = (event: AgentSessionEvent) => void;
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Deliver one event to one listener, containing both synchronous throws and
|
|
926
|
+
* async rejections. Listeners are `void`-typed but interactive mode subscribes
|
|
927
|
+
* with an `async` one whose handlers can persist (plan approval calls
|
|
928
|
+
* `session.prompt()`); a rejection there, e.g. the managed append fence after
|
|
929
|
+
* another process took over the transcript, must not escape as an unhandled
|
|
930
|
+
* rejection and terminate the process.
|
|
931
|
+
*/
|
|
932
|
+
function deliverSessionEvent(
|
|
933
|
+
listener: AgentSessionEventListener,
|
|
934
|
+
event: AgentSessionEvent,
|
|
935
|
+
onError: (error: unknown) => void,
|
|
936
|
+
): void {
|
|
937
|
+
try {
|
|
938
|
+
const result: unknown = listener(event);
|
|
939
|
+
if (result instanceof Promise) result.catch(onError);
|
|
940
|
+
} catch (error) {
|
|
941
|
+
onError(error);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
925
945
|
export type AsyncJobSnapshotItem = Pick<
|
|
926
946
|
AsyncJob,
|
|
927
947
|
"id" | "type" | "status" | "label" | "startTime" | "endTime" | "metadata"
|
|
@@ -1990,7 +2010,7 @@ async function discardPreparedNewSessionAfterFailure(
|
|
|
1990
2010
|
// ============================================================================
|
|
1991
2011
|
|
|
1992
2012
|
/** Tools that require user permission before execution when an ACP client is connected. */
|
|
1993
|
-
const PERMISSION_REQUIRED_TOOLS = new Set(["bash", "monitor", "eval", "edit", "delete", "move"]);
|
|
2013
|
+
const PERMISSION_REQUIRED_TOOLS = new Set(["bash", "monitor", "eval", "edit", "delete", "move", "github"]);
|
|
1994
2014
|
|
|
1995
2015
|
function isShellExecutionPermissionTool(toolName: string): boolean {
|
|
1996
2016
|
return toolName === "bash" || toolName === "monitor";
|
|
@@ -2114,6 +2134,7 @@ function getPermissionIntent(
|
|
|
2114
2134
|
cacheKey: "edit:move",
|
|
2115
2135
|
};
|
|
2116
2136
|
}
|
|
2137
|
+
if (toolName === "github") return githubPermissionIntent(args);
|
|
2117
2138
|
return undefined;
|
|
2118
2139
|
}
|
|
2119
2140
|
|
|
@@ -6931,11 +6952,9 @@ export class AgentSession {
|
|
|
6931
6952
|
/** Emit an event to all listeners without letting one subscriber poison lifecycle settlement. */
|
|
6932
6953
|
#emit(event: AgentSessionEvent): void {
|
|
6933
6954
|
for (const listener of this.#eventListenerSnapshot) {
|
|
6934
|
-
|
|
6935
|
-
listener(event);
|
|
6936
|
-
} catch (error) {
|
|
6955
|
+
deliverSessionEvent(listener, event, error => {
|
|
6937
6956
|
logger.warn("Agent session event subscriber failed", { event: event.type, error: String(error) });
|
|
6938
|
-
}
|
|
6957
|
+
});
|
|
6939
6958
|
}
|
|
6940
6959
|
}
|
|
6941
6960
|
|
|
@@ -11815,7 +11834,9 @@ export class AgentSession {
|
|
|
11815
11834
|
: undefined;
|
|
11816
11835
|
const commandContent = command
|
|
11817
11836
|
? [{ type: "content" as const, content: { type: "text" as const, text: `$ ${command}` } }]
|
|
11818
|
-
:
|
|
11837
|
+
: target.name === "github"
|
|
11838
|
+
? [{ type: "content" as const, content: { type: "text" as const, text: permissionIntent.title } }]
|
|
11839
|
+
: undefined;
|
|
11819
11840
|
if (this.#sdkPermissionMode === "allow") {
|
|
11820
11841
|
return await target.execute(toolCallId, args as never, signal, onUpdate, ctx);
|
|
11821
11842
|
}
|
|
@@ -11928,7 +11949,7 @@ export class AgentSession {
|
|
|
11928
11949
|
/**
|
|
11929
11950
|
/** Wrap a tool with the workflow mutation guard before permissions or execution. */
|
|
11930
11951
|
#wrapToolForWorkflowMutationGuard<T extends AgentTool>(tool: T): T {
|
|
11931
|
-
if (!
|
|
11952
|
+
if (!isWorkflowMutationTool(tool.name)) return tool;
|
|
11932
11953
|
return new Proxy(tool, {
|
|
11933
11954
|
get: (target, prop) => {
|
|
11934
11955
|
if (prop !== "execute") return Reflect.get(target, prop, target);
|
|
@@ -18985,14 +19006,12 @@ export class AgentSession {
|
|
|
18985
19006
|
if (thinkingLevelChanged) {
|
|
18986
19007
|
const event: AgentSessionEvent = { type: "thinking_level_changed", thinkingLevel };
|
|
18987
19008
|
for (const listener of this.#eventListenerSnapshot) {
|
|
18988
|
-
|
|
18989
|
-
listener(event);
|
|
18990
|
-
} catch {
|
|
19009
|
+
deliverSessionEvent(listener, event, () => {
|
|
18991
19010
|
logger.warn("Default model selection event listener failed", {
|
|
18992
19011
|
code: "default_model_selection_listener_failed",
|
|
18993
19012
|
disposition: "continue",
|
|
18994
19013
|
});
|
|
18995
|
-
}
|
|
19014
|
+
});
|
|
18996
19015
|
}
|
|
18997
19016
|
}
|
|
18998
19017
|
this.#applyPreparedDefaultModelSelectionPrompt(systemPrompt);
|
|
@@ -20983,7 +21002,28 @@ export class AgentSession {
|
|
|
20983
21002
|
const compactionEntry = getLatestCompactionEntry(this.sessionManager.getBranch());
|
|
20984
21003
|
const errorIsFromBeforeCompaction =
|
|
20985
21004
|
compactionEntry !== null && assistantMessage.timestamp < new Date(compactionEntry.timestamp).getTime();
|
|
21005
|
+
// A successful empty stop with nonzero usage is not overflow evidence by usage
|
|
21006
|
+
// alone. Zero-usage empty stops stay on the legacy proxy-overflow path, and typed
|
|
21007
|
+
// overflow classification is preserved; only the empty-stop heuristic is disabled.
|
|
21008
|
+
const hasOverflowEvidenceBeyondEmptyStopHeuristic =
|
|
21009
|
+
assistantMessage.stopReason === "stop" &&
|
|
21010
|
+
assistantMessage.content.length === 0 &&
|
|
21011
|
+
classifyContextOverflow(
|
|
21012
|
+
{ ...assistantMessage, content: [{ type: "text", text: "" }] },
|
|
21013
|
+
assistantMessage.transportFailure,
|
|
21014
|
+
contextWindow,
|
|
21015
|
+
);
|
|
21016
|
+
const emptyStopPromptTokens =
|
|
21017
|
+
assistantMessage.usage.input + assistantMessage.usage.cacheRead + assistantMessage.usage.cacheWrite;
|
|
21018
|
+
const successfulEmptyStop =
|
|
21019
|
+
assistantMessage.stopReason === "stop" &&
|
|
21020
|
+
assistantMessage.content.length === 0 &&
|
|
21021
|
+
(emptyStopPromptTokens + assistantMessage.usage.output > 0 ||
|
|
21022
|
+
assistantMessage.usage.totalTokens > 0) &&
|
|
21023
|
+
emptyStopPromptTokens <= contextWindow &&
|
|
21024
|
+
!hasOverflowEvidenceBeyondEmptyStopHeuristic;
|
|
20986
21025
|
if (
|
|
21026
|
+
!successfulEmptyStop &&
|
|
20987
21027
|
sameModel &&
|
|
20988
21028
|
!errorIsFromBeforeCompaction &&
|
|
20989
21029
|
classifyContextOverflow(assistantMessage, assistantMessage.transportFailure, contextWindow)
|
|
@@ -23677,6 +23717,7 @@ export class AgentSession {
|
|
|
23677
23717
|
|
|
23678
23718
|
#managedFallbackPromptOptions(): {
|
|
23679
23719
|
fallbackManaged?: boolean;
|
|
23720
|
+
contextOverflowManaged?: boolean;
|
|
23680
23721
|
nextFallbackAttempt?: (model: Model) => FallbackAttemptToken;
|
|
23681
23722
|
onManagedAttemptAccepted?: () => void;
|
|
23682
23723
|
onManagedAttemptOutcome?: (
|
|
@@ -23684,9 +23725,10 @@ export class AgentSession {
|
|
|
23684
23725
|
) => ManagedAttemptDecision | Promise<ManagedAttemptDecision>;
|
|
23685
23726
|
} {
|
|
23686
23727
|
const controller = this.#defaultFallbackChain();
|
|
23687
|
-
if (controller.chain.entries.length < 2) return {};
|
|
23728
|
+
if (controller.chain.entries.length < 2) return { contextOverflowManaged: true };
|
|
23688
23729
|
return {
|
|
23689
23730
|
fallbackManaged: true,
|
|
23731
|
+
contextOverflowManaged: true,
|
|
23690
23732
|
nextFallbackAttempt: model => {
|
|
23691
23733
|
controller.onAttemptStarted();
|
|
23692
23734
|
this.#managedFallbackProviderAttemptCount++;
|
package/src/session/artifacts.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
publishManagedFileNoReplace,
|
|
16
16
|
publishManagedFileNoReplaceSync,
|
|
17
17
|
} from "./internal/managed-session-storage";
|
|
18
|
-
import type
|
|
18
|
+
import { type SessionStorageStat, writeExplicitOwnerOnlyTextSync } from "./session-storage";
|
|
19
19
|
import { DEFAULT_ARTIFACT_MAX_BYTES, truncateHeadBytes } from "./streaming-output";
|
|
20
20
|
|
|
21
21
|
export interface ManagedOutputGeneration {
|
|
@@ -246,7 +246,8 @@ export class ArtifactManager {
|
|
|
246
246
|
if (!/^[a-zA-Z0-9_.-]+$/.test(filename)) throw new Error("Unsafe named artifact");
|
|
247
247
|
await this.#ensureDir();
|
|
248
248
|
if (this.#store) await this.#store.replace(filename, Buffer.from(content, "utf8"));
|
|
249
|
-
|
|
249
|
+
// Named files, including draft.txt, are created here.
|
|
250
|
+
else writeExplicitOwnerOnlyTextSync(path.join(this.#dir, filename), content);
|
|
250
251
|
}
|
|
251
252
|
|
|
252
253
|
async replaceNamedBytes(filename: string, bytes: Uint8Array): Promise<void> {
|