@gajae-code/coding-agent 0.11.8 → 0.11.10
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 +35 -1
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/config/model-profiles.d.ts +2 -3
- package/dist/types/config/model-registry.d.ts +2 -0
- package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +12 -5
- package/dist/types/gjc-runtime/deep-interview-draft.d.ts +8 -0
- package/dist/types/gjc-runtime/deep-interview-payload.d.ts +41 -0
- package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +32 -17
- package/dist/types/gjc-runtime/deep-interview-repair.d.ts +17 -0
- package/dist/types/gjc-runtime/deep-interview-state.d.ts +135 -4
- package/dist/types/gjc-runtime/state-writer.d.ts +45 -0
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +5 -3
- package/dist/types/modes/components/welcome.d.ts +2 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +16 -8
- package/dist/types/runtime-mcp/redaction.d.ts +2 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +3 -1
- package/dist/types/sdk/bus/daemon-paths.d.ts +1 -0
- package/dist/types/sdk/bus/index.d.ts +8 -1
- package/dist/types/sdk/bus/operator-runtime.d.ts +1 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +14 -7
- package/dist/types/sdk/bus/telegram-daemon.d.ts +74 -5
- package/dist/types/sdk/session.d.ts +7 -0
- package/dist/types/session/agent-session.d.ts +2 -0
- package/dist/types/session/internal/managed-session-scope.d.ts +13 -3
- package/dist/types/session/internal/managed-session-storage.d.ts +8 -3
- package/dist/types/session/session-manager.d.ts +5 -1
- package/dist/types/session/session-storage.d.ts +13 -0
- package/dist/types/skill-state/active-state.d.ts +4 -0
- package/dist/types/task/provider-retry-status.d.ts +13 -0
- package/dist/types/task/types.d.ts +3 -0
- package/dist/types/tools/index.d.ts +3 -1
- package/package.json +8 -8
- package/scripts/generate-sdk-operation-inventory.ts +1 -0
- package/src/cli/mcp-cli.ts +4 -21
- package/src/cli/notify-cli.ts +1 -0
- package/src/cli.ts +32 -0
- package/src/commands/deep-interview.ts +9 -4
- package/src/commit/agentic/index.ts +3 -3
- package/src/commit/map-reduce/index.ts +2 -2
- package/src/config/model-profiles.ts +9 -10
- package/src/config/model-registry.ts +4 -2
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +78 -163
- package/src/eval/js/tool-bridge.ts +1 -1
- package/src/gjc-runtime/deep-interview-ambiguity.ts +68 -47
- package/src/gjc-runtime/deep-interview-draft.ts +843 -0
- package/src/gjc-runtime/deep-interview-payload.ts +262 -0
- package/src/gjc-runtime/deep-interview-recorder.ts +310 -227
- package/src/gjc-runtime/deep-interview-repair.ts +1674 -0
- package/src/gjc-runtime/deep-interview-runtime.ts +264 -103
- package/src/gjc-runtime/deep-interview-state.ts +916 -4
- package/src/gjc-runtime/ralplan-runtime.ts +3 -1
- package/src/gjc-runtime/state-writer.ts +166 -2
- package/src/gjc-runtime/workflow-manifest.generated.json +386 -1
- package/src/gjc-runtime/workflow-manifest.ts +191 -5
- package/src/hooks/skill-state.ts +23 -1
- package/src/internal-urls/docs-index.generated.ts +6 -5
- package/src/modes/components/welcome.ts +10 -2
- package/src/modes/controllers/selector-controller.ts +38 -8
- package/src/modes/interactive-mode.ts +29 -9
- package/src/prompts/agent-fragments/restricted-bash.md +1 -1
- package/src/prompts/agents/architect.md +8 -1
- package/src/prompts/agents/critic.md +8 -1
- package/src/prompts/agents/planner.md +8 -1
- package/src/prompts/system/system-prompt.md +1 -0
- package/src/runtime-mcp/json-rpc.ts +7 -4
- package/src/runtime-mcp/redaction.ts +30 -0
- package/src/sdk/broker/identity.ts +22 -12
- package/src/sdk/broker/session-index.ts +11 -1
- package/src/sdk/bus/chat-daemon-control.ts +5 -3
- package/src/sdk/bus/daemon-paths.ts +2 -0
- package/src/sdk/bus/index.ts +60 -5
- package/src/sdk/bus/notification-service.ts +19 -5
- package/src/sdk/bus/operator-runtime.ts +31 -5
- package/src/sdk/bus/telegram-cli.ts +6 -13
- package/src/sdk/bus/telegram-daemon-cli.ts +8 -3
- package/src/sdk/bus/telegram-daemon-contract.ts +15 -7
- package/src/sdk/bus/telegram-daemon-control.ts +14 -5
- package/src/sdk/bus/telegram-daemon.ts +685 -120
- package/src/sdk/protocol/operation-inventory.generated.json +11 -0
- package/src/sdk/session.ts +12 -0
- package/src/session/agent-session.ts +140 -10
- package/src/session/internal/managed-session-scope.ts +339 -228
- package/src/session/internal/managed-session-storage.ts +17 -4
- package/src/session/session-manager.ts +96 -33
- package/src/session/session-storage.ts +23 -0
- package/src/skill-state/active-state.ts +10 -0
- package/src/skill-state/workflow-mutation-guard.ts +41 -7
- package/src/task/executor.ts +154 -44
- package/src/task/provider-retry-status.ts +88 -0
- package/src/task/render.ts +45 -26
- package/src/task/types.ts +3 -0
- package/src/tools/ask.ts +1 -0
- package/src/tools/bash-allowed-prefixes.ts +45 -1
- package/src/tools/index.ts +3 -1
- package/src/tools/subagent-render.ts +74 -16
- package/src/tools/subagent.ts +2 -0
- package/vendor/insane-search/MANIFEST.json +4 -1
- package/vendor/insane-search/engine/bias_check.py +5 -0
- package/vendor/insane-search/engine/fetch_chain.py +67 -1
- package/vendor/insane-search/engine/transport.py +13 -2
- package/vendor/insane-search/engine/validators.py +4 -1
|
@@ -21,7 +21,7 @@ import * as fs from "node:fs";
|
|
|
21
21
|
import * as path from "node:path";
|
|
22
22
|
import { getAgentDir } from "@gajae-code/utils";
|
|
23
23
|
import { tokenFingerprint } from "./config";
|
|
24
|
-
import {
|
|
24
|
+
import { isFreshLiveOwner, readOwnerFreshnessSnapshot } from "./telegram-daemon";
|
|
25
25
|
import { runTelegramReferenceClient } from "./telegram-reference";
|
|
26
26
|
|
|
27
27
|
interface CliArgs {
|
|
@@ -134,17 +134,9 @@ function pidAlive(pid: number): boolean {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
function
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return JSON.parse(raw) as DaemonState;
|
|
141
|
-
} catch {
|
|
142
|
-
return undefined;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function activeDaemonOwnsToken(input: { botToken: string; chatId: string }): boolean {
|
|
147
|
-
const state = readDaemonState();
|
|
137
|
+
async function activeDaemonOwnsToken(input: { botToken: string; chatId: string }): Promise<boolean> {
|
|
138
|
+
const snapshot = await readOwnerFreshnessSnapshot({ settings: { getAgentDir } as never });
|
|
139
|
+
const state = snapshot.state;
|
|
148
140
|
if (!state) return false;
|
|
149
141
|
return isFreshLiveOwner({
|
|
150
142
|
state,
|
|
@@ -152,6 +144,7 @@ function activeDaemonOwnsToken(input: { botToken: string; chatId: string }): boo
|
|
|
152
144
|
tokenFingerprint: tokenFingerprint(input.botToken),
|
|
153
145
|
chatId: input.chatId,
|
|
154
146
|
pidAlive,
|
|
147
|
+
effectiveHeartbeatAt: snapshot.effectiveHeartbeatAt,
|
|
155
148
|
});
|
|
156
149
|
}
|
|
157
150
|
|
|
@@ -176,7 +169,7 @@ async function main(): Promise<void> {
|
|
|
176
169
|
}
|
|
177
170
|
|
|
178
171
|
const chatId = args.chatId ?? process.env.GJC_TG_CHAT_ID ?? (await resolveChatId(botToken, apiBase));
|
|
179
|
-
if (!args.force && activeDaemonOwnsToken({ botToken, chatId })) {
|
|
172
|
+
if (!args.force && (await activeDaemonOwnsToken({ botToken, chatId }))) {
|
|
180
173
|
process.stderr.write(
|
|
181
174
|
"an active gjc notifications daemon already owns this bot token; running a second poller will cause Telegram 409 conflicts. Re-run with --force to override.\n",
|
|
182
175
|
);
|
|
@@ -14,6 +14,7 @@ import { daemonPaths, HEARTBEAT_TTL_MS } from "./daemon-paths";
|
|
|
14
14
|
import {
|
|
15
15
|
type DaemonState,
|
|
16
16
|
readDaemonState,
|
|
17
|
+
readOwnerFreshnessSnapshot,
|
|
17
18
|
type TelegramDaemonOptions,
|
|
18
19
|
TelegramNotificationDaemon,
|
|
19
20
|
} from "./telegram-daemon";
|
|
@@ -254,15 +255,19 @@ export async function runDaemonInternal(argv: string[], deps: RunDaemonInternalD
|
|
|
254
255
|
if (!watchdogActive || watchdogTickInFlight || stopRequested) return;
|
|
255
256
|
watchdogTickInFlight = true;
|
|
256
257
|
try {
|
|
257
|
-
const
|
|
258
|
+
const snapshot = deps.readDaemonState
|
|
259
|
+
? { state: await readState(settings as Settings), effectiveHeartbeatAt: undefined }
|
|
260
|
+
: await readOwnerFreshnessSnapshot({ settings: settings as Settings });
|
|
261
|
+
const state = snapshot.state;
|
|
262
|
+
const heartbeatAt = snapshot.effectiveHeartbeatAt ?? state?.heartbeatAt;
|
|
258
263
|
if (!watchdogActive || !state) return;
|
|
259
264
|
if (state.ownerId !== ownerId) {
|
|
260
265
|
stopRequested = true;
|
|
261
266
|
daemon.requestStop("stop");
|
|
262
267
|
return;
|
|
263
268
|
}
|
|
264
|
-
if (lastHeartbeatAt === undefined ||
|
|
265
|
-
lastHeartbeatAt =
|
|
269
|
+
if (lastHeartbeatAt === undefined || heartbeatAt !== lastHeartbeatAt) {
|
|
270
|
+
lastHeartbeatAt = heartbeatAt;
|
|
266
271
|
stalledSince = now();
|
|
267
272
|
return;
|
|
268
273
|
}
|
|
@@ -7,12 +7,9 @@
|
|
|
7
7
|
export const NOTIFICATION_PROTOCOL_VERSION = 3;
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* freshly-upgraded host must still recognize an older, still-live daemon that
|
|
14
|
-
* predates capability-gated frame enforcement and trigger a reload. Bump this
|
|
15
|
-
* on every daemon-behavior change independent of the wire version.
|
|
10
|
+
* Guarded behavior-inventory version for the current daemon build. Bump this
|
|
11
|
+
* on every guarded daemon-behavior change independent of the wire version; it
|
|
12
|
+
* does not force a live daemon reload by itself.
|
|
16
13
|
* The current development baseline already includes #2299's generation 4,
|
|
17
14
|
* incarnation fencing in generation 5, owner-lock authority in generation 6,
|
|
18
15
|
* identity-atomic transition markers in generation 7, stable signaling plus
|
|
@@ -38,5 +35,16 @@ export const NOTIFICATION_PROTOCOL_VERSION = 3;
|
|
|
38
35
|
* Generation 25 adds startup dead-root prune + leak-artifact self-heal
|
|
39
36
|
* on TelegramNotificationDaemon.run (#2958). Generation 26 adds bounded reload
|
|
40
37
|
* cooldown and lazy Telegram topic lifecycle safeguards (#2956, #2960, #2984).
|
|
38
|
+
* Generation 27 refreshes retained native path and process authority semantics.
|
|
39
|
+
* Generation 28 rejects special files before retained native authority opens.
|
|
40
|
+
* Generation 29 adds serving-epoch compatibility, sidecar heartbeat, root GC,
|
|
41
|
+
* and Bot API cooldown structural fixes (#2956, #2960, #3048).
|
|
41
42
|
*/
|
|
42
|
-
export const DAEMON_GENERATION =
|
|
43
|
+
export const DAEMON_GENERATION = 29;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Serving-compatibility boundary for daemon lifecycle requests. Epoch 1 covers
|
|
47
|
+
* all builds published before this field existed; bump this to force serving
|
|
48
|
+
* convergence and reload of compatible live predecessors.
|
|
49
|
+
*/
|
|
50
|
+
export const SERVING_EPOCH = 2;
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
readAttestedLegacyDaemonOwner,
|
|
41
41
|
readDaemonRoots,
|
|
42
42
|
readDaemonState,
|
|
43
|
+
readOwnerFreshnessSnapshot,
|
|
43
44
|
spawnTelegramDaemonOwner,
|
|
44
45
|
type TelegramDaemonDeps,
|
|
45
46
|
type TelegramDaemonFs,
|
|
@@ -224,7 +225,8 @@ export class TelegramDaemonController implements BuiltInDaemonController {
|
|
|
224
225
|
if (!configured) {
|
|
225
226
|
return { kind: this.kind, configured: false, health: "not_configured", runtime };
|
|
226
227
|
}
|
|
227
|
-
const
|
|
228
|
+
const snapshot = await readOwnerFreshnessSnapshot({ settings: this.settings, fs: this.fsImpl });
|
|
229
|
+
const state = snapshot.state;
|
|
228
230
|
const roots = await readDaemonRoots(this.settings, this.fsImpl);
|
|
229
231
|
const health: DaemonHealth =
|
|
230
232
|
!state || state.stoppedAt !== undefined || !this.pidAlive(state.pid)
|
|
@@ -236,6 +238,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
|
|
|
236
238
|
chatId: cfg.chatId as string,
|
|
237
239
|
pidAlive: this.pidAlive,
|
|
238
240
|
pidIncarnation: this.deps.pidIncarnation,
|
|
241
|
+
effectiveHeartbeatAt: snapshot.effectiveHeartbeatAt,
|
|
239
242
|
})
|
|
240
243
|
? "running"
|
|
241
244
|
: "stale";
|
|
@@ -246,7 +249,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
|
|
|
246
249
|
pid: state?.pid,
|
|
247
250
|
ownerId: state?.ownerId,
|
|
248
251
|
startedAt: state?.startedAt,
|
|
249
|
-
heartbeatAt:
|
|
252
|
+
heartbeatAt: snapshot.effectiveHeartbeatAt,
|
|
250
253
|
roots,
|
|
251
254
|
rootCount: roots.length,
|
|
252
255
|
runtime,
|
|
@@ -480,7 +483,8 @@ export class TelegramDaemonController implements BuiltInDaemonController {
|
|
|
480
483
|
const gracefulTimeoutMs = opts.gracefulTimeoutMs ?? DEFAULT_GRACEFUL_TIMEOUT_MS;
|
|
481
484
|
const killTimeoutMs = opts.killTimeoutMs ?? DEFAULT_KILL_TIMEOUT_MS;
|
|
482
485
|
|
|
483
|
-
const
|
|
486
|
+
const ownerSnapshot = await readOwnerFreshnessSnapshot({ settings: this.settings, fs: this.fsImpl });
|
|
487
|
+
const state = ownerSnapshot.state;
|
|
484
488
|
const attestedLegacyOwner = attestedLegacyUpgrade
|
|
485
489
|
? await readAttestedLegacyDaemonOwner({
|
|
486
490
|
settings: this.settings,
|
|
@@ -501,6 +505,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
|
|
|
501
505
|
chatId,
|
|
502
506
|
pidAlive: this.pidAlive,
|
|
503
507
|
pidIncarnation: this.deps.pidIncarnation,
|
|
508
|
+
effectiveHeartbeatAt: ownerSnapshot.effectiveHeartbeatAt,
|
|
504
509
|
}) &&
|
|
505
510
|
isSignalableMatchingOwner({
|
|
506
511
|
state,
|
|
@@ -628,7 +633,8 @@ export class TelegramDaemonController implements BuiltInDaemonController {
|
|
|
628
633
|
let dead = await this.waitForPidDeath(oldPid, gracefulTimeoutMs);
|
|
629
634
|
if (!dead) {
|
|
630
635
|
// Old pid still alive after the cooperative SIGTERM. Inspect current ownership.
|
|
631
|
-
const
|
|
636
|
+
const currentSnapshot = await readOwnerFreshnessSnapshot({ settings: this.settings, fs: this.fsImpl });
|
|
637
|
+
const current = currentSnapshot.state;
|
|
632
638
|
const changedToLiveOwner =
|
|
633
639
|
current !== undefined &&
|
|
634
640
|
current.ownerId !== oldOwnerId &&
|
|
@@ -639,6 +645,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
|
|
|
639
645
|
chatId,
|
|
640
646
|
pidAlive: this.pidAlive,
|
|
641
647
|
pidIncarnation: this.deps.pidIncarnation,
|
|
648
|
+
effectiveHeartbeatAt: currentSnapshot.effectiveHeartbeatAt,
|
|
642
649
|
});
|
|
643
650
|
if (changedToLiveOwner) {
|
|
644
651
|
await this.clearOwnRequest(requestId);
|
|
@@ -701,7 +708,8 @@ export class TelegramDaemonController implements BuiltInDaemonController {
|
|
|
701
708
|
warnings.push(...spawned.warnings);
|
|
702
709
|
const after = await this.status();
|
|
703
710
|
if (spawned.result === "attached") {
|
|
704
|
-
const
|
|
711
|
+
const attachedSnapshot = await readOwnerFreshnessSnapshot({ settings: this.settings, fs: this.fsImpl });
|
|
712
|
+
const attachedState = attachedSnapshot.state;
|
|
705
713
|
if (
|
|
706
714
|
!isCurrentCompatibleOwner({
|
|
707
715
|
state: attachedState,
|
|
@@ -710,6 +718,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
|
|
|
710
718
|
chatId,
|
|
711
719
|
pidAlive: this.pidAlive,
|
|
712
720
|
pidIncarnation: this.deps.pidIncarnation,
|
|
721
|
+
effectiveHeartbeatAt: attachedSnapshot.effectiveHeartbeatAt,
|
|
713
722
|
})
|
|
714
723
|
) {
|
|
715
724
|
return this.result(
|