@gajae-code/coding-agent 0.18.5 → 0.18.6
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 +101 -0
- package/dist/types/cli-commands.d.ts +10 -0
- package/dist/types/cli-ordinary.d.ts +13 -0
- package/dist/types/cli.d.ts +12 -3
- package/dist/types/commands/contribution-prep.d.ts +0 -3
- package/dist/types/commands/sdk.d.ts +3 -0
- package/dist/types/commands/update.d.ts +1 -0
- package/dist/types/config/model-profile-activation.d.ts +19 -0
- package/dist/types/coordinator-mcp/session-reaper.d.ts +5 -0
- package/dist/types/edit/modes/replace.d.ts +3 -3
- package/dist/types/edit/streaming.d.ts +2 -2
- package/dist/types/exec/bash-shell-supervisor.d.ts +12 -0
- package/dist/types/sdk/broker/discovery.d.ts +8 -0
- package/dist/types/sdk/broker/ensure.d.ts +1 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +4 -0
- package/dist/types/sdk/broker/runtime.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +1 -0
- package/dist/types/sdk/cli/diagnostics-cli.d.ts +18 -0
- package/dist/types/sdk/diagnostics/observe-broker.d.ts +185 -0
- package/dist/types/sdk/host/control/operations.d.ts +1 -1
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +2 -0
- package/dist/types/sdk/session.d.ts +13 -0
- package/dist/types/session/agent-session.d.ts +5 -1
- package/dist/types/tools/ask-contract.d.ts +75 -254
- package/dist/types/tools/bash.d.ts +1 -1
- package/package.json +7 -7
- package/scripts/build-sdk-package-smoke.ts +5 -0
- package/src/cli/public-command-entry.ts +5 -0
- package/src/cli/ssh-cli.ts +6 -3
- package/src/cli/web-search-cli.ts +9 -3
- package/src/cli-commands.ts +14 -0
- package/src/cli-ordinary.ts +197 -0
- package/src/cli.ts +25 -182
- package/src/commands/contribution-prep.ts +1 -3
- package/src/commands/sdk.ts +59 -0
- package/src/commands/update.ts +15 -1
- package/src/config/file-lock.ts +91 -2
- package/src/config/model-profile-activation.ts +70 -4
- package/src/config/model-profile-contract.ts +4 -1
- package/src/config/model-profiles.ts +23 -31
- package/src/config/model-resolver.ts +9 -1
- package/src/coordinator-mcp/event-webhook.ts +19 -14
- package/src/coordinator-mcp/policy.ts +14 -4
- package/src/coordinator-mcp/server.ts +142 -7
- package/src/coordinator-mcp/session-reaper.ts +9 -1
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/edit/modes/replace.ts +6 -6
- package/src/edit/streaming.ts +15 -15
- package/src/exec/bash-shell-supervisor.ts +60 -3
- package/src/internal-urls/docs-index.generated.ts +10 -9
- package/src/memories/index.ts +8 -2
- package/src/modes/acp/acp-agent.ts +649 -367
- package/src/modes/components/tool-execution.ts +1 -1
- package/src/prompts/tools/ask.md +2 -0
- package/src/sdk/broker/broker.ts +46 -0
- package/src/sdk/broker/daemon-entry.ts +67 -6
- package/src/sdk/broker/discovery.ts +8 -0
- package/src/sdk/broker/ensure.ts +156 -20
- package/src/sdk/broker/lifecycle-ledger.ts +110 -12
- package/src/sdk/broker/lifecycle.ts +225 -341
- package/src/sdk/broker/runtime.ts +5 -1
- package/src/sdk/broker/transport.ts +5 -1
- package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
- package/src/sdk/bus/telegram-daemon-control.ts +15 -12
- package/src/sdk/bus/telegram-daemon.ts +34 -1
- package/src/sdk/cli/diagnostics-cli.ts +247 -0
- package/src/sdk/diagnostics/observe-broker.ts +654 -0
- package/src/sdk/host/control/dispatch.ts +52 -4
- package/src/sdk/host/control/operations.ts +1 -1
- package/src/sdk/host/session-runtime.test.ts +40 -2
- package/src/sdk/host/session-runtime.ts +13 -5
- package/src/sdk/index.ts +1 -0
- package/src/sdk/lifecycle-session.ts +1 -0
- package/src/sdk/protocol/operation-registry.ts +1 -1
- package/src/sdk/router/session-router.ts +7 -1
- package/src/sdk/session.ts +37 -8
- package/src/session/agent-session.ts +114 -39
- package/src/session/blob-store.ts +78 -33
- package/src/session/internal/managed-session-storage.ts +96 -3
- package/src/setup/hermes/templates/operator-instructions.v1.md +19 -1
- package/src/setup/hermes-setup.ts +4 -1
- package/src/slash-commands/builtin-registry.ts +8 -5
- package/src/tools/ask-contract.test.ts +76 -1
- package/src/tools/ask-contract.ts +57 -6
- package/src/tools/ask.ts +16 -7
- package/src/tools/bash.ts +38 -29
- package/src/tools/descriptors.test.ts +29 -0
- package/src/tools/tool-catalog.generated.ts +7 -4
- package/src/web/search/index.ts +2 -2
|
@@ -74,6 +74,8 @@ export interface LifecycleDurableEffectsReceipt {
|
|
|
74
74
|
export interface LifecycleLedgerEntry {
|
|
75
75
|
operationKey?: string;
|
|
76
76
|
fingerprint?: string;
|
|
77
|
+
/** True only when a session.close request supplied immutable generation authority. */
|
|
78
|
+
closeAuthorityBound?: boolean;
|
|
77
79
|
version: typeof SDK_STATE_VERSION;
|
|
78
80
|
identity: string;
|
|
79
81
|
requestHash: string;
|
|
@@ -213,6 +215,20 @@ function pendingCleanupSessionId(response: unknown): string | undefined {
|
|
|
213
215
|
return canonicalCleanupSessionId(cleanup?.sessionId) ? cleanup.sessionId : undefined;
|
|
214
216
|
}
|
|
215
217
|
|
|
218
|
+
function retirementCreateIdentity(response: unknown): string | undefined {
|
|
219
|
+
if (!response || typeof response !== "object") return undefined;
|
|
220
|
+
const error = (response as { error?: unknown }).error;
|
|
221
|
+
if (!error || typeof error !== "object") return undefined;
|
|
222
|
+
const cleanup = (error as { cleanup?: unknown }).cleanup;
|
|
223
|
+
if (!cleanup || typeof cleanup !== "object") return undefined;
|
|
224
|
+
const receipt = (cleanup as { uncertainRetirement?: unknown }).uncertainRetirement;
|
|
225
|
+
if (!receipt || typeof receipt !== "object") return undefined;
|
|
226
|
+
const identity = (receipt as { identity?: unknown }).identity;
|
|
227
|
+
if (!identity || typeof identity !== "object") return undefined;
|
|
228
|
+
const createIdentity = (identity as { createIdentity?: unknown }).createIdentity;
|
|
229
|
+
return typeof createIdentity === "string" && createIdentity.length > 0 ? createIdentity : undefined;
|
|
230
|
+
}
|
|
231
|
+
|
|
216
232
|
function hasValidTerminalDigests(entry: LifecycleLedgerEntry): boolean {
|
|
217
233
|
const response = entry.response as { ok?: unknown; error?: { code?: unknown; cleanup?: unknown } } | undefined;
|
|
218
234
|
const cleanupPendingResponse =
|
|
@@ -646,23 +662,91 @@ export class LifecycleLedger {
|
|
|
646
662
|
await directory.close();
|
|
647
663
|
}
|
|
648
664
|
}
|
|
649
|
-
async #compact(
|
|
665
|
+
async #compact(
|
|
666
|
+
replacement?: LifecycleLedgerEntry,
|
|
667
|
+
incoming?: { readonly bytes: number; readonly rows: number },
|
|
668
|
+
): Promise<boolean> {
|
|
650
669
|
const anchors = new Map<string, LifecycleLedgerEntry>();
|
|
651
670
|
for (const entry of this.#entries) {
|
|
652
671
|
const latest = replacement?.identity === entry.identity ? replacement : this.#byIdentity.get(entry.identity);
|
|
653
672
|
if (entry.state === "accepted" && !anchors.has(entry.identity) && entry.requestHash === latest?.requestHash)
|
|
654
673
|
anchors.set(entry.identity, entry);
|
|
655
674
|
}
|
|
656
|
-
const snapshot: LifecycleLedgerEntry[] = [];
|
|
657
675
|
const compacted = new Map(this.#byIdentity);
|
|
658
676
|
if (replacement) compacted.set(replacement.identity, replacement);
|
|
659
|
-
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
677
|
+
const buildSnapshot = (): LifecycleLedgerEntry[] => {
|
|
678
|
+
const next: LifecycleLedgerEntry[] = [];
|
|
679
|
+
for (const [identity, latest] of compacted) {
|
|
680
|
+
const anchor = anchors.get(identity);
|
|
681
|
+
if (!anchor) throw new Error("Lifecycle ledger compaction requires an accepted identity anchor.");
|
|
682
|
+
next.push(replacement?.identity === identity && latest.state === "accepted" ? latest : anchor);
|
|
683
|
+
if (latest.state !== "accepted") next.push(latest);
|
|
684
|
+
}
|
|
685
|
+
return next;
|
|
686
|
+
};
|
|
687
|
+
let snapshot = buildSnapshot();
|
|
688
|
+
let contents = Buffer.from(snapshot.map(entry => `${JSON.stringify(entry)}\n`).join(""));
|
|
689
|
+
const needsEviction = incoming
|
|
690
|
+
? snapshot.length + incoming.rows > this.#limits.maxRows ||
|
|
691
|
+
contents.length + incoming.bytes > this.#limits.maxBytes
|
|
692
|
+
: replacement === undefined
|
|
693
|
+
? snapshot.length >= this.#limits.maxRows || contents.length >= this.#limits.maxBytes
|
|
694
|
+
: snapshot.length > this.#limits.maxRows || contents.length > this.#limits.maxBytes;
|
|
695
|
+
if (needsEviction) {
|
|
696
|
+
const protectedCreateIdentities = new Set<string>();
|
|
697
|
+
for (const entry of compacted.values()) {
|
|
698
|
+
const createIdentity =
|
|
699
|
+
retirementCreateIdentity(entry.response) ?? retirementCreateIdentity(entry.unresolvedCleanupResponse);
|
|
700
|
+
if (createIdentity !== undefined) protectedCreateIdentities.add(createIdentity);
|
|
701
|
+
}
|
|
702
|
+
const evictable = [...compacted.values()]
|
|
703
|
+
.filter(
|
|
704
|
+
latest =>
|
|
705
|
+
latest.identity !== replacement?.identity &&
|
|
706
|
+
terminal(latest.state) &&
|
|
707
|
+
latest.operationKey !== undefined &&
|
|
708
|
+
latest.fingerprint !== undefined &&
|
|
709
|
+
(!latest.operationKey.startsWith("session.close\u0000") || latest.closeAuthorityBound === true) &&
|
|
710
|
+
!protectedCreateIdentities.has(latest.identity) &&
|
|
711
|
+
pendingCleanupSessionId(latest.response) === undefined &&
|
|
712
|
+
pendingCleanupSessionId(latest.unresolvedCleanupResponse) === undefined,
|
|
713
|
+
)
|
|
714
|
+
.sort((left, right) => left.ts - right.ts);
|
|
715
|
+
const rowsByIdentity = new Map<string, number>();
|
|
716
|
+
const bytesByIdentity = new Map<string, number>();
|
|
717
|
+
for (const entry of snapshot) {
|
|
718
|
+
rowsByIdentity.set(entry.identity, (rowsByIdentity.get(entry.identity) ?? 0) + 1);
|
|
719
|
+
bytesByIdentity.set(
|
|
720
|
+
entry.identity,
|
|
721
|
+
(bytesByIdentity.get(entry.identity) ?? 0) + Buffer.byteLength(`${JSON.stringify(entry)}\n`),
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
let remainingRows = snapshot.length;
|
|
725
|
+
let remainingBytes = contents.length;
|
|
726
|
+
const evicted = new Set<string>();
|
|
727
|
+
for (const latest of evictable) {
|
|
728
|
+
if (
|
|
729
|
+
remainingRows <= this.#limits.maxRows / 2 &&
|
|
730
|
+
remainingBytes <= this.#limits.maxBytes / 2 &&
|
|
731
|
+
remainingRows + (incoming?.rows ?? 0) <= this.#limits.maxRows &&
|
|
732
|
+
remainingBytes + (incoming?.bytes ?? 0) <= this.#limits.maxBytes
|
|
733
|
+
)
|
|
734
|
+
break;
|
|
735
|
+
evicted.add(latest.identity);
|
|
736
|
+
remainingRows -= rowsByIdentity.get(latest.identity) ?? 0;
|
|
737
|
+
remainingBytes -= bytesByIdentity.get(latest.identity) ?? 0;
|
|
738
|
+
}
|
|
739
|
+
for (const identity of evicted) compacted.delete(identity);
|
|
740
|
+
snapshot = buildSnapshot();
|
|
741
|
+
contents = Buffer.from(snapshot.map(entry => `${JSON.stringify(entry)}\n`).join(""));
|
|
742
|
+
// Replay is guaranteed only for identities retained in the compacted ledger.
|
|
664
743
|
}
|
|
665
|
-
|
|
744
|
+
if (
|
|
745
|
+
incoming &&
|
|
746
|
+
(snapshot.length + incoming.rows > this.#limits.maxRows ||
|
|
747
|
+
contents.length + incoming.bytes > this.#limits.maxBytes)
|
|
748
|
+
)
|
|
749
|
+
throw new Error("Lifecycle ledger append exceeds configured bounds.");
|
|
666
750
|
if (
|
|
667
751
|
snapshot.length > this.#limits.maxRows ||
|
|
668
752
|
contents.length > this.#limits.maxBytes ||
|
|
@@ -735,7 +819,7 @@ export class LifecycleLedger {
|
|
|
735
819
|
async migrateIdentity(
|
|
736
820
|
from: string,
|
|
737
821
|
to: string,
|
|
738
|
-
metadata: { operationKey: string; fingerprint: string },
|
|
822
|
+
metadata: { operationKey: string; fingerprint: string; closeAuthorityBound?: boolean },
|
|
739
823
|
): Promise<LifecycleLedgerEntry | undefined> {
|
|
740
824
|
return this.#mutate(async () => {
|
|
741
825
|
const existing = this.#byIdentity.get(to);
|
|
@@ -776,9 +860,12 @@ export class LifecycleLedger {
|
|
|
776
860
|
);
|
|
777
861
|
if (line.length - 1 > this.#limits.maxLineBytes)
|
|
778
862
|
throw new Error("Lifecycle ledger row exceeds the maximum byte length.");
|
|
863
|
+
if (line.length > this.#limits.maxBytes) throw new Error("Lifecycle ledger append exceeds configured bounds.");
|
|
779
864
|
let replacementCompacted = false;
|
|
780
865
|
if (this.#rowCount + 1 > this.#limits.maxRows || this.#byteCount + line.length > this.#limits.maxBytes)
|
|
781
|
-
replacementCompacted =
|
|
866
|
+
replacementCompacted = this.#byIdentity.has(entry.identity)
|
|
867
|
+
? await this.#compact(entry)
|
|
868
|
+
: await this.#compact(undefined, { bytes: line.length, rows: 1 });
|
|
782
869
|
if (replacementCompacted) return entry;
|
|
783
870
|
if (this.#rowCount + 1 > this.#limits.maxRows || this.#byteCount + line.length > this.#limits.maxBytes)
|
|
784
871
|
throw new Error("Lifecycle ledger append exceeds configured bounds.");
|
|
@@ -798,7 +885,12 @@ export class LifecycleLedger {
|
|
|
798
885
|
async begin(
|
|
799
886
|
identity: string,
|
|
800
887
|
requestHash: string,
|
|
801
|
-
metadata: {
|
|
888
|
+
metadata: {
|
|
889
|
+
operationKey?: string;
|
|
890
|
+
fingerprint?: string;
|
|
891
|
+
intendedSessionId?: string;
|
|
892
|
+
closeAuthorityBound?: boolean;
|
|
893
|
+
} = {},
|
|
802
894
|
): Promise<BeginResult> {
|
|
803
895
|
return this.#mutate(async () => this.#begin(identity, requestHash, metadata));
|
|
804
896
|
}
|
|
@@ -806,7 +898,12 @@ export class LifecycleLedger {
|
|
|
806
898
|
async #begin(
|
|
807
899
|
identity: string,
|
|
808
900
|
requestHash: string,
|
|
809
|
-
metadata: {
|
|
901
|
+
metadata: {
|
|
902
|
+
operationKey?: string;
|
|
903
|
+
fingerprint?: string;
|
|
904
|
+
intendedSessionId?: string;
|
|
905
|
+
closeAuthorityBound?: boolean;
|
|
906
|
+
},
|
|
810
907
|
): Promise<BeginResult> {
|
|
811
908
|
const prior = this.#byIdentity.get(identity);
|
|
812
909
|
if (!prior)
|
|
@@ -819,6 +916,7 @@ export class LifecycleLedger {
|
|
|
819
916
|
operationKey: metadata.operationKey,
|
|
820
917
|
fingerprint: metadata.fingerprint,
|
|
821
918
|
intendedSessionId: metadata.intendedSessionId,
|
|
919
|
+
closeAuthorityBound: metadata.closeAuthorityBound,
|
|
822
920
|
state: "accepted",
|
|
823
921
|
ts: Date.now(),
|
|
824
922
|
}),
|