instar 1.3.201 → 1.3.203
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/dist/cli.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/route.d.ts.map +1 -1
- package/dist/commands/route.js +2 -0
- package/dist/commands/route.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +25 -10
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/setup.d.ts +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +47 -12
- package/dist/commands/setup.js.map +1 -1
- package/dist/core/Config.d.ts +12 -2
- package/dist/core/Config.d.ts.map +1 -1
- package/dist/core/Config.js +36 -10
- package/dist/core/Config.js.map +1 -1
- package/dist/core/FeatureRegistry.d.ts.map +1 -1
- package/dist/core/FeatureRegistry.js +6 -0
- package/dist/core/FeatureRegistry.js.map +1 -1
- package/dist/core/FrameworkSessionStore.d.ts +2 -9
- package/dist/core/FrameworkSessionStore.d.ts.map +1 -1
- package/dist/core/FrameworkSessionStore.js +16 -0
- package/dist/core/FrameworkSessionStore.js.map +1 -1
- package/dist/core/GeminiCliIntelligenceProvider.d.ts +44 -0
- package/dist/core/GeminiCliIntelligenceProvider.d.ts.map +1 -0
- package/dist/core/GeminiCliIntelligenceProvider.js +65 -0
- package/dist/core/GeminiCliIntelligenceProvider.js.map +1 -0
- package/dist/core/IdentityRenderer.d.ts.map +1 -1
- package/dist/core/IdentityRenderer.js +6 -3
- package/dist/core/IdentityRenderer.js.map +1 -1
- package/dist/core/LeaseCoordinator.d.ts +40 -0
- package/dist/core/LeaseCoordinator.d.ts.map +1 -1
- package/dist/core/LeaseCoordinator.js +54 -0
- package/dist/core/LeaseCoordinator.js.map +1 -1
- package/dist/core/LocalLeaseStore.d.ts +11 -0
- package/dist/core/LocalLeaseStore.d.ts.map +1 -1
- package/dist/core/LocalLeaseStore.js +18 -0
- package/dist/core/LocalLeaseStore.js.map +1 -1
- package/dist/core/MultiMachineCoordinator.d.ts +35 -0
- package/dist/core/MultiMachineCoordinator.d.ts.map +1 -1
- package/dist/core/MultiMachineCoordinator.js +94 -0
- package/dist/core/MultiMachineCoordinator.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +7 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/PreCompactionFlush.d.ts +3 -1
- package/dist/core/PreCompactionFlush.d.ts.map +1 -1
- package/dist/core/PreCompactionFlush.js +3 -1
- package/dist/core/PreCompactionFlush.js.map +1 -1
- package/dist/core/ResumeValidator.d.ts +1 -1
- package/dist/core/ResumeValidator.d.ts.map +1 -1
- package/dist/core/SqliteRegistry.d.ts +59 -0
- package/dist/core/SqliteRegistry.d.ts.map +1 -0
- package/dist/core/SqliteRegistry.js +97 -0
- package/dist/core/SqliteRegistry.js.map +1 -0
- package/dist/core/StopGateDb.d.ts +2 -0
- package/dist/core/StopGateDb.d.ts.map +1 -1
- package/dist/core/StopGateDb.js +22 -0
- package/dist/core/StopGateDb.js.map +1 -1
- package/dist/core/TopicFrameworksStore.d.ts.map +1 -1
- package/dist/core/TopicFrameworksStore.js +1 -0
- package/dist/core/TopicFrameworksStore.js.map +1 -1
- package/dist/core/TopicResumeMap.d.ts.map +1 -1
- package/dist/core/TopicResumeMap.js +13 -0
- package/dist/core/TopicResumeMap.js.map +1 -1
- package/dist/core/frameworkSessionLaunch.d.ts.map +1 -1
- package/dist/core/frameworkSessionLaunch.js +73 -0
- package/dist/core/frameworkSessionLaunch.js.map +1 -1
- package/dist/core/intelligenceProviderFactory.d.ts +8 -1
- package/dist/core/intelligenceProviderFactory.d.ts.map +1 -1
- package/dist/core/intelligenceProviderFactory.js +13 -1
- package/dist/core/intelligenceProviderFactory.js.map +1 -1
- package/dist/core/types.d.ts +6 -4
- package/dist/core/types.d.ts.map +1 -1
- package/dist/memory/SemanticMemory.d.ts.map +1 -1
- package/dist/memory/SemanticMemory.js +8 -0
- package/dist/memory/SemanticMemory.js.map +1 -1
- package/dist/memory/TopicMemory.d.ts.map +1 -1
- package/dist/memory/TopicMemory.js +7 -0
- package/dist/memory/TopicMemory.js.map +1 -1
- package/dist/messaging/MessageProcessingLedger.d.ts.map +1 -1
- package/dist/messaging/MessageProcessingLedger.js +7 -0
- package/dist/messaging/MessageProcessingLedger.js.map +1 -1
- package/dist/messaging/imessage/NativeBackend.d.ts.map +1 -1
- package/dist/messaging/imessage/NativeBackend.js +6 -0
- package/dist/messaging/imessage/NativeBackend.js.map +1 -1
- package/dist/messaging/pending-relay-store.d.ts.map +1 -1
- package/dist/messaging/pending-relay-store.js +6 -0
- package/dist/messaging/pending-relay-store.js.map +1 -1
- package/dist/messaging/shared/telegramRelayPrompt.d.ts +1 -1
- package/dist/messaging/shared/telegramRelayPrompt.d.ts.map +1 -1
- package/dist/messaging/shared/telegramRelayPrompt.js.map +1 -1
- package/dist/monitoring/CompactionSentinel.d.ts +2 -0
- package/dist/monitoring/CompactionSentinel.d.ts.map +1 -1
- package/dist/monitoring/CompactionSentinel.js +10 -0
- package/dist/monitoring/CompactionSentinel.js.map +1 -1
- package/dist/monitoring/CorrectionLedger.d.ts.map +1 -1
- package/dist/monitoring/CorrectionLedger.js +6 -0
- package/dist/monitoring/CorrectionLedger.js.map +1 -1
- package/dist/monitoring/FailureLedger.d.ts.map +1 -1
- package/dist/monitoring/FailureLedger.js +6 -0
- package/dist/monitoring/FailureLedger.js.map +1 -1
- package/dist/monitoring/FeatureMetricsLedger.d.ts.map +1 -1
- package/dist/monitoring/FeatureMetricsLedger.js +6 -0
- package/dist/monitoring/FeatureMetricsLedger.js.map +1 -1
- package/dist/monitoring/FrameworkIssueLedger.d.ts.map +1 -1
- package/dist/monitoring/FrameworkIssueLedger.js +6 -0
- package/dist/monitoring/FrameworkIssueLedger.js.map +1 -1
- package/dist/monitoring/RateLimitSentinel.d.ts +2 -0
- package/dist/monitoring/RateLimitSentinel.d.ts.map +1 -1
- package/dist/monitoring/RateLimitSentinel.js +15 -1
- package/dist/monitoring/RateLimitSentinel.js.map +1 -1
- package/dist/monitoring/RevertDetector.d.ts.map +1 -1
- package/dist/monitoring/RevertDetector.js +7 -1
- package/dist/monitoring/RevertDetector.js.map +1 -1
- package/dist/monitoring/SessionReaper.d.ts +1 -1
- package/dist/monitoring/SessionReaper.d.ts.map +1 -1
- package/dist/monitoring/SessionReaper.js +7 -0
- package/dist/monitoring/SessionReaper.js.map +1 -1
- package/dist/monitoring/TokenLedger.d.ts.map +1 -1
- package/dist/monitoring/TokenLedger.js +8 -0
- package/dist/monitoring/TokenLedger.js.map +1 -1
- package/dist/monitoring/frameworkActivitySignals.d.ts.map +1 -1
- package/dist/monitoring/frameworkActivitySignals.js +17 -0
- package/dist/monitoring/frameworkActivitySignals.js.map +1 -1
- package/dist/monitoring/frameworkProcessSignals.d.ts.map +1 -1
- package/dist/monitoring/frameworkProcessSignals.js +15 -0
- package/dist/monitoring/frameworkProcessSignals.js.map +1 -1
- package/dist/providers/adapters/gemini-cli/capabilities.d.ts +28 -0
- package/dist/providers/adapters/gemini-cli/capabilities.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/capabilities.js +38 -0
- package/dist/providers/adapters/gemini-cli/capabilities.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/config.d.ts +50 -0
- package/dist/providers/adapters/gemini-cli/config.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/config.js +36 -0
- package/dist/providers/adapters/gemini-cli/config.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/control/geminiHardKill.d.ts +19 -0
- package/dist/providers/adapters/gemini-cli/control/geminiHardKill.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/control/geminiHardKill.js +67 -0
- package/dist/providers/adapters/gemini-cli/control/geminiHardKill.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/credentials.d.ts +40 -0
- package/dist/providers/adapters/gemini-cli/credentials.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/credentials.js +41 -0
- package/dist/providers/adapters/gemini-cli/credentials.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/errors.d.ts +23 -0
- package/dist/providers/adapters/gemini-cli/errors.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/errors.js +41 -0
- package/dist/providers/adapters/gemini-cli/errors.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/index.d.ts +38 -0
- package/dist/providers/adapters/gemini-cli/index.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/index.js +66 -0
- package/dist/providers/adapters/gemini-cli/index.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/models.d.ts +29 -0
- package/dist/providers/adapters/gemini-cli/models.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/models.js +43 -0
- package/dist/providers/adapters/gemini-cli/models.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/observability/sessionId.d.ts +26 -0
- package/dist/providers/adapters/gemini-cli/observability/sessionId.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/observability/sessionId.js +52 -0
- package/dist/providers/adapters/gemini-cli/observability/sessionId.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/observability/sessionPaths.d.ts +72 -0
- package/dist/providers/adapters/gemini-cli/observability/sessionPaths.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/observability/sessionPaths.js +202 -0
- package/dist/providers/adapters/gemini-cli/observability/sessionPaths.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/transport/geminiSpawn.d.ts +79 -0
- package/dist/providers/adapters/gemini-cli/transport/geminiSpawn.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/transport/geminiSpawn.js +221 -0
- package/dist/providers/adapters/gemini-cli/transport/geminiSpawn.js.map +1 -0
- package/dist/providers/adapters/gemini-cli/transport/oneShotCompletion.d.ts +21 -0
- package/dist/providers/adapters/gemini-cli/transport/oneShotCompletion.d.ts.map +1 -0
- package/dist/providers/adapters/gemini-cli/transport/oneShotCompletion.js +80 -0
- package/dist/providers/adapters/gemini-cli/transport/oneShotCompletion.js.map +1 -0
- package/dist/providers/parity/rules/skillParityRule.d.ts.map +1 -1
- package/dist/providers/parity/rules/skillParityRule.js +8 -0
- package/dist/providers/parity/rules/skillParityRule.js.map +1 -1
- package/dist/providers/uxConfirm/PreferenceStore.d.ts +1 -0
- package/dist/providers/uxConfirm/PreferenceStore.d.ts.map +1 -1
- package/dist/providers/uxConfirm/PreferenceStore.js +13 -0
- package/dist/providers/uxConfirm/PreferenceStore.js.map +1 -1
- package/dist/threadline/SpawnLedger.d.ts +1 -0
- package/dist/threadline/SpawnLedger.d.ts.map +1 -1
- package/dist/threadline/SpawnLedger.js +13 -0
- package/dist/threadline/SpawnLedger.js.map +1 -1
- package/dist/threadline/ThreadResumeMap.d.ts.map +1 -1
- package/dist/threadline/ThreadResumeMap.js +14 -0
- package/dist/threadline/ThreadResumeMap.js.map +1 -1
- package/dist/threadline/relay/RegistryStore.d.ts.map +1 -1
- package/dist/threadline/relay/RegistryStore.js +6 -0
- package/dist/threadline/relay/RegistryStore.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +50 -50
- package/src/templates/scripts/convergence-check.sh +49 -0
- package/upgrades/1.3.202.md +65 -0
- package/upgrades/1.3.203.md +30 -0
- package/upgrades/side-effects/APPRENTICESHIP-STEP2-GEMINI-RUNTIME-ADAPTER-SPEC.md +78 -0
- package/upgrades/side-effects/evo003-revertdetector-git-arg.md +106 -0
- package/upgrades/side-effects/git-less-lease-convergence.md +31 -0
- package/upgrades/side-effects/sqlite-close-on-exit-registry.md +27 -0
- package/upgrades/side-effects/time-awareness-component4-reporting-nudge.md +20 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter-specific error helpers for gemini-cli.
|
|
3
|
+
*
|
|
4
|
+
* Maps raw failures (gemini CLI non-zero exit, timeout/abort) to the
|
|
5
|
+
* canonical ProviderError hierarchy. Mirrors openai-codex/errors.ts but
|
|
6
|
+
* scoped to the minimal-body surface.
|
|
7
|
+
*/
|
|
8
|
+
import { AbortError, AuthError, NetworkError, QuotaError, RateLimitError, TimeoutError, UnexpectedError, } from '../../errors.js';
|
|
9
|
+
export const GEMINI_CLI_ID = 'gemini-cli';
|
|
10
|
+
/**
|
|
11
|
+
* Map a raw spawn-style error from spawning `gemini` into a canonical
|
|
12
|
+
* provider error. Stderr is inspected for auth / rate-limit / quota /
|
|
13
|
+
* network signatures (the same classification shape codex uses) so the
|
|
14
|
+
* circuit breaker's rate-limit classifier can see usage/limit language.
|
|
15
|
+
*/
|
|
16
|
+
export function mapExecError(err, stderr = '') {
|
|
17
|
+
if (err.name === 'AbortError') {
|
|
18
|
+
return new AbortError('Gemini exec aborted', GEMINI_CLI_ID, err);
|
|
19
|
+
}
|
|
20
|
+
if (err.signal === 'SIGTERM' || err.killed) {
|
|
21
|
+
return new TimeoutError(`gemini CLI killed: ${err.message}`, GEMINI_CLI_ID, 0, { cause: err });
|
|
22
|
+
}
|
|
23
|
+
if (err.code === 'ENOENT') {
|
|
24
|
+
return new UnexpectedError(`gemini CLI binary not found: ${err.path ?? '(unknown)'}`, GEMINI_CLI_ID, err);
|
|
25
|
+
}
|
|
26
|
+
const message = stderr ? stderr.slice(0, 500) : err.message;
|
|
27
|
+
if (/unauthor|forbidden|invalid.*token|invalid.*key|401|403/i.test(stderr)) {
|
|
28
|
+
return new AuthError(message, GEMINI_CLI_ID, err);
|
|
29
|
+
}
|
|
30
|
+
if (/rate.?limit|429|too many requests|resource.?exhausted/i.test(stderr)) {
|
|
31
|
+
return new RateLimitError(message, GEMINI_CLI_ID, { cause: err });
|
|
32
|
+
}
|
|
33
|
+
if (/quota|usage.?limit/i.test(stderr)) {
|
|
34
|
+
return new QuotaError(message, GEMINI_CLI_ID, { cause: err });
|
|
35
|
+
}
|
|
36
|
+
if (/network|ECONN|ETIMEDOUT|dns/i.test(stderr)) {
|
|
37
|
+
return new NetworkError(message, GEMINI_CLI_ID, err);
|
|
38
|
+
}
|
|
39
|
+
return new UnexpectedError(message, GEMINI_CLI_ID, err);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../src/providers/adapters/gemini-cli/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,UAAU,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,cAAc,EACd,YAAY,EACZ,eAAe,GAEhB,MAAM,iBAAiB,CAAC;AAGzB,MAAM,CAAC,MAAM,aAAa,GAAG,YAA0B,CAAC;AAExD;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAyF,EACzF,MAAM,GAAG,EAAE;IAEX,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC9B,OAAO,IAAI,UAAU,CAAC,qBAAqB,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAC3C,OAAO,IAAI,YAAY,CACrB,sBAAsB,GAAG,CAAC,OAAO,EAAE,EACnC,aAAa,EACb,CAAC,EACD,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,eAAe,CACxB,gCAAgC,GAAG,CAAC,IAAI,IAAI,WAAW,EAAE,EACzD,aAAa,EACb,GAAG,CACJ,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IAC5D,IAAI,yDAAyD,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,wDAAwD,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1E,OAAO,IAAI,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,UAAU,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,8BAA8B,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gemini-cli adapter — entry point (MINIMAL BODY, apprenticeship Step 2).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the openai-codex adapter shape (a factory that builds an `impls`
|
|
5
|
+
* map and returns a `ProviderAdapter`), but declares a SMALLER, honest
|
|
6
|
+
* capability set for the minimal body. Only the MANDATORY floor is wired:
|
|
7
|
+
* OneShotCompletion, SessionId, HardKill. The CONDITIONAL primitives
|
|
8
|
+
* (HookEventReceiver / CompactionLifecycle / SessionResumeIndex) are NOT
|
|
9
|
+
* wired here — their live contract is uncharacterized, so shipping them
|
|
10
|
+
* half-built would be a capability-declaration lie (tracked as `programNeeds`
|
|
11
|
+
* need-gem-001 instead).
|
|
12
|
+
*
|
|
13
|
+
* DORMANCY: this registry adapter is the parity-harness / future-routing
|
|
14
|
+
* surface — `server.ts` registers no adapters against the production registry.
|
|
15
|
+
* The ALIVE transport runs through `GeminiCliIntelligenceProvider`
|
|
16
|
+
* (src/core/), constructed by `buildIntelligenceProvider`. This adapter and
|
|
17
|
+
* that class share the one-shot transport, but the alive proof flows through
|
|
18
|
+
* the class, not this registry.
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
*
|
|
22
|
+
* import { createGeminiCliAdapter } from
|
|
23
|
+
* './providers/adapters/gemini-cli/index.js';
|
|
24
|
+
* import { registry } from './providers/registry.js';
|
|
25
|
+
*
|
|
26
|
+
* await registry.register(createGeminiCliAdapter({ ... }));
|
|
27
|
+
*/
|
|
28
|
+
import type { ProviderAdapter } from '../../registry.js';
|
|
29
|
+
import { type GeminiCliConfig } from './config.js';
|
|
30
|
+
/**
|
|
31
|
+
* Create the gemini-cli adapter with the given config (or environment
|
|
32
|
+
* defaults if omitted).
|
|
33
|
+
*/
|
|
34
|
+
export declare function createGeminiCliAdapter(partialConfig?: Partial<GeminiCliConfig>): ProviderAdapter;
|
|
35
|
+
export type { GeminiCliConfig } from './config.js';
|
|
36
|
+
export { configFromEnv } from './config.js';
|
|
37
|
+
export { GEMINI_CLI_ID } from './errors.js';
|
|
38
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/providers/adapters/gemini-cli/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIzD,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAQlE;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,GAAE,OAAO,CAAC,eAAe,CAAM,GAC3C,eAAe,CA4BjB;AAED,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gemini-cli adapter — entry point (MINIMAL BODY, apprenticeship Step 2).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the openai-codex adapter shape (a factory that builds an `impls`
|
|
5
|
+
* map and returns a `ProviderAdapter`), but declares a SMALLER, honest
|
|
6
|
+
* capability set for the minimal body. Only the MANDATORY floor is wired:
|
|
7
|
+
* OneShotCompletion, SessionId, HardKill. The CONDITIONAL primitives
|
|
8
|
+
* (HookEventReceiver / CompactionLifecycle / SessionResumeIndex) are NOT
|
|
9
|
+
* wired here — their live contract is uncharacterized, so shipping them
|
|
10
|
+
* half-built would be a capability-declaration lie (tracked as `programNeeds`
|
|
11
|
+
* need-gem-001 instead).
|
|
12
|
+
*
|
|
13
|
+
* DORMANCY: this registry adapter is the parity-harness / future-routing
|
|
14
|
+
* surface — `server.ts` registers no adapters against the production registry.
|
|
15
|
+
* The ALIVE transport runs through `GeminiCliIntelligenceProvider`
|
|
16
|
+
* (src/core/), constructed by `buildIntelligenceProvider`. This adapter and
|
|
17
|
+
* that class share the one-shot transport, but the alive proof flows through
|
|
18
|
+
* the class, not this registry.
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
*
|
|
22
|
+
* import { createGeminiCliAdapter } from
|
|
23
|
+
* './providers/adapters/gemini-cli/index.js';
|
|
24
|
+
* import { registry } from './providers/registry.js';
|
|
25
|
+
*
|
|
26
|
+
* await registry.register(createGeminiCliAdapter({ ... }));
|
|
27
|
+
*/
|
|
28
|
+
import { UnsupportedCapabilityError } from '../../errors.js';
|
|
29
|
+
import { geminiCliCapabilities } from './capabilities.js';
|
|
30
|
+
import { GEMINI_CLI_ID } from './errors.js';
|
|
31
|
+
import { configFromEnv } from './config.js';
|
|
32
|
+
import { createOneShotCompletion } from './transport/oneShotCompletion.js';
|
|
33
|
+
import { createSessionId } from './observability/sessionId.js';
|
|
34
|
+
import { createHardKill } from './control/geminiHardKill.js';
|
|
35
|
+
import { CapabilityFlag as Cap } from '../../capabilities.js';
|
|
36
|
+
/**
|
|
37
|
+
* Create the gemini-cli adapter with the given config (or environment
|
|
38
|
+
* defaults if omitted).
|
|
39
|
+
*/
|
|
40
|
+
export function createGeminiCliAdapter(partialConfig = {}) {
|
|
41
|
+
const config = {
|
|
42
|
+
...configFromEnv(),
|
|
43
|
+
...partialConfig,
|
|
44
|
+
};
|
|
45
|
+
const impls = new Map();
|
|
46
|
+
// Transport
|
|
47
|
+
impls.set(Cap.OneShotCompletion, createOneShotCompletion(config));
|
|
48
|
+
// Observability
|
|
49
|
+
impls.set(Cap.SessionId, createSessionId());
|
|
50
|
+
// Control
|
|
51
|
+
impls.set(Cap.HardKill, createHardKill());
|
|
52
|
+
return {
|
|
53
|
+
id: GEMINI_CLI_ID,
|
|
54
|
+
capabilities: geminiCliCapabilities,
|
|
55
|
+
primitive(capability) {
|
|
56
|
+
const impl = impls.get(capability);
|
|
57
|
+
if (impl === undefined) {
|
|
58
|
+
throw new UnsupportedCapabilityError(capability, GEMINI_CLI_ID);
|
|
59
|
+
}
|
|
60
|
+
return impl;
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export { configFromEnv } from './config.js';
|
|
65
|
+
export { GEMINI_CLI_ID } from './errors.js';
|
|
66
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/providers/adapters/gemini-cli/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAwB,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,cAAc,IAAI,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,gBAA0C,EAAE;IAE5C,MAAM,MAAM,GAAoB;QAC9B,GAAG,aAAa,EAAE;QAClB,GAAG,aAAa;KACjB,CAAC;IAEF,MAAM,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEjD,YAAY;IACZ,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC;IAElE,gBAAgB;IAChB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;IAE5C,UAAU;IACV,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;IAE1C,OAAO;QACL,EAAE,EAAE,aAAa;QACjB,YAAY,EAAE,qBAAqB;QACnC,SAAS,CAAC,UAA0B;YAClC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACnC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,IAAI,0BAA0B,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;YAClE,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-tier resolution for gemini-cli.
|
|
3
|
+
*
|
|
4
|
+
* Maps the canonical ModelTier ('fast' | 'balanced' | 'capable') onto a
|
|
5
|
+
* concrete Gemini model name. Gemini CLI selects the model via `-m <name>`.
|
|
6
|
+
*
|
|
7
|
+
* Verified facts (apprenticeship Step 2, gemini CLI v0.25.2, authed via
|
|
8
|
+
* `~/.gemini` OAuth):
|
|
9
|
+
* - `gemini -m gemini-2.5-flash "<prompt>"` → clean stdout, exit 0. This
|
|
10
|
+
* is the verified-working default and the `fast`/`balanced` tier.
|
|
11
|
+
* - `gemini-2.5-pro` is the capable/heavy tier (the `route.ts` KNOWN_MODELS
|
|
12
|
+
* list already names it). It is NOT re-probed here — the exact ids beyond
|
|
13
|
+
* the verified `gemini-2.5-flash` are a §6 build-time discovery item, kept
|
|
14
|
+
* in sync with `resolveModelForFramework('gemini-cli', …)`.
|
|
15
|
+
*
|
|
16
|
+
* Drift risk: model availability changes per Gemini version. This map is a
|
|
17
|
+
* Rule-3 surface; the authoritative-name check belongs in a dedicated canary
|
|
18
|
+
* (a §6 conditional, added when the model surface is characterized).
|
|
19
|
+
*/
|
|
20
|
+
import type { ModelTier } from '../../types.js';
|
|
21
|
+
/** The default model when no tier or id is supplied. */
|
|
22
|
+
export declare const GEMINI_DEFAULT_MODEL = "gemini-2.5-flash";
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a tier or raw model string to a concrete model name to pass to
|
|
25
|
+
* the gemini CLI's `-m` flag. If `tierOrModel` doesn't match a known tier,
|
|
26
|
+
* it's returned verbatim (treated as a raw model name).
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveCliModelFlag(tierOrModel: string | ModelTier | undefined): string;
|
|
29
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../../../src/providers/adapters/gemini-cli/models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAWhD,wDAAwD;AACxD,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAMvF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-tier resolution for gemini-cli.
|
|
3
|
+
*
|
|
4
|
+
* Maps the canonical ModelTier ('fast' | 'balanced' | 'capable') onto a
|
|
5
|
+
* concrete Gemini model name. Gemini CLI selects the model via `-m <name>`.
|
|
6
|
+
*
|
|
7
|
+
* Verified facts (apprenticeship Step 2, gemini CLI v0.25.2, authed via
|
|
8
|
+
* `~/.gemini` OAuth):
|
|
9
|
+
* - `gemini -m gemini-2.5-flash "<prompt>"` → clean stdout, exit 0. This
|
|
10
|
+
* is the verified-working default and the `fast`/`balanced` tier.
|
|
11
|
+
* - `gemini-2.5-pro` is the capable/heavy tier (the `route.ts` KNOWN_MODELS
|
|
12
|
+
* list already names it). It is NOT re-probed here — the exact ids beyond
|
|
13
|
+
* the verified `gemini-2.5-flash` are a §6 build-time discovery item, kept
|
|
14
|
+
* in sync with `resolveModelForFramework('gemini-cli', …)`.
|
|
15
|
+
*
|
|
16
|
+
* Drift risk: model availability changes per Gemini version. This map is a
|
|
17
|
+
* Rule-3 surface; the authoritative-name check belongs in a dedicated canary
|
|
18
|
+
* (a §6 conditional, added when the model surface is characterized).
|
|
19
|
+
*/
|
|
20
|
+
const TIER_TO_MODEL = {
|
|
21
|
+
// light/fast — the verified-working one-shot default.
|
|
22
|
+
fast: 'gemini-2.5-flash',
|
|
23
|
+
// medium — balanced; same flash model (verified one-shot path).
|
|
24
|
+
balanced: 'gemini-2.5-flash',
|
|
25
|
+
// heavy — frontier; the pro tier for hard problems + main chat.
|
|
26
|
+
capable: 'gemini-2.5-pro',
|
|
27
|
+
};
|
|
28
|
+
/** The default model when no tier or id is supplied. */
|
|
29
|
+
export const GEMINI_DEFAULT_MODEL = 'gemini-2.5-flash';
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a tier or raw model string to a concrete model name to pass to
|
|
32
|
+
* the gemini CLI's `-m` flag. If `tierOrModel` doesn't match a known tier,
|
|
33
|
+
* it's returned verbatim (treated as a raw model name).
|
|
34
|
+
*/
|
|
35
|
+
export function resolveCliModelFlag(tierOrModel) {
|
|
36
|
+
if (!tierOrModel)
|
|
37
|
+
return GEMINI_DEFAULT_MODEL;
|
|
38
|
+
if (tierOrModel in TIER_TO_MODEL) {
|
|
39
|
+
return TIER_TO_MODEL[tierOrModel];
|
|
40
|
+
}
|
|
41
|
+
return tierOrModel;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../../src/providers/adapters/gemini-cli/models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,MAAM,aAAa,GAA8B;IAC/C,sDAAsD;IACtD,IAAI,EAAE,kBAAkB;IACxB,gEAAgE;IAChE,QAAQ,EAAE,kBAAkB;IAC5B,gEAAgE;IAChE,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF,wDAAwD;AACxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAA2C;IAC7E,IAAI,CAAC,WAAW;QAAE,OAAO,oBAAoB,CAAC;IAC9C,IAAI,WAAW,IAAI,aAAa,EAAE,CAAC;QACjC,OAAO,aAAa,CAAC,WAAwB,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionId implementation for gemini-cli.
|
|
3
|
+
*
|
|
4
|
+
* Gemini assigns a UUID to each session (the `"sessionId"` field in its
|
|
5
|
+
* on-disk session file). The adapter's SessionHandle binds to that
|
|
6
|
+
* gemini-side session UUID. This primitive provides the binding both
|
|
7
|
+
* directions.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors openai-codex/observability/sessionId.ts: an in-memory bidirectional
|
|
10
|
+
* map, populated when the adapter observes a session's id, plus a synthetic
|
|
11
|
+
* handle for a known session id without a live process.
|
|
12
|
+
*/
|
|
13
|
+
import type { SessionHandle } from '../../../types.js';
|
|
14
|
+
import type { SessionId } from '../../../primitives/observability/sessionId.js';
|
|
15
|
+
/** Bind a Gemini session UUID to a SessionHandle. */
|
|
16
|
+
export declare function bindGeminiSessionId(handle: SessionHandle, sessionId: string): void;
|
|
17
|
+
/** Look up the SessionHandle for a Gemini session UUID. */
|
|
18
|
+
export declare function handleForGeminiSession(sessionId: string): SessionHandle | null;
|
|
19
|
+
/** Construct a session handle for a known gemini session without a live process. */
|
|
20
|
+
export declare function syntheticHandleForGeminiSession(sessionId: string): SessionHandle;
|
|
21
|
+
/** Construct a process-pid handle for a live one-shot spawn (used by HardKill). */
|
|
22
|
+
export declare function pidHandle(pid: number): SessionHandle;
|
|
23
|
+
export declare function createSessionId(): SessionId;
|
|
24
|
+
/** Test-only: clear the in-memory session-id binding maps. */
|
|
25
|
+
export declare function _resetGeminiSessionIdMaps(): void;
|
|
26
|
+
//# sourceMappingURL=sessionId.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionId.d.ts","sourceRoot":"","sources":["../../../../../src/providers/adapters/gemini-cli/observability/sessionId.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAuB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAE5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gDAAgD,CAAC;AAmBhF,qDAAqD;AACrD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAGlF;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAE9E;AAED,oFAAoF;AACpF,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAEhF;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAEpD;AAED,wBAAgB,eAAe,IAAI,SAAS,CAE3C;AAED,8DAA8D;AAC9D,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionId implementation for gemini-cli.
|
|
3
|
+
*
|
|
4
|
+
* Gemini assigns a UUID to each session (the `"sessionId"` field in its
|
|
5
|
+
* on-disk session file). The adapter's SessionHandle binds to that
|
|
6
|
+
* gemini-side session UUID. This primitive provides the binding both
|
|
7
|
+
* directions.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors openai-codex/observability/sessionId.ts: an in-memory bidirectional
|
|
10
|
+
* map, populated when the adapter observes a session's id, plus a synthetic
|
|
11
|
+
* handle for a known session id without a live process.
|
|
12
|
+
*/
|
|
13
|
+
import { sessionHandle } from '../../../types.js';
|
|
14
|
+
import { CapabilityFlag } from '../../../capabilities.js';
|
|
15
|
+
import { GEMINI_CLI_ID } from '../errors.js';
|
|
16
|
+
const handleToSession = new Map();
|
|
17
|
+
const sessionToHandle = new Map();
|
|
18
|
+
class GeminiCliSessionId {
|
|
19
|
+
capability = CapabilityFlag.SessionId;
|
|
20
|
+
async providerIdFor(session, _options) {
|
|
21
|
+
return handleToSession.get(session) ?? null;
|
|
22
|
+
}
|
|
23
|
+
async handleFor(providerSessionId, _options) {
|
|
24
|
+
return sessionToHandle.get(providerSessionId) ?? null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Bind a Gemini session UUID to a SessionHandle. */
|
|
28
|
+
export function bindGeminiSessionId(handle, sessionId) {
|
|
29
|
+
handleToSession.set(handle, sessionId);
|
|
30
|
+
sessionToHandle.set(sessionId, handle);
|
|
31
|
+
}
|
|
32
|
+
/** Look up the SessionHandle for a Gemini session UUID. */
|
|
33
|
+
export function handleForGeminiSession(sessionId) {
|
|
34
|
+
return sessionToHandle.get(sessionId) ?? null;
|
|
35
|
+
}
|
|
36
|
+
/** Construct a session handle for a known gemini session without a live process. */
|
|
37
|
+
export function syntheticHandleForGeminiSession(sessionId) {
|
|
38
|
+
return sessionHandle(`${GEMINI_CLI_ID}/session-${sessionId}`);
|
|
39
|
+
}
|
|
40
|
+
/** Construct a process-pid handle for a live one-shot spawn (used by HardKill). */
|
|
41
|
+
export function pidHandle(pid) {
|
|
42
|
+
return sessionHandle(`${GEMINI_CLI_ID}/pid-${pid}`);
|
|
43
|
+
}
|
|
44
|
+
export function createSessionId() {
|
|
45
|
+
return new GeminiCliSessionId();
|
|
46
|
+
}
|
|
47
|
+
/** Test-only: clear the in-memory session-id binding maps. */
|
|
48
|
+
export function _resetGeminiSessionIdMaps() {
|
|
49
|
+
handleToSession.clear();
|
|
50
|
+
sessionToHandle.clear();
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=sessionId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionId.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/gemini-cli/observability/sessionId.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAyB,CAAC;AACzD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAyB,CAAC;AAEzD,MAAM,kBAAkB;IACb,UAAU,GAAG,cAAc,CAAC,SAAS,CAAC;IAE/C,KAAK,CAAC,aAAa,CAAC,OAAsB,EAAE,QAA8B;QACxE,OAAO,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,iBAAyB,EAAE,QAA8B;QACvE,OAAO,eAAe,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC;IACxD,CAAC;CACF;AAED,qDAAqD;AACrD,MAAM,UAAU,mBAAmB,CAAC,MAAqB,EAAE,SAAiB;IAC1E,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACvC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,OAAO,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AAChD,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,+BAA+B,CAAC,SAAiB;IAC/D,OAAO,aAAa,CAAC,GAAG,aAAa,YAAY,SAAS,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,aAAa,CAAC,GAAG,aAAa,QAAQ,GAAG,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,kBAAkB,EAAE,CAAC;AAClC,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,yBAAyB;IACvC,eAAe,CAAC,KAAK,EAAE,CAAC;IACxB,eAAe,CAAC,KAAK,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for locating Gemini session files on disk.
|
|
3
|
+
*
|
|
4
|
+
* Gemini CLI writes per-project session files to:
|
|
5
|
+
* ~/.gemini/tmp/<projectHash>/chats/session-<ISO-ts>-<short8>.json[l]
|
|
6
|
+
*
|
|
7
|
+
* Verified against gemini CLI v0.25.2 (apprenticeship Step 2):
|
|
8
|
+
* - The directory is `~/.gemini/tmp/<projectHash>/chats/`.
|
|
9
|
+
* - Each session file's basename is `session-<ISO-timestamp>-<short>.{json,jsonl}`
|
|
10
|
+
* where `<short>` is the FIRST 8 hex chars of the session UUID.
|
|
11
|
+
* - Each file's JSON body carries a `"sessionId"` field = the full UUID.
|
|
12
|
+
*
|
|
13
|
+
* So a session UUID `9b06d03d-f990-49c0-...` lives in a file named
|
|
14
|
+
* `session-2026-06-02T05-32-9b06d03d.json`. This module finds a session's
|
|
15
|
+
* file by UUID: it matches the filename's `<short8>` suffix against the
|
|
16
|
+
* UUID's first 8 chars (fast, no read) and confirms via the in-file
|
|
17
|
+
* `sessionId` only when the cheap filename match is ambiguous.
|
|
18
|
+
*
|
|
19
|
+
* This is the layout the framework-blind resolvers (ThreadResumeMap.jsonlExists,
|
|
20
|
+
* RateLimitSentinel/CompactionSentinel recovery-verification) route through for
|
|
21
|
+
* gemini sessions — exactly as those resolvers route codex sessions through
|
|
22
|
+
* openai-codex/observability/sessionPaths.ts. Without it, a gemini session has
|
|
23
|
+
* no claude jsonl and no codex rollout, so every framework-blind path falls
|
|
24
|
+
* through to a wrong/default file and silently breaks fleet-wide.
|
|
25
|
+
*
|
|
26
|
+
* RULE 3.1 RATIONALE
|
|
27
|
+
* Criticality: high (resume + recovery-verification correctness).
|
|
28
|
+
* Frequency: per-resume / per-recovery-check.
|
|
29
|
+
* Stability: semi-stable (Gemini may change the session layout).
|
|
30
|
+
* Fallback: none — a layout change yields empty results (caught by a
|
|
31
|
+
* geminiSessionLayoutCanary when that conditional ships, §6).
|
|
32
|
+
* Verdict: deterministic FS walk.
|
|
33
|
+
*/
|
|
34
|
+
/** Resolve the Gemini home directory (`~/.gemini` unless overridden). */
|
|
35
|
+
export declare function geminiHomeFromConfig(geminiHome?: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Find a Gemini session file by session UUID. Returns the absolute path or
|
|
38
|
+
* null on miss. Synchronous — the resume-map `jsonlExists` guard runs on a
|
|
39
|
+
* sync code path and cannot await. A missing `~/.gemini/tmp` (e.g. a pure
|
|
40
|
+
* Claude/Codex agent) returns null fast.
|
|
41
|
+
*
|
|
42
|
+
* Strategy:
|
|
43
|
+
* 1. Walk `<geminiHome>/tmp/<projectHash>/chats/` for `session-*` files.
|
|
44
|
+
* 2. Match the filename's `<short8>` against the UUID's first 8 chars.
|
|
45
|
+
* 3. On a filename match, confirm via the in-file `sessionId` (cheap head
|
|
46
|
+
* read) so two sessions sharing an 8-char prefix can't collide.
|
|
47
|
+
* 4. Also accept a file whose body contains the full UUID even if the
|
|
48
|
+
* filename short-id was absent (defensive against a layout tweak).
|
|
49
|
+
*/
|
|
50
|
+
export declare function findGeminiSessionFileSync(uuid: string, geminiHome?: string): string | null;
|
|
51
|
+
/**
|
|
52
|
+
* Find the single newest Gemini session file (by mtime) SYNCHRONOUSLY →
|
|
53
|
+
* `{ path, size, mtime }` (or null when none / not a gemini tree).
|
|
54
|
+
*
|
|
55
|
+
* Used by the gemini branch of the RateLimitSentinel + CompactionSentinel
|
|
56
|
+
* recovery-verification: "did the throttle clear / did compaction recover?"
|
|
57
|
+
* == "is gemini producing output again?" == "did the newest session file
|
|
58
|
+
* grow?". The sentinels compare this against the captured baseline size.
|
|
59
|
+
*
|
|
60
|
+
* Mirrors the codex `findNewestRolloutSync` contract (the account-wide
|
|
61
|
+
* growth signal), adapted to gemini's `tmp/<hash>/chats/` layout. Walks all
|
|
62
|
+
* project-hash chat dirs and statSyncs `session-*` files, returning the
|
|
63
|
+
* newest by mtime. (Gemini's per-project session counts are far smaller than
|
|
64
|
+
* codex's tens-of-thousands of rollouts, so a full stat walk is acceptable
|
|
65
|
+
* for the rarely-run recovery check.)
|
|
66
|
+
*/
|
|
67
|
+
export declare function findNewestGeminiSessionSync(geminiHome?: string): {
|
|
68
|
+
path: string;
|
|
69
|
+
size: number;
|
|
70
|
+
mtime: number;
|
|
71
|
+
} | null;
|
|
72
|
+
//# sourceMappingURL=sessionPaths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionPaths.d.ts","sourceRoot":"","sources":["../../../../../src/providers/adapters/gemini-cli/observability/sessionPaths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAMH,yEAAyE;AACzE,wBAAgB,oBAAoB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhE;AA+CD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgD1F;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,CAAC,EAAE,MAAM,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiCtD"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for locating Gemini session files on disk.
|
|
3
|
+
*
|
|
4
|
+
* Gemini CLI writes per-project session files to:
|
|
5
|
+
* ~/.gemini/tmp/<projectHash>/chats/session-<ISO-ts>-<short8>.json[l]
|
|
6
|
+
*
|
|
7
|
+
* Verified against gemini CLI v0.25.2 (apprenticeship Step 2):
|
|
8
|
+
* - The directory is `~/.gemini/tmp/<projectHash>/chats/`.
|
|
9
|
+
* - Each session file's basename is `session-<ISO-timestamp>-<short>.{json,jsonl}`
|
|
10
|
+
* where `<short>` is the FIRST 8 hex chars of the session UUID.
|
|
11
|
+
* - Each file's JSON body carries a `"sessionId"` field = the full UUID.
|
|
12
|
+
*
|
|
13
|
+
* So a session UUID `9b06d03d-f990-49c0-...` lives in a file named
|
|
14
|
+
* `session-2026-06-02T05-32-9b06d03d.json`. This module finds a session's
|
|
15
|
+
* file by UUID: it matches the filename's `<short8>` suffix against the
|
|
16
|
+
* UUID's first 8 chars (fast, no read) and confirms via the in-file
|
|
17
|
+
* `sessionId` only when the cheap filename match is ambiguous.
|
|
18
|
+
*
|
|
19
|
+
* This is the layout the framework-blind resolvers (ThreadResumeMap.jsonlExists,
|
|
20
|
+
* RateLimitSentinel/CompactionSentinel recovery-verification) route through for
|
|
21
|
+
* gemini sessions — exactly as those resolvers route codex sessions through
|
|
22
|
+
* openai-codex/observability/sessionPaths.ts. Without it, a gemini session has
|
|
23
|
+
* no claude jsonl and no codex rollout, so every framework-blind path falls
|
|
24
|
+
* through to a wrong/default file and silently breaks fleet-wide.
|
|
25
|
+
*
|
|
26
|
+
* RULE 3.1 RATIONALE
|
|
27
|
+
* Criticality: high (resume + recovery-verification correctness).
|
|
28
|
+
* Frequency: per-resume / per-recovery-check.
|
|
29
|
+
* Stability: semi-stable (Gemini may change the session layout).
|
|
30
|
+
* Fallback: none — a layout change yields empty results (caught by a
|
|
31
|
+
* geminiSessionLayoutCanary when that conditional ships, §6).
|
|
32
|
+
* Verdict: deterministic FS walk.
|
|
33
|
+
*/
|
|
34
|
+
import { readdirSync, statSync, readFileSync } from 'node:fs';
|
|
35
|
+
import { homedir } from 'node:os';
|
|
36
|
+
import path from 'node:path';
|
|
37
|
+
/** Resolve the Gemini home directory (`~/.gemini` unless overridden). */
|
|
38
|
+
export function geminiHomeFromConfig(geminiHome) {
|
|
39
|
+
return geminiHome ?? path.join(homedir(), '.gemini');
|
|
40
|
+
}
|
|
41
|
+
/** The per-project session root: `<geminiHome>/tmp`. */
|
|
42
|
+
function sessionsRoot(geminiHome) {
|
|
43
|
+
return path.join(geminiHomeFromConfig(geminiHome), 'tmp');
|
|
44
|
+
}
|
|
45
|
+
/** A gemini session file matches `session-...json` or `session-...jsonl`. */
|
|
46
|
+
function isSessionFile(name) {
|
|
47
|
+
return name.startsWith('session-') && (name.endsWith('.json') || name.endsWith('.jsonl'));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The 8-char short id Gemini embeds at the END of a session filename
|
|
51
|
+
* (before the extension): `session-<ISO>-<short8>.json[l]`.
|
|
52
|
+
*/
|
|
53
|
+
function shortIdFromFilename(name) {
|
|
54
|
+
const base = name.replace(/\.jsonl?$/, '');
|
|
55
|
+
const m = /-([0-9a-f]{8})$/i.exec(base);
|
|
56
|
+
return m ? m[1].toLowerCase() : null;
|
|
57
|
+
}
|
|
58
|
+
/** First 8 hex chars of a UUID (Gemini's filename short-id form). */
|
|
59
|
+
function shortIdFromUuid(uuid) {
|
|
60
|
+
return uuid.replace(/-/g, '').slice(0, 8).toLowerCase();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Confirm a candidate file actually carries the requested sessionId by
|
|
64
|
+
* reading its `"sessionId"` field. Both the `.json` (whole-object) and
|
|
65
|
+
* `.jsonl` (first line is a header object with `sessionId`) layouts put the
|
|
66
|
+
* id near the top, so a small head-read suffices. Returns true on match.
|
|
67
|
+
*/
|
|
68
|
+
function fileHasSessionId(full, uuid) {
|
|
69
|
+
try {
|
|
70
|
+
const head = readFileSync(full, 'utf-8').slice(0, 4096);
|
|
71
|
+
// Cheap substring check first (avoids JSON.parse on the common path).
|
|
72
|
+
if (head.includes(uuid))
|
|
73
|
+
return true;
|
|
74
|
+
// jsonl header line is a complete JSON object on line 1.
|
|
75
|
+
const firstLine = head.split('\n', 1)[0];
|
|
76
|
+
const parsed = JSON.parse(firstLine);
|
|
77
|
+
return parsed.sessionId === uuid;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Find a Gemini session file by session UUID. Returns the absolute path or
|
|
85
|
+
* null on miss. Synchronous — the resume-map `jsonlExists` guard runs on a
|
|
86
|
+
* sync code path and cannot await. A missing `~/.gemini/tmp` (e.g. a pure
|
|
87
|
+
* Claude/Codex agent) returns null fast.
|
|
88
|
+
*
|
|
89
|
+
* Strategy:
|
|
90
|
+
* 1. Walk `<geminiHome>/tmp/<projectHash>/chats/` for `session-*` files.
|
|
91
|
+
* 2. Match the filename's `<short8>` against the UUID's first 8 chars.
|
|
92
|
+
* 3. On a filename match, confirm via the in-file `sessionId` (cheap head
|
|
93
|
+
* read) so two sessions sharing an 8-char prefix can't collide.
|
|
94
|
+
* 4. Also accept a file whose body contains the full UUID even if the
|
|
95
|
+
* filename short-id was absent (defensive against a layout tweak).
|
|
96
|
+
*/
|
|
97
|
+
export function findGeminiSessionFileSync(uuid, geminiHome) {
|
|
98
|
+
if (!uuid)
|
|
99
|
+
return null;
|
|
100
|
+
const root = sessionsRoot(geminiHome);
|
|
101
|
+
const want = shortIdFromUuid(uuid);
|
|
102
|
+
let projectHashes;
|
|
103
|
+
try {
|
|
104
|
+
projectHashes = readdirSync(root);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
let bodyFallback = null;
|
|
110
|
+
for (const projectHash of projectHashes) {
|
|
111
|
+
const chatsDir = path.join(root, projectHash, 'chats');
|
|
112
|
+
let files;
|
|
113
|
+
try {
|
|
114
|
+
files = readdirSync(chatsDir);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
for (const file of files) {
|
|
120
|
+
if (!isSessionFile(file))
|
|
121
|
+
continue;
|
|
122
|
+
const full = path.join(chatsDir, file);
|
|
123
|
+
let stat;
|
|
124
|
+
try {
|
|
125
|
+
stat = statSync(full);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (!stat.isFile())
|
|
131
|
+
continue;
|
|
132
|
+
const short = shortIdFromFilename(file);
|
|
133
|
+
if (short === want) {
|
|
134
|
+
// Confirm via in-file sessionId to defeat an 8-char-prefix collision.
|
|
135
|
+
if (fileHasSessionId(full, uuid))
|
|
136
|
+
return full;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
// Defensive: a filename without a short-id but whose body holds the
|
|
140
|
+
// full UUID still resolves (kept as a fallback so the fast path wins).
|
|
141
|
+
if (short === null && bodyFallback === null && fileHasSessionId(full, uuid)) {
|
|
142
|
+
bodyFallback = full;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return bodyFallback;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Find the single newest Gemini session file (by mtime) SYNCHRONOUSLY →
|
|
150
|
+
* `{ path, size, mtime }` (or null when none / not a gemini tree).
|
|
151
|
+
*
|
|
152
|
+
* Used by the gemini branch of the RateLimitSentinel + CompactionSentinel
|
|
153
|
+
* recovery-verification: "did the throttle clear / did compaction recover?"
|
|
154
|
+
* == "is gemini producing output again?" == "did the newest session file
|
|
155
|
+
* grow?". The sentinels compare this against the captured baseline size.
|
|
156
|
+
*
|
|
157
|
+
* Mirrors the codex `findNewestRolloutSync` contract (the account-wide
|
|
158
|
+
* growth signal), adapted to gemini's `tmp/<hash>/chats/` layout. Walks all
|
|
159
|
+
* project-hash chat dirs and statSyncs `session-*` files, returning the
|
|
160
|
+
* newest by mtime. (Gemini's per-project session counts are far smaller than
|
|
161
|
+
* codex's tens-of-thousands of rollouts, so a full stat walk is acceptable
|
|
162
|
+
* for the rarely-run recovery check.)
|
|
163
|
+
*/
|
|
164
|
+
export function findNewestGeminiSessionSync(geminiHome) {
|
|
165
|
+
const root = sessionsRoot(geminiHome);
|
|
166
|
+
let projectHashes;
|
|
167
|
+
try {
|
|
168
|
+
projectHashes = readdirSync(root);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
let newest = null;
|
|
174
|
+
for (const projectHash of projectHashes) {
|
|
175
|
+
const chatsDir = path.join(root, projectHash, 'chats');
|
|
176
|
+
let files;
|
|
177
|
+
try {
|
|
178
|
+
files = readdirSync(chatsDir);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
for (const file of files) {
|
|
184
|
+
if (!isSessionFile(file))
|
|
185
|
+
continue;
|
|
186
|
+
const full = path.join(chatsDir, file);
|
|
187
|
+
try {
|
|
188
|
+
const st = statSync(full);
|
|
189
|
+
if (!st.isFile())
|
|
190
|
+
continue;
|
|
191
|
+
if (newest === null || st.mtimeMs > newest.mtime) {
|
|
192
|
+
newest = { path: full, size: st.size, mtime: st.mtimeMs };
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return newest;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=sessionPaths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionPaths.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/gemini-cli/observability/sessionPaths.ts"],"names":[],"mappings":"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"}
|