SYMBOL INDEX (305 symbols across 50 files) FILE: .claude/skills/x-integration/agent.ts constant IPC_DIR (line 18) | const IPC_DIR = '/workspace/ipc'; constant TASKS_DIR (line 19) | const TASKS_DIR = path.join(IPC_DIR, 'tasks'); constant RESULTS_DIR (line 20) | const RESULTS_DIR = path.join(IPC_DIR, 'x_results'); function writeIpcFile (line 22) | function writeIpcFile(dir: string, data: object): string { function waitForResult (line 32) | async function waitForResult(requestId: string, maxWait = 60000): Promis... type SkillToolsContext (line 54) | interface SkillToolsContext { function createXTools (line 62) | function createXTools(ctx: SkillToolsContext) { FILE: .claude/skills/x-integration/host.ts type SkillResult (line 18) | interface SkillResult { function runScript (line 25) | async function runScript(script: string, args: object): Promise(): Promise { function writeResult (line 41) | function writeResult(result: ScriptResult): void { function cleanupLockFiles (line 48) | function cleanupLockFiles(): void { function validateContent (line 60) | function validateContent(content: string | undefined, type = 'Tweet'): S... function getBrowserContext (line 73) | async function getBrowserContext(): Promise { function extractTweetId (line 94) | function extractTweetId(input: string): string | null { function navigateToTweet (line 104) | async function navigateToTweet( function runScript (line 134) | async function runScript( FILE: .claude/skills/x-integration/lib/config.ts constant PROJECT_ROOT (line 11) | const PROJECT_ROOT = process.env.NANOCLAW_ROOT || process.cwd(); FILE: .claude/skills/x-integration/scripts/like.ts type LikeInput (line 9) | interface LikeInput { function likeTweet (line 13) | async function likeTweet(input: LikeInput): Promise { FILE: .claude/skills/x-integration/scripts/post.ts type PostInput (line 9) | interface PostInput { function postTweet (line 13) | async function postTweet(input: PostInput): Promise { FILE: .claude/skills/x-integration/scripts/quote.ts type QuoteInput (line 9) | interface QuoteInput { function quoteTweet (line 14) | async function quoteTweet(input: QuoteInput): Promise { FILE: .claude/skills/x-integration/scripts/reply.ts type ReplyInput (line 9) | interface ReplyInput { function replyToTweet (line 14) | async function replyToTweet(input: ReplyInput): Promise { FILE: .claude/skills/x-integration/scripts/retweet.ts type RetweetInput (line 9) | interface RetweetInput { function retweet (line 13) | async function retweet(input: RetweetInput): Promise { FILE: .claude/skills/x-integration/scripts/setup.ts function setup (line 15) | async function setup(): Promise { FILE: container/agent-runner/src/index.ts type ContainerInput (line 22) | interface ContainerInput { type ContainerOutput (line 32) | interface ContainerOutput { type SessionEntry (line 39) | interface SessionEntry { type SessionsIndex (line 46) | interface SessionsIndex { type SDKUserMessage (line 50) | interface SDKUserMessage { constant IPC_INPUT_DIR (line 57) | const IPC_INPUT_DIR = '/workspace/ipc/input'; constant IPC_INPUT_CLOSE_SENTINEL (line 58) | const IPC_INPUT_CLOSE_SENTINEL = path.join(IPC_INPUT_DIR, '_close'); constant IPC_POLL_MS (line 59) | const IPC_POLL_MS = 500; class MessageStream (line 65) | class MessageStream { method push (line 70) | push(text: string): void { method end (line 80) | end(): void { method [Symbol.asyncIterator] (line 85) | async *[Symbol.asyncIterator](): AsyncGenerator { function readStdin (line 97) | async function readStdin(): Promise { constant OUTPUT_START_MARKER (line 107) | const OUTPUT_START_MARKER = '---NANOCLAW_OUTPUT_START---'; constant OUTPUT_END_MARKER (line 108) | const OUTPUT_END_MARKER = '---NANOCLAW_OUTPUT_END---'; function writeOutput (line 110) | function writeOutput(output: ContainerOutput): void { function log (line 116) | function log(message: string): void { function getSessionSummary (line 120) | function getSessionSummary(sessionId: string, transcriptPath: string): s... function createPreCompactHook (line 145) | function createPreCompactHook(assistantName?: string): HookCallback { function sanitizeFilename (line 187) | function sanitizeFilename(summary: string): string { function generateFallbackName (line 195) | function generateFallbackName(): string { type ParsedMessage (line 200) | interface ParsedMessage { function parseTranscript (line 205) | function parseTranscript(content: string): ParsedMessage[] { function formatTranscriptMarkdown (line 231) | function formatTranscriptMarkdown(messages: ParsedMessage[], title?: str... function shouldClose (line 264) | function shouldClose(): boolean { function drainIpcInput (line 276) | function drainIpcInput(): string[] { function waitForIpcMessage (line 308) | function waitForIpcMessage(): Promise { function runQuery (line 332) | async function runQuery( function main (line 467) | async function main(): Promise { FILE: container/agent-runner/src/ipc-mcp-stdio.ts constant IPC_DIR (line 14) | const IPC_DIR = '/workspace/ipc'; constant MESSAGES_DIR (line 15) | const MESSAGES_DIR = path.join(IPC_DIR, 'messages'); constant TASKS_DIR (line 16) | const TASKS_DIR = path.join(IPC_DIR, 'tasks'); function writeIpcFile (line 23) | function writeIpcFile(dir: string, data: object): string { FILE: scripts/run-migrations.ts function compareSemver (line 6) | function compareSemver(a: string, b: string): number { function resolveTsx (line 17) | function resolveTsx(): string { type MigrationResult (line 42) | interface MigrationResult { FILE: setup/container.ts function parseArgs (line 12) | function parseArgs(args: string[]): { runtime: string } { function run (line 23) | async function run(args: string[]): Promise { FILE: setup/environment.ts function run (line 15) | async function run(_args: string[]): Promise { FILE: setup/groups.ts function parseArgs (line 17) | function parseArgs(args: string[]): { list: boolean; limit: number } { function run (line 30) | async function run(args: string[]): Promise { function listGroups (line 42) | async function listGroups(limit: number): Promise { function syncGroups (line 66) | async function syncGroups(projectRoot: string): Promise { FILE: setup/index.ts constant STEPS (line 8) | const STEPS: Record< function main (line 21) | async function main(): Promise { FILE: setup/mounts.ts function parseArgs (line 13) | function parseArgs(args: string[]): { empty: boolean; json: string } { function run (line 26) | async function run(args: string[]): Promise { FILE: setup/platform.ts type Platform (line 8) | type Platform = 'macos' | 'linux' | 'unknown'; type ServiceManager (line 9) | type ServiceManager = 'launchd' | 'systemd' | 'none'; function getPlatform (line 11) | function getPlatform(): Platform { function isWSL (line 18) | function isWSL(): boolean { function isRoot (line 28) | function isRoot(): boolean { function isHeadless (line 32) | function isHeadless(): boolean { function hasSystemd (line 41) | function hasSystemd(): boolean { function openBrowser (line 56) | function openBrowser(url: string): boolean { function getServiceManager (line 91) | function getServiceManager(): ServiceManager { function getNodePath (line 101) | function getNodePath(): string { function commandExists (line 109) | function commandExists(name: string): boolean { function getNodeVersion (line 118) | function getNodeVersion(): string | null { function getNodeMajorVersion (line 127) | function getNodeMajorVersion(): number | null { FILE: setup/register.test.ts function createTestDb (line 12) | function createTestDb(): Database.Database { FILE: setup/register.ts type RegisterArgs (line 16) | interface RegisterArgs { function parseArgs (line 27) | function parseArgs(args: string[]): RegisterArgs { function run (line 71) | async function run(args: string[]): Promise { FILE: setup/service.test.ts function generatePlist (line 12) | function generatePlist( function generateSystemdUnit (line 49) | function generateSystemdUnit( FILE: setup/service.ts function run (line 23) | async function run(_args: string[]): Promise { function setupLaunchd (line 71) | function setupLaunchd( function setupLinux (line 147) | function setupLinux( function killOrphanedProcesses (line 166) | function killOrphanedProcesses(projectRoot: string): void { function checkDockerGroupStale (line 186) | function checkDockerGroupStale(): boolean { function setupSystemd (line 204) | function setupSystemd( function setupNohupFallback (line 309) | function setupNohupFallback( FILE: setup/status.ts function emitStatus (line 6) | function emitStatus( FILE: setup/verify.ts function run (line 25) | async function run(_args: string[]): Promise { FILE: src/channels/registry.ts type ChannelOpts (line 8) | interface ChannelOpts { type ChannelFactory (line 14) | type ChannelFactory = (opts: ChannelOpts) => Channel | null; function registerChannel (line 18) | function registerChannel(name: string, factory: ChannelFactory): void { function getChannelFactory (line 22) | function getChannelFactory(name: string): ChannelFactory | undefined { function getRegisteredChannelNames (line 26) | function getRegisteredChannelNames(): string[] { FILE: src/config.ts constant ASSISTANT_NAME (line 11) | const ASSISTANT_NAME = constant ASSISTANT_HAS_OWN_NUMBER (line 13) | const ASSISTANT_HAS_OWN_NUMBER = constant POLL_INTERVAL (line 16) | const POLL_INTERVAL = 2000; constant SCHEDULER_POLL_INTERVAL (line 17) | const SCHEDULER_POLL_INTERVAL = 60000; constant PROJECT_ROOT (line 20) | const PROJECT_ROOT = process.cwd(); constant HOME_DIR (line 21) | const HOME_DIR = process.env.HOME || os.homedir(); constant MOUNT_ALLOWLIST_PATH (line 24) | const MOUNT_ALLOWLIST_PATH = path.join( constant SENDER_ALLOWLIST_PATH (line 30) | const SENDER_ALLOWLIST_PATH = path.join( constant STORE_DIR (line 36) | const STORE_DIR = path.resolve(PROJECT_ROOT, 'store'); constant GROUPS_DIR (line 37) | const GROUPS_DIR = path.resolve(PROJECT_ROOT, 'groups'); constant DATA_DIR (line 38) | const DATA_DIR = path.resolve(PROJECT_ROOT, 'data'); constant CONTAINER_IMAGE (line 40) | const CONTAINER_IMAGE = constant CONTAINER_TIMEOUT (line 42) | const CONTAINER_TIMEOUT = parseInt( constant CONTAINER_MAX_OUTPUT_SIZE (line 46) | const CONTAINER_MAX_OUTPUT_SIZE = parseInt( constant CREDENTIAL_PROXY_PORT (line 50) | const CREDENTIAL_PROXY_PORT = parseInt( constant IPC_POLL_INTERVAL (line 54) | const IPC_POLL_INTERVAL = 1000; constant IDLE_TIMEOUT (line 55) | const IDLE_TIMEOUT = parseInt(process.env.IDLE_TIMEOUT || '1800000', 10); constant MAX_CONCURRENT_CONTAINERS (line 56) | const MAX_CONCURRENT_CONTAINERS = Math.max( function escapeRegex (line 61) | function escapeRegex(str: string): string { constant TRIGGER_PATTERN (line 65) | const TRIGGER_PATTERN = new RegExp( constant TIMEZONE (line 72) | const TIMEZONE = FILE: src/container-runner.test.ts constant OUTPUT_START_MARKER (line 6) | const OUTPUT_START_MARKER = '---NANOCLAW_OUTPUT_START---'; constant OUTPUT_END_MARKER (line 7) | const OUTPUT_END_MARKER = '---NANOCLAW_OUTPUT_END---'; function createFakeProcess (line 55) | function createFakeProcess() { function emitOutputMarker (line 106) | function emitOutputMarker( FILE: src/container-runner.ts constant OUTPUT_START_MARKER (line 33) | const OUTPUT_START_MARKER = '---NANOCLAW_OUTPUT_START---'; constant OUTPUT_END_MARKER (line 34) | const OUTPUT_END_MARKER = '---NANOCLAW_OUTPUT_END---'; type ContainerInput (line 36) | interface ContainerInput { type ContainerOutput (line 46) | interface ContainerOutput { type VolumeMount (line 53) | interface VolumeMount { function buildVolumeMounts (line 59) | function buildVolumeMounts( function buildContainerArgs (line 215) | function buildContainerArgs( function runContainerAgent (line 267) | async function runContainerAgent( function writeTasksSnapshot (line 659) | function writeTasksSnapshot( type AvailableGroup (line 685) | interface AvailableGroup { function writeGroupsSnapshot (line 697) | function writeGroupsSnapshot( FILE: src/container-runtime.ts constant CONTAINER_RUNTIME_BIN (line 12) | const CONTAINER_RUNTIME_BIN = 'docker'; constant CONTAINER_HOST_GATEWAY (line 15) | const CONTAINER_HOST_GATEWAY = 'host.docker.internal'; constant PROXY_BIND_HOST (line 23) | const PROXY_BIND_HOST = function detectProxyBindHost (line 26) | function detectProxyBindHost(): string { function hostGatewayArgs (line 44) | function hostGatewayArgs(): string[] { function readonlyMountArgs (line 53) | function readonlyMountArgs( function stopContainer (line 61) | function stopContainer(name: string): string { function ensureContainerRuntimeRunning (line 66) | function ensureContainerRuntimeRunning(): void { function cleanupOrphans (line 104) | function cleanupOrphans(): void { FILE: src/credential-proxy.test.ts function makeRequest (line 16) | function makeRequest( function startProxy (line 73) | async function startProxy(env: Record): Promise { FILE: src/credential-proxy.ts type AuthMode (line 20) | type AuthMode = 'api-key' | 'oauth'; type ProxyConfig (line 22) | interface ProxyConfig { function startCredentialProxy (line 26) | function startCredentialProxy( function detectAuthMode (line 122) | function detectAuthMode(): AuthMode { FILE: src/db.test.ts function store (line 23) | function store(overrides: { FILE: src/db.ts function createSchema (line 17) | function createSchema(database: Database.Database): void { function initDatabase (line 144) | function initDatabase(): void { function _initTestDatabase (line 156) | function _initTestDatabase(): void { function storeChatMetadata (line 165) | function storeChatMetadata( function updateChatName (line 206) | function updateChatName(chatJid: string, name: string): void { type ChatInfo (line 215) | interface ChatInfo { function getAllChats (line 226) | function getAllChats(): ChatInfo[] { function getLastGroupSync (line 241) | function getLastGroupSync(): string | null { function setLastGroupSync (line 252) | function setLastGroupSync(): void { function storeMessage (line 263) | function storeMessage(msg: NewMessage): void { function storeMessageDirect (line 281) | function storeMessageDirect(msg: { function getNewMessages (line 305) | function getNewMessages( function getMessagesSince (line 341) | function getMessagesSince( function createTask (line 366) | function createTask( function getTaskById (line 388) | function getTaskById(id: string): ScheduledTask | undefined { function getTasksForGroup (line 394) | function getTasksForGroup(groupFolder: string): ScheduledTask[] { function getAllTasks (line 402) | function getAllTasks(): ScheduledTask[] { function updateTask (line 408) | function updateTask( function deleteTask (line 449) | function deleteTask(id: string): void { function getDueTasks (line 455) | function getDueTasks(): ScheduledTask[] { function updateTaskAfterRun (line 468) | function updateTaskAfterRun( function logTaskRun (line 483) | function logTaskRun(log: TaskRunLog): void { function getRouterState (line 501) | function getRouterState(key: string): string | undefined { function setRouterState (line 508) | function setRouterState(key: string, value: string): void { function getSession (line 516) | function getSession(groupFolder: string): string | undefined { function setSession (line 523) | function setSession(groupFolder: string, sessionId: string): void { function getAllSessions (line 529) | function getAllSessions(): Record { function getRegisteredGroup (line 542) | function getRegisteredGroup( function setRegisteredGroup (line 582) | function setRegisteredGroup(jid: string, group: RegisteredGroup): void { function getAllRegisteredGroups (line 601) | function getAllRegisteredGroups(): Record { function migrateJsonState (line 639) | function migrateJsonState(): void { FILE: src/env.ts function readEnvFile (line 11) | function readEnvFile(keys: string[]): Record { FILE: src/formatting.test.ts function makeMsg (line 12) | function makeMsg(overrides: Partial = {}): NewMessage { function shouldRequireTrigger (line 211) | function shouldRequireTrigger( function shouldProcess (line 218) | function shouldProcess( FILE: src/group-folder.ts constant GROUP_FOLDER_PATTERN (line 5) | const GROUP_FOLDER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/; constant RESERVED_FOLDERS (line 6) | const RESERVED_FOLDERS = new Set(['global']); function isValidGroupFolder (line 8) | function isValidGroupFolder(folder: string): boolean { function assertValidGroupFolder (line 18) | function assertValidGroupFolder(folder: string): void { function ensureWithinBase (line 24) | function ensureWithinBase(baseDir: string, resolvedPath: string): void { function resolveGroupFolderPath (line 31) | function resolveGroupFolderPath(folder: string): string { function resolveGroupIpcPath (line 38) | function resolveGroupIpcPath(folder: string): string { FILE: src/group-queue.ts type QueuedTask (line 8) | interface QueuedTask { constant MAX_RETRIES (line 14) | const MAX_RETRIES = 5; constant BASE_RETRY_MS (line 15) | const BASE_RETRY_MS = 5000; type GroupState (line 17) | interface GroupState { class GroupQueue (line 30) | class GroupQueue { method getGroup (line 38) | private getGroup(groupJid: string): GroupState { method setProcessMessagesFn (line 58) | setProcessMessagesFn(fn: (groupJid: string) => Promise): void { method enqueueMessageCheck (line 62) | enqueueMessageCheck(groupJid: string): void { method enqueueTask (line 90) | enqueueTask(groupJid: string, taskId: string, fn: () => Promise)... method registerProcess (line 132) | registerProcess( method notifyIdle (line 148) | notifyIdle(groupJid: string): void { method sendMessage (line 160) | sendMessage(groupJid: string, text: string): boolean { method closeStdin (line 183) | closeStdin(groupJid: string): void { method runForGroup (line 196) | private async runForGroup( method runTask (line 234) | private async runTask(groupJid: string, task: QueuedTask): Promise { FILE: src/index.ts function loadState (line 76) | function loadState(): void { function saveState (line 93) | function saveState(): void { function registerGroup (line 98) | function registerGroup(jid: string, group: RegisteredGroup): void { function getAvailableGroups (line 126) | function getAvailableGroups(): import('./container-runner.js').Available... function _setRegisteredGroups (line 141) | function _setRegisteredGroups( function processGroupMessages (line 151) | async function processGroupMessages(chatJid: string): Promise { function runAgent (line 268) | async function runAgent( function startMessageLoop (line 349) | async function startMessageLoop(): Promise { function recoverPendingMessages (line 454) | function recoverPendingMessages(): void { function ensureContainerSystemRunning (line 468) | function ensureContainerSystemRunning(): void { function main (line 473) | async function main(): Promise { FILE: src/ipc-auth.test.ts constant MAIN_GROUP (line 15) | const MAIN_GROUP: RegisteredGroup = { constant OTHER_GROUP (line 23) | const OTHER_GROUP: RegisteredGroup = { constant THIRD_GROUP (line 30) | const THIRD_GROUP: RegisteredGroup = { function isMessageAuthorized (line 391) | function isMessageAuthorized( FILE: src/ipc.ts type IpcDeps (line 13) | interface IpcDeps { function startIpcWatcher (line 30) | function startIpcWatcher(deps: IpcDeps): void { function processTaskIpc (line 157) | async function processTaskIpc( FILE: src/mount-security.ts constant DEFAULT_BLOCKED_PATTERNS (line 29) | const DEFAULT_BLOCKED_PATTERNS = [ function loadMountAllowlist (line 54) | function loadMountAllowlist(): MountAllowlist | null { function expandPath (line 124) | function expandPath(p: string): string { function getRealPath (line 139) | function getRealPath(p: string): string | null { function matchesBlockedPattern (line 150) | function matchesBlockedPattern( function findAllowedRoot (line 176) | function findAllowedRoot( function isValidContainerPath (line 202) | function isValidContainerPath(containerPath: string): boolean { type MountValidationResult (line 221) | interface MountValidationResult { function validateMount (line 233) | function validateMount( function validateAdditionalMounts (line 336) | function validateAdditionalMounts( function generateAllowlistTemplate (line 390) | function generateAllowlistTemplate(): string { FILE: src/remote-control.test.ts function createMockProcess (line 26) | function createMockProcess(pid = 12345) { FILE: src/remote-control.ts type RemoteControlSession (line 8) | interface RemoteControlSession { constant URL_REGEX (line 18) | const URL_REGEX = /https:\/\/claude\.ai\/code\S+/; constant URL_TIMEOUT_MS (line 19) | const URL_TIMEOUT_MS = 30_000; constant URL_POLL_MS (line 20) | const URL_POLL_MS = 200; constant STATE_FILE (line 21) | const STATE_FILE = path.join(DATA_DIR, 'remote-control.json'); constant STDOUT_FILE (line 22) | const STDOUT_FILE = path.join(DATA_DIR, 'remote-control.stdout'); constant STDERR_FILE (line 23) | const STDERR_FILE = path.join(DATA_DIR, 'remote-control.stderr'); function saveState (line 25) | function saveState(session: RemoteControlSession): void { function clearState (line 30) | function clearState(): void { function isProcessAlive (line 38) | function isProcessAlive(pid: number): boolean { function restoreRemoteControl (line 51) | function restoreRemoteControl(): void { function getActiveSession (line 75) | function getActiveSession(): RemoteControlSession | null { function _resetForTesting (line 80) | function _resetForTesting(): void { function _getStateFilePath (line 85) | function _getStateFilePath(): string { function startRemoteControl (line 89) | async function startRemoteControl( function stopRemoteControl (line 205) | function stopRemoteControl(): FILE: src/router.ts function escapeXml (line 4) | function escapeXml(s: string): string { function formatMessages (line 13) | function formatMessages( function stripInternalTags (line 27) | function stripInternalTags(text: string): string { function formatOutbound (line 31) | function formatOutbound(rawText: string): string { function routeOutbound (line 37) | function routeOutbound( function findChannel (line 47) | function findChannel( FILE: src/sender-allowlist.test.ts function cfgPath (line 16) | function cfgPath(name = 'sender-allowlist.json'): string { function writeConfig (line 20) | function writeConfig(config: unknown, name?: string): string { FILE: src/sender-allowlist.ts type ChatAllowlistEntry (line 6) | interface ChatAllowlistEntry { type SenderAllowlistConfig (line 11) | interface SenderAllowlistConfig { constant DEFAULT_CONFIG (line 17) | const DEFAULT_CONFIG: SenderAllowlistConfig = { function isValidEntry (line 23) | function isValidEntry(entry: unknown): entry is ChatAllowlistEntry { function loadSenderAllowlist (line 33) | function loadSenderAllowlist( function getEntry (line 91) | function getEntry( function isSenderAllowed (line 98) | function isSenderAllowed( function shouldDropMessage (line 108) | function shouldDropMessage( function isTriggerAllowed (line 115) | function isTriggerAllowed( FILE: src/task-scheduler.ts function computeNextRun (line 31) | function computeNextRun(task: ScheduledTask): string | null { type SchedulerDependencies (line 65) | interface SchedulerDependencies { function runTask (line 78) | async function runTask( function startSchedulerLoop (line 243) | function startSchedulerLoop(deps: SchedulerDependencies): void { function _resetSchedulerLoopForTests (line 280) | function _resetSchedulerLoopForTests(): void { FILE: src/timezone.ts function formatLocalTime (line 5) | function formatLocalTime(utcIso: string, timezone: string): string { FILE: src/types.ts type AdditionalMount (line 1) | interface AdditionalMount { type MountAllowlist (line 12) | interface MountAllowlist { type AllowedRoot (line 21) | interface AllowedRoot { type ContainerConfig (line 30) | interface ContainerConfig { type RegisteredGroup (line 35) | interface RegisteredGroup { type NewMessage (line 45) | interface NewMessage { type ScheduledTask (line 56) | interface ScheduledTask { type TaskRunLog (line 71) | interface TaskRunLog { type Channel (line 82) | interface Channel { type OnInboundMessage (line 96) | type OnInboundMessage = (chatJid: string, message: NewMessage) => void; type OnChatMetadata (line 101) | type OnChatMetadata = (