@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
|
@@ -13,7 +13,9 @@ export type ChatDaemonAction = "stop" | "reload";
|
|
|
13
13
|
* authority declaration contract with bounded frame-delivery acknowledgement.
|
|
14
14
|
* Generation 11 accepts typed retained exact-unlink cleanup authority — a
|
|
15
15
|
* concrete detached quarantine plus a proven-absent canonical lock pathname —
|
|
16
|
-
* when deleting an observed owner-lock lease.
|
|
16
|
+
* when deleting an observed owner-lock lease. Generation 12 refreshes retained
|
|
17
|
+
* native path and process authority semantics. Generation 13 rejects special
|
|
18
|
+
* files before retained native authority opens.
|
|
17
19
|
*/
|
|
18
20
|
export declare const CHAT_DAEMON_GENERATIONS: Readonly<Record<ChatDaemonKind, number>>;
|
|
19
21
|
export declare function chatDaemonGeneration(kind: ChatDaemonKind): number;
|
|
@@ -29,7 +29,7 @@ import { CursorRegistry, RevisionStore } from "../host/query";
|
|
|
29
29
|
import { type SdkStartupFailure } from "../startup-capability";
|
|
30
30
|
import { type NotificationConfig } from "./config";
|
|
31
31
|
import { NotificationSessionController } from "./session-control";
|
|
32
|
-
import { type EnsureDaemonResult } from "./telegram-daemon";
|
|
32
|
+
import { type EnsureDaemonResult, type RegisterNotificationRootResult } from "./telegram-daemon";
|
|
33
33
|
/** Where a `session_create` should run. Discriminated by `kind`. */
|
|
34
34
|
export type SessionCreateTarget = {
|
|
35
35
|
kind: "existing_path";
|
|
@@ -324,6 +324,12 @@ interface SessionRuntime {
|
|
|
324
324
|
hostStopped: boolean;
|
|
325
325
|
serverStopped: boolean;
|
|
326
326
|
brokerRegistrationReleased: boolean;
|
|
327
|
+
/** Managed Telegram root registration released during terminal teardown. */
|
|
328
|
+
notificationRootRegistration?: {
|
|
329
|
+
settings: Settings;
|
|
330
|
+
cwd: string;
|
|
331
|
+
registrationToken?: string;
|
|
332
|
+
};
|
|
327
333
|
verbosity: "lean" | "verbose";
|
|
328
334
|
sessionTag: string;
|
|
329
335
|
/** Whether the agent loop is currently running (drives the typing indicator). */
|
|
@@ -511,6 +517,7 @@ export declare function createNotificationsExtension(api: ExtensionAPI, options?
|
|
|
511
517
|
settings: Settings;
|
|
512
518
|
cwd: string;
|
|
513
519
|
sessionId: string;
|
|
520
|
+
onRegistered?: (registration: RegisterNotificationRootResult) => void;
|
|
514
521
|
}) => Promise<EnsureDaemonResult>;
|
|
515
522
|
ensureProviderDaemon?: (provider: "discord" | "slack", settings: Settings) => Promise<unknown>;
|
|
516
523
|
/** Suppress auto-delivery for a GJC-spawned child under `sessionScope=primary`. */
|
|
@@ -47,6 +47,7 @@ export declare class NotificationOperatorRuntime {
|
|
|
47
47
|
stopInterval(name: string): void;
|
|
48
48
|
stopAllIntervals(): void;
|
|
49
49
|
runExclusive(name: string, fn: () => Promise<void>): Promise<void>;
|
|
50
|
+
joinExclusive(name: string, timeoutMs: number): Promise<boolean>;
|
|
50
51
|
sleep(ms: number, signal?: AbortSignal): Promise<void>;
|
|
51
52
|
now(): number;
|
|
52
53
|
}
|
|
@@ -5,12 +5,9 @@
|
|
|
5
5
|
/** Protocol version the daemon advertises in its ClientHello. */
|
|
6
6
|
export declare const NOTIFICATION_PROTOCOL_VERSION = 3;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* freshly-upgraded host must still recognize an older, still-live daemon that
|
|
12
|
-
* predates capability-gated frame enforcement and trigger a reload. Bump this
|
|
13
|
-
* on every daemon-behavior change independent of the wire version.
|
|
8
|
+
* Guarded behavior-inventory version for the current daemon build. Bump this
|
|
9
|
+
* on every guarded daemon-behavior change independent of the wire version; it
|
|
10
|
+
* does not force a live daemon reload by itself.
|
|
14
11
|
* The current development baseline already includes #2299's generation 4,
|
|
15
12
|
* incarnation fencing in generation 5, owner-lock authority in generation 6,
|
|
16
13
|
* identity-atomic transition markers in generation 7, stable signaling plus
|
|
@@ -36,5 +33,15 @@ export declare const NOTIFICATION_PROTOCOL_VERSION = 3;
|
|
|
36
33
|
* Generation 25 adds startup dead-root prune + leak-artifact self-heal
|
|
37
34
|
* on TelegramNotificationDaemon.run (#2958). Generation 26 adds bounded reload
|
|
38
35
|
* cooldown and lazy Telegram topic lifecycle safeguards (#2956, #2960, #2984).
|
|
36
|
+
* Generation 27 refreshes retained native path and process authority semantics.
|
|
37
|
+
* Generation 28 rejects special files before retained native authority opens.
|
|
38
|
+
* Generation 29 adds serving-epoch compatibility, sidecar heartbeat, root GC,
|
|
39
|
+
* and Bot API cooldown structural fixes (#2956, #2960, #3048).
|
|
39
40
|
*/
|
|
40
|
-
export declare const DAEMON_GENERATION =
|
|
41
|
+
export declare const DAEMON_GENERATION = 29;
|
|
42
|
+
/**
|
|
43
|
+
* Serving-compatibility boundary for daemon lifecycle requests. Epoch 1 covers
|
|
44
|
+
* all builds published before this field existed; bump this to force serving
|
|
45
|
+
* convergence and reload of compatible live predecessors.
|
|
46
|
+
*/
|
|
47
|
+
export declare const SERVING_EPOCH = 2;
|
|
@@ -5,10 +5,10 @@ import { HEARTBEAT_TTL_MS } from "./daemon-paths";
|
|
|
5
5
|
import { type DaemonTransitionLock, type NotificationEndpointFile, type NotificationEndpointFileIdentity, type NotificationExactUnlinkResult } from "./notification-service";
|
|
6
6
|
import { type DaemonProcessReference } from "./telegram-daemon-control";
|
|
7
7
|
import { type TelegramSetupPreflight } from "./telegram-setup";
|
|
8
|
-
export { DAEMON_GENERATION, NOTIFICATION_PROTOCOL_VERSION } from "./telegram-daemon-contract";
|
|
8
|
+
export { DAEMON_GENERATION, NOTIFICATION_PROTOCOL_VERSION, SERVING_EPOCH } from "./telegram-daemon-contract";
|
|
9
9
|
import { type ControlServerLike, type LifecycleControlServerFactory } from "./lifecycle-control-runtime";
|
|
10
10
|
import type { OrchestratorDeps } from "./lifecycle-orchestrator";
|
|
11
|
-
import { NotificationOperatorRuntime
|
|
11
|
+
import { NotificationOperatorRuntime } from "./operator-runtime";
|
|
12
12
|
import { type AliasTable, type CallbackRoute } from "./telegram-reference";
|
|
13
13
|
import { type TopicEndpointBinding } from "./topic-registry";
|
|
14
14
|
export type EnsureDaemonResult = "owner_spawned" | "attached" | "disabled" | "blocked";
|
|
@@ -41,6 +41,8 @@ export interface DaemonState {
|
|
|
41
41
|
* notification wire protocol version. Absent on pre-generation state.
|
|
42
42
|
*/
|
|
43
43
|
generation?: number;
|
|
44
|
+
/** Lifecycle-serving compatibility epoch; absent pre-epoch records are epoch 1. */
|
|
45
|
+
servingEpoch?: number;
|
|
44
46
|
stoppedAt?: number;
|
|
45
47
|
}
|
|
46
48
|
export interface TelegramDaemonFs {
|
|
@@ -201,15 +203,59 @@ export declare function liveOwnershipLockDecision(input: {
|
|
|
201
203
|
attached: false;
|
|
202
204
|
provisional: true;
|
|
203
205
|
} | undefined;
|
|
206
|
+
type OwnerHeartbeatSidecar = {
|
|
207
|
+
pid: number;
|
|
208
|
+
incarnation: string;
|
|
209
|
+
ownerId: string;
|
|
210
|
+
acquisitionId: string;
|
|
211
|
+
heartbeatAt: number;
|
|
212
|
+
};
|
|
213
|
+
export interface OwnerFreshnessSnapshot {
|
|
214
|
+
ownerTag: Pick<OwnerHeartbeatSidecar, "pid" | "incarnation" | "ownerId" | "acquisitionId"> | null;
|
|
215
|
+
effectiveHeartbeatAt: number | undefined;
|
|
216
|
+
legacyEmbedded: boolean;
|
|
217
|
+
state: DaemonState | undefined;
|
|
218
|
+
}
|
|
219
|
+
export declare function readOwnerFreshnessSnapshot(input: {
|
|
220
|
+
settings: Settings;
|
|
221
|
+
fs?: TelegramDaemonFs;
|
|
222
|
+
}): Promise<OwnerFreshnessSnapshot>;
|
|
223
|
+
/** Marker-free steady heartbeat renewal. The final lock reread fences a stale writer. */
|
|
224
|
+
export declare function renewOwnerHeartbeatSidecar(input: {
|
|
225
|
+
settings: Settings;
|
|
226
|
+
ownerId: string;
|
|
227
|
+
acquisitionId?: string;
|
|
228
|
+
fs?: TelegramDaemonFs;
|
|
229
|
+
now?: () => number;
|
|
230
|
+
pid?: number;
|
|
231
|
+
pidIncarnation?: (pid: number) => string | undefined;
|
|
232
|
+
}): Promise<boolean>;
|
|
233
|
+
export interface NotificationRootRegistration {
|
|
234
|
+
root?: string;
|
|
235
|
+
managed?: boolean;
|
|
236
|
+
token?: string;
|
|
237
|
+
}
|
|
238
|
+
export declare function readNotificationRootRegistration(input: {
|
|
239
|
+
settings: Settings;
|
|
240
|
+
sessionId: string;
|
|
241
|
+
fs?: TelegramDaemonFs;
|
|
242
|
+
}): Promise<NotificationRootRegistration>;
|
|
243
|
+
export interface RegisterNotificationRootResult {
|
|
244
|
+
root: string;
|
|
245
|
+
/** Per-registration ownership token fencing a stale same-session cleanup from deleting a live replacement registration. */
|
|
246
|
+
token: string;
|
|
247
|
+
}
|
|
204
248
|
export declare function registerNotificationRoot(input: {
|
|
205
249
|
settings: Settings;
|
|
206
250
|
cwd: string;
|
|
207
251
|
sessionId: string;
|
|
208
252
|
fs?: TelegramDaemonFs;
|
|
209
|
-
}): Promise<
|
|
253
|
+
}): Promise<RegisterNotificationRootResult>;
|
|
210
254
|
export interface UnregisterNotificationRootResult {
|
|
211
255
|
root: string;
|
|
212
256
|
remainingRoots: number;
|
|
257
|
+
/** Opaque fingerprint of the exact registry written by this successful unregister. */
|
|
258
|
+
registryFingerprint?: string;
|
|
213
259
|
}
|
|
214
260
|
/** Remove one session's Telegram scan root without disturbing other live session roots. */
|
|
215
261
|
export declare function unregisterNotificationRoot(input: {
|
|
@@ -217,7 +263,16 @@ export declare function unregisterNotificationRoot(input: {
|
|
|
217
263
|
cwd: string;
|
|
218
264
|
sessionId: string;
|
|
219
265
|
fs?: TelegramDaemonFs;
|
|
266
|
+
/** Ownership token minted by this runtime's own registration; a stale cleanup presenting an older token never deletes a replacement registration. */
|
|
267
|
+
registrationToken?: string;
|
|
220
268
|
}): Promise<UnregisterNotificationRootResult>;
|
|
269
|
+
/** Run an action while the roots registry lock excludes any registration or unregister. */
|
|
270
|
+
export declare function withNotificationRootRegistryFence(input: {
|
|
271
|
+
settings: Settings;
|
|
272
|
+
registryFingerprint: string;
|
|
273
|
+
action: () => Promise<void>;
|
|
274
|
+
fs?: TelegramDaemonFs;
|
|
275
|
+
}): Promise<boolean>;
|
|
221
276
|
/**
|
|
222
277
|
* Leak artifact prefixes left when native exact-unlink cleanup is retained
|
|
223
278
|
* (#2956). Nothing previously reaped these; they accumulate in the notifications
|
|
@@ -319,6 +374,7 @@ export declare function isFreshLiveOwner(input: {
|
|
|
319
374
|
chatId: string;
|
|
320
375
|
pidAlive: (pid: number) => boolean;
|
|
321
376
|
pidIncarnation?: (pid: number) => string | undefined;
|
|
377
|
+
effectiveHeartbeatAt?: number;
|
|
322
378
|
}): boolean;
|
|
323
379
|
/** True only when a physically live matching owner can serve this build's daemon lifecycle contract. */
|
|
324
380
|
export declare function isCurrentCompatibleOwner(input: {
|
|
@@ -328,6 +384,7 @@ export declare function isCurrentCompatibleOwner(input: {
|
|
|
328
384
|
chatId: string;
|
|
329
385
|
pidAlive: (pid: number) => boolean;
|
|
330
386
|
pidIncarnation?: (pid: number) => string | undefined;
|
|
387
|
+
effectiveHeartbeatAt?: number;
|
|
331
388
|
}): boolean;
|
|
332
389
|
export declare function acquireDaemonOwnership(input: {
|
|
333
390
|
settings: Settings;
|
|
@@ -399,7 +456,7 @@ export declare function retireProvisionalDaemonOwnership(input: {
|
|
|
399
456
|
/** Only no-child confirmation may retire a ready-like launcher publication. */
|
|
400
457
|
allowReadyWithoutChildPid?: boolean;
|
|
401
458
|
}): Promise<boolean>;
|
|
402
|
-
/** Wait for a matching
|
|
459
|
+
/** Wait for a matching compatible owner to publish a ready state. Readiness is serving-epoch gated (same-epoch cross-generation owners attach, per isCurrentCompatibleOwner); generation is inventory-only here. Mutation paths still require exact current-generation equality. */
|
|
403
460
|
export declare function waitForTelegramDaemonReady(input: {
|
|
404
461
|
settings: Settings;
|
|
405
462
|
ownerId?: string;
|
|
@@ -548,6 +605,9 @@ export declare function ensureTelegramDaemonRunningDetailed(input: {
|
|
|
548
605
|
settings: Settings;
|
|
549
606
|
cwd: string;
|
|
550
607
|
sessionId: string;
|
|
608
|
+
registerRoot?: boolean;
|
|
609
|
+
/** Receives each registration this ensure operation minted so the caller can fence its own later cleanup. */
|
|
610
|
+
onRegistered?: (registration: RegisterNotificationRootResult) => void;
|
|
551
611
|
}, deps?: TelegramDaemonDeps): Promise<EnsureTelegramDaemonDetailedResult>;
|
|
552
612
|
/**
|
|
553
613
|
* Legacy compatibility mapping for callers that only distinguish ownership from
|
|
@@ -600,7 +660,10 @@ export type TelegramPollResult = {
|
|
|
600
660
|
export interface TelegramUpdatePollerOptions {
|
|
601
661
|
botApi: BotApi;
|
|
602
662
|
runtime: NotificationOperatorRuntime;
|
|
603
|
-
backoff:
|
|
663
|
+
backoff: {
|
|
664
|
+
next(): number;
|
|
665
|
+
reset(): void;
|
|
666
|
+
};
|
|
604
667
|
processUpdate: (update: unknown) => Promise<TelegramUpdateOutcome>;
|
|
605
668
|
health?: TelegramPollHealth;
|
|
606
669
|
}
|
|
@@ -785,6 +848,9 @@ export declare class TelegramNotificationDaemon {
|
|
|
785
848
|
private readonly pool;
|
|
786
849
|
private readonly poller;
|
|
787
850
|
private readonly dispatchState;
|
|
851
|
+
/** Bot-wide flood-control window; inbound polling remains eligible during it. */
|
|
852
|
+
private botCooldownUntil;
|
|
853
|
+
private warnedBotCooldownUntil;
|
|
788
854
|
/** Original markdown of rich messages we sent (chat+message_id), for restoring reply context on inbound replies. */
|
|
789
855
|
private readonly replyStore;
|
|
790
856
|
/** Per-session debounce + monotonic draft-id state for opt-in draft streaming. */
|
|
@@ -871,6 +937,9 @@ export declare class TelegramNotificationDaemon {
|
|
|
871
937
|
private refreshBotIdentity;
|
|
872
938
|
/** Map a lifecycle response/error to a user-facing message (G010 surfacing). */
|
|
873
939
|
private formatLifecycleResponse;
|
|
940
|
+
private callBotApi;
|
|
941
|
+
private readonly callBotApiClassified;
|
|
942
|
+
private botApiWithOutcomeCollector;
|
|
874
943
|
constructor(opts: TelegramDaemonOptions);
|
|
875
944
|
private createSessionRouter;
|
|
876
945
|
loadAliases(): Promise<void>;
|
|
@@ -149,6 +149,13 @@ export interface CreateAgentSessionOptions {
|
|
|
149
149
|
goalToolAllowedOps?: readonly ("create" | "get" | "complete" | "resume" | "drop" | "pause")[];
|
|
150
150
|
/** Optional per-session allowlist for tools exposed through search_tool_bm25. */
|
|
151
151
|
discoverableToolAllowedNames?: readonly string[];
|
|
152
|
+
/**
|
|
153
|
+
* Discoverable built-in tools that must stay in the initial active set even when
|
|
154
|
+
* `tools.discoveryMode === "all"` would otherwise hide them behind `search_tool_bm25`.
|
|
155
|
+
* Used for coordination tools (e.g. `irc`) that a subagent must be able to use
|
|
156
|
+
* immediately without first spending a discovery round-trip to find them.
|
|
157
|
+
*/
|
|
158
|
+
alwaysActiveToolNames?: readonly string[];
|
|
152
159
|
/** Optional shared agent registry for IRC routing. Default: AgentRegistry.global(). */
|
|
153
160
|
agentRegistry?: AgentRegistry;
|
|
154
161
|
/** Parent task ID prefix for nested artifact naming (e.g., "6-Extensions") */
|
|
@@ -677,6 +677,8 @@ export declare class AgentSession {
|
|
|
677
677
|
* Get a tool by name from the registry.
|
|
678
678
|
*/
|
|
679
679
|
getToolByName(name: string): AgentTool | undefined;
|
|
680
|
+
/** Get a registered tool with the same guards used for model-facing execution. */
|
|
681
|
+
getToolForExecution(name: string): AgentTool | undefined;
|
|
680
682
|
/**
|
|
681
683
|
* Register a UI/control-plane request handler for a currently foregrounded
|
|
682
684
|
* managed bash execution. This is intentionally narrower than generic
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as native from "@gajae-code/natives";
|
|
2
2
|
import type { ResumeSessionIdentity } from "../session-manager";
|
|
3
|
-
import { type
|
|
3
|
+
import { type NativeDirectoryTreeSnapshot } from "../session-storage";
|
|
4
|
+
import { type ManagedDirectoryRoot, type ManagedSessionSecurityPolicy, type ManagedStorageLock } from "./managed-session-storage";
|
|
4
5
|
export declare const MANAGED_SESSION_LAYOUT_VERSION: 2;
|
|
5
6
|
export declare const MANAGED_SESSION_IDENTITY_VERSION: 1;
|
|
6
7
|
export declare const MANAGED_SESSION_BINDING_FILE = ".gjc-managed-session-scope.v2.json";
|
|
@@ -67,7 +68,7 @@ export type ManagedCandidateListing = {
|
|
|
67
68
|
code: "scan_failed" | "unsafe_root" | "invalid_candidate";
|
|
68
69
|
message: string;
|
|
69
70
|
};
|
|
70
|
-
export type ManagedOpenFailure = "migration_busy" | "binding_conflict" | "binding_invalid" | "destination_conflict" | "source_changed" | "unsafe_artifacts" | "durability_failed" | "atomic_unavailable" | "invalid_request" | "durability_not_provable" | "migration_retired" | "legacy_migration_disabled" | "managed_storage_unsupported";
|
|
71
|
+
export type ManagedOpenFailure = "migration_busy" | "binding_conflict" | "binding_invalid" | "destination_conflict" | "source_changed" | "unsafe_artifacts" | "artifact_capacity_exceeded" | "durability_failed" | "atomic_unavailable" | "invalid_request" | "durability_not_provable" | "migration_retired" | "legacy_migration_disabled" | "managed_storage_unsupported";
|
|
71
72
|
export type ManagedOpenCandidateResult = {
|
|
72
73
|
kind: "opened";
|
|
73
74
|
path: string;
|
|
@@ -114,12 +115,21 @@ interface ManagedScopeInput {
|
|
|
114
115
|
export declare function resolveManagedScope(input: ManagedScopeInput): ManagedScopeResolution;
|
|
115
116
|
/** Resolve a scope for a synchronous write without mutating an existing ACL mismatch. */
|
|
116
117
|
export declare function resolveManagedScopeForWrite(input: ManagedScopeInput): ManagedScopeResolution;
|
|
118
|
+
export declare function canonicalBindingOpenFlags(platform?: NodeJS.Platform): number;
|
|
119
|
+
export declare function fsyncCanonicalBinding(bindingPath: string, expected: string): void;
|
|
117
120
|
export declare function ensureManagedScope(scope: ManagedScope, policy?: ManagedSessionSecurityPolicy): Promise<ManagedScopeResolution>;
|
|
118
121
|
/** Synchronously create and validate the v2 binding before a default session writer exists. */
|
|
119
122
|
export declare function prepareManagedSessionScopeForWriteSync(scope: ManagedScope, policy?: ManagedSessionSecurityPolicy, authority?: ManagedCandidateWriteAuthority): ManagedScopeResolution;
|
|
120
123
|
export declare function listManagedCandidates(scope: ManagedScope): ManagedCandidateListing;
|
|
124
|
+
export declare function matchesMigrationArtifactRoot(pathname: string, identity: {
|
|
125
|
+
dev: bigint;
|
|
126
|
+
ino: bigint;
|
|
127
|
+
size: bigint;
|
|
128
|
+
mtimeNs: bigint;
|
|
129
|
+
}, expectedTree: NativeDirectoryTreeSnapshot, platform?: NodeJS.Platform): boolean;
|
|
130
|
+
export declare function restorePreparedArtifactRoot(scope: ManagedScope, source: ManagedCandidate, lock?: ManagedStorageLock): void;
|
|
121
131
|
/** Resume tombstoned cleanup under its original operation lease without restoring retired candidates. */
|
|
122
|
-
export declare function reconcileManagedTombstones(scope: ManagedScope): Promise<void>;
|
|
132
|
+
export declare function reconcileManagedTombstones(scope: ManagedScope, expectedCandidate?: ManagedCandidate): Promise<void>;
|
|
123
133
|
/** Create the v2 binding and private write protocol directories before managed writes. */
|
|
124
134
|
export declare function prepareManagedSessionScopeForWrite(scope: ManagedScope, policy?: ManagedSessionSecurityPolicy, authority?: ManagedCandidateWriteAuthority, expectedCandidate?: ManagedCandidate, expectedIdentity?: ResumeSessionIdentity): Promise<ManagedScopeResolution>;
|
|
125
135
|
/**
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type NativeDirectoryTreeSnapshot, type NativeOwnerOnlySecurityResult, type RecoveryFsRoot } from "@gajae-code/natives";
|
|
2
2
|
import { type NativePublishOutcome } from "./native-publish-outcome";
|
|
3
3
|
export declare const MANAGED_ARTIFACT_MAX_DEPTH = 32;
|
|
4
|
-
export declare const MANAGED_ARTIFACT_MAX_FILES =
|
|
4
|
+
export declare const MANAGED_ARTIFACT_MAX_FILES = 50000;
|
|
5
5
|
export declare const MANAGED_ARTIFACT_MAX_FILE_BYTES: number;
|
|
6
6
|
export declare const MANAGED_ARTIFACT_MAX_TOTAL_BYTES: number;
|
|
7
|
+
export declare const MANAGED_ARTIFACT_COPY_BATCH_SIZE = 256;
|
|
7
8
|
export declare class ManagedPublishError extends Error {
|
|
8
9
|
readonly classification: "destination_conflict" | "atomic_unavailable" | "invalid_request" | "durability_not_provable" | "identity_mismatch" | "io_error" | "durability_failed";
|
|
9
10
|
readonly diagnostic: string;
|
|
@@ -12,7 +13,7 @@ export declare class ManagedPublishError extends Error {
|
|
|
12
13
|
/** Cleanup is safe only when the native move reports that it did not commit. */
|
|
13
14
|
export declare function mayCleanManagedTreeStaging(error: unknown): boolean;
|
|
14
15
|
export type ManagedSessionSecurityPolicy = "default" | "windows-existing-verify-first";
|
|
15
|
-
export type ManagedStorageFailure = "migration_busy" | "binding_conflict" | "binding_invalid" | "destination_conflict" | "source_changed" | "unsafe_artifacts" | "durability_failed" | "atomic_unavailable" | "durability_not_provable" | "migration_retired" | "managed_storage_unsupported";
|
|
16
|
+
export type ManagedStorageFailure = "migration_busy" | "binding_conflict" | "binding_invalid" | "destination_conflict" | "source_changed" | "unsafe_artifacts" | "artifact_capacity_exceeded" | "durability_failed" | "atomic_unavailable" | "durability_not_provable" | "migration_retired" | "managed_storage_unsupported";
|
|
16
17
|
export interface ManagedStorageLock {
|
|
17
18
|
path: string;
|
|
18
19
|
attemptId: string;
|
|
@@ -104,8 +105,12 @@ export declare function replaceManagedFile(destination: string, bytes: Uint8Arra
|
|
|
104
105
|
export declare function copyManagedFileNoReplace(source: string, destination: string, snapshot?: ManagedFileSnapshot, root?: ManagedDirectoryRoot, policy?: ManagedSessionSecurityPolicy): Promise<void>;
|
|
105
106
|
/** Acquire a lease lock with bounded wait, heartbeats, conservative stale reclaim, and fencing. */
|
|
106
107
|
export declare function acquireManagedLock(locksDirectory: string, name: string, root?: ManagedDirectoryRoot, policy?: ManagedSessionSecurityPolicy): Promise<ManagedStorageLock>;
|
|
108
|
+
export interface ManagedArtifactTreeLimits {
|
|
109
|
+
maxFiles?: number;
|
|
110
|
+
maxTotalBytes?: number;
|
|
111
|
+
}
|
|
107
112
|
/** Bounds a no-follow artifact tree before it can be copied or deleted. */
|
|
108
|
-
export declare function validateManagedArtifactTree(root: string): void;
|
|
113
|
+
export declare function validateManagedArtifactTree(root: string, limits?: ManagedArtifactTreeLimits): void;
|
|
109
114
|
/** Flush a copied managed artifact tree, including empty directories, before publishing its receipt. */
|
|
110
115
|
export declare function fsyncManagedArtifactTree(root: string): NativeDirectoryTreeSnapshot;
|
|
111
116
|
export declare function publishManagedTombstone(destination: string, record: Record<string, unknown>, assertOwned?: () => void): Promise<void>;
|
|
@@ -327,6 +327,9 @@ export declare class SessionMigrationPolicyError extends Error {
|
|
|
327
327
|
readonly code = "legacy_migration_disabled";
|
|
328
328
|
constructor();
|
|
329
329
|
}
|
|
330
|
+
export declare class SessionArtifactCapacityError extends Error {
|
|
331
|
+
constructor(message: string);
|
|
332
|
+
}
|
|
330
333
|
export type ResumeTailInspection = ResumeTailResumable | ResumeTailTerminal | ResumeTailError;
|
|
331
334
|
export interface StrictSessionOpenSuccess {
|
|
332
335
|
kind: "opened";
|
|
@@ -334,7 +337,8 @@ export interface StrictSessionOpenSuccess {
|
|
|
334
337
|
}
|
|
335
338
|
export interface StrictSessionOpenFailure {
|
|
336
339
|
kind: "error";
|
|
337
|
-
reason: ResumeTailError["reason"] | "identity-mismatch" | "migration-required";
|
|
340
|
+
reason: ResumeTailError["reason"] | "identity-mismatch" | "migration-required" | "artifact_capacity_exceeded";
|
|
341
|
+
message?: string;
|
|
338
342
|
}
|
|
339
343
|
/** Exact transcript bytes and authority captured from one descriptor-bound read. */
|
|
340
344
|
export interface CapturedSessionTranscriptSnapshot {
|
|
@@ -112,6 +112,11 @@ export interface SessionStorage {
|
|
|
112
112
|
readSnapshotSync?(path: string): SessionStorageSnapshot;
|
|
113
113
|
statSync(path: string): SessionStorageStat;
|
|
114
114
|
listFilesSync(dir: string, pattern: string): string[];
|
|
115
|
+
/** List matching files with mtimes without issuing one JavaScript stat call per path. */
|
|
116
|
+
listFilesByMtime?(dir: string, pattern: string): Promise<Array<{
|
|
117
|
+
path: string;
|
|
118
|
+
mtimeMs: number;
|
|
119
|
+
}>>;
|
|
115
120
|
/**
|
|
116
121
|
* Strict directory scan that never suppresses scan/root errors. Used by strict
|
|
117
122
|
* authorization inventory; the forgiving {@link listFilesSync} stays display-only.
|
|
@@ -267,6 +272,10 @@ export declare class FileSessionStorage implements SessionStorage {
|
|
|
267
272
|
readSnapshotSync(fpath: string): SessionStorageSnapshot;
|
|
268
273
|
statSync(path: string): SessionStorageStat;
|
|
269
274
|
listFilesSync(dir: string, pattern: string): string[];
|
|
275
|
+
listFilesByMtime(dir: string, pattern: string): Promise<Array<{
|
|
276
|
+
path: string;
|
|
277
|
+
mtimeMs: number;
|
|
278
|
+
}>>;
|
|
270
279
|
listFilesStrictSync(dir: string, pattern: string): string[];
|
|
271
280
|
exists(path: string): Promise<boolean>;
|
|
272
281
|
readText(path: string): Promise<string>;
|
|
@@ -299,6 +308,10 @@ export declare class MemorySessionStorage implements SessionStorage {
|
|
|
299
308
|
readSnapshotSync(path: string): SessionStorageSnapshot;
|
|
300
309
|
statSync(path: string): SessionStorageStat;
|
|
301
310
|
listFilesSync(dir: string, pattern: string): string[];
|
|
311
|
+
listFilesByMtime(dir: string, pattern: string): Promise<Array<{
|
|
312
|
+
path: string;
|
|
313
|
+
mtimeMs: number;
|
|
314
|
+
}>>;
|
|
302
315
|
listFilesStrictSync(dir: string, pattern: string): string[];
|
|
303
316
|
exists(path: string): Promise<boolean>;
|
|
304
317
|
readText(path: string): Promise<string>;
|
|
@@ -45,6 +45,8 @@ export interface SkillActiveEntry {
|
|
|
45
45
|
handoff_at?: string;
|
|
46
46
|
active_subskills?: ActiveSubskillEntry[];
|
|
47
47
|
source_state_revision?: number;
|
|
48
|
+
/** Durable ordering token from the source workflow mode-state, not this cache file's revision. */
|
|
49
|
+
committed_mode_state_revision?: number;
|
|
48
50
|
}
|
|
49
51
|
export interface SkillActiveState {
|
|
50
52
|
version?: number;
|
|
@@ -85,6 +87,8 @@ export interface SyncSkillActiveStateOptions {
|
|
|
85
87
|
handoff_at?: string;
|
|
86
88
|
active_subskills?: ActiveSubskillEntry[];
|
|
87
89
|
sourceRevision?: number;
|
|
90
|
+
/** Durable ordering token from the source workflow mode-state, not this cache file's revision. */
|
|
91
|
+
committedModeRevision?: number;
|
|
88
92
|
}
|
|
89
93
|
export declare function normalizeWorkflowHudSummary(raw: unknown): WorkflowHudSummary | undefined;
|
|
90
94
|
export declare function isCanonicalGjcWorkflowSkill(skill: string): skill is CanonicalGjcWorkflowSkill;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AgentProgress, TaskToolDetails } from "./types";
|
|
2
|
+
export type ProviderRetryKind = NonNullable<AgentProgress["retryState"]>["kind"];
|
|
3
|
+
export declare function classifyProviderRetry(errorMessage: string): ProviderRetryKind;
|
|
4
|
+
export declare function providerNameFromModel(model: string | undefined): string | undefined;
|
|
5
|
+
export declare function providerRetryPhaseLabel(kind: ProviderRetryKind): string;
|
|
6
|
+
export declare function providerProgressAgeLabel(retryState: NonNullable<AgentProgress["retryState"]>, nowMs: number): string;
|
|
7
|
+
export declare function hasActiveProviderRetryInTaskDetails(details: TaskToolDetails, seen?: WeakSet<object>): boolean;
|
|
8
|
+
export declare function hasActiveProviderRetryInProgress(progress: AgentProgress, seen?: WeakSet<object>): boolean;
|
|
9
|
+
export interface ProviderDegradationGroup {
|
|
10
|
+
provider: string;
|
|
11
|
+
count: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function collectProviderDegradationGroups(progress: readonly AgentProgress[]): ProviderDegradationGroup[];
|
|
@@ -416,6 +416,9 @@ export interface AgentProgress {
|
|
|
416
416
|
attempt: number;
|
|
417
417
|
maxAttempts: number;
|
|
418
418
|
unbounded?: boolean;
|
|
419
|
+
kind: "first_event_timeout" | "idle_stream_stall" | "provider_error";
|
|
420
|
+
provider?: string;
|
|
421
|
+
lastProviderProgressAtMs?: number;
|
|
419
422
|
delayMs: number;
|
|
420
423
|
errorMessage: string;
|
|
421
424
|
startedAtMs: number;
|
|
@@ -198,9 +198,11 @@ export interface ToolSession {
|
|
|
198
198
|
/** Agent identity used for IRC routing. Returns the registry id (e.g. "0-Main", "0-AuthLoader"). */
|
|
199
199
|
getAgentId?: () => string | null;
|
|
200
200
|
/** Look up a registered tool by name (used by the eval js backend's tool bridge). */
|
|
201
|
+
getToolByName?: (name: string) => AgentTool | undefined;
|
|
202
|
+
/** Look up a registered tool with the session's execution guards applied. */
|
|
203
|
+
getToolForExecution?: (name: string) => AgentTool | undefined;
|
|
201
204
|
/** Purge undelivered queued custom messages matching the predicate. Returns counts. */
|
|
202
205
|
purgeQueuedCustomMessages?: (predicate: (message: CustomMessage) => boolean) => PurgeQueuedCustomMessagesResult;
|
|
203
|
-
getToolByName?: (name: string) => AgentTool | undefined;
|
|
204
206
|
/** Agent registry for IRC routing across live sessions. */
|
|
205
207
|
agentRegistry?: AgentRegistry;
|
|
206
208
|
/** Optional restricted bash command prefixes for read-only role agents and constrained modes. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/coding-agent",
|
|
4
|
-
"version": "0.11.
|
|
4
|
+
"version": "0.11.10",
|
|
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 and Gajae Code Contributors",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
"@agentclientprotocol/sdk": "1.2.1",
|
|
54
54
|
"@babel/parser": "^7.29.3",
|
|
55
55
|
"@mozilla/readability": "^0.6.0",
|
|
56
|
-
"@gajae-code/stats": "0.11.
|
|
57
|
-
"@gajae-code/agent-core": "0.11.
|
|
58
|
-
"@gajae-code/ai": "0.11.
|
|
59
|
-
"@gajae-code/bridge-client": "0.11.
|
|
60
|
-
"@gajae-code/natives": "0.11.
|
|
61
|
-
"@gajae-code/tui": "0.11.
|
|
62
|
-
"@gajae-code/utils": "0.11.
|
|
56
|
+
"@gajae-code/stats": "0.11.10",
|
|
57
|
+
"@gajae-code/agent-core": "0.11.10",
|
|
58
|
+
"@gajae-code/ai": "0.11.10",
|
|
59
|
+
"@gajae-code/bridge-client": "0.11.10",
|
|
60
|
+
"@gajae-code/natives": "0.11.10",
|
|
61
|
+
"@gajae-code/tui": "0.11.10",
|
|
62
|
+
"@gajae-code/utils": "0.11.10",
|
|
63
63
|
"@puppeteer/browsers": "^2.13.0",
|
|
64
64
|
"@types/turndown": "5.0.6",
|
|
65
65
|
"@xterm/headless": "^6.0.0",
|
|
@@ -70,6 +70,7 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
70
70
|
"agent_session:getAsyncDeliveryStateForAcp":
|
|
71
71
|
"internal ACP lifecycle quiescence plumbing, not a user-facing control seam",
|
|
72
72
|
"agent_session:getToolByName": "internal accessor/plumbing, not a user-facing control seam",
|
|
73
|
+
"agent_session:getToolForExecution": "internal accessor/plumbing, not a user-facing control seam",
|
|
73
74
|
"agent_session:registerForegroundBashBackgroundRequestHandler":
|
|
74
75
|
"internal accessor/plumbing, not a user-facing control seam",
|
|
75
76
|
"agent_session:hasForegroundBashBackgroundRequestHandler":
|
package/src/cli/mcp-cli.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { getMCPConfigPath, getProjectDir } from "@gajae-code/utils";
|
|
8
8
|
import { getMCPServer, readMCPConfigFile, removeMCPServer, upsertMCPServer } from "../runtime-mcp/config-writer";
|
|
9
|
+
import { redactMCPEndpoint } from "../runtime-mcp/redaction";
|
|
9
10
|
import type { MCPConfigFile, MCPServerConfig } from "../runtime-mcp/types";
|
|
10
11
|
|
|
11
12
|
export type MCPAction = "add" | "list" | "remove";
|
|
@@ -141,24 +142,6 @@ function redactRecord(
|
|
|
141
142
|
);
|
|
142
143
|
}
|
|
143
144
|
|
|
144
|
-
function redactUrl(value: string | undefined): string | undefined {
|
|
145
|
-
if (!value) return value;
|
|
146
|
-
try {
|
|
147
|
-
const url = new URL(value);
|
|
148
|
-
if (url.username) url.username = REDACTED;
|
|
149
|
-
if (url.password) url.password = REDACTED;
|
|
150
|
-
if (url.search) {
|
|
151
|
-
for (const key of Array.from(url.searchParams.keys())) {
|
|
152
|
-
url.searchParams.set(key, REDACTED);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
url.hash = "";
|
|
156
|
-
return url.toString();
|
|
157
|
-
} catch {
|
|
158
|
-
return SENSITIVE_KEY_PATTERN.test(value) ? REDACTED : value;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
145
|
function redactArgs(args: string[] | undefined): string[] | undefined {
|
|
163
146
|
if (!args) return undefined;
|
|
164
147
|
const redacted: string[] = [];
|
|
@@ -196,7 +179,7 @@ export function redactMCPServerConfig(config: MCPServerConfig): MCPServerConfig
|
|
|
196
179
|
if (headers) redacted.headers = headers;
|
|
197
180
|
}
|
|
198
181
|
if ("url" in redacted) {
|
|
199
|
-
const url =
|
|
182
|
+
const url = redactMCPEndpoint(redacted.url);
|
|
200
183
|
if (url) redacted.url = url;
|
|
201
184
|
}
|
|
202
185
|
if ("args" in redacted) {
|
|
@@ -207,7 +190,7 @@ export function redactMCPServerConfig(config: MCPServerConfig): MCPServerConfig
|
|
|
207
190
|
redacted.auth = {
|
|
208
191
|
type: redacted.auth.type,
|
|
209
192
|
credentialId: redacted.auth.credentialId ? REDACTED : undefined,
|
|
210
|
-
tokenUrl:
|
|
193
|
+
tokenUrl: redactMCPEndpoint(redacted.auth.tokenUrl),
|
|
211
194
|
clientId: redacted.auth.clientId ? REDACTED : undefined,
|
|
212
195
|
clientSecret: redacted.auth.clientSecret ? REDACTED : undefined,
|
|
213
196
|
};
|
|
@@ -216,7 +199,7 @@ export function redactMCPServerConfig(config: MCPServerConfig): MCPServerConfig
|
|
|
216
199
|
redacted.oauth = {
|
|
217
200
|
clientId: redacted.oauth.clientId ? REDACTED : undefined,
|
|
218
201
|
clientSecret: redacted.oauth.clientSecret ? REDACTED : undefined,
|
|
219
|
-
redirectUri:
|
|
202
|
+
redirectUri: redactMCPEndpoint(redacted.oauth.redirectUri),
|
|
220
203
|
callbackPort: redacted.oauth.callbackPort,
|
|
221
204
|
callbackPath: redacted.oauth.callbackPath,
|
|
222
205
|
};
|
package/src/cli/notify-cli.ts
CHANGED
|
@@ -413,6 +413,7 @@ async function runTelegramSetup(cmd: NotifyCommandArgs, deps: NotifyCommandDeps)
|
|
|
413
413
|
settings,
|
|
414
414
|
cwd: process.cwd(),
|
|
415
415
|
sessionId: `notify-cli-${process.pid}`,
|
|
416
|
+
registerRoot: false,
|
|
416
417
|
}),
|
|
417
418
|
persistInactive: async marker => await persistTelegramActivationMarker(settings, marker),
|
|
418
419
|
clearInactive: async marker => await clearTelegramActivationMarker(settings, marker),
|
package/src/cli.ts
CHANGED
|
@@ -118,6 +118,36 @@ Options:
|
|
|
118
118
|
`);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
export function interactiveBootstrapText(
|
|
122
|
+
argv: readonly string[],
|
|
123
|
+
stdinIsTTY = process.stdin.isTTY,
|
|
124
|
+
stdoutIsTTY = process.stdout.isTTY,
|
|
125
|
+
): string | undefined {
|
|
126
|
+
if (!stdinIsTTY || !stdoutIsTTY || argv[0] !== "launch") return undefined;
|
|
127
|
+
for (let index = 1; index < argv.length; index++) {
|
|
128
|
+
const arg = argv[index];
|
|
129
|
+
if (
|
|
130
|
+
arg === "--print" ||
|
|
131
|
+
arg?.startsWith("--print=") ||
|
|
132
|
+
arg === "-p" ||
|
|
133
|
+
arg === "--export" ||
|
|
134
|
+
arg?.startsWith("--export=") ||
|
|
135
|
+
arg === "--list-models" ||
|
|
136
|
+
arg?.startsWith("--list-models=") ||
|
|
137
|
+
arg === "--mode" ||
|
|
138
|
+
arg?.startsWith("--mode=") ||
|
|
139
|
+
arg === "--help" ||
|
|
140
|
+
arg?.startsWith("--help=") ||
|
|
141
|
+
arg === "-h" ||
|
|
142
|
+
arg === "--version" ||
|
|
143
|
+
arg?.startsWith("--version=") ||
|
|
144
|
+
arg === "-v"
|
|
145
|
+
)
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
return "\u001b[?25h\u001b[38;5;45mGJC\u001b[0m warming workspace\r\n\r\n> ";
|
|
149
|
+
}
|
|
150
|
+
|
|
121
151
|
function isNotifyDaemonInternalFastPath(argv: string[]): boolean {
|
|
122
152
|
return argv[0] === "notify" && argv[1] === "daemon-internal";
|
|
123
153
|
}
|
|
@@ -412,6 +442,8 @@ export async function runCli(argv: string[]): Promise<void> {
|
|
|
412
442
|
showStatsFastHelp();
|
|
413
443
|
return;
|
|
414
444
|
}
|
|
445
|
+
const bootstrap = interactiveBootstrapText(runArgv);
|
|
446
|
+
if (bootstrap) process.stdout.write(bootstrap);
|
|
415
447
|
await installRuntimeGlobals();
|
|
416
448
|
return run({ bin: APP_NAME, version: VERSION, argv: runArgv, commands, help: showHelp });
|
|
417
449
|
}
|