export interface BacklogMcpConfig { domain: string; apiKey: string; projectKey: string; isDefault?: boolean; } /** * MCP 設定ファイルのパスを返す */ export declare function getMcpConfigPath(projectDir: string): string; /** * MCP 設定 JSON を構築する * * token はファイルに書かない。環境変数参照にする。 */ export declare function buildMcpConfig(apiUrl: string, projectCode: string, mcpServerPath: string, tenantCode: string): Record; /** * ブラウザローカルポートの環境変数名 */ export declare const BROWSER_LOCAL_PORT_ENV = "AI_SUPPORT_BROWSER_LOCAL_PORT"; /** * 実際のSlackチャット会話ID(conversationId)の環境変数名。 * * read_slack_thread MCPツールが子プロセス(Claude Code CLI がさらに spawn する * MCP サーバー)側で `process.env[CONVERSATION_ID_ENV]` として読み取り、現在処理中の * Slackスレッドを逆引きするために使用する。 * * 注意: `@modelcontextprotocol/sdk` の `StdioClientTransport` は MCP サーバー子プロセスへ * `{ ...getDefaultEnvironment(), ...serverParams.env }` のみを渡す実装になっており、 * `getDefaultEnvironment()` は HOME/LOGNAME/PATH/SHELL/TERM/USER(Windows: APPDATA 等) * のみを継承する。つまり呼び出し元プロセス(claude/codex CLI)が任意に持つ * `process.env.AI_SUPPORT_CONVERSATION_ID` は MCP サーバー子プロセスへは自動継承されず、 * MCP 設定ファイルの `env` に明示的に含まれている場合のみ子プロセスに渡る * (`node_modules/@modelcontextprotocol/sdk/dist/cjs/client/stdio.js` で確認済み)。 * このため conversationId は `writeMcpConfig` が書くプロジェクト単位の静的ファイルではなく、 * チャットコマンド単位で `writeCommandMcpConfig` が書く per-command ファイルの `env` に * 明示的に埋め込む必要がある。 */ export declare const CONVERSATION_ID_ENV = "AI_SUPPORT_CONVERSATION_ID"; /** * 実行中タスクのIDの環境変数名。 * * `trigger_e2e_test` MCPツールが子プロセス側で `process.env[TASK_ID_ENV]` として * 読み取り、起動したE2E実行をこのタスクに紐付ける(タスク詳細画面のE2Eテストタブ * からの逆引き用)。`CONVERSATION_ID_ENV` と同じ理由(`StdioClientTransport` が * 呼び出し元プロセスの任意の環境変数をMCPサーバー子プロセスへ自動継承しない)により、 * `writeCommandMcpConfig` が書く per-command ファイルの `env` に明示的に埋め込む * 必要がある。 */ export declare const TASK_ID_ENV = "AI_SUPPORT_TASK_ID"; /** * このナレッジ登録依頼の元になったチャットコマンドのID の環境変数名。 * * `update_system_knowledge` MCPツールが子プロセス側で * `process.env[KNOWLEDGE_COMMAND_ID_ENV]` として読み取り、ナレッジ登録/改訂API * (`POST /api/:tenantCode/agent/knowledge`)へ `commandId` として渡す。api側はこの * `commandId` を使って `AgentCommandQueueService.getCommand(commandId, agentId, tenantCode)` * によりコマンド生成時に刻印された本物の `knowledgeCanPublish`/`knowledgeRequesterUserId` * を引き当てる(クライアント自己申告の値は信用しない)。LLM/モデルがツール呼び出し引数として * 自由に指定できる値ではないため、ツールのスキーマには含めず、`CONVERSATION_ID_ENV`/ * `TASK_ID_ENV` と同じ理由(`StdioClientTransport` が呼び出し元プロセスの任意の環境変数を * MCPサーバー子プロセスへ自動継承しない)により、per-command ファイルの `env` に明示的に * 埋め込む必要がある。値は `writeCommandMcpConfig` の `commandId` 引数(呼び出し元が既に * 持っている値)をそのまま使うため、常に埋め込まれる。 */ export declare const KNOWLEDGE_COMMAND_ID_ENV = "AI_SUPPORT_AGENT_KNOWLEDGE_COMMAND_ID"; /** * エージェント自身の agentId の環境変数名。`KNOWLEDGE_COMMAND_ID_ENV` と組み合わせて * api側が `AgentCommandQueueService.getCommand(commandId, agentId, tenantCode)` で * コマンドレコードを引き当てるために使う。`KNOWLEDGE_COMMAND_ID_ENV` と同じ理由・同じ経路で * per-command ファイルの `env` に埋め込む必要がある。 */ export declare const KNOWLEDGE_AGENT_ID_ENV = "AI_SUPPORT_AGENT_KNOWLEDGE_AGENT_ID"; /** * The replica identity that holds the assignment for this command. * * The knowledge endpoint grants `published` status based on `commandId`, so the * server fences it to the assigned replica — a request without these headers is * rejected with 409 for an assigned command. The MCP server runs in a *child * process* that only receives the env keys listed here, so its own `ApiClient` * would otherwise resolve a different instance id (HOSTNAME fallback) and have * an empty in-memory generation map, and every knowledge write for an assigned * command would fail. */ export declare const ASSIGNMENT_INSTANCE_ID_ENV = "AI_SUPPORT_AGENT_ASSIGNMENT_INSTANCE_ID"; /** The fencing token (assignment generation) for {@link ASSIGNMENT_INSTANCE_ID_ENV}. */ export declare const ASSIGNMENT_GENERATION_ENV = "AI_SUPPORT_AGENT_ASSIGNMENT_GENERATION"; /** * MCP 設定ファイルを書き出す * * 0o600 権限で作成し、token は環境変数参照にする。 */ export declare function writeMcpConfig(projectDir: string, apiUrl: string, token: string, projectCode: string, mcpServerPath: string, backlogConfigs?: BacklogMcpConfig[], tenantCode?: string, browserLocalPort?: number): string; /** * チャットコマンド(Slackメッセージ)単位の MCP 設定ファイルを書き出す。 * * `writeMcpConfig` が書く `.ai-support-agent/mcp/config.json` はプロジェクト単位の * 静的ファイルで、config sync 時にのみ再生成され、複数のチャットコマンド(複数の * Slack会話が並行/連続実行される場合を含む)から共有される。conversationId は * コマンド単位で変わる値であり、この静的ファイルに書き込むと「別会話の * conversationId が残ったまま次のコマンドに使われる」「並行実行時に競合する」 * リスクがある(`agent-transport.ts` の `void handleNotification(...)` により、 * 同一エージェントが複数コマンドを並行処理しうるため)。 * * そのため、`ai-support-agent` サーバーの `env` に conversationId を埋め込んだ * コマンド専用の設定ファイルを都度書き出す。呼び出し元はコマンド完了後に * このファイルを削除すること。 * * ファイル名には commandId(サニタイズ済み、デバッグ用)に加えて `randomUUID()` を * 必ず含める。commandId は外部API由来で形式保証がなく、サニタイズ後に別の commandId * と衝突しうる(例: `cmd/a` と `cmd_a` はいずれも `cmd_a` に正規化される)。UUID を * 含めないと、並行実行中の別コマンドの設定ファイルを誤って参照・削除してしまい、 * conversationId の混線やMCPサーバー起動失敗を招く。書き込みは排他生成(`wx` フラグ) * で行い、万一の衝突は例外として検知する(呼び出し元は失敗時に共有静的設定へ * フォールバックする設計になっている)。 * * `read_slack_thread` ツールが子プロセス側で `process.env[CONVERSATION_ID_ENV]` として * 読み取れるのは、MCP サーバー子プロセスへは `StdioClientTransport` 経由で * 設定ファイルの `env` に明示されたキーのみが渡され、呼び出し元プロセス * (claude/codex CLI)の任意の環境変数は自動継承されないため(`CONVERSATION_ID_ENV` * の定義コメント参照)。 */ export declare function writeCommandMcpConfig(baseConfigPath: string, commandId: string, conversationId: string, taskId?: string, agentId?: string, /** * The assignment held for `commandId`. Passed through so the MCP child * process can present the same fencing identity (see * {@link ASSIGNMENT_INSTANCE_ID_ENV}). */ assignment?: { instanceId: string; generation: number; }): string; /** * 孤立した per-command MCP 設定ファイル(`config-*.json`)を一括削除する。 * * 通常はコマンド完了時(chat-executor.ts の cleanupCommandMcpConfig)に削除されるが、 * エージェント process が SIGKILL / OOM 等で異常終了した場合、平文トークンと * conversationId を含む孤立ファイルが `.ai-support-agent/mcp/` に残り続ける。 * `TerminalSession.cleanupStaleSandboxes` と同じパターンで、一定時間以上前のものを * 掃除する。共有静的ファイル(`config.json` 自体、`baseConfigPath` の basename)や * 無関係なファイルには触れない。 * * @param baseConfigPath `getMcpConfigPath(projectDir)` が返す静的設定ファイルのパス * @param maxAgeMs 削除対象とする経過時間 (ms)。デフォルト 24 時間。0 で全削除 * @returns 削除した件数 */ export declare function cleanupStaleCommandMcpConfigs(baseConfigPath: string, maxAgeMs?: number): number; //# sourceMappingURL=config-writer.d.ts.map