···77 DEFAULT_COMMAND_TIMEOUT_MS,
88 USE_DOCKER_SHELL,
99 normalizeTimeoutMs,
1010-} from "./config.js"
1111-import type { RunRawOptions } from "./types.js"
1010+} from "./config"
1111+import type { RunRawOptions } from "./types"
12121313/**
1414 * Strip ANSI/VT escape sequences and normalize line endings from PTY output.
···11import test from "node:test"
22import assert from "node:assert/strict"
33-import type { Message } from "./types.js"
44-import { __memoryTest } from "./memory.js"
33+import type { Message } from "./types"
44+import { __memoryTest } from "./memory/index"
5566test("latestMemoryRecallQuery falls back past scheduled heartbeat", () => {
77 const conversation: Message[] = [
···22import fs from "fs"
33import path from "path"
44import type OpenAI from "openai"
55-import { HOME_DIR } from "./container/config.js"
66-import { getDb } from "./db.js"
77-import type { Message } from "./types.js"
88-import type { MemorySearchResult } from "./memory.js"
55+import { HOME_DIR } from "./container/config"
66+import { getDb } from "./db"
77+import type { Message } from "./types"
88+import type { MemorySearchResult } from "./memory/index"
991010export interface BaseMetricEvent {
1111 timestamp: string
···172172 return new Date(Date.now() - days * 24 * 60 * 60_000).toISOString()
173173}
174174175175-export function pruneOldMetrics(days = metricsRetentionDays()): number {
175175+function pruneOldMetrics(days = metricsRetentionDays()): number {
176176 if (!db) return 0
177177178178 const cutoff = metricsRetentionCutoff(days)
···11import OpenAI from "openai"
22-import type { LoopState } from "./types.js"
33-import type { FunctionToolCall } from "./loop-shared.js"
22+import type { LoopState } from "./types"
33+import type { FunctionToolCall } from "./loop-shared"
4455/**
66 * Normalizes assistant/tool message content into plain text.
···11import assert from "node:assert/strict"
22import test from "node:test"
33-import { __loopTest } from "./loop.js"
44-import type { Message } from "../types.js"
55-import type { LoopState } from "./types.js"
66-import type { Message } from "../types.js"
33+import { __loopTest } from "./loop"
44+import type { Message } from "../types"
55+import type { LoopState } from "./types"
66+import type { Message } from "../types"
7788function makeState(): LoopState {
99 return {
···22import path from "path"
33import { fileURLToPath } from "url"
44import OpenAI from "openai"
55-import { imageRootForModelInput } from "../container/index.js"
66-import type { Message } from "../types.js"
77-import type { ImageDetail, ToolArgs } from "./types.js"
55+import { imageRootForModelInput } from "../container/index"
66+import type { Message } from "../types"
77+import type { ImageDetail } from "./types"
88+import type { ToolArgs } from "./loop-shared"
89910const PROJECT_ROOT = path.resolve(fileURLToPath(import.meta.url), "../../..")
1011const SESSION_FILE = path.join(PROJECT_ROOT, "session.json")
···11-import type { UserMessage } from "../types.js"
11+import type { UserMessage } from "../types"
2233export function fromBsky(body: unknown): UserMessage {
44 const b = body as Record<string, unknown>
···11-import type { UserMessage } from "../types.js"
11+import type { UserMessage } from "../types"
2233export function fromChat(body: unknown): UserMessage {
44 const b = body as Record<string, unknown>
···11-import type { UserMessage } from "../types.js"
11+import type { UserMessage } from "../types"
2233export function fromCron(): UserMessage {
44 return {
···11-import type { UserMessage } from "../types.js"
11+import type { UserMessage } from "../types"
2233export function fromWebhook(body: unknown): UserMessage {
44 const b = body as Record<string, unknown>