dsh-agy-link 0.4.32 → 0.4.33

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.33 (2026-09-18)
4
+
5
+ ### English
6
+
7
+ - **Fix: thinking / tool-args invisible for pool accounts.** agy conversation SQLite DBs for isolated accounts live under `~/.dsh/agy-accounts/<id>/.gemini/antigravity-cli/conversations`, not system `~/.gemini`. The reader now searches the run's account home, `GEMINI_CLI_HOME`, system home, and pool account dirs.
8
+ - **Fix: `/agy status` could hang the command UI.** Auth probe is now bounded (8s) so command results always return (issue #29 symptom).
9
+
10
+ ### 中文 (Chinese)
11
+
12
+ - **修复:号池隔离账号看不到思维链/工具参数** — 会话库在账号自己的 HOME 下,读取时会搜索账号目录。
13
+ - **修复:`/agy status` 可能挂起导致命令无输出** — 探测加 8s 超时。
14
+
3
15
  ## 0.4.32 (2026-09-17)
4
16
 
5
17
  ### English
package/dist/index.js CHANGED
@@ -400,6 +400,8 @@ var RunRecording = class {
400
400
  fullArgs = null;
401
401
  /** DB-resolved thoughts keyed by event index (set during span driving). */
402
402
  thoughts = null;
403
+ /** Isolated pool-account HOME used for this run's agy conversation DB. */
404
+ accountHome = void 0;
403
405
  /**
404
406
  * Set by the adapter right after spawn. A mid-turn user steer makes DSH
405
407
  * open a NEW stream() call for the same session while this run's process
@@ -2228,6 +2230,43 @@ async function probeProcess(bin, args, timeoutMs = 3e4, signal, env) {
2228
2230
  //#region src/host/agy-db.ts
2229
2231
  const execFileAsync = promisify(execFile);
2230
2232
  let AGY_DB_DIR = join(homedir(), ".gemini", "antigravity-cli", "conversations");
2233
+ /**
2234
+ * Candidate conversations directories for a conversation id.
2235
+ * Pool/isolated accounts write agy state under their own HOME
2236
+ * (~/.dsh/agy-accounts/<id>/.gemini/...), NOT the system ~/.gemini
2237
+ * (issue: thinking/tool-args invisible when using isolated accounts).
2238
+ */
2239
+ function conversationsDirCandidates(accountHome) {
2240
+ const dirs = [];
2241
+ const push = (d) => {
2242
+ if (!dirs.includes(d)) dirs.push(d);
2243
+ };
2244
+ if (accountHome !== void 0 && accountHome !== "") push(join(accountHome, ".gemini", "antigravity-cli", "conversations"));
2245
+ const gch = process.env.GEMINI_CLI_HOME;
2246
+ if (gch !== void 0 && gch !== "") push(join(gch, "antigravity-cli", "conversations"));
2247
+ push(AGY_DB_DIR);
2248
+ push(join(homedir(), ".gemini", "antigravity-cli", "conversations"));
2249
+ const poolBase = join(homedir(), ".dsh", "agy-accounts");
2250
+ try {
2251
+ for (const ent of readdirSync(poolBase)) {
2252
+ if (ent.startsWith(".")) continue;
2253
+ push(join(poolBase, ent, ".gemini", "antigravity-cli", "conversations"));
2254
+ }
2255
+ } catch {}
2256
+ return dirs;
2257
+ }
2258
+ /** Locate an existing conversation DB across system + pool homes. */
2259
+ function findConversationDb(conversationId, accountHome) {
2260
+ if (!isSafeConversationId(conversationId)) return null;
2261
+ const name = `${conversationId}.db`;
2262
+ for (const dir of conversationsDirCandidates(accountHome)) {
2263
+ const p = join(dir, name);
2264
+ try {
2265
+ if (existsSync(p)) return p;
2266
+ } catch {}
2267
+ }
2268
+ return null;
2269
+ }
2231
2270
  const TOOL_STEP_TYPES = /* @__PURE__ */ new Set([
2232
2271
  5,
2233
2272
  7,
@@ -2333,7 +2372,7 @@ function extractStepThoughts(payload) {
2333
2372
  * Copy the agy SQLite DB to a temp path (avoiding WAL lock issues), then
2334
2373
  * query tool and thought step payloads via sqlite3 CLI.
2335
2374
  */
2336
- async function loadAgyDbData(conversationId) {
2375
+ async function loadAgyDbData(conversationId, accountHome) {
2337
2376
  const steps = /* @__PURE__ */ new Map();
2338
2377
  const thoughts = /* @__PURE__ */ new Map();
2339
2378
  const seenSteps = /* @__PURE__ */ new Set();
@@ -2342,20 +2381,12 @@ async function loadAgyDbData(conversationId) {
2342
2381
  thoughts,
2343
2382
  seenSteps
2344
2383
  };
2345
- const dbPath = join(AGY_DB_DIR, `${conversationId}.db`);
2346
- try {
2347
- if ((await stat(dbPath)).size === 0) return {
2348
- steps,
2349
- thoughts,
2350
- seenSteps
2351
- };
2352
- } catch {
2353
- return {
2354
- steps,
2355
- thoughts,
2356
- seenSteps
2357
- };
2358
- }
2384
+ const dbPath = findConversationDb(conversationId, accountHome);
2385
+ if (dbPath === null) return {
2386
+ steps,
2387
+ thoughts,
2388
+ seenSteps
2389
+ };
2359
2390
  const tmpDb = join(tmpdir(), `agy-db-${conversationId.slice(0, 8)}-${Date.now()}.db`);
2360
2391
  try {
2361
2392
  await copyFile(dbPath, tmpDb);
@@ -2531,7 +2562,7 @@ function scanFallbackJson(payload) {
2531
2562
  * Results are cached per conversationId for up to 5 minutes to avoid
2532
2563
  * repeated DB reads within the same session.
2533
2564
  */
2534
- async function readFullToolArgs(conversationId, stepIndex) {
2565
+ async function readFullToolArgs(conversationId, stepIndex, accountHome) {
2535
2566
  if (!isSafeConversationId(conversationId)) return null;
2536
2567
  const now = Date.now();
2537
2568
  if (cache?.conversationId === conversationId && cache.loaded && now - cacheTime < MAX_CACHE_AGE_MS) {
@@ -2539,7 +2570,7 @@ async function readFullToolArgs(conversationId, stepIndex) {
2539
2570
  if (cached !== void 0) return cached;
2540
2571
  if (cache.checkedSteps.has(stepIndex)) return null;
2541
2572
  }
2542
- const data = await loadAgyDbData(conversationId);
2573
+ const data = await loadAgyDbData(conversationId, accountHome);
2543
2574
  cache = {
2544
2575
  conversationId,
2545
2576
  steps: data.steps,
@@ -2555,7 +2586,7 @@ async function readFullToolArgs(conversationId, stepIndex) {
2555
2586
  * conversation database. Returns null when the DB is unavailable or the
2556
2587
  * step does not contain thought text.
2557
2588
  */
2558
- async function readStepThoughts(conversationId, stepIndex) {
2589
+ async function readStepThoughts(conversationId, stepIndex, accountHome) {
2559
2590
  if (!isSafeConversationId(conversationId)) return null;
2560
2591
  const now = Date.now();
2561
2592
  if (cache?.conversationId === conversationId && cache.loaded && now - cacheTime < MAX_CACHE_AGE_MS) {
@@ -2563,7 +2594,7 @@ async function readStepThoughts(conversationId, stepIndex) {
2563
2594
  if (cached !== void 0) return cached;
2564
2595
  if (cache.checkedSteps.has(stepIndex)) return null;
2565
2596
  }
2566
- const data = await loadAgyDbData(conversationId);
2597
+ const data = await loadAgyDbData(conversationId, accountHome);
2567
2598
  cache = {
2568
2599
  conversationId,
2569
2600
  steps: data.steps,
@@ -2964,6 +2995,7 @@ var AgyAdapter = class extends LlmAdapter {
2964
2995
  }
2965
2996
  const before = snapshotConversations();
2966
2997
  const rec = this.deps.runs.create();
2998
+ rec.accountHome = account && account.dir ? account.dir : void 0;
2967
2999
  const parser = new StreamJsonParser();
2968
3000
  this.deps.onParser?.(parser);
2969
3001
  let streamCid = null;
@@ -3179,10 +3211,10 @@ var AgyAdapter = class extends LlmAdapter {
3179
3211
  const activeConvId = rec.conversationId ?? (typeof rawObj?.conversation_id === "string" ? rawObj.conversation_id : null) ?? (typeof stepUpdate?.conversation_id === "string" ? stepUpdate.conversation_id : null);
3180
3212
  const stepIdx = parseInt(ev.stepKey, 10);
3181
3213
  if (activeConvId !== null && Number.isFinite(stepIdx)) try {
3182
- let th = await readStepThoughts(activeConvId, stepIdx);
3214
+ let th = await readStepThoughts(activeConvId, stepIdx, rec.accountHome);
3183
3215
  if (th === null && (ev.state === "DONE" || (ev.usage?.thinking_tokens ?? 0) > 0 || ev.stepKind === "thinking")) {
3184
3216
  await new Promise((r) => setTimeout(r, 50));
3185
- th = await readStepThoughts(activeConvId, stepIdx);
3217
+ th = await readStepThoughts(activeConvId, stepIdx, rec.accountHome);
3186
3218
  }
3187
3219
  if (th !== null && th.trim() !== "") {
3188
3220
  resolvedThoughts.set(i, th);
@@ -3196,10 +3228,10 @@ var AgyAdapter = class extends LlmAdapter {
3196
3228
  const activeConvId = rec.conversationId ?? (typeof rawObj?.conversation_id === "string" ? rawObj.conversation_id : null) ?? (typeof stepUpdate?.conversation_id === "string" ? stepUpdate.conversation_id : null);
3197
3229
  const stepIdx = parseInt(ev.stepKey, 10);
3198
3230
  if (activeConvId !== null && Number.isFinite(stepIdx)) try {
3199
- let full = await readFullToolArgs(activeConvId, stepIdx);
3231
+ let full = await readFullToolArgs(activeConvId, stepIdx, rec.accountHome);
3200
3232
  if (full === null) {
3201
3233
  await new Promise((r) => setTimeout(r, 50));
3202
- full = await readFullToolArgs(activeConvId, stepIdx);
3234
+ full = await readFullToolArgs(activeConvId, stepIdx, rec.accountHome);
3203
3235
  }
3204
3236
  if (full !== null && full.args !== void 0) {
3205
3237
  resolved.set(i, full.args);
@@ -27685,7 +27717,7 @@ async function renderStatus(deps) {
27685
27717
  const cfg = deps.cfg();
27686
27718
  const bin = deps.bin();
27687
27719
  const authHelper = deps.auth();
27688
- const auth = authHelper ? await authHelper.resolvedStatus() : void 0;
27720
+ const auth = authHelper ? await Promise.race([authHelper.resolvedStatus(), new Promise((r) => setTimeout(() => r(void 0), 8e3))]) : void 0;
27689
27721
  const cat = deps.catalog().get();
27690
27722
  const bindings = Object.keys(deps.store().all()).length;
27691
27723
  const last = deps.lastRun();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-agy-link",
3
- "version": "0.4.32",
3
+ "version": "0.4.33",
4
4
  "description": "Google Antigravity (agy CLI) models for DeepSeek Harness — stream Gemini/Claude/GPT-OSS subscriptions into DSH with thinking, tool activity, token usage and in-GUI Google OAuth login.",
5
5
  "type": "module",
6
6
  "license": "MIT",