fix: CLI tools use Store class for v2 format compatibility (#235)

shared.ts was parsing lettabot-agent.json as v1 format directly,
returning null for v2 stores. Now uses the Store class which
handles v1/v2 transparently.

Affects lettabot-message, lettabot-react, and lettabot-history.

Written by Cameron ◯ Letta Code

"Simplicity is the ultimate sophistication." -- Leonardo da Vinci
This commit is contained in:
Cameron
2026-02-09 10:32:51 -08:00
committed by GitHub
parent 16b5e5b7b7
commit b8a248b0fb
5 changed files with 14 additions and 44 deletions

View File

@@ -1,9 +1,5 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
import { fetchDiscordHistory, fetchHistory, fetchSlackHistory, isValidLimit, parseFetchArgs } from './history-core.js';
import { loadLastTarget } from './shared.js';
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
const ORIGINAL_ENV = { ...process.env };
@@ -45,22 +41,8 @@ describe('isValidLimit', () => {
});
});
describe('loadLastTarget', () => {
it('loads the last message target from the store path', () => {
const dir = mkdtempSync(join(tmpdir(), 'lettabot-history-'));
const storePath = join(dir, 'lettabot-agent.json');
writeFileSync(
storePath,
JSON.stringify({ lastMessageTarget: { channel: 'slack', chatId: 'C123' } }),
'utf-8'
);
const target = loadLastTarget(storePath);
expect(target).toEqual({ channel: 'slack', chatId: 'C123' });
rmSync(dir, { recursive: true, force: true });
});
});
// loadLastTarget is now backed by the Store class (handles v1/v2 transparently).
// Store-level tests in src/core/store.test.ts cover lastMessageTarget persistence.
describe('fetchDiscordHistory', () => {
it('formats Discord history responses', async () => {

View File

@@ -11,7 +11,7 @@ import { loadConfig, applyConfigToEnv } from '../config/index.js';
const config = loadConfig();
applyConfigToEnv(config);
import { fetchHistory, isValidLimit, parseFetchArgs } from './history-core.js';
import { loadLastTarget, STORE_PATH } from './shared.js';
import { loadLastTarget } from './shared.js';
async function fetchCommand(args: string[]): Promise<void> {
const parsed = parseFetchArgs(args);
@@ -27,7 +27,7 @@ async function fetchCommand(args: string[]): Promise<void> {
}
if (!channel || !chatId) {
const lastTarget = loadLastTarget(STORE_PATH);
const lastTarget = loadLastTarget();
if (lastTarget) {
channel = channel || lastTarget.channel;
chatId = chatId || lastTarget.chatId;

View File

@@ -15,7 +15,7 @@ import { loadConfig, applyConfigToEnv } from '../config/index.js';
const config = loadConfig();
applyConfigToEnv(config);
import { existsSync, readFileSync } from 'node:fs';
import { loadLastTarget, STORE_PATH } from './shared.js';
import { loadLastTarget } from './shared.js';
// Channel senders
async function sendTelegram(chatId: string, text: string): Promise<void> {

View File

@@ -13,7 +13,7 @@
import { loadConfig, applyConfigToEnv } from '../config/index.js';
const config = loadConfig();
applyConfigToEnv(config);
import { loadLastTarget, STORE_PATH } from './shared.js';
import { loadLastTarget } from './shared.js';
const EMOJI_ALIAS_TO_UNICODE: Record<string, string> = {
eyes: '👀',

View File

@@ -1,6 +1,4 @@
import { existsSync, readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { getDataDir } from '../utils/paths.js';
import { Store } from '../core/store.js';
export interface LastTarget {
channel: string;
@@ -8,21 +6,11 @@ export interface LastTarget {
messageId?: string;
}
interface AgentStore {
agentId?: string;
lastMessageTarget?: LastTarget;
}
export const STORE_PATH = resolve(getDataDir(), 'lettabot-agent.json');
export function loadLastTarget(storePath: string = STORE_PATH): LastTarget | null {
try {
if (existsSync(storePath)) {
const store: AgentStore = JSON.parse(readFileSync(storePath, 'utf-8'));
/**
* Load the last message target from the agent store.
* Uses Store class which handles both v1 and v2 formats transparently.
*/
export function loadLastTarget(): LastTarget | null {
const store = new Store('lettabot-agent.json');
return store.lastMessageTarget || null;
}
} catch {
// Ignore
}
return null;
}