Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,13 @@ tests/
| `src/lib/prompt-response-body-builder.ts` | プロンプト応答リクエストボディ構築ユーティリティ(Issue #287: buildPromptResponseBody()関数でpromptType/defaultOptionNumberを含むリクエストボディを生成、DRY原則対応、useAutoYes/WorktreeDetailRefactoredから共通化) |
| `src/lib/cli-tools/` | CLIツール抽象化(Strategy パターン) |
| `src/lib/cli-tools/codex.ts` | Codex CLI tmuxセッション管理(Issue #212: 複数行メッセージのPasted text検知+Enter再送、getErrorMessage()ヘルパー抽出) |
| `src/lib/session-cleanup.ts` | セッション/ポーラー停止の一元管理(Facade パターン) |
| `src/lib/session-cleanup.ts` | セッション/ポーラー/スケジューラー停止の一元管理(Facade パターン。**Issue #294: stopScheduleForWorktree()呼び出し追加**) |
| `src/lib/env-sanitizer.ts` | 環境変数サニタイズユーティリティ(Issue #294: SENSITIVE_ENV_KEYS配列[CLAUDECODE, CM_AUTH_TOKEN_HASH, CM_AUTH_EXPIRE, CM_HTTPS_KEY, CM_HTTPS_CERT, CM_ALLOWED_IPS, CM_TRUST_PROXY, CM_DB_PATH] + sanitizeEnvForChildProcess()関数。S1-001/S4-001: CLAUDECODE除去ロジックの一元管理) |
| `src/lib/cmate-parser.ts` | CMATE.md汎用パーサー(Issue #294: parseCmateFile()→Map<string,string[][]>、parseSchedulesSection()→ScheduleEntry[]、sanitizeMessageContent()でUnicode制御文字除去[S4-002]、NAME_PATTERN/MAX_NAME_LENGTH でName列バリデーション[S4-011]、validateCmatePath()でパストラバーサル防御、isValidCronExpression()でcron式バリデーション) |
| `src/types/cmate.ts` | CMATE.md型定義(Issue #294: ScheduleEntry interface、CmateConfig型) |
| `src/lib/claude-executor.ts` | claude -p プロセス実行エンジン(Issue #294: child_process.execFile使用[SEC-001]、sanitizeEnvForChildProcess()でSENSITIVE_ENV_KEYS除去、MAX_OUTPUT_SIZE=1MB/MAX_STORED_OUTPUT_SIZE=100KB[S1-014]、EXECUTION_TIMEOUT_MS=5分、MAX_MESSAGE_LENGTH=10000、executeClaudeCommand()、truncateOutput()) |
| `src/lib/schedule-manager.ts` | サーバーサイドスケジューラー(Issue #294: globalThis.__scheduleManagerStates/globalThis.__scheduleActiveProcesses、cronパターンでcron評価[croner]、単一タイマー全worktree巡回[60秒]、同時実行防止、MAX_CONCURRENT_SCHEDULES=100、再起動リカバリ[status=running→failed]、initScheduleManager()はinitializeWorktrees()完了後に呼び出し[S3-010]、stopAllSchedules()でSIGKILL fire-and-forget[S3-001]) |
| `src/config/schedule-config.ts` | スケジュール関連設定定数の一元管理(Issue #294リファクタリング: UUID_V4_PATTERN、isValidUuidV4()、MAX_NAME_LENGTH、MAX_MESSAGE_LENGTH、MAX_CRON_LENGTH。DRY原則対応) |
| `src/lib/url-normalizer.ts` | Git URL正規化(重複検出用) |
| `src/lib/url-path-encoder.ts` | ファイルパスのURLエンコード(Issue #300: encodePathForUrl()関数、スラッシュを保護しながら各セグメントを個別にencodeURIComponent、catch-allルートのパス分割を維持) |
| `src/lib/clone-manager.ts` | クローン処理管理(DBベース排他制御。**Issue #308: basePath修正** - resolveDefaultBasePath()でCM_ROOT_DIR/WORKTREE_BASE_PATH/process.cwd()優先順位制御、WORKTREE_BASE_PATH非推奨警告(モジュールスコープwarnedWorktreeBasePathフラグで初回のみ出力)、path.resolve()による絶対パス正規化、resetWorktreeBasePathWarning()テスト用エクスポート) |
Expand Down
1 change: 1 addition & 0 deletions docs/implementation-history.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

| Issue | 種別 | 概要 | 主要変更ファイル | 設計書 |
|-------|------|------|-----------------|--------|
| #294 | feat | スケジュール実行の登録(CMATE.md ## Schedulesセクションでcron定義→claude -p自動実行、execution_logs DBに結果保存、NotesAndLogsPane UIでメモ+実行ログ表示、env-sanitizer.tsでSENSITIVE_ENV_KEYS一元管理、PRAGMA foreign_keys = ON、v17マイグレーション孤児クリーンアップ) | `env-sanitizer.ts`, `cmate-parser.ts`, `types/cmate.ts`, `claude-executor.ts`, `schedule-manager.ts`, `config/schedule-config.ts`, `db-instance.ts`, `db-migrations.ts`, `session-cleanup.ts`, `server.ts`, `schedules/route.ts`, `schedules/[scheduleId]/route.ts`, `execution-logs/route.ts`, `execution-logs/[logId]/route.ts`, `NotesAndLogsPane.tsx`, `ExecutionLogPane.tsx`, `WorktreeDetailRefactored.tsx`, `locales/*/schedule.json` | [link](../dev-reports/design/issue-294-schedule-execution-design-policy.md) |
| #343 | feat | スラッシュコマンドセレクターで .claude/skills も表示(loadSkills()追加、safeParseFrontmatter()でgray-matter RCE対策、deduplicateByName()でcommand優先重複排除、skillsCache独立管理、CATEGORY_ORDER/CATEGORY_LABELS/'skill'追加、sources.skill APIレスポンス) | `slash-commands.ts`, `types/slash-commands.ts`, `command-merger.ts`, `api/worktrees/[id]/slash-commands/route.ts` | [link](../dev-reports/design/issue-343-skills-loader-design-policy.md) |
| #332 | feat | IP制限オプション(CM_ALLOWED_IPS/CM_TRUST_PROXY環境変数、CIDR対応、Edge Runtime互換、parseAllowedIps/getAllowedRanges/isIpAllowed/normalizeIp/isIpRestrictionEnabled/getClientIp、MAX_ALLOWED_IP_ENTRIES=256/MAX_CIDR_ENTRY_LENGTH=18 DoS防御、モジュールスコープキャッシュ、middleware統合) | `ip-restriction.ts`, `auth-config.ts`, `middleware.ts` | - |
| #331 | feat | トークン認証・HTTPS対応(SHA-256ハッシュ認証、Cookie/レート制限、TLS証明書、Edge Runtime互換ミドルウェア、WebSocket認証、ログインUI) | `auth.ts`, `auth-config.ts`, `middleware.ts`, `ws-server.ts`, `server.ts`, `start.ts`, `login/page.tsx`, `login/route.ts`, `logout/route.ts`, `status/route.ts` | [link](../dev-reports/design/issue-331-token-auth-design-policy.md) |
Expand Down
36 changes: 36 additions & 0 deletions locales/en/schedule.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"title": "Schedules",
"executionLogs": "Execution Logs",
"noSchedules": "No schedules configured. Add a CMATE.md with a Schedules section.",
"noSchedulesTitle": "No schedules configured",
"noSchedulesStep1": "Switch to the Files tab",
"noSchedulesStep2": "Click the CMATE button in the toolbar to create CMATE.md",
"noSchedulesStep3": "Edit the Schedules table (Name, Cron, Message, CLI Tool, Enabled, Permission)",
"noSchedulesStep4": "Click CMATE again to validate",
"noLogs": "No execution logs yet.",
"status": {
"running": "Running",
"completed": "Completed",
"failed": "Failed",
"timeout": "Timeout",
"cancelled": "Cancelled"
},
"enabled": "Enabled",
"disabled": "Disabled",
"lastRun": "Last run",
"cron": "Cron",
"exitCode": "Exit",
"noOutput": "(no output)",
"retry": "Retry",
"loading": "Loading...",
"notes": "Notes",
"logs": "Schedules",
"notesAndLogs": "CMATE",
"cmateCreated": "CMATE.md created with template. Edit it to configure schedules.",
"cmateValidation": {
"noSchedulesSection": "CMATE.md has no Schedules section.",
"valid": "{count} schedule(s) validated successfully.",
"errors": "{errorCount} validation error(s) found: {details}",
"failed": "Failed to process CMATE.md."
}
}
36 changes: 36 additions & 0 deletions locales/ja/schedule.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"title": "スケジュール",
"executionLogs": "実行ログ",
"noSchedules": "スケジュールが設定されていません。CMATE.mdにSchedulesセクションを追加してください。",
"noSchedulesTitle": "スケジュールが設定されていません",
"noSchedulesStep1": "Files タブに切り替えてください",
"noSchedulesStep2": "ツールバーの CMATE ボタンをクリックして CMATE.md を作成",
"noSchedulesStep3": "Schedules テーブルを編集(Name, Cron, Message, CLI Tool, Enabled, Permission)",
"noSchedulesStep4": "再度 CMATE をクリックしてバリデーション",
"noLogs": "実行ログはまだありません。",
"status": {
"running": "実行中",
"completed": "完了",
"failed": "失敗",
"timeout": "タイムアウト",
"cancelled": "キャンセル"
},
"enabled": "有効",
"disabled": "無効",
"lastRun": "最終実行",
"cron": "Cron式",
"exitCode": "終了コード",
"noOutput": "(出力なし)",
"retry": "再試行",
"loading": "読み込み中...",
"notes": "メモ",
"logs": "Schedules",
"notesAndLogs": "CMATE",
"cmateCreated": "CMATE.mdをテンプレートで作成しました。スケジュールを設定してください。",
"cmateValidation": {
"noSchedulesSection": "CMATE.mdにSchedulesセクションがありません。",
"valid": "{count}件のスケジュールが正常に検証されました。",
"errors": "{errorCount}件の検証エラー: {details}",
"failed": "CMATE.mdの処理に失敗しました。"
}
}
156 changes: 88 additions & 68 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"autoprefixer": "^10.4.22",
"better-sqlite3": "^12.4.1",
"commander": "^14.0.2",
"croner": "^10.0.1",
"date-fns": "^4.1.0",
"dotenv": "^17.2.3",
"gray-matter": "^4.0.3",
Expand Down
7 changes: 7 additions & 0 deletions server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
import { getDbInstance } from './src/lib/db-instance';
import { stopAllPolling } from './src/lib/response-poller';
import { stopAllAutoYesPolling } from './src/lib/auto-yes-manager';
import { initScheduleManager, stopAllSchedules } from './src/lib/schedule-manager';
import { runMigrations } from './src/lib/db-migrations';
import { getEnvByKey } from './src/lib/env';
import { registerAndFilterRepositories, resolveRepositoryPath } from './src/lib/db-repository';
Expand Down Expand Up @@ -253,6 +254,9 @@ app.prepare().then(() => {

// Initialize worktrees after server starts
await initializeWorktrees();

// [S3-010] Initialize schedule manager AFTER worktrees are ready
initScheduleManager();
});

// Graceful shutdown with timeout
Expand All @@ -273,6 +277,9 @@ app.prepare().then(() => {
// Issue #138: Stop all auto-yes pollers
stopAllAutoYesPolling();

// Issue #294: Stop all scheduled executions (SIGKILL fire-and-forget)
stopAllSchedules();

// Close WebSocket connections immediately (don't wait)
closeWebSocket();

Expand Down
Loading