From d061ad08d8297d180b0d801ed2a181d7b9f4d5a0 Mon Sep 17 00:00:00 2001 From: oss-sync Date: Thu, 11 Jun 2026 01:52:48 +0000 Subject: [PATCH] sync: update from private repo (e62f5c7) --- .gitea/workflows/ci.yml | 4 +- Dockerfile | 17 +- GEMINI.md | 38 - README.ja.md | 74 ++ README.md | 70 +- config.yaml.example | 7 +- docs/README.en.draft.md | 96 +++ docs/SECURITY.draft.md | 24 + docs/architecture.ja.md | 87 ++ docs/architecture.md | 109 +-- docs/configuration.ja.md | 231 ++++++ docs/configuration.md | 246 +++--- docs/design/README.md | 151 ---- docs/design/colors_and_type.css | 128 --- .../admin-legacy/ChatPane.jsx | 128 --- .../admin-legacy/DetailPanel.jsx | 134 --- .../admin-legacy/Primitives.jsx | 86 -- .../ui_kits_reference/admin-legacy/README.md | 12 - .../admin-legacy/TaskList.jsx | 92 -- .../ui_kits_reference/admin-legacy/TopBar.jsx | 62 -- .../ui_kits_reference/admin-legacy/index.html | 231 ------ .../ui_kits_reference/admin/ChatPane.jsx | 197 ----- .../ui_kits_reference/admin/DetailPanel.jsx | 134 --- .../ui_kits_reference/admin/Primitives.jsx | 169 ---- docs/design/ui_kits_reference/admin/README.md | 34 - .../ui_kits_reference/admin/SchedulesPage.jsx | 427 ---------- .../ui_kits_reference/admin/SettingsPage.jsx | 318 ------- .../ui_kits_reference/admin/TaskList.jsx | 199 ----- .../design/ui_kits_reference/admin/TopBar.jsx | 57 -- .../ui_kits_reference/admin/UsersPage.jsx | 313 ------- .../design/ui_kits_reference/admin/index.html | 399 --------- .../design/ui_kits_reference/compare-cta.html | 31 - docs/getting-started.ja.md | 109 +++ docs/getting-started.md | 98 +-- docs/oss-docs-cleanup-plan.md | 370 +++++++++ docs/tools/browseweb.md | 4 + scripts/setup.sh | 26 +- src/bridge/auth.ts | 43 + src/bridge/branding-api.test.ts | 18 + src/bridge/branding-api.ts | 6 + src/bridge/console-session-api.test.ts | 32 +- src/bridge/console-ws-api.ts | 8 +- src/bridge/local-api-helpers.test.ts | 41 + src/bridge/local-api-helpers.ts | 17 + src/bridge/local-files-api.ts | 4 +- src/bridge/login-rate-limit.test.ts | 115 +++ src/bridge/login-rate-limit.ts | 136 +++ src/bridge/server.ts | 51 +- src/bridge/share-api.ts | 4 +- src/bridge/subtask-files-api.ts | 3 +- src/bridge/user-folder-api.test.ts | 12 + src/bridge/user-folder-api.ts | 3 + .../reflection/reflection-prompt.test.ts | 8 +- src/engine/reflection/reflection-prompt.ts | 49 +- .../reflection/semantic-validator.test.ts | 95 +++ src/engine/reflection/semantic-validator.ts | 118 +++ src/engine/reflection/types.ts | 3 +- src/engine/tools/browser.ts | 32 +- src/engine/tools/shared/ssrf.ts | 72 +- src/net/ssrf-strict.test.ts | 41 +- src/net/ssrf-strict.ts | 17 +- src/worker-bootstrap.ts | 15 +- ui/package-lock.json | 105 ++- ui/package.json | 6 +- ui/src/App.tsx | 12 +- ui/src/components/admin/LocalUserDialogs.tsx | 55 +- .../browser/BrowserSessionPanel.tsx | 4 +- ui/src/components/browser/PipButton.tsx | 24 +- .../browser/SaveRecordingButton.tsx | 18 +- ui/src/components/chat/ChatMessage.tsx | 12 +- ui/src/components/chat/ChatPane.tsx | 36 +- ui/src/components/chat/MovementGroup.tsx | 4 +- ui/src/components/chat/SubtaskInlineCard.tsx | 10 +- ui/src/components/command/CommandPalette.tsx | 10 +- .../components/create/AttachmentDropzone.tsx | 6 +- ui/src/components/create/CreateTaskDialog.tsx | 72 +- ui/src/components/create/ScheduleFields.tsx | 28 +- .../components/dashboard/AddWidgetDialog.tsx | 34 +- .../components/dashboard/MarkdownWidget.tsx | 16 +- .../components/dashboard/NodeStatusWidget.tsx | 14 +- ui/src/components/dashboard/SideInfoPanel.tsx | 6 +- ui/src/components/dashboard/WidgetTabBar.tsx | 13 +- .../dashboard/WorkerStatusWidget.tsx | 11 +- .../detail/ContinueWithPieceDialog.tsx | 18 +- ui/src/components/detail/DetailHeader.tsx | 32 +- ui/src/components/detail/DetailPanel.tsx | 44 +- ui/src/components/detail/tabs/BrowserTab.tsx | 40 +- ui/src/components/detail/tabs/ConsoleTab.tsx | 34 +- ui/src/components/detail/tabs/OutputTab.tsx | 8 +- ui/src/components/detail/tabs/OverviewTab.tsx | 57 +- ui/src/components/detail/tabs/ProgressTab.tsx | 16 +- .../detail/tabs/SubtaskActivitySection.tsx | 6 +- .../components/detail/tabs/SubtasksPanel.tsx | 21 +- ui/src/components/detail/tabs/TimelineTab.tsx | 4 +- ui/src/components/detail/tabs/TraceTab.tsx | 12 +- .../detail/tabs/console/MobileKeyboardBar.tsx | 16 +- .../tabs/console/ScrollToBottomButton.tsx | 4 +- .../components/embed/AmazonProductsCard.tsx | 8 +- .../components/embed/AmazonProductsDetail.tsx | 15 +- ui/src/components/embed/EmbedModal.tsx | 4 +- ui/src/components/embed/MapPlacesCard.tsx | 8 +- ui/src/components/embed/MapPlacesDetail.tsx | 6 +- ui/src/components/embed/XPostsCard.tsx | 8 +- ui/src/components/embed/XPostsDetail.tsx | 14 +- ui/src/components/embed/YouTubeVideosCard.tsx | 8 +- .../components/embed/YouTubeVideosDetail.tsx | 6 +- ui/src/components/files/FileBrowser.tsx | 21 +- ui/src/components/files/FilePreview.tsx | 31 +- ui/src/components/layout/NavDrawer.tsx | 6 +- ui/src/components/layout/ResizeHandle.tsx | 4 +- ui/src/components/layout/ThemeToggle.tsx | 16 +- ui/src/components/layout/TopBar.tsx | 36 +- .../layout/VerticalResizeHandle.tsx | 4 +- ui/src/components/list/FilterBar.tsx | 25 +- ui/src/components/list/RailPanel.tsx | 10 +- ui/src/components/list/TaskListPanel.tsx | 21 +- .../components/settings/AskSubtasksForm.tsx | 8 +- ui/src/components/settings/AuthForm.tsx | 47 +- ui/src/components/settings/BrandingForm.tsx | 49 +- .../settings/BrowserSettingsForm.tsx | 38 +- ui/src/components/settings/ConfigForm.tsx | 22 +- ui/src/components/settings/ContextForm.tsx | 21 +- ui/src/components/settings/ExecutionForm.tsx | 14 +- .../settings/GatewayKeyCreateDialog.tsx | 12 +- .../settings/GatewayKeyRawKeyDialog.tsx | 15 +- .../settings/GatewayKeyUsagePanel.tsx | 12 +- .../settings/GatewayKeysSection.tsx | 29 +- .../components/settings/GatewayServerForm.tsx | 45 +- .../settings/KnowledgeNamespacesForm.tsx | 16 +- ui/src/components/settings/LlmWorkersForm.tsx | 65 +- ui/src/components/settings/McpForm.tsx | 40 +- .../settings/MemoryLearningForm.tsx | 131 +-- ui/src/components/settings/MetricsForm.tsx | 16 +- .../components/settings/MovementAccordion.tsx | 4 +- ui/src/components/settings/MovementForm.tsx | 6 +- .../components/settings/NamespaceEditor.tsx | 8 +- ui/src/components/settings/NotesForm.tsx | 18 +- .../components/settings/NotificationsForm.tsx | 88 +- ui/src/components/settings/OrgsForm.tsx | 30 +- .../components/settings/PathsStorageForm.tsx | 22 +- ui/src/components/settings/PieceEditor.tsx | 30 +- ui/src/components/settings/PieceMetaForm.tsx | 10 +- .../components/settings/PreferencesForm.tsx | 41 +- .../settings/PushNotificationsForm.tsx | 35 +- ui/src/components/settings/ReflectionForm.tsx | 67 +- ui/src/components/settings/RulesTable.tsx | 6 +- ui/src/components/settings/SafetyForm.tsx | 46 +- .../components/settings/SearchFilterForm.tsx | 18 +- .../components/settings/SettingsSidebar.tsx | 7 +- ui/src/components/settings/SshAuditLog.tsx | 10 +- ui/src/components/settings/SshConfigForm.tsx | 103 +-- ui/src/components/settings/SshForm.tsx | 8 +- .../settings/SshGlobalConnectionsForm.tsx | 76 +- ui/src/components/settings/SshGrantsForm.tsx | 66 +- .../settings/SshMasterKeyRotationForm.tsx | 40 +- .../components/settings/StringArrayEditor.tsx | 4 +- ui/src/components/settings/ToolTagInput.tsx | 12 +- .../components/settings/ToolsExternalForm.tsx | 60 +- ui/src/components/settings/ToolsForm.tsx | 118 ++- ui/src/components/settings/ToolsMediaForm.tsx | 54 +- ui/src/components/settings/ToolsWebForm.tsx | 26 +- ui/src/components/settings/WorkspaceForm.tsx | 18 +- ui/src/components/settings/formUtils.tsx | 5 +- ui/src/components/shared/EmptyState.tsx | 10 +- .../userfolder/AddBrowserSessionDialog.tsx | 32 +- .../components/userfolder/AgentsMdPanel.tsx | 14 +- .../userfolder/BrowserSessionsPanel.tsx | 38 +- ui/src/components/userfolder/FileTree.tsx | 9 +- ui/src/components/userfolder/McpPanel.tsx | 75 +- ui/src/components/userfolder/MemoryPanel.tsx | 90 +- ui/src/components/userfolder/NewFileForm.tsx | 22 +- ui/src/components/userfolder/NotesPanel.tsx | 47 +- ui/src/components/userfolder/PetsPanel.tsx | 57 +- .../userfolder/SshConnectionForm.tsx | 61 +- .../userfolder/SshConnectionsPanel.tsx | 68 +- .../userfolder/SshHostKeyDialog.tsx | 16 +- .../userfolder/SshPublicKeyDialog.tsx | 20 +- .../userfolder/SubscriptionsPanel.tsx | 58 +- .../components/userfolder/UserFolderTab.tsx | 124 +-- ui/src/hooks/useFilePreview.ts | 10 +- ui/src/hooks/useTaskOperations.ts | 20 +- ui/src/i18n/CONVENTIONS.md | 84 ++ ui/src/i18n/index.ts | 50 ++ ui/src/i18n/locales/en/admin.json | 76 ++ ui/src/i18n/locales/en/auth.json | 33 + ui/src/i18n/locales/en/browser.json | 28 + ui/src/i18n/locales/en/chat.json | 44 + ui/src/i18n/locales/en/common.json | 16 + ui/src/i18n/locales/en/console.json | 11 + ui/src/i18n/locales/en/create.json | 60 ++ ui/src/i18n/locales/en/dashboard.json | 50 ++ ui/src/i18n/locales/en/detail.json | 80 ++ ui/src/i18n/locales/en/embed.json | 23 + ui/src/i18n/locales/en/files.json | 21 + ui/src/i18n/locales/en/help.json | 16 + ui/src/i18n/locales/en/knowledge.json | 1 + ui/src/i18n/locales/en/layout.json | 61 ++ ui/src/i18n/locales/en/list.json | 46 + ui/src/i18n/locales/en/pieces.json | 31 + ui/src/i18n/locales/en/schedules.json | 166 ++++ ui/src/i18n/locales/en/settings.json | 783 ++++++++++++++++++ ui/src/i18n/locales/en/shared.json | 12 + ui/src/i18n/locales/en/userfolder.json | 442 ++++++++++ ui/src/i18n/locales/ja/admin.json | 76 ++ ui/src/i18n/locales/ja/auth.json | 33 + ui/src/i18n/locales/ja/browser.json | 28 + ui/src/i18n/locales/ja/chat.json | 44 + ui/src/i18n/locales/ja/common.json | 16 + ui/src/i18n/locales/ja/console.json | 11 + ui/src/i18n/locales/ja/create.json | 60 ++ ui/src/i18n/locales/ja/dashboard.json | 50 ++ ui/src/i18n/locales/ja/detail.json | 80 ++ ui/src/i18n/locales/ja/embed.json | 23 + ui/src/i18n/locales/ja/files.json | 21 + ui/src/i18n/locales/ja/help.json | 16 + ui/src/i18n/locales/ja/knowledge.json | 1 + ui/src/i18n/locales/ja/layout.json | 61 ++ ui/src/i18n/locales/ja/list.json | 46 + ui/src/i18n/locales/ja/pieces.json | 31 + ui/src/i18n/locales/ja/schedules.json | 166 ++++ ui/src/i18n/locales/ja/settings.json | 783 ++++++++++++++++++ ui/src/i18n/locales/ja/shared.json | 12 + ui/src/i18n/locales/ja/userfolder.json | 442 ++++++++++ ui/src/lib/command-palette.ts | 19 +- ui/src/lib/notifications.test.ts | 2 +- ui/src/lib/notifications.ts | 16 +- ui/src/lib/unsavedGuard.ts | 3 +- ui/src/lib/usePictureInPicture.ts | 18 +- ui/src/lib/utils.ts | 13 +- ui/src/main.tsx | 1 + ui/src/pages/AdminCaptchaPage.tsx | 30 +- ui/src/pages/HelpPage.tsx | 30 +- ui/src/pages/PiecesPage.tsx | 37 +- ui/src/pages/SchedulesPage.tsx | 265 +++--- ui/src/pages/SettingsPage.tsx | 4 +- ui/src/pages/SharedView.tsx | 21 +- ui/src/pages/UsersPage.tsx | 96 ++- 237 files changed, 8441 insertions(+), 5549 deletions(-) delete mode 100644 GEMINI.md create mode 100644 README.ja.md create mode 100644 docs/README.en.draft.md create mode 100644 docs/SECURITY.draft.md create mode 100644 docs/architecture.ja.md create mode 100644 docs/configuration.ja.md delete mode 100644 docs/design/README.md delete mode 100644 docs/design/colors_and_type.css delete mode 100644 docs/design/ui_kits_reference/admin-legacy/ChatPane.jsx delete mode 100644 docs/design/ui_kits_reference/admin-legacy/DetailPanel.jsx delete mode 100644 docs/design/ui_kits_reference/admin-legacy/Primitives.jsx delete mode 100644 docs/design/ui_kits_reference/admin-legacy/README.md delete mode 100644 docs/design/ui_kits_reference/admin-legacy/TaskList.jsx delete mode 100644 docs/design/ui_kits_reference/admin-legacy/TopBar.jsx delete mode 100644 docs/design/ui_kits_reference/admin-legacy/index.html delete mode 100644 docs/design/ui_kits_reference/admin/ChatPane.jsx delete mode 100644 docs/design/ui_kits_reference/admin/DetailPanel.jsx delete mode 100644 docs/design/ui_kits_reference/admin/Primitives.jsx delete mode 100644 docs/design/ui_kits_reference/admin/README.md delete mode 100644 docs/design/ui_kits_reference/admin/SchedulesPage.jsx delete mode 100644 docs/design/ui_kits_reference/admin/SettingsPage.jsx delete mode 100644 docs/design/ui_kits_reference/admin/TaskList.jsx delete mode 100644 docs/design/ui_kits_reference/admin/TopBar.jsx delete mode 100644 docs/design/ui_kits_reference/admin/UsersPage.jsx delete mode 100644 docs/design/ui_kits_reference/admin/index.html delete mode 100644 docs/design/ui_kits_reference/compare-cta.html create mode 100644 docs/getting-started.ja.md create mode 100644 docs/oss-docs-cleanup-plan.md create mode 100644 src/bridge/local-api-helpers.test.ts create mode 100644 src/bridge/login-rate-limit.test.ts create mode 100644 src/bridge/login-rate-limit.ts create mode 100644 ui/src/i18n/CONVENTIONS.md create mode 100644 ui/src/i18n/index.ts create mode 100644 ui/src/i18n/locales/en/admin.json create mode 100644 ui/src/i18n/locales/en/auth.json create mode 100644 ui/src/i18n/locales/en/browser.json create mode 100644 ui/src/i18n/locales/en/chat.json create mode 100644 ui/src/i18n/locales/en/common.json create mode 100644 ui/src/i18n/locales/en/console.json create mode 100644 ui/src/i18n/locales/en/create.json create mode 100644 ui/src/i18n/locales/en/dashboard.json create mode 100644 ui/src/i18n/locales/en/detail.json create mode 100644 ui/src/i18n/locales/en/embed.json create mode 100644 ui/src/i18n/locales/en/files.json create mode 100644 ui/src/i18n/locales/en/help.json create mode 100644 ui/src/i18n/locales/en/knowledge.json create mode 100644 ui/src/i18n/locales/en/layout.json create mode 100644 ui/src/i18n/locales/en/list.json create mode 100644 ui/src/i18n/locales/en/pieces.json create mode 100644 ui/src/i18n/locales/en/schedules.json create mode 100644 ui/src/i18n/locales/en/settings.json create mode 100644 ui/src/i18n/locales/en/shared.json create mode 100644 ui/src/i18n/locales/en/userfolder.json create mode 100644 ui/src/i18n/locales/ja/admin.json create mode 100644 ui/src/i18n/locales/ja/auth.json create mode 100644 ui/src/i18n/locales/ja/browser.json create mode 100644 ui/src/i18n/locales/ja/chat.json create mode 100644 ui/src/i18n/locales/ja/common.json create mode 100644 ui/src/i18n/locales/ja/console.json create mode 100644 ui/src/i18n/locales/ja/create.json create mode 100644 ui/src/i18n/locales/ja/dashboard.json create mode 100644 ui/src/i18n/locales/ja/detail.json create mode 100644 ui/src/i18n/locales/ja/embed.json create mode 100644 ui/src/i18n/locales/ja/files.json create mode 100644 ui/src/i18n/locales/ja/help.json create mode 100644 ui/src/i18n/locales/ja/knowledge.json create mode 100644 ui/src/i18n/locales/ja/layout.json create mode 100644 ui/src/i18n/locales/ja/list.json create mode 100644 ui/src/i18n/locales/ja/pieces.json create mode 100644 ui/src/i18n/locales/ja/schedules.json create mode 100644 ui/src/i18n/locales/ja/settings.json create mode 100644 ui/src/i18n/locales/ja/shared.json create mode 100644 ui/src/i18n/locales/ja/userfolder.json diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 0cbc6a9..6f6a47f 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -8,8 +8,8 @@ jobs: build-and-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 22 cache: npm diff --git a/Dockerfile b/Dockerfile index a3eefbf..dc6d98c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,10 +16,17 @@ RUN npm --prefix ui ci --ignore-scripts # npm の @novnc/novnc は lib のみで vnc.html を含まないため、 # Browser タブの iframe 用に GitHub から tarball を取得する。 ARG NOVNC_VERSION=1.6.0 +# Pinned SHA256 of the v${NOVNC_VERSION} source tarball. Verify the integrity of +# the download before extracting so a compromised/MITM'd tarball can't inject +# code into the image. To bump NOVNC_VERSION, recompute via: +# curl -fSL "https://github.com/novnc/noVNC/archive/refs/tags/v.tar.gz" | sha256sum +ARG NOVNC_SHA256=5066103959ef4e9b10f37e5a148627360dd8414e4cf8a7db92bdbd022e728aaa RUN apk add --no-cache --virtual .novnc-fetch curl tar \ && mkdir -p /app/vendor/noVNC \ - && curl -fSL "https://github.com/novnc/noVNC/archive/refs/tags/v${NOVNC_VERSION}.tar.gz" \ - | tar -xz -C /app/vendor/noVNC --strip-components=1 \ + && curl -fSL "https://github.com/novnc/noVNC/archive/refs/tags/v${NOVNC_VERSION}.tar.gz" -o /tmp/novnc.tar.gz \ + && echo "${NOVNC_SHA256} /tmp/novnc.tar.gz" | sha256sum -c - \ + && tar -xz -C /app/vendor/noVNC --strip-components=1 -f /tmp/novnc.tar.gz \ + && rm -f /tmp/novnc.tar.gz \ && test -f /app/vendor/noVNC/vnc.html \ && apk del .novnc-fetch @@ -104,8 +111,14 @@ COPY config.yaml.example ./config.yaml RUN mkdir -p /app/data /workspaces \ && chown -R node:node /app/data /workspaces config.yaml +# HOST=0.0.0.0 is required INSIDE the container so the published port is +# reachable. This is safe because docker-compose maps it to 127.0.0.1:9876 on +# the host — the container is not exposed to the LAN unless the operator changes +# that mapping. The app's own default (when HOST is unset, e.g. bare-metal) is +# 127.0.0.1; see createCoreServer in src/bridge/server.ts. ENV NODE_ENV=production \ PORT=9876 \ + HOST=0.0.0.0 \ DB_PATH=/app/data/maestro.db EXPOSE 9876 diff --git a/GEMINI.md b/GEMINI.md deleted file mode 100644 index 0a3e5c8..0000000 --- a/GEMINI.md +++ /dev/null @@ -1,38 +0,0 @@ - -## MCP Tools: code-review-graph - -**IMPORTANT: This project has a knowledge graph. ALWAYS use the -code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore -the codebase.** The graph is faster, cheaper (fewer tokens), and gives -you structural context (callers, dependents, test coverage) that file -scanning cannot. - -### When to use graph tools FIRST - -- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep -- **Understanding impact**: `get_impact_radius` instead of manually tracing imports -- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files -- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for -- **Architecture questions**: `get_architecture_overview` + `list_communities` - -Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need. - -### Key Tools - -| Tool | Use when | -|------|----------| -| `detect_changes` | Reviewing code changes — gives risk-scored analysis | -| `get_review_context` | Need source snippets for review — token-efficient | -| `get_impact_radius` | Understanding blast radius of a change | -| `get_affected_flows` | Finding which execution paths are impacted | -| `query_graph` | Tracing callers, callees, imports, tests, dependencies | -| `semantic_search_nodes` | Finding functions/classes by name or keyword | -| `get_architecture_overview` | Understanding high-level codebase structure | -| `refactor_tool` | Planning renames, finding dead code | - -### Workflow - -1. The graph auto-updates on file changes (via hooks). -2. Use `detect_changes` for code review. -3. Use `get_affected_flows` to understand impact. -4. Use `query_graph` pattern="tests_for" to check coverage. diff --git a/README.ja.md b/README.ja.md new file mode 100644 index 0000000..6a236dc --- /dev/null +++ b/README.ja.md @@ -0,0 +1,74 @@ +[English](README.md) | 日本語 + +# MAESTRO + +![License](https://img.shields.io/badge/license-Apache--2.0-blue) + +**MAESTRO** — タスクを LLM 駆動で実行するエージェントオーケストレーションプラットフォーム。タスクの種類を LLM が自動判定し、適切なワークフロー(**Piece**)で処理する。ツールはサンドボックス化されたランタイムで実行され、ワークスペース・ファイル・進捗を Web UI で管理できる。 + +OpenAI 互換の LLM エンドポイント([Ollama](https://ollama.com/) / vLLM など)があれば単体で動作する。 + +## 主な機能 + +- **タスク自動ルーティング** — タスク本文を LLM が分類し、最適な Piece(YAML ワークフロー)へ振り分け。 +- **Piece × Movement** — ReAct ループで LLM とツールが対話しながら、段階的にタスクを進める。 +- **豊富なツール群** — ファイル操作(Read/Write/Edit/Bash/Glob/Grep)、Office(PDF/Excel/Docx/PPTX)、Web 取得、ブラウザ操作(Playwright)、画像、SQLite、ナレッジ検索(RAG)、SSH、サブタスク並列実行、MCP 連携、ほか。 +- **Bash サンドボックス** — bwrap によるファイルシステム/ネットワーク/環境変数の隔離(不在時は強化版 whitelist にフォールバック)。Python パッケージはプリベイク。 +- **LLM Gateway(任意)** — 仮想キー・予算・メトリクス付きの LLM プロキシ。複数 GPU/チームでの共有運用に対応。 +- **学習(Reflection)・定期タスク・タスク共有・OAuth 認証(Google/Gitea)** — いずれも任意で有効化。 +- **Web UI** — タスク作成・進捗・成果物プレビュー・設定編集・スキル/Piece 管理。 + +## クイックスタート + +### Docker(最短) + +```bash +cp .env.example .env # OLLAMA_BASE_URL / OLLAMA_MODEL を設定 +docker compose up -d +# http://localhost:9876 を開く +``` + +Compose は安全のため `127.0.0.1:9876` のみに公開する。別ホストからアクセス可能にする前に OAuth 認証を設定し、TLS 対応のリバースプロキシを配置すること。LLM エンドポイントは `.env` / `config.yaml` で指定する。 + +### ソースから + +```bash +git clone https://gitea.example.com/your-org/maestro.git +cd maestro +npm ci && npm --prefix ui ci +cp config.yaml.example config.yaml # provider / workers を編集 +scripts/build-all.sh +scripts/server.sh start # http://localhost:9876 +``` + +詳しい手順は **[docs/getting-started.md](docs/getting-started.md)** を参照。 + +## 必要要件 + +- **Node.js 22+** +- **OpenAI 互換の LLM エンドポイント**(Ollama / vLLM など) +- 任意(Bash サンドボックス用): `bwrap`(bubblewrap, 非特権 user namespace)+ `python3`/`pip` + +## ドキュメント + +- **[docs/getting-started.md](docs/getting-started.md)** — インストール・初回起動・最初のタスク・認証/サンドボックスの有効化 +- **[docs/configuration.md](docs/configuration.md)** — `config.yaml` の全設定項目リファレンス +- **[docs/architecture.md](docs/architecture.md)** — 実行フロー・Piece/Movement・ツール・DB・サンドボックス +- **[docs/tools/](docs/tools/)** — 各ツールの詳細 +- **[docs/operations/bash-sandbox-provisioning.md](docs/operations/bash-sandbox-provisioning.md)** — 本番でのサンドボックス有効化手順 +- **[AGENTS.md](AGENTS.md)** / **[CONTRIBUTING.md](CONTRIBUTING.md)** — コントリビュータ向け +- **[SECURITY.md](SECURITY.md)** — セキュリティ方針・脆弱性報告 + +## セキュリティ + +既定では認証なしで動作するため、信頼できないネットワークへ直接公開しないこと。複数ユーザーまたは外部公開環境では OAuth 認証、`safety.bash_sandbox: always`、TLS リバースプロキシを有効にする。詳細は [SECURITY.md](SECURITY.md) を参照。 + +## サーバー管理 + +```bash +scripts/server.sh start | stop | restart | status | logs +``` + +## ライセンス + +[Apache-2.0](LICENSE)。 diff --git a/README.md b/README.md index d96e67e..eb7a297 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,74 @@ +English | [日本語](README.ja.md) + # MAESTRO ![License](https://img.shields.io/badge/license-Apache--2.0-blue) -**MAESTRO** — タスクを LLM 駆動で実行するエージェントオーケストレーションプラットフォーム。タスクの種類を LLM が自動判定し、適切なワークフロー(**Piece**)で処理する。ツールはサンドボックス化されたランタイムで実行され、ワークスペース・ファイル・進捗を Web UI で管理できる。 +**MAESTRO** — an agent orchestration platform that runs tasks driven by an LLM. The LLM automatically classifies the kind of task and handles it with the appropriate workflow (**Piece**). Tools run in a sandboxed runtime, and you manage workspaces, files, and progress through a web UI. -OpenAI 互換の LLM エンドポイント([Ollama](https://ollama.com/) / vLLM など)があれば単体で動作する。 +It works standalone as long as you have an OpenAI-compatible LLM endpoint ([Ollama](https://ollama.com/) / vLLM, etc.). -## 主な機能 +## Key features -- **タスク自動ルーティング** — タスク本文を LLM が分類し、最適な Piece(YAML ワークフロー)へ振り分け。 -- **Piece × Movement** — ReAct ループで LLM とツールが対話しながら、段階的にタスクを進める。 -- **豊富なツール群** — ファイル操作(Read/Write/Edit/Bash/Glob/Grep)、Office(PDF/Excel/Docx/PPTX)、Web 取得、ブラウザ操作(Playwright)、画像、SQLite、ナレッジ検索(RAG)、SSH、サブタスク並列実行、MCP 連携、ほか。 -- **Bash サンドボックス** — bwrap によるファイルシステム/ネットワーク/環境変数の隔離(不在時は強化版 whitelist にフォールバック)。Python パッケージはプリベイク。 -- **LLM Gateway(任意)** — 仮想キー・予算・メトリクス付きの LLM プロキシ。複数 GPU/チームでの共有運用に対応。 -- **学習(Reflection)・定期タスク・タスク共有・OAuth 認証(Google/Gitea)** — いずれも任意で有効化。 -- **Web UI** — タスク作成・進捗・成果物プレビュー・設定編集・スキル/Piece 管理。 +- **Automatic task routing** — the LLM classifies the task body and dispatches it to the best-fit Piece (a YAML workflow). +- **Piece × Movement** — the LLM and tools converse in a ReAct loop, advancing the task step by step. +- **Rich tool set** — file operations (Read/Write/Edit/Bash/Glob/Grep), Office (PDF/Excel/Docx/PPTX), web fetching, browser automation (Playwright), images, SQLite, knowledge search (RAG), SSH, parallel subtask execution, MCP integration, and more. +- **Bash sandbox** — isolates the filesystem, network, and environment variables via bwrap (falls back to a hardened whitelist when bwrap is absent). Python packages are pre-baked. +- **LLM Gateway (optional)** — an LLM proxy with virtual keys, budgets, and metrics. Supports shared operation across multiple GPUs/teams. +- **Learning (Reflection), scheduled tasks, task sharing, OAuth authentication (Google/Gitea)** — all optional, enabled on demand. +- **Web UI** — task creation, progress, deliverable previews, settings editing, and skill/Piece management. -## クイックスタート +## Quickstart -### Docker(最短) +### Docker (fastest) ```bash -cp .env.example .env # OLLAMA_BASE_URL / OLLAMA_MODEL を設定 +cp .env.example .env # set OLLAMA_BASE_URL / OLLAMA_MODEL docker compose up -d -# http://localhost:9876 を開く +# open http://localhost:9876 ``` -Compose は安全のため `127.0.0.1:9876` のみに公開する。別ホストからアクセス可能にする前に OAuth 認証を設定し、TLS 対応のリバースプロキシを配置すること。LLM エンドポイントは `.env` / `config.yaml` で指定する。 +For safety, Compose exposes only `127.0.0.1:9876`. Before making it reachable from another host, configure OAuth authentication and place a TLS-enabled reverse proxy in front. Specify the LLM endpoint in `.env` / `config.yaml`. -### ソースから +### From source ```bash git clone https://gitea.example.com/your-org/maestro.git cd maestro npm ci && npm --prefix ui ci -cp config.yaml.example config.yaml # provider / workers を編集 +cp config.yaml.example config.yaml # edit provider / workers scripts/build-all.sh scripts/server.sh start # http://localhost:9876 ``` -詳しい手順は **[docs/getting-started.md](docs/getting-started.md)** を参照。 +For detailed instructions, see **[docs/getting-started.md](docs/getting-started.md)**. -## 必要要件 +## Requirements - **Node.js 22+** -- **OpenAI 互換の LLM エンドポイント**(Ollama / vLLM など) -- 任意(Bash サンドボックス用): `bwrap`(bubblewrap, 非特権 user namespace)+ `python3`/`pip` +- **An OpenAI-compatible LLM endpoint** (Ollama / vLLM, etc.) +- Optional (for the Bash sandbox): `bwrap` (bubblewrap, unprivileged user namespaces) + `python3`/`pip` -## ドキュメント +## Documentation -- **[docs/getting-started.md](docs/getting-started.md)** — インストール・初回起動・最初のタスク・認証/サンドボックスの有効化 -- **[docs/configuration.md](docs/configuration.md)** — `config.yaml` の全設定項目リファレンス -- **[docs/architecture.md](docs/architecture.md)** — 実行フロー・Piece/Movement・ツール・DB・サンドボックス -- **[docs/tools/](docs/tools/)** — 各ツールの詳細 -- **[docs/operations/bash-sandbox-provisioning.md](docs/operations/bash-sandbox-provisioning.md)** — 本番でのサンドボックス有効化手順 -- **[AGENTS.md](AGENTS.md)** / **[CONTRIBUTING.md](CONTRIBUTING.md)** — コントリビュータ向け -- **[SECURITY.md](SECURITY.md)** — セキュリティ方針・脆弱性報告 +- **[docs/getting-started.md](docs/getting-started.md)** — installation, first launch, your first task, enabling auth/sandbox +- **[docs/configuration.md](docs/configuration.md)** — full reference of every `config.yaml` setting +- **[docs/architecture.md](docs/architecture.md)** — execution flow, Piece/Movement, tools, DB, sandbox +- **[docs/tools/](docs/tools/)** — details of each tool +- **[docs/operations/bash-sandbox-provisioning.md](docs/operations/bash-sandbox-provisioning.md)** — how to enable the sandbox in production +- **[AGENTS.md](AGENTS.md)** / **[CONTRIBUTING.md](CONTRIBUTING.md)** — for contributors +- **[SECURITY.md](SECURITY.md)** — security policy and vulnerability reporting -## セキュリティ +## Security -既定では認証なしで動作するため、信頼できないネットワークへ直接公開しないこと。複数ユーザーまたは外部公開環境では OAuth 認証、`safety.bash_sandbox: always`、TLS リバースプロキシを有効にする。詳細は [SECURITY.md](SECURITY.md) を参照。 +By default it runs without authentication, so do not expose it directly to an untrusted network. For multi-user or externally exposed environments, enable OAuth authentication, `safety.bash_sandbox: always`, and a TLS reverse proxy. See [SECURITY.md](SECURITY.md) for details. -## サーバー管理 +## Server management ```bash scripts/server.sh start | stop | restart | status | logs ``` -## ライセンス +## License -[Apache-2.0](LICENSE)。 +[Apache-2.0](LICENSE). diff --git a/config.yaml.example b/config.yaml.example index 1bd61f2..a5bad8a 100644 --- a/config.yaml.example +++ b/config.yaml.example @@ -310,9 +310,12 @@ tools: # ─── 認証 (オプション) ──────────────────────────────────────── # 未設定なら認証なしで動作 (従来互換)。 # auth: -# session_secret: "ランダムな文字列を設定してください" +# # 空のままだと起動時にプロセスごとのランダム値で代替する (再起動でセッション失効)。 +# # 本番では `openssl rand -hex 32` 等で固定値を生成して設定すること。 +# # ⚠ プレースホルダ文字列をそのまま使わない (公開された secret は偽造・改ざんに使われる)。 +# session_secret: "" # session_max_age: 86400000 # 24h (ms) -# secure_cookie: false # HTTPS 環境では true +# secure_cookie: false # HTTPS 環境では true (TLS 終端の背後では必須) # admin_emails: # - "admin@example.com" # # primary_provider: gitea # 'google' | 'gitea' | 'local'。複数有効時に明示 diff --git a/docs/README.en.draft.md b/docs/README.en.draft.md new file mode 100644 index 0000000..0138b6f --- /dev/null +++ b/docs/README.en.draft.md @@ -0,0 +1,96 @@ + + +# MAESTRO + +[English](README.md) | [日本語](README.ja.md) + + +![License](https://img.shields.io/badge/license-Apache--2.0-blue) +![Node](https://img.shields.io/badge/node-22%2B-brightgreen) + +**MAESTRO** is an agent orchestration platform that runs tasks with LLMs. An LLM +classifies each task and routes it to the right workflow (a **Piece**); tools run +in a sandboxed runtime, and you manage workspaces, files, and progress from a web +UI. It works standalone against any OpenAI-compatible LLM endpoint +([Ollama](https://ollama.com/), vLLM, …). + + + +## Features + +- **Automatic task routing** — an LLM classifies the request and dispatches it to + the best Piece (a YAML workflow). +- **Pieces × Movements** — a ReAct loop where the LLM and tools collaborate to + advance the task step by step. +- **Rich tool set** — files (Read/Write/Edit/Bash/Glob/Grep), Office + (PDF/Excel/Docx/PPTX), web fetch, browser automation (Playwright), images, + SQLite, knowledge search (RAG), SSH, parallel sub-tasks, MCP integration, more. +- **Bash sandbox** — bwrap-based filesystem/network/env isolation, with a hardened + whitelist fallback; Python packages are pre-baked. +- **Optional LLM Gateway** — a proxy with virtual keys, budgets, and metrics for + shared multi-GPU / multi-team use. +- **Reflection learning, scheduled tasks, task sharing, OAuth (Google/Gitea)** — + all opt-in. +- **Web UI** — create tasks, watch progress, preview artifacts, edit settings, + manage skills and Pieces. + +## Quickstart + +### Docker (fastest) + +```bash +cp .env.example .env # set OLLAMA_BASE_URL / OLLAMA_MODEL +docker compose up -d +# open http://localhost:9876 +``` + +Compose binds to `127.0.0.1:9876` only. Before exposing it to other hosts, +configure OAuth and put it behind a TLS reverse proxy. + +> Linux note: `host.docker.internal` may not resolve by default. Use your host's +> gateway IP, add `extra_hosts: ["host.docker.internal:host-gateway"]` to +> compose, or point at the LAN IP of the machine running Ollama. + +### From source + +```bash +git clone maestro +cd maestro +npm ci && npm --prefix ui ci +npm run setup # interactive: configure the LLM endpoint +scripts/build-all.sh +scripts/server.sh start # http://localhost:9876 +``` + +See **[docs/getting-started.md](docs/getting-started.md)** for the full walkthrough. + +## Requirements + +- **Node.js 22+** +- **An OpenAI-compatible LLM endpoint** (Ollama / vLLM / …). MAESTRO does not run + the model itself. +- Optional (Bash sandbox): `bwrap` (bubblewrap, unprivileged user namespaces) plus + `python3`/`pip`. + +## Documentation + +- **[docs/getting-started.md](docs/getting-started.md)** — install, first run, first task, auth/sandbox. +- **[docs/configuration.md](docs/configuration.md)** — full `config.yaml` reference. +- **[docs/architecture.md](docs/architecture.md)** — execution flow, Pieces/Movements, tools, DB, sandbox. +- **[docs/docker.md](docs/docker.md)** — Docker deployment (TODO: add). +- **[AGENTS.md](AGENTS.md)** / **[CONTRIBUTING.md](CONTRIBUTING.md)** — for contributors. +- **[SECURITY.md](SECURITY.md)** — security policy and reporting. + +## Security + +MAESTRO runs without auth by default — do not expose it directly to untrusted +networks. For multi-user or public deployments, enable OAuth, +`safety.bash_sandbox: always`, and a TLS reverse proxy. See [SECURITY.md](SECURITY.md). + +## License + +[Apache-2.0](LICENSE). diff --git a/docs/SECURITY.draft.md b/docs/SECURITY.draft.md new file mode 100644 index 0000000..41522bf --- /dev/null +++ b/docs/SECURITY.draft.md @@ -0,0 +1,24 @@ + + +# Security Policy (DRAFT stub — see oss/overlay/SECURITY.md) + +The authoritative security policy is **[oss/overlay/SECURITY.md](../oss/overlay/SECURITY.md)**, +which ships publicly as `SECURITY.md`. It covers: + +- Supported versions (latest release + `main`). +- Private vulnerability reporting (no public issues for undisclosed vulns; + use the host's private reporting feature or contact the owner; 7-day ack). +- Deployment baseline (localhost until OAuth, TLS reverse proxy, + `safety.bash_sandbox: always`, secret hygiene, `/metrics` restriction, + tool/integration review). + +No separate top-level `SECURITY.md` is needed. Delete this draft after confirming +the overlay policy. diff --git a/docs/architecture.ja.md b/docs/architecture.ja.md new file mode 100644 index 0000000..9da2581 --- /dev/null +++ b/docs/architecture.ja.md @@ -0,0 +1,87 @@ +[English](architecture.md) | 日本語 + +# Architecture Overview + +MAESTRO は、ユーザーが投げたタスクを LLM 駆動のワークフロー(Piece)で実行する +エージェントオーケストレーターである。コントリビュータ向けのコードマップは +[../AGENTS.md](../AGENTS.md) も参照。 + +## 実行フロー + +``` +UI (POST /api/local/tasks) + → bridge/server.ts (Express API) + → Repository (SQLite: jobs テーブルに enqueue) + → Worker.poll() が queued ジョブを取得 + → piece-classifier.ts: LLM がタスクを分類し Piece を選択 + → piece-runner.ts: pieces/*.yaml を読み、movements を順に実行 + → agent-loop.ts: 1 movement の ReAct ループ (LLM ↔ tool calls) + ├─ 中間遷移: transition ツール + └─ 終了: complete ツール (success / aborted / needs_user_input) + → ジョブ完了: DB 更新 + 進捗コメント。成果物は workspace/output/ +``` + +1. **API 受付** — `bridge/server.ts` がタスクを受け、`Repository` 経由で `jobs` テーブルに `queued` で登録する。 +2. **ワーカー** — `worker.ts` が DB をポーリングし、自分の `profiles`/`task_classes` に合致するジョブを取得(複数ワーカーが並走)。 +3. **分類** — `piece-classifier.ts` がタスク本文と全 Piece の description を LLM に渡し、最適な Piece を選ぶ。 +4. **Piece 実行** — `piece-runner.ts` が Piece の movements を順に回す。verify movement のフィードバックは次の execute に引き継がれ、`transition.lessons` で movement 間の教訓が蓄積される。 +5. **ReAct ループ** — `agent-loop.ts` が 1 movement 内で LLM とツールを往復させる。`ContextManager` が LLM の `usage` からトークン使用量を追跡し、閾値(70/85/95%)で warn / prompt / force_transition を発火する。 + +## Piece と Movement + +- **Piece** = `pieces/*.yaml`。`movements` 配列で構成。 +- 各 **Movement** は `allowed_tools`(LLM に提示するツール)、`edit`(Write/Edit 可否)、`rules`(遷移条件)を持つ。`allowed_tools` 外のツールは LLM から見えない。 +- **遷移**: 中間ホップは `transition`(`rules[].next` に列挙した宛先のみ選択可)、終了は `complete`。`complete.result` がユーザーに見える唯一の最終出力。 +- **`default_next`** はエンジン内部の sentinel(コンテキスト溢れ時の強制遷移、ASK 上限時のフォールバック)。 +- **Progressive pressure**: 同一 movement への連続訪問が増えると警告を注入し、閾値超過で ABORT。 + +## ツールランタイム + +ツールは `src/engine/tools/*.ts` のモジュール群。`tools/index.ts` が動的にロードし dispatch する。各ツールは 1 行の description(毎 LLM 呼び出しに乗るため簡潔に)を持ち、詳細手順は `docs/tools/.md`(`ReadToolDoc` で取得)に置く。主なモジュールは [../AGENTS.md](../AGENTS.md#tool-modules) の一覧を参照。 + +Read 系ツールは並列実行される。Write/Edit は movement の `edit: true` のときのみ提示され、書き込みは主に `workspace/output/` に限られる。 + +## Bash サンドボックス + +エージェントの Bash 実行は、利用可能なら **bwrap サンドボックス**で隔離する: + +- **ファイルシステム**: タスクの workspace のみ rw bind、`/usr` 等は ro、他タスクの workspace やホスト `/home` は不可視。 +- **環境変数**: `--clearenv` + 最小 allowlist のみ注入(シークレット env はサンドボックス内から見えない)。 +- **ネットワーク**: `--unshare-net` で遮断(外向き通信は SSRF ガード付きの WebFetch/MCP に集約)。 +- **各 Bash コールは独立**したサンドボックス(揮発 `/tmp`・毎回新名前空間)。永続するのは workspace のみ。 + +`safety.bash_sandbox` でモードを選ぶ(`auto`/`always`/`off`)。bwrap 不在時は **hardened フォールバック**(コマンド許可リスト + パススコープ検査 + env スクラブ付き exec)になる。実行時 `pip`/`npm install` は全モードで拒否され、Python パッケージは `runtime/python-requirements.txt` からプリベイクされる。詳細は [operations/bash-sandbox-provisioning.md](operations/bash-sandbox-provisioning.md)。 + +## ワークスペース構造(ジョブ実行時) + +``` +{worktree_dir}/local/{taskId}/ + input/ アップロード・DownloadFile の保存先 + output/ 成果物(Write/Edit が許可される主な場所) + logs/ activity.log / 各種履歴 + subtasks/ SpawnSubTask の結果 + skills/ ReadSkill で materialize されたスキルファイル +``` + +## データベース + +SQLite(better-sqlite3)。`db/schema.sql` が初期スキーマ。追加カラムは `db/migrate.ts` で +`PRAGMA table_info` → 存在チェック → `ALTER TABLE ADD COLUMN` のパターンで冪等に適用する +(バージョン管理テーブルは使わない)。主なテーブル: `jobs` / `local_tasks` / +`local_task_comments` / `audit_log` ほか。 + +## ジョブのライフサイクル + +`queued` → `dispatching` → `running` → `succeeded` / `failed` / `waiting_human`(ASK 回答待ち)/ `waiting_subtasks`(並列サブタスク待ち)。失敗時は `retry` で再 `queued`(最大 `retry.max_attempts` 回)。 + +## オプションのサブシステム + +- **LLM Gateway**(`src/gateway/`) — MAESTRO 自身を OpenAI 互換 LLM プロキシとして公開(仮想キー・予算・Prometheus メトリクス)。複数 GPU/チーム共有向け。env/接続種別が `AAO_*`/`aao_gateway` の歴史的接頭辞を使う。 +- **MCP** — Model Context Protocol サーバー連携(`MCP_ENCRYPTION_KEY` 必須)。 +- **Reflection** — ジョブ完了ごとにユーザーメモリを LLM が自動更新(既定 OFF、revert 可)。 +- **認証** — Passport による Google/Gitea OAuth(任意)。`private`/`org`/`public` の可視性モデル。 +- **スケジューラ** — cron 式の定期タスク。 + +## フロントエンド + +React + Vite + TailwindCSS + @tanstack/react-query。`ui/src/App.tsx` がルート。2 カラム(list + detail)レイアウトで、タスク一覧・スケジュール・設定・スキル/Piece 管理を扱う。 diff --git a/docs/architecture.md b/docs/architecture.md index 69b2916..4877451 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,85 +1,86 @@ +English | [日本語](architecture.ja.md) + # Architecture Overview -MAESTRO は、ユーザーが投げたタスクを LLM 駆動のワークフロー(Piece)で実行する -エージェントオーケストレーターである。コントリビュータ向けのコードマップは -[../AGENTS.md](../AGENTS.md) も参照。 +MAESTRO is an agent orchestrator that runs the tasks a user submits with LLM-driven workflows (Pieces). +For a code map aimed at contributors, see also [../AGENTS.md](../AGENTS.md). -## 実行フロー +## Execution flow ``` UI (POST /api/local/tasks) → bridge/server.ts (Express API) - → Repository (SQLite: jobs テーブルに enqueue) - → Worker.poll() が queued ジョブを取得 - → piece-classifier.ts: LLM がタスクを分類し Piece を選択 - → piece-runner.ts: pieces/*.yaml を読み、movements を順に実行 - → agent-loop.ts: 1 movement の ReAct ループ (LLM ↔ tool calls) - ├─ 中間遷移: transition ツール - └─ 終了: complete ツール (success / aborted / needs_user_input) - → ジョブ完了: DB 更新 + 進捗コメント。成果物は workspace/output/ + → Repository (SQLite: enqueue into the jobs table) + → Worker.poll() picks up queued jobs + → piece-classifier.ts: the LLM classifies the task and selects a Piece + → piece-runner.ts: reads pieces/*.yaml and runs the movements in order + → agent-loop.ts: the ReAct loop for one movement (LLM ↔ tool calls) + ├─ intermediate transition: the transition tool + └─ termination: the complete tool (success / aborted / needs_user_input) + → job complete: update DB + post a progress comment. Deliverables go to workspace/output/ ``` -1. **API 受付** — `bridge/server.ts` がタスクを受け、`Repository` 経由で `jobs` テーブルに `queued` で登録する。 -2. **ワーカー** — `worker.ts` が DB をポーリングし、自分の `profiles`/`task_classes` に合致するジョブを取得(複数ワーカーが並走)。 -3. **分類** — `piece-classifier.ts` がタスク本文と全 Piece の description を LLM に渡し、最適な Piece を選ぶ。 -4. **Piece 実行** — `piece-runner.ts` が Piece の movements を順に回す。verify movement のフィードバックは次の execute に引き継がれ、`transition.lessons` で movement 間の教訓が蓄積される。 -5. **ReAct ループ** — `agent-loop.ts` が 1 movement 内で LLM とツールを往復させる。`ContextManager` が LLM の `usage` からトークン使用量を追跡し、閾値(70/85/95%)で warn / prompt / force_transition を発火する。 +1. **API intake** — `bridge/server.ts` receives the task and registers it in the `jobs` table as `queued` via the `Repository`. +2. **Worker** — `worker.ts` polls the DB and picks up jobs matching its `profiles`/`task_classes` (multiple workers run in parallel). +3. **Classification** — `piece-classifier.ts` passes the task body and the descriptions of all Pieces to the LLM and chooses the best-fit Piece. +4. **Piece execution** — `piece-runner.ts` iterates through the Piece's movements in order. Feedback from a verify movement is carried over to the next execute, and lessons between movements accumulate via `transition.lessons`. +5. **ReAct loop** — `agent-loop.ts` shuttles between the LLM and tools within one movement. `ContextManager` tracks token usage from the LLM's `usage` and fires warn / prompt / force_transition at thresholds (70/85/95%). -## Piece と Movement +## Piece and Movement -- **Piece** = `pieces/*.yaml`。`movements` 配列で構成。 -- 各 **Movement** は `allowed_tools`(LLM に提示するツール)、`edit`(Write/Edit 可否)、`rules`(遷移条件)を持つ。`allowed_tools` 外のツールは LLM から見えない。 -- **遷移**: 中間ホップは `transition`(`rules[].next` に列挙した宛先のみ選択可)、終了は `complete`。`complete.result` がユーザーに見える唯一の最終出力。 -- **`default_next`** はエンジン内部の sentinel(コンテキスト溢れ時の強制遷移、ASK 上限時のフォールバック)。 -- **Progressive pressure**: 同一 movement への連続訪問が増えると警告を注入し、閾値超過で ABORT。 +- **Piece** = `pieces/*.yaml`. Composed of a `movements` array. +- Each **Movement** has `allowed_tools` (the tools presented to the LLM), `edit` (whether Write/Edit is allowed), and `rules` (transition conditions). Tools outside `allowed_tools` are invisible to the LLM. +- **Transitions**: an intermediate hop uses `transition` (only the destinations listed in `rules[].next` are selectable); termination uses `complete`. `complete.result` is the only final output visible to the user. +- **`default_next`** is an engine-internal sentinel (forced transition on context overflow, fallback at the ASK limit). +- **Progressive pressure**: as consecutive revisits to the same movement increase, warnings are injected, and exceeding the threshold triggers ABORT. -## ツールランタイム +## Tool runtime -ツールは `src/engine/tools/*.ts` のモジュール群。`tools/index.ts` が動的にロードし dispatch する。各ツールは 1 行の description(毎 LLM 呼び出しに乗るため簡潔に)を持ち、詳細手順は `docs/tools/.md`(`ReadToolDoc` で取得)に置く。主なモジュールは [../AGENTS.md](../AGENTS.md#tool-modules) の一覧を参照。 +Tools are a set of modules in `src/engine/tools/*.ts`. `tools/index.ts` loads and dispatches them dynamically. Each tool has a one-line description (kept concise because it rides on every LLM call), and detailed instructions live in `docs/tools/.md` (fetched with `ReadToolDoc`). For the main modules, see the list in [../AGENTS.md](../AGENTS.md#tool-modules). -Read 系ツールは並列実行される。Write/Edit は movement の `edit: true` のときのみ提示され、書き込みは主に `workspace/output/` に限られる。 +Read-type tools run in parallel. Write/Edit is only presented when the movement has `edit: true`, and writes are mostly limited to `workspace/output/`. -## Bash サンドボックス +## Bash sandbox -エージェントの Bash 実行は、利用可能なら **bwrap サンドボックス**で隔離する: +The agent's Bash execution is isolated with the **bwrap sandbox** when available: -- **ファイルシステム**: タスクの workspace のみ rw bind、`/usr` 等は ro、他タスクの workspace やホスト `/home` は不可視。 -- **環境変数**: `--clearenv` + 最小 allowlist のみ注入(シークレット env はサンドボックス内から見えない)。 -- **ネットワーク**: `--unshare-net` で遮断(外向き通信は SSRF ガード付きの WebFetch/MCP に集約)。 -- **各 Bash コールは独立**したサンドボックス(揮発 `/tmp`・毎回新名前空間)。永続するのは workspace のみ。 +- **Filesystem**: only the task's workspace is rw-bound, `/usr` etc. are ro, and other tasks' workspaces and the host `/home` are invisible. +- **Environment variables**: `--clearenv` + injecting only a minimal allowlist (secret env vars are invisible from inside the sandbox). +- **Network**: blocked with `--unshare-net` (outbound communication is consolidated into WebFetch/MCP with SSRF guards). +- **Each Bash call** gets an independent sandbox (volatile `/tmp`, a fresh namespace each time). Only the workspace persists. -`safety.bash_sandbox` でモードを選ぶ(`auto`/`always`/`off`)。bwrap 不在時は **hardened フォールバック**(コマンド許可リスト + パススコープ検査 + env スクラブ付き exec)になる。実行時 `pip`/`npm install` は全モードで拒否され、Python パッケージは `runtime/python-requirements.txt` からプリベイクされる。詳細は [operations/bash-sandbox-provisioning.md](operations/bash-sandbox-provisioning.md)。 +`safety.bash_sandbox` selects the mode (`auto`/`always`/`off`). When bwrap is absent, it falls back to a **hardened fallback** (an exec with a command allowlist + path-scope checks + env scrubbing). Runtime `pip`/`npm install` are rejected in all modes, and Python packages are pre-baked from `runtime/python-requirements.txt`. For details, see [operations/bash-sandbox-provisioning.md](operations/bash-sandbox-provisioning.md). -## ワークスペース構造(ジョブ実行時) +## Workspace structure (during job execution) ``` {worktree_dir}/local/{taskId}/ - input/ アップロード・DownloadFile の保存先 - output/ 成果物(Write/Edit が許可される主な場所) - logs/ activity.log / 各種履歴 - subtasks/ SpawnSubTask の結果 - skills/ ReadSkill で materialize されたスキルファイル + input/ where uploads and DownloadFile saves go + output/ deliverables (the main place where Write/Edit is allowed) + logs/ activity.log / various histories + subtasks/ results from SpawnSubTask + skills/ skill files materialized by ReadSkill ``` -## データベース +## Database -SQLite(better-sqlite3)。`db/schema.sql` が初期スキーマ。追加カラムは `db/migrate.ts` で -`PRAGMA table_info` → 存在チェック → `ALTER TABLE ADD COLUMN` のパターンで冪等に適用する -(バージョン管理テーブルは使わない)。主なテーブル: `jobs` / `local_tasks` / -`local_task_comments` / `audit_log` ほか。 +SQLite (better-sqlite3). `db/schema.sql` is the initial schema. Additional columns are applied idempotently in `db/migrate.ts` +with the pattern `PRAGMA table_info` → existence check → `ALTER TABLE ADD COLUMN` +(no version-management table is used). Main tables: `jobs` / `local_tasks` / +`local_task_comments` / `audit_log`, and others. -## ジョブのライフサイクル +## Job lifecycle -`queued` → `dispatching` → `running` → `succeeded` / `failed` / `waiting_human`(ASK 回答待ち)/ `waiting_subtasks`(並列サブタスク待ち)。失敗時は `retry` で再 `queued`(最大 `retry.max_attempts` 回)。 +`queued` → `dispatching` → `running` → `succeeded` / `failed` / `waiting_human` (waiting for an ASK answer) / `waiting_subtasks` (waiting for parallel subtasks). On failure, `retry` re-queues it (up to `retry.max_attempts` times). -## オプションのサブシステム +## Optional subsystems -- **LLM Gateway**(`src/gateway/`) — MAESTRO 自身を OpenAI 互換 LLM プロキシとして公開(仮想キー・予算・Prometheus メトリクス)。複数 GPU/チーム共有向け。env/接続種別が `AAO_*`/`aao_gateway` の歴史的接頭辞を使う。 -- **MCP** — Model Context Protocol サーバー連携(`MCP_ENCRYPTION_KEY` 必須)。 -- **Reflection** — ジョブ完了ごとにユーザーメモリを LLM が自動更新(既定 OFF、revert 可)。 -- **認証** — Passport による Google/Gitea OAuth(任意)。`private`/`org`/`public` の可視性モデル。 -- **スケジューラ** — cron 式の定期タスク。 +- **LLM Gateway** (`src/gateway/`) — exposes MAESTRO itself as an OpenAI-compatible LLM proxy (virtual keys, budgets, Prometheus metrics). For sharing across multiple GPUs/teams. Its env vars and connection type use the historical `AAO_*`/`aao_gateway` prefixes. +- **MCP** — Model Context Protocol server integration (`MCP_ENCRYPTION_KEY` required). +- **Reflection** — the LLM automatically updates user memory after each job completes (OFF by default, revertible). +- **Authentication** — Google/Gitea OAuth via Passport (optional). A `private`/`org`/`public` visibility model. +- **Scheduler** — cron-expression scheduled tasks. -## フロントエンド +## Frontend -React + Vite + TailwindCSS + @tanstack/react-query。`ui/src/App.tsx` がルート。2 カラム(list + detail)レイアウトで、タスク一覧・スケジュール・設定・スキル/Piece 管理を扱う。 +React + Vite + TailwindCSS + @tanstack/react-query. `ui/src/App.tsx` is the root. A two-column (list + detail) layout handles the task list, schedule, settings, and skill/Piece management. diff --git a/docs/configuration.ja.md b/docs/configuration.ja.md new file mode 100644 index 0000000..cec8771 --- /dev/null +++ b/docs/configuration.ja.md @@ -0,0 +1,231 @@ +[English](configuration.md) | 日本語 + +# Configuration Reference + +MAESTRO は単一の `config.yaml`(`config.yaml.example` をコピーして作成)で設定する。 + +- **YAML キーは snake_case**(`max_concurrency`)、コード内は camelCase。`src/config.ts` の `transformKeys` が変換する。 +- 一部は**環境変数で上書き**できる([末尾参照](#environment-variable-overrides))。 +- `config_version: 2` が現行スキーマ。 + +> 値の一次ソースは `config.yaml.example`(コメント付き)と `src/config.ts`。本リファレンスは各項目の意味をまとめたもの。 + +--- + +## `llm` — ジョブ実行時の LLM 接続 + +| キー | 既定 | 意味 | +|------|------|------| +| `timeout_minutes` | 10 | 1 リクエスト全体の上限(分)。 | +| `retry.max_attempts` | 3 | 429/5xx/一時接続失敗時の再試行回数。 | +| `retry.backoff_ms` | [2000,5000,15000] | 各再試行の待機(ms)。 | +| `retry.retryable_status` | [429,500,502,503,504] | 再試行対象の HTTP ステータス。 | + +### `llm.workers[]` — ジョブ実行に使う接続先(必須) + +| キー | 意味 | +|------|------| +| `id` | ワーカー識別子。 | +| `connection_type` | `direct`(Ollama/vLLM 等の OpenAI 互換 backend に直結)/ `aao_gateway`(別 Gateway 経由、Gateway Key 必須)。 | +| `endpoint` | OpenAI 互換 API のベース URL(例 `http://localhost:11434/v1`)。 | +| `model` | 使用モデル名(ワーカーごとに明示。`default_model` は廃止)。 | +| `api_key` | `aao_gateway` 時の virtual key 等(任意)。 | +| `roles` | 用途フィルタ: `auto`/`fast`/`quality`/`title`/`reflection` 等。`[title]` のみ=タイトル生成専用。 | +| `max_concurrency` | このワーカーの並列度。 | +| `vlm` | `true` で画像入力対応(ReadImage は VLM ワーカーを優先)。 | +| `enabled` | 有効/無効。 | + +### `llm.metrics` — Prometheus exporter(worker 側) + +| キー | 既定 | 意味 | +|------|------|------| +| `enabled` | true | `/metrics`(bridge HTTP, 既定 `PORT=9876`)に mount。 | +| `prefix` | `aao_worker` | メトリクス名 prefix。 | +| `bearer_token` | — | 設定すると Bearer 認証必須(`env:NAME` 形式可)。 | +| `allowed_hosts` | localhost のみ | 許可元 IP。本番は bearer か allowlist を必ず設定。 | + +--- + +## `gateway` — LLM Gateway サーバー(任意) + +MAESTRO 自身を OpenAI 互換の LLM Gateway として公開する(仮想キー・予算・メトリクス付き、複数 GPU/チーム共有向け)。**env 変数や接続種別が `AAO_*` / `aao_gateway` という歴史的な接頭辞を使う点に注意(AAO = この Gateway 機能の旧称)。** 詳細は [aao-gateway-overview.md](aao-gateway-overview.md)。 + +| キー | 既定 | 意味 | +|------|------|------| +| `enabled` | false | true で同 process gateway が起動(hot reload 対応)。 | +| `listen_port` | 4000 | separate-deploy 時のみ。 | +| `request_timeout_sec` | 600 | 1 リクエスト全体(streaming 込み)。 | +| `upstream_timeout_sec` | 30 | 各 upstream の TTFB 上限。 | +| `shutdown_graceful_sec` | 30 | SIGTERM 後の SSE drain 上限。 | +| `backends[]` | — | `id`/`endpoint`/`model`/`max_slots`/`api_key`。model 厳密一致で routing。 | +| `virtual_keys[]` | — | bootstrap/backup 用(`key`/`team`/`allowed_models`/`tokens_budget`/`rate_limit_rpm`)。新規発行は admin API 推奨。 | +| `metrics` | enabled | `prefix: aao_gateway`、team/key_prefix/backend ラベル。auth 必須運用。 | + +Virtual Key の発行・rotation は admin REST API(`POST /api/admin/gateway/keys`)または UI(Settings → LLM → Gateway Server)で行う。 + +--- + +## `storage` — パス・容量 + +| キー | 既定 | 意味 | +|------|------|------| +| `worktree_dir` | ./data/workspaces | ジョブ作業ディレクトリのベース。 | +| `custom_pieces_dir` | — | リポジトリ内 `pieces/` に加えて読む Piece dir(任意)。 | +| `user_folder_root` | ./data/users | `{root}/{userId}/` に AGENTS.md/scripts/notes 等を保存。 | +| `task_upload_max_size_mb` | 50 | タスク/コメント body 上限(base64 込み。範囲 1–1000)。 | +| `trash_retention_days` | 30 | `trash/` の自動 sweep。0 で都度全削除。 | + +--- + +## Execution — 並列度・上限・再試行 + +| キー | 既定 | 意味 | +|------|------|------| +| `concurrency` | 4 | 全ワーカー合算の最大並列ジョブ数(env `CONCURRENCY`)。 | +| `max_movements` | 200 | 1 ジョブ内の最大 movement 数(loop 防止)。 | +| `retry.max_attempts` | 3 | ジョブ失敗時の最大再試行。 | +| `retry.backoff_seconds` | [60,300,900] | 各 attempt 間の待機秒。 | +| `ask.max_per_job` | 2 | 1 ジョブの ASK(ユーザー質問)上限。 | +| `subtasks.max_depth` | 2 | SpawnSubTask のネスト最大深度。 | +| `subtasks.max_per_parent` | 10 | 1 ジョブが生成できるサブタスク最大数。 | + +--- + +## `context` — LLM コンテキスト管理 + +| キー | 既定 | 意味 | +|------|------|------| +| `limit_tokens` | 自動取得→128000 | コンテキスト上限。省略時はプロバイダ API から自動取得。 | +| `thresholds[]` | 0.7=warn / 0.85=prompt / 0.95=force_transition | 使用率閾値ごとの動作。 | + +--- + +## `safety` — 暴走防止・Bash サンドボックス + +| キー | 既定 | 意味 | +|------|------|------| +| `max_iterations` | 200 | 1 movement 内の最大イテレーション。 | +| `max_revisits` | 3 | 同一 movement の最大再訪問。超過で ABORT。 | +| `prompt_guard_ratio` | 0.8 | プロンプトがコンテキスト上限の何%まで許容するか(0.5–0.95)。 | +| `history_summarization.enabled` | true | 古い turn を構造化要約に置換して粘る。 | +| `history_summarization.tail_turns` | 2 | 末尾何 turn を保護するか。 | +| `history_summarization.preserve_recent_budget` | 8000 | 末尾保護の最大トークン。 | +| `bash_unrestricted` | false | true で Bash のコマンド許可リストを撤廃(**サンドボックス機構は別途 `bash_sandbox` が制御**)。 | +| `bash_sandbox` | auto | Bash 隔離機構: `auto`(bwrap あれば使用、無ければ hardened-whitelist)/ `always`(bwrap 強制・不在なら起動失敗、本番推奨)/ `off`(bwrap 不使用、env スクラブは維持)。詳細 [operations/bash-sandbox-provisioning.md](operations/bash-sandbox-provisioning.md)。 | + +--- + +## `search_filter` — WebSearch の機密情報漏洩防止 + +| キー | 既定 | 意味 | +|------|------|------| +| `blocked_patterns[]` | — | 完全一致で検索クエリから除去するパターン。 | +| `auto_block.private_ip` | true | 10/172.16-31/192.168/127.* を自動ブロック。 | +| `auto_block.internal_domain` | true | `.local`/`.internal`/`.lan`/`.intranet`/`.corp`/`.home`。 | +| `auto_block.email` / `phone` | true | メール/電話番号。 | + +--- + +## `browser` — BrowseWeb ランタイム + +| キー | 既定 | 意味 | +|------|------|------| +| `page_timeout` | 60000 | ページ遷移 timeout(ms)。 | +| `action_timeout` | 30000 | アクション timeout(ms)。 | +| `captcha_solve` | skip | `skip` / `novnc`(人手 CAPTCHA 解決)。 | +| `max_captcha_pages` | 5 | CAPTCHA ページ上限。 | +| `channel` | chromium | `chromium`/`chrome`/`msedge`。 | +| `executable_path` | — | ブラウザ実行ファイル(channel と排他)。 | + +--- + +## `tools` — ツール設定 + +UI 上は Web & Search / Browser / Media & Documents / External Services / Legacy Knowledge に分かれるが YAML は `tools` 1 ブロック。主な項目: + +**Web & Search**: `searxng_url`(WebSearch フォールバック先), `webfetch_timeout`(sec), `websearch_timeout`, `webfetch_allowed_hosts[]`(SSRF 例外: private IP/.local を許可する場合)。 + +**Media & Documents**: `vision_model`/`vision_base_url`/`vision_timeout`/`vision_max_tokens`(ReadImage 用 VLM), `ocr_model`, `office_{excel,docx,pdf}_max_size_mb`(既定 10), `office_pptx_max_size_mb`(50), `office_pptx_max_uncompressed_mb`(200, zip-bomb 検知), `speech_server_url`/`speech_timeout`/`speech_language`。 + +**External Services**: `x_*`(Twitter/X CLI 連携: `x_cli_command`/`x_auth_token`/`x_ct0`/`x_proxy`/`x_download_*` 等), `google_maps_api_key`/`maps_timeout`(未設定で Nominatim/OSRM), `amazon_affiliate_tag`/`keepa_api_key`。 + +**User scripts**: `user_scripts_enabled`(RunUserScript。plain runtime は Node `--permission` で sandbox 化), `user_scripts_allow_userids[]`。 + +**Legacy Knowledge**: `knowledge_service_url`(未設定で knowledge ツール無効), `knowledge_namespaces`(namespace ごとの api_key)。新規 namespace は MCP 経由を推奨。 + +--- + +## `notes` — Shared Knowledge Notes 注入 + +`data/users/{userId}/notes/` のノートをシステムプロンプトに注入。`inject.per_note_max_kb`(日本語は 4 推奨), `inject.total_max_kb`, `inject.over_budget_strategy`(`truncate_last`/`skip_remaining`/`degrade_to_search`)。 + +--- + +## `auth` — 認証(任意) + +未設定なら認証なしで動作。 + +| キー | 意味 | +|------|------| +| `session_secret` | セッション署名鍵(ランダム文字列)。 | +| `session_max_age` | セッション有効期間(ms, 既定 86400000=24h)。 | +| `secure_cookie` | HTTPS 環境では true。 | +| `admin_emails[]` | admin ロールにするメール。 | +| `primary_provider` | `google` / `gitea`(両方有効時に明示)。 | +| `providers.google` | `client_id`/`client_secret`/`callback_url`。 | +| `providers.gitea` | `client_id`/`client_secret`/`base_url`/`callback_url`。ログイン時に Gitea org を取得し可視性に利用。 | + +--- + +## `branding`(任意) + +`app_name`/`primary_color`/`login_page_title`/`logo_url`/`favicon_url`/`footer_text`。Settings → System → Branding(admin)で GUI 編集可。`config.yaml`・`data/branding/` は gitignore 済み。 + +--- + +## `secrets` + +`master_key_path`(既定 `./data/secrets/master.key`, 32 byte, 初回起動で自動生成・mode 0600)。SSH 鍵・MCP トークン等の暗号化に使う。 + +--- + +## `reflection` — 学習(既定 OFF) + +ON で毎ジョブ完了後にユーザーメモリを LLM が自動更新(snapshot は revert 可)。`enabled`, `max_memory_changes_per_job`(3), `piece_edit_cooldown_hours`(24), `snapshot_retention_days`(90), `per_user_daily_budget_tokens`(200000)。 + +--- + +## `mcp` — Model Context Protocol + +サーバーは admin UI(global)/各ユーザー(self-hosted)で管理。**`MCP_ENCRYPTION_KEY` env(64 hex)が必須。** `call_timeout_seconds`(60), `max_binary_size_mb`(20), `max_output_files_per_job`(10), `max_output_size_mb_per_job`(200), `tool_cache_ttl_seconds`(600), `oauth_pending_ttl_minutes`(10), `allow_private_addresses`(private 網の MCP server 用、既定 false)。 + +--- + +## `ssh` — SSH ツール(既定 OFF) + +`enabled`, `allow_private_addresses`(global 既定、admin は per-connection grant 可), `call_timeout_seconds`(30), `max_output_bytes`(32768), `max_{upload,download}_size_mb`(100), `audit_retention_days`(90), `admin_bypasses_grants`(true), abuse 検知(`abuse_window_minutes`/`abuse_failure_threshold`/`abuse_lock_minutes`)。 + +**Interactive Console**(`ssh.console`): `enabled`, `idle_timeout_seconds`(1800), `max_session_duration_seconds`(14400), `scrollback_bytes`(524288), `max_sessions_per_connection`(3) ほか。手順は [ssh.md](ssh.md)。 + +--- + +## `notifications.push` — Web Push(V2, 任意) + +HTTPS ホスティング必須(iOS は PWA インストール)。`enabled`, `vapid_subject`(RFC 8292), `vapid_current_path`(自動生成・mode 0600), `vapid_history_dir`, `payload_max_bytes`(3072, 上限 4096), `queue_concurrency`(8), `per_send_timeout_ms`(10000)。鍵ローテーション: `npm run vapid-rotate`。 + +--- + +## Environment variable overrides + +一部設定は環境変数で上書きできる: + +| 環境変数 | 上書き対象 | +|----------|------------| +| `OLLAMA_BASE_URL` | LLM エンドポイント | +| `OLLAMA_MODEL` | モデル名 | +| `WORKTREE_DIR` | `storage.worktree_dir` | +| `CONCURRENCY` | `concurrency` | +| `DB_PATH` | SQLite DB パス | +| `PORT` | bridge HTTP ポート(既定 9876) | +| `LOG_LEVEL` | `debug`/`info`/`warn`/`error`(既定 info) | +| `MCP_ENCRYPTION_KEY` | MCP/SSH 秘密の暗号化鍵(MCP 利用時必須) | diff --git a/docs/configuration.md b/docs/configuration.md index b82294d..8c57b2b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,229 +1,231 @@ +English | [日本語](configuration.ja.md) + # Configuration Reference -MAESTRO は単一の `config.yaml`(`config.yaml.example` をコピーして作成)で設定する。 +MAESTRO is configured with a single `config.yaml` (created by copying `config.yaml.example`). -- **YAML キーは snake_case**(`max_concurrency`)、コード内は camelCase。`src/config.ts` の `transformKeys` が変換する。 -- 一部は**環境変数で上書き**できる([末尾参照](#environment-variable-overrides))。 -- `config_version: 2` が現行スキーマ。 +- **YAML keys are snake_case** (`max_concurrency`), camelCase in the code. `transformKeys` in `src/config.ts` converts them. +- Some can be **overridden by environment variables** ([see the end](#environment-variable-overrides)). +- `config_version: 2` is the current schema. -> 値の一次ソースは `config.yaml.example`(コメント付き)と `src/config.ts`。本リファレンスは各項目の意味をまとめたもの。 +> The primary source for values is `config.yaml.example` (with comments) and `src/config.ts`. This reference summarizes the meaning of each option. --- -## `llm` — ジョブ実行時の LLM 接続 +## `llm` — LLM connection for job execution -| キー | 既定 | 意味 | +| Key | Default | Meaning | |------|------|------| -| `timeout_minutes` | 10 | 1 リクエスト全体の上限(分)。 | -| `retry.max_attempts` | 3 | 429/5xx/一時接続失敗時の再試行回数。 | -| `retry.backoff_ms` | [2000,5000,15000] | 各再試行の待機(ms)。 | -| `retry.retryable_status` | [429,500,502,503,504] | 再試行対象の HTTP ステータス。 | +| `timeout_minutes` | 10 | Overall limit per request (minutes). | +| `retry.max_attempts` | 3 | Number of retries on 429/5xx/transient connection failures. | +| `retry.backoff_ms` | [2000,5000,15000] | Wait per retry (ms). | +| `retry.retryable_status` | [429,500,502,503,504] | HTTP statuses eligible for retry. | -### `llm.workers[]` — ジョブ実行に使う接続先(必須) +### `llm.workers[]` — connection targets used for job execution (required) -| キー | 意味 | +| Key | Meaning | |------|------| -| `id` | ワーカー識別子。 | -| `connection_type` | `direct`(Ollama/vLLM 等の OpenAI 互換 backend に直結)/ `aao_gateway`(別 Gateway 経由、Gateway Key 必須)。 | -| `endpoint` | OpenAI 互換 API のベース URL(例 `http://localhost:11434/v1`)。 | -| `model` | 使用モデル名(ワーカーごとに明示。`default_model` は廃止)。 | -| `api_key` | `aao_gateway` 時の virtual key 等(任意)。 | -| `roles` | 用途フィルタ: `auto`/`fast`/`quality`/`title`/`reflection` 等。`[title]` のみ=タイトル生成専用。 | -| `max_concurrency` | このワーカーの並列度。 | -| `vlm` | `true` で画像入力対応(ReadImage は VLM ワーカーを優先)。 | -| `enabled` | 有効/無効。 | +| `id` | Worker identifier. | +| `connection_type` | `direct` (connect directly to an OpenAI-compatible backend such as Ollama/vLLM) / `aao_gateway` (via a separate Gateway, Gateway Key required). | +| `endpoint` | Base URL of the OpenAI-compatible API (e.g. `http://localhost:11434/v1`). | +| `model` | Model name to use (specify explicitly per worker; `default_model` is removed). | +| `api_key` | Virtual key etc. for `aao_gateway` (optional). | +| `roles` | Purpose filter: `auto`/`fast`/`quality`/`title`/`reflection`, etc. `[title]` only = dedicated to title generation. | +| `max_concurrency` | This worker's concurrency. | +| `vlm` | `true` enables image input (ReadImage prefers VLM workers). | +| `enabled` | Enabled/disabled. | -### `llm.metrics` — Prometheus exporter(worker 側) +### `llm.metrics` — Prometheus exporter (worker side) -| キー | 既定 | 意味 | +| Key | Default | Meaning | |------|------|------| -| `enabled` | true | `/metrics`(bridge HTTP, 既定 `PORT=9876`)に mount。 | -| `prefix` | `aao_worker` | メトリクス名 prefix。 | -| `bearer_token` | — | 設定すると Bearer 認証必須(`env:NAME` 形式可)。 | -| `allowed_hosts` | localhost のみ | 許可元 IP。本番は bearer か allowlist を必ず設定。 | +| `enabled` | true | Mounted on `/metrics` (bridge HTTP, default `PORT=9876`). | +| `prefix` | `aao_worker` | Metric name prefix. | +| `bearer_token` | — | When set, Bearer auth is required (the `env:NAME` form is allowed). | +| `allowed_hosts` | localhost only | Permitted source IPs. In production, always set a bearer or allowlist. | --- -## `gateway` — LLM Gateway サーバー(任意) +## `gateway` — LLM Gateway server (optional) -MAESTRO 自身を OpenAI 互換の LLM Gateway として公開する(仮想キー・予算・メトリクス付き、複数 GPU/チーム共有向け)。**env 変数や接続種別が `AAO_*` / `aao_gateway` という歴史的な接頭辞を使う点に注意(AAO = この Gateway 機能の旧称)。** 詳細は [aao-gateway-overview.md](aao-gateway-overview.md)。 +Exposes MAESTRO itself as an OpenAI-compatible LLM Gateway (with virtual keys, budgets, and metrics, for sharing across multiple GPUs/teams). **Note that its env vars and connection type use the historical `AAO_*` / `aao_gateway` prefix (AAO = the old name of this Gateway feature).** For details, see [aao-gateway-overview.md](aao-gateway-overview.md). -| キー | 既定 | 意味 | +| Key | Default | Meaning | |------|------|------| -| `enabled` | false | true で同 process gateway が起動(hot reload 対応)。 | -| `listen_port` | 4000 | separate-deploy 時のみ。 | -| `request_timeout_sec` | 600 | 1 リクエスト全体(streaming 込み)。 | -| `upstream_timeout_sec` | 30 | 各 upstream の TTFB 上限。 | -| `shutdown_graceful_sec` | 30 | SIGTERM 後の SSE drain 上限。 | -| `backends[]` | — | `id`/`endpoint`/`model`/`max_slots`/`api_key`。model 厳密一致で routing。 | -| `virtual_keys[]` | — | bootstrap/backup 用(`key`/`team`/`allowed_models`/`tokens_budget`/`rate_limit_rpm`)。新規発行は admin API 推奨。 | -| `metrics` | enabled | `prefix: aao_gateway`、team/key_prefix/backend ラベル。auth 必須運用。 | +| `enabled` | false | true starts the gateway in the same process (supports hot reload). | +| `listen_port` | 4000 | Only for separate-deploy. | +| `request_timeout_sec` | 600 | Per whole request (including streaming). | +| `upstream_timeout_sec` | 30 | TTFB limit per upstream. | +| `shutdown_graceful_sec` | 30 | SSE drain limit after SIGTERM. | +| `backends[]` | — | `id`/`endpoint`/`model`/`max_slots`/`api_key`. Routing by exact model match. | +| `virtual_keys[]` | — | For bootstrap/backup (`key`/`team`/`allowed_models`/`tokens_budget`/`rate_limit_rpm`). Issuing new ones via the admin API is recommended. | +| `metrics` | enabled | `prefix: aao_gateway`, team/key_prefix/backend labels. Run with auth required. | -Virtual Key の発行・rotation は admin REST API(`POST /api/admin/gateway/keys`)または UI(Settings → LLM → Gateway Server)で行う。 +Issue and rotate Virtual Keys via the admin REST API (`POST /api/admin/gateway/keys`) or the UI (Settings → LLM → Gateway Server). --- -## `storage` — パス・容量 +## `storage` — paths and capacity -| キー | 既定 | 意味 | +| Key | Default | Meaning | |------|------|------| -| `worktree_dir` | ./data/workspaces | ジョブ作業ディレクトリのベース。 | -| `custom_pieces_dir` | — | リポジトリ内 `pieces/` に加えて読む Piece dir(任意)。 | -| `user_folder_root` | ./data/users | `{root}/{userId}/` に AGENTS.md/scripts/notes 等を保存。 | -| `task_upload_max_size_mb` | 50 | タスク/コメント body 上限(base64 込み。範囲 1–1000)。 | -| `trash_retention_days` | 30 | `trash/` の自動 sweep。0 で都度全削除。 | +| `worktree_dir` | ./data/workspaces | Base for job working directories. | +| `custom_pieces_dir` | — | A Piece dir read in addition to the in-repo `pieces/` (optional). | +| `user_folder_root` | ./data/users | Stores AGENTS.md/scripts/notes etc. under `{root}/{userId}/`. | +| `task_upload_max_size_mb` | 50 | Upper limit for task/comment body (including base64; range 1–1000). | +| `trash_retention_days` | 30 | Auto-sweep of `trash/`. 0 deletes everything each time. | --- -## Execution — 並列度・上限・再試行 +## Execution — concurrency, limits, retry -| キー | 既定 | 意味 | +| Key | Default | Meaning | |------|------|------| -| `concurrency` | 4 | 全ワーカー合算の最大並列ジョブ数(env `CONCURRENCY`)。 | -| `max_movements` | 200 | 1 ジョブ内の最大 movement 数(loop 防止)。 | -| `retry.max_attempts` | 3 | ジョブ失敗時の最大再試行。 | -| `retry.backoff_seconds` | [60,300,900] | 各 attempt 間の待機秒。 | -| `ask.max_per_job` | 2 | 1 ジョブの ASK(ユーザー質問)上限。 | -| `subtasks.max_depth` | 2 | SpawnSubTask のネスト最大深度。 | -| `subtasks.max_per_parent` | 10 | 1 ジョブが生成できるサブタスク最大数。 | +| `concurrency` | 4 | Max concurrent jobs across all workers (env `CONCURRENCY`). | +| `max_movements` | 200 | Max movements within one job (loop prevention). | +| `retry.max_attempts` | 3 | Max retries when a job fails. | +| `retry.backoff_seconds` | [60,300,900] | Wait seconds between each attempt. | +| `ask.max_per_job` | 2 | ASK (user question) limit per job. | +| `subtasks.max_depth` | 2 | Max nesting depth of SpawnSubTask. | +| `subtasks.max_per_parent` | 10 | Max subtasks one job can spawn. | --- -## `context` — LLM コンテキスト管理 +## `context` — LLM context management -| キー | 既定 | 意味 | +| Key | Default | Meaning | |------|------|------| -| `limit_tokens` | 自動取得→128000 | コンテキスト上限。省略時はプロバイダ API から自動取得。 | -| `thresholds[]` | 0.7=warn / 0.85=prompt / 0.95=force_transition | 使用率閾値ごとの動作。 | +| `limit_tokens` | auto-fetched→128000 | Context limit. When omitted, auto-fetched from the provider API. | +| `thresholds[]` | 0.7=warn / 0.85=prompt / 0.95=force_transition | Action per usage-ratio threshold. | --- -## `safety` — 暴走防止・Bash サンドボックス +## `safety` — runaway prevention and Bash sandbox -| キー | 既定 | 意味 | +| Key | Default | Meaning | |------|------|------| -| `max_iterations` | 200 | 1 movement 内の最大イテレーション。 | -| `max_revisits` | 3 | 同一 movement の最大再訪問。超過で ABORT。 | -| `prompt_guard_ratio` | 0.8 | プロンプトがコンテキスト上限の何%まで許容するか(0.5–0.95)。 | -| `history_summarization.enabled` | true | 古い turn を構造化要約に置換して粘る。 | -| `history_summarization.tail_turns` | 2 | 末尾何 turn を保護するか。 | -| `history_summarization.preserve_recent_budget` | 8000 | 末尾保護の最大トークン。 | -| `bash_unrestricted` | false | true で Bash のコマンド許可リストを撤廃(**サンドボックス機構は別途 `bash_sandbox` が制御**)。 | -| `bash_sandbox` | auto | Bash 隔離機構: `auto`(bwrap あれば使用、無ければ hardened-whitelist)/ `always`(bwrap 強制・不在なら起動失敗、本番推奨)/ `off`(bwrap 不使用、env スクラブは維持)。詳細 [operations/bash-sandbox-provisioning.md](operations/bash-sandbox-provisioning.md)。 | +| `max_iterations` | 200 | Max iterations within one movement. | +| `max_revisits` | 3 | Max revisits to the same movement. Exceeding it triggers ABORT. | +| `prompt_guard_ratio` | 0.8 | Up to what % of the context limit the prompt is allowed to use (0.5–0.95). | +| `history_summarization.enabled` | true | Replace old turns with a structured summary to hang on longer. | +| `history_summarization.tail_turns` | 2 | How many trailing turns to protect. | +| `history_summarization.preserve_recent_budget` | 8000 | Max tokens for tail protection. | +| `bash_unrestricted` | false | true removes Bash's command allowlist (**the sandbox mechanism is controlled separately by `bash_sandbox`**). | +| `bash_sandbox` | auto | Bash isolation mechanism: `auto` (use bwrap if present, otherwise hardened-whitelist) / `always` (force bwrap; fail to start if absent, recommended for production) / `off` (do not use bwrap; env scrubbing is kept). Details: [operations/bash-sandbox-provisioning.md](operations/bash-sandbox-provisioning.md). | --- -## `search_filter` — WebSearch の機密情報漏洩防止 +## `search_filter` — preventing sensitive-info leakage in WebSearch -| キー | 既定 | 意味 | +| Key | Default | Meaning | |------|------|------| -| `blocked_patterns[]` | — | 完全一致で検索クエリから除去するパターン。 | -| `auto_block.private_ip` | true | 10/172.16-31/192.168/127.* を自動ブロック。 | -| `auto_block.internal_domain` | true | `.local`/`.internal`/`.lan`/`.intranet`/`.corp`/`.home`。 | -| `auto_block.email` / `phone` | true | メール/電話番号。 | +| `blocked_patterns[]` | — | Patterns removed from the search query by exact match. | +| `auto_block.private_ip` | true | Automatically block 10/172.16-31/192.168/127.*. | +| `auto_block.internal_domain` | true | `.local`/`.internal`/`.lan`/`.intranet`/`.corp`/`.home`. | +| `auto_block.email` / `phone` | true | Email/phone number. | --- -## `browser` — BrowseWeb ランタイム +## `browser` — BrowseWeb runtime -| キー | 既定 | 意味 | +| Key | Default | Meaning | |------|------|------| -| `page_timeout` | 60000 | ページ遷移 timeout(ms)。 | -| `action_timeout` | 30000 | アクション timeout(ms)。 | -| `captcha_solve` | skip | `skip` / `novnc`(人手 CAPTCHA 解決)。 | -| `max_captcha_pages` | 5 | CAPTCHA ページ上限。 | -| `channel` | chromium | `chromium`/`chrome`/`msedge`。 | -| `executable_path` | — | ブラウザ実行ファイル(channel と排他)。 | +| `page_timeout` | 60000 | Page navigation timeout (ms). | +| `action_timeout` | 30000 | Action timeout (ms). | +| `captcha_solve` | skip | `skip` / `novnc` (manual CAPTCHA solving). | +| `max_captcha_pages` | 5 | CAPTCHA page limit. | +| `channel` | chromium | `chromium`/`chrome`/`msedge`. | +| `executable_path` | — | Browser executable (mutually exclusive with channel). | --- -## `tools` — ツール設定 +## `tools` — tool settings -UI 上は Web & Search / Browser / Media & Documents / External Services / Legacy Knowledge に分かれるが YAML は `tools` 1 ブロック。主な項目: +In the UI these are split into Web & Search / Browser / Media & Documents / External Services / Legacy Knowledge, but in YAML they are a single `tools` block. Main items: -**Web & Search**: `searxng_url`(WebSearch フォールバック先), `webfetch_timeout`(sec), `websearch_timeout`, `webfetch_allowed_hosts[]`(SSRF 例外: private IP/.local を許可する場合)。 +**Web & Search**: `searxng_url` (WebSearch fallback target), `webfetch_timeout` (sec), `websearch_timeout`, `webfetch_allowed_hosts[]` (SSRF exceptions: when allowing private IP/.local). -**Media & Documents**: `vision_model`/`vision_base_url`/`vision_timeout`/`vision_max_tokens`(ReadImage 用 VLM), `ocr_model`, `office_{excel,docx,pdf}_max_size_mb`(既定 10), `office_pptx_max_size_mb`(50), `office_pptx_max_uncompressed_mb`(200, zip-bomb 検知), `speech_server_url`/`speech_timeout`/`speech_language`。 +**Media & Documents**: `vision_model`/`vision_base_url`/`vision_timeout`/`vision_max_tokens` (VLM for ReadImage), `ocr_model`, `office_{excel,docx,pdf}_max_size_mb` (default 10), `office_pptx_max_size_mb` (50), `office_pptx_max_uncompressed_mb` (200, zip-bomb detection), `speech_server_url`/`speech_timeout`/`speech_language`. -**External Services**: `x_*`(Twitter/X CLI 連携: `x_cli_command`/`x_auth_token`/`x_ct0`/`x_proxy`/`x_download_*` 等), `google_maps_api_key`/`maps_timeout`(未設定で Nominatim/OSRM), `amazon_affiliate_tag`/`keepa_api_key`。 +**External Services**: `x_*` (Twitter/X CLI integration: `x_cli_command`/`x_auth_token`/`x_ct0`/`x_proxy`/`x_download_*` etc.), `google_maps_api_key`/`maps_timeout` (Nominatim/OSRM when unset), `amazon_affiliate_tag`/`keepa_api_key`. -**User scripts**: `user_scripts_enabled`(RunUserScript。plain runtime は Node `--permission` で sandbox 化), `user_scripts_allow_userids[]`。 +**User scripts**: `user_scripts_enabled` (RunUserScript; the plain runtime is sandboxed with Node `--permission`), `user_scripts_allow_userids[]`. -**Legacy Knowledge**: `knowledge_service_url`(未設定で knowledge ツール無効), `knowledge_namespaces`(namespace ごとの api_key)。新規 namespace は MCP 経由を推奨。 +**Legacy Knowledge**: `knowledge_service_url` (knowledge tools disabled when unset), `knowledge_namespaces` (per-namespace api_key). For new namespaces, using MCP is recommended. --- -## `notes` — Shared Knowledge Notes 注入 +## `notes` — Shared Knowledge Notes injection -`data/users/{userId}/notes/` のノートをシステムプロンプトに注入。`inject.per_note_max_kb`(日本語は 4 推奨), `inject.total_max_kb`, `inject.over_budget_strategy`(`truncate_last`/`skip_remaining`/`degrade_to_search`)。 +Injects notes from `data/users/{userId}/notes/` into the system prompt. `inject.per_note_max_kb` (4 recommended for Japanese), `inject.total_max_kb`, `inject.over_budget_strategy` (`truncate_last`/`skip_remaining`/`degrade_to_search`). --- -## `auth` — 認証(任意) +## `auth` — authentication (optional) -未設定なら認証なしで動作。 +Runs without authentication when unset. -| キー | 意味 | +| Key | Meaning | |------|------| -| `session_secret` | セッション署名鍵(ランダム文字列)。 | -| `session_max_age` | セッション有効期間(ms, 既定 86400000=24h)。 | -| `secure_cookie` | HTTPS 環境では true。 | -| `admin_emails[]` | admin ロールにするメール。 | -| `primary_provider` | `google` / `gitea`(両方有効時に明示)。 | -| `providers.google` | `client_id`/`client_secret`/`callback_url`。 | -| `providers.gitea` | `client_id`/`client_secret`/`base_url`/`callback_url`。ログイン時に Gitea org を取得し可視性に利用。 | +| `session_secret` | Session signing key (a random string). | +| `session_max_age` | Session lifetime (ms, default 86400000=24h). | +| `secure_cookie` | true in HTTPS environments. | +| `admin_emails[]` | Emails granted the admin role. | +| `primary_provider` | `google` / `gitea` (specify explicitly when both are enabled). | +| `providers.google` | `client_id`/`client_secret`/`callback_url`. | +| `providers.gitea` | `client_id`/`client_secret`/`base_url`/`callback_url`. Fetches Gitea orgs at login and uses them for visibility. | --- -## `branding`(任意) +## `branding` (optional) -`app_name`/`primary_color`/`login_page_title`/`logo_url`/`favicon_url`/`footer_text`。Settings → System → Branding(admin)で GUI 編集可。`config.yaml`・`data/branding/` は gitignore 済み。 +`app_name`/`primary_color`/`login_page_title`/`logo_url`/`favicon_url`/`footer_text`. Editable via GUI at Settings → System → Branding (admin). `config.yaml` and `data/branding/` are gitignored. --- ## `secrets` -`master_key_path`(既定 `./data/secrets/master.key`, 32 byte, 初回起動で自動生成・mode 0600)。SSH 鍵・MCP トークン等の暗号化に使う。 +`master_key_path` (default `./data/secrets/master.key`, 32 bytes, auto-generated on first launch with mode 0600). Used to encrypt SSH keys, MCP tokens, etc. --- -## `reflection` — 学習(既定 OFF) +## `reflection` — learning (OFF by default) -ON で毎ジョブ完了後にユーザーメモリを LLM が自動更新(snapshot は revert 可)。`enabled`, `max_memory_changes_per_job`(3), `piece_edit_cooldown_hours`(24), `snapshot_retention_days`(90), `per_user_daily_budget_tokens`(200000)。 +When ON, the LLM automatically updates user memory after each job completes (snapshots are revertible). `enabled`, `max_memory_changes_per_job` (3), `piece_edit_cooldown_hours` (24), `snapshot_retention_days` (90), `per_user_daily_budget_tokens` (200000). --- ## `mcp` — Model Context Protocol -サーバーは admin UI(global)/各ユーザー(self-hosted)で管理。**`MCP_ENCRYPTION_KEY` env(64 hex)が必須。** `call_timeout_seconds`(60), `max_binary_size_mb`(20), `max_output_files_per_job`(10), `max_output_size_mb_per_job`(200), `tool_cache_ttl_seconds`(600), `oauth_pending_ttl_minutes`(10), `allow_private_addresses`(private 網の MCP server 用、既定 false)。 +Servers are managed in the admin UI (global) / per user (self-hosted). **The `MCP_ENCRYPTION_KEY` env (64 hex) is required.** `call_timeout_seconds` (60), `max_binary_size_mb` (20), `max_output_files_per_job` (10), `max_output_size_mb_per_job` (200), `tool_cache_ttl_seconds` (600), `oauth_pending_ttl_minutes` (10), `allow_private_addresses` (for MCP servers on a private network, default false). --- -## `ssh` — SSH ツール(既定 OFF) +## `ssh` — SSH tool (OFF by default) -`enabled`, `allow_private_addresses`(global 既定、admin は per-connection grant 可), `call_timeout_seconds`(30), `max_output_bytes`(32768), `max_{upload,download}_size_mb`(100), `audit_retention_days`(90), `admin_bypasses_grants`(true), abuse 検知(`abuse_window_minutes`/`abuse_failure_threshold`/`abuse_lock_minutes`)。 +`enabled`, `allow_private_addresses` (global default; admins can grant per-connection), `call_timeout_seconds` (30), `max_output_bytes` (32768), `max_{upload,download}_size_mb` (100), `audit_retention_days` (90), `admin_bypasses_grants` (true), abuse detection (`abuse_window_minutes`/`abuse_failure_threshold`/`abuse_lock_minutes`). -**Interactive Console**(`ssh.console`): `enabled`, `idle_timeout_seconds`(1800), `max_session_duration_seconds`(14400), `scrollback_bytes`(524288), `max_sessions_per_connection`(3) ほか。手順は [ssh.md](ssh.md)。 +**Interactive Console** (`ssh.console`): `enabled`, `idle_timeout_seconds` (1800), `max_session_duration_seconds` (14400), `scrollback_bytes` (524288), `max_sessions_per_connection` (3), and others. For the procedure, see [ssh.md](ssh.md). --- -## `notifications.push` — Web Push(V2, 任意) +## `notifications.push` — Web Push (V2, optional) -HTTPS ホスティング必須(iOS は PWA インストール)。`enabled`, `vapid_subject`(RFC 8292), `vapid_current_path`(自動生成・mode 0600), `vapid_history_dir`, `payload_max_bytes`(3072, 上限 4096), `queue_concurrency`(8), `per_send_timeout_ms`(10000)。鍵ローテーション: `npm run vapid-rotate`。 +HTTPS hosting required (iOS requires a PWA install). `enabled`, `vapid_subject` (RFC 8292), `vapid_current_path` (auto-generated, mode 0600), `vapid_history_dir`, `payload_max_bytes` (3072, max 4096), `queue_concurrency` (8), `per_send_timeout_ms` (10000). Key rotation: `npm run vapid-rotate`. --- ## Environment variable overrides -一部設定は環境変数で上書きできる: +Some settings can be overridden by environment variables: -| 環境変数 | 上書き対象 | +| Environment variable | Overrides | |----------|------------| -| `OLLAMA_BASE_URL` | LLM エンドポイント | -| `OLLAMA_MODEL` | モデル名 | +| `OLLAMA_BASE_URL` | LLM endpoint | +| `OLLAMA_MODEL` | Model name | | `WORKTREE_DIR` | `storage.worktree_dir` | | `CONCURRENCY` | `concurrency` | -| `DB_PATH` | SQLite DB パス | -| `PORT` | bridge HTTP ポート(既定 9876) | -| `LOG_LEVEL` | `debug`/`info`/`warn`/`error`(既定 info) | -| `MCP_ENCRYPTION_KEY` | MCP/SSH 秘密の暗号化鍵(MCP 利用時必須) | +| `DB_PATH` | SQLite DB path | +| `PORT` | bridge HTTP port (default 9876) | +| `LOG_LEVEL` | `debug`/`info`/`warn`/`error` (default info) | +| `MCP_ENCRYPTION_KEY` | Encryption key for MCP/SSH secrets (required when using MCP) | diff --git a/docs/design/README.md b/docs/design/README.md deleted file mode 100644 index e27b10f..0000000 --- a/docs/design/README.md +++ /dev/null @@ -1,151 +0,0 @@ -# Agent Orchestrator — Design System - -A local, single-tenant agent orchestration platform. Users submit natural-language tasks via a small Japanese-language admin UI; an LLM classifier routes each task into a named **Piece** (workflow), which runs a multi-step **Movement** chain against local Ollama workers and emits progress/results back to the UI as chat-style comments. - -## Product at a glance - -- **One product, one surface:** a React + Vite + TailwindCSS admin dashboard at `/ui/` on the orchestrator server (`http://this-machine:9876/ui/`). Mobile (single-column), tablet (list + chat), desktop (list + chat + detail) layouts. -- **Language:** Japanese throughout (UI labels, empty states, toasts). Latin/mono treatment reserved for identifiers, status keywords, version tags, wordmark. -- **Primary objects:** Task → Job → Movement → Tool call. Status kanban: `queued / running / waiting_human / waiting_subtasks / retry / succeeded / failed / cancelled`. -- **Interaction model:** a threaded chat with progress cards interleaved between user requests and agent results (green = result, amber = ASK, blue bubble = user, grey pill card = progress). - -## Sources consulted -- **Codebase (read-only local mount):** `gitea-agent-orchestrator/` - - `ui/tailwind.config.js`, `ui/src/index.css` — tokens, fonts - - `ui/src/lib/utils.ts` — `statusTone()`, `relativeTime()`, activity parsing - - `ui/src/components/**` — TopBar, FilterBar, TaskListItem, ChatPane, ChatMessage, DetailHeader, OverviewTab, ProgressTab, CreateTaskDialog, EmptyState, StatChip, StatusBadge, LoadingSpinner - - `ui/public/favicon.svg` — the "hub + 3 agents" mark - - `README.md` (root) — product narrative, piece list, tool registry -- **No Figma, no slide templates, no marketing site** were provided; this design system documents the existing admin UI only. - -## Index - -| File | Purpose | -|---|---| -| `README.md` | This document | -| `SKILL.md` | Agent Skill wrapper (portable to Claude Code) | -| `colors_and_type.css` | CSS variables for color/type/spacing/radii/shadow | -| `assets/logo.svg` | 32×32 brand mark (blue rounded square, orchestrator hub + 3 agent nodes) | -| `assets/wordmark.svg` | Logo + "AGENT ORCHESTRATOR" mono wordmark lockup | -| `preview/*.html` | Atomic design-system cards (registered in review) | -| `ui_kits/admin/` | High-fidelity React recreation of the admin dashboard | - ---- - -## Content fundamentals - -**Voice.** Terse, functional, Japanese. Almost no marketing flourish. Labels are nouns or imperative verbs — "新しい依頼" (new request), "Task 作成" (create Task), "詳細" (details), "送信" (send), "共有停止" (stop sharing). - -**Person.** Neither "あなた" nor "私" — the UI talks about objects, not people. Empty state uses a numbered list of actions ("左パネルからタスクを選択する" — "select a task from the left panel") rather than second-person. - -**Case & casing.** -- Japanese sentences where there's human prose. -- English identifiers kept English, capitalized as in code: **Tasks / Schedules / Settings / Users** (TopBar navs), **Inbox / Running / Waiting / Subtasks / Retry / Done / Failed / Cancelled** (status columns). These are not translated, even in a Japanese UI. -- Meta labels are SMALL-CAPS UPPERCASE with wide tracking in the mono face: `STEP`, `TOOL`, `PREVIEW`, `FINAL`, `ASK`, `LOG`. -- "Agent Orchestrator" wordmark: uppercase, mono, letter-spacing: 0.16em, blue-600. -- Product name "agent-orchestrator" in kebab-case in docs; UI header is Title Case. - -**Example strings** (verbatim from code): -- `新しい依頼` (new request) — primary CTA -- `スレッドを選択してください` (please select a thread) — empty state title -- `左の一覧から選ぶと、会話、進捗、成果物を追えます。` — empty state description -- `メッセージを入力... (Ctrl+Enter で送信)` — composer placeholder -- `まだ進行情報がありません。` (no progress info yet) -- `(activity.log がまだありません)` — empty log fallback -- `良かった` / `改善が必要` — feedback thumbs labels - -**Numbers & units.** Counts render as ` 件` (items), ` 実行中` (running), ` 待機` (waiting). Relative time in Japanese: `たった今 / N分前 / N時間前 / N日前`. Durations mix units: `ms`, `s`, `m Ns`. - -**Tone.** Operator-facing, not consumer-facing. No exclamation marks, no emoji in UI chrome. Emoji appear only as **domain signals inside agent content**: 👍 / 👎 on feedback buttons, 📋 on checklist progress cards. Unicode symbols (☑ ✗ ⊘ ☐ ▶) are used as list markers inside agent-emitted checklists. Do not introduce new emoji outside these established spots. - ---- - -## Visual foundations - -**Palette.** A near-monochromatic slate neutral scale (Tailwind `slate-50…900`) carrying the entire surface, with **#2563eb (blue-600)** as the only brand color for primary actions, active states, focus rings, and the logo. Semantic status pills add pastel bg / deep fg pairs: green (running/success), amber (waiting/retry), indigo (subtasks), red (failed), blue (succeeded/queued edge cases), slate (queued/cancelled). All defined verbatim in `statusTone()` in `ui/src/lib/utils.ts`. - -**Type.** `IBM Plex Sans JP` for everything, `IBM Plex Mono` for identifiers, log output, version tags, wordmark, cron expressions, and the micro-label uppercase treatment. Body is **13px** — small and dense. Titles jump to 18px (detail) or 20px (dialog); chat bubbles are 14px leading-relaxed. Mobile forces input `font-size: 16px !important` to prevent iOS auto-zoom. - - *Font substitution note:* IBM Plex is already loaded from Google Fonts in the codebase; no substitution required. - -**Weight.** Heavy. 700 ("bold") is the workhorse — buttons, pill labels, status chips, even 10px/11px micro labels. 800 ("extra-bold") is reserved for titles and primary CTAs. 400/500 appear in body copy only. - -**Spacing.** Tailwind 4px scale. Gutters between panels are `8px` (`p-2 gap-2`). Cards pad `16px` (`p-4`). Buttons pad `6px 10px` (small chips), `8px 16px` (primary). The desktop layout is a 3-column grid: `clamp(240px, 22vw, 280px)` list / flexible chat / `clamp(280px, 26vw, 440px)` detail (or `clamp(360px, 30vw, 560px)` wide). - -**Backgrounds.** Flat solid colors — **never gradients**. App root is `#f3f6fb` (between slate-50 and slate-100); content cards are white. Activity log switches to an inverted surface: `bg-slate-900 text-slate-100` as a "terminal" zone. No illustrations, no patterns, no photos, no blur/glassmorphism. - -**Animation.** Minimal and purposeful. Only three motion idioms: -1. `transition-colors` on hover/active states (Tailwind default ~150ms). -2. `animate-pulse` on a 2px blue dot while a job is running. -3. `animate-spin` on the loading spinner (2px slate-200 border, blue-600 top-border). -No fades, no slides, no springs, no bounces. Expand/collapse caret rotates 90° (`rotate-90`) on click. - -**Hover states.** Buttons and list items darken one step: transparent → `bg-slate-100`, `bg-blue-600` → `bg-blue-700`, border-slate-200 → border-slate-300. Text links: `hover:underline` only on small text actions. No scale, no shadow-lift. - -**Press / active states.** Active navigation uses **filled accent**: `bg-blue-600 text-white`. Active filter pills use **tinted** style: `border-blue-600 bg-blue-50 text-blue-700`. Active list item: `border-blue-500 bg-blue-50`. No shrink, no darken-further. - -**Focus.** `focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500`. Inputs on focus: `focus:border-blue-400 focus:ring-2 focus:ring-blue-100`. - -**Borders.** 1px, `#e2e8f0` (slate-200) by default. Active states promote to `slate-300` (hover) or `blue-500/600` (selected). Chat bubbles have no border on the user (blue-filled) bubble but do on ask/result bubbles to soften the pastel. - -**Shadows.** Two tiers only: -- `shadow-sm` — resting card (every panel, chip, list item). Nearly invisible, but cards in Vite have it. -- `shadow-2xl` — Dialog overlay only. -No colored shadows, no inner shadows, no glows. - -**Radii (heavy rounding).** The product reads "rounded" first, flat second. -- `rounded-lg` (8px): small selects, small buttons, rotating caret container, log surface. -- `rounded-xl` (12px): **default** — cards, buttons, inputs, list items, panels. -- `rounded-2xl` (16px): dialogs, chat bubbles (tail reduced to `rounded-br-md` / `rounded-bl-md`). -- `rounded-full` (9999px): status pills, filter tabs, avatar, pulse dot. - -**Transparency & blur.** Modal overlay uses `bg-slate-900/50` or `bg-black/40` — straight alpha, no backdrop-blur. No frosted chrome anywhere. - -**Cards.** White fill, 1px slate-200 border, `rounded-xl`, `shadow-sm`. Padded `p-3` or `p-4`. The admin list panel is itself a card; list items inside are nested mini-cards with the same recipe. - -**Chat bubbles.** -- User: `rounded-2xl rounded-br-md`, `bg-blue-600 text-white`, `shadow`. -- Agent ASK: `rounded-2xl rounded-bl-md`, `bg-amber-50 border border-amber-200`, `shadow-sm`. -- Agent RESULT: `rounded-2xl rounded-bl-md`, `bg-green-50 border border-green-200`, `shadow-sm`, renders Markdown. -- Progress card: centered, `bg-slate-50 border border-slate-200 rounded-xl`, 12px slate-500 text, click-to-expand. - -**Protection gradients vs capsules.** Never gradients. Always capsules/pills for chips and status, always rectangular cards for containers. - -**Imagery vibe.** The brand has no photography. The single branded image is the `favicon.svg`: a rounded blue square with a white central "hub" and three satellite nodes connected by thin 55%-opacity white lines — a literal orchestrator-connecting-workers glyph. Keep this as the only decorative asset unless explicitly asked. - -**Layout rules.** Fixed TopBar at top (white, slate-200 bottom border). Main content fills remaining `h-dvh` and is `overflow-hidden` at the root — panels handle their own scroll. Toasts slide in at the top-center (`mx-4 mt-2`). Dialogs center-screen, `max-width: min(860px, 92vw)`, `max-height: 88dvh`, scroll internally. - ---- - -## Iconography - -**No icon font, no icon library dependency.** Icons are inline SVG written directly in components, drawn at `w-3.5 h-3.5`, `w-4 h-4`, or `w-5 h-5`, stroke-based, `stroke-width="2"`, `strokeLinecap="round"`, `strokeLinejoin="round"`, `fill="none"`. Style is close to **Lucide / Feather** — 2px stroke, round caps, 24×24 viewBox, minimal. Example glyphs in source: magnifying-glass (search), paperclip (attach), cross (close), VNC monitor square, chevron-right caret. - -**Substitution policy.** When extending the system, prefer **Lucide** (`https://unpkg.com/lucide-static`) or hand-write a 2px-stroke, round-cap, 24×24 SVG inline. Do **not** introduce Heroicons solid, Material, or Phosphor — those break the line-weight consistency. - -**Unicode glyphs** are used functionally inside agent-generated content: -- `☑ ✗ ⊘ ☐` — checklist item states (done / failed / skipped / pending) -- `▶` — expand caret (rotates to down) -- `×` — close buttons within attachment chips -- `✕` — mobile dialog close -- `+` / `+` — add/create indicators -- `·` — meta separator (`worker: … · mode: …`) - -**Emoji.** Deliberately limited: -- 👍 / 👎 — feedback rating only -- 📋 — checklist progress card header only - -Do not introduce new emoji. When agent markdown renders emoji, the `prose` plugin styles them at 14px inline — do not restyle. - -**Logo usage.** The 32×32 favicon is the only mark. Minimum size 16×16. Clear space: `x/4` on all sides where `x` is the square's edge. Do not recolor the blue fill; if placing on blue, invert to a white square with blue contents. - ---- - -## Component notes (see `ui_kits/admin/`) - -The admin UI kit recreates: TopBar, FilterBar, TaskListItem, TaskListPanel, ChatPane, ChatMessage (user/ask/result/progress variants), DetailPanel with tab pills, StatusBadge, StatChip, EmptyState, LoadingSpinner, CreateTaskDialog, and the composite desktop 3-column layout. - -## Caveats - -- No external brand guide, marketing site, or Figma was provided — this system is derived strictly from the live admin UI source. -- No printed/decorative imagery exists in the codebase; the only "brand asset" is the favicon logo. -- Fonts load from Google Fonts CDN (same as production); no local TTFs needed. diff --git a/docs/design/colors_and_type.css b/docs/design/colors_and_type.css deleted file mode 100644 index 877d070..0000000 --- a/docs/design/colors_and_type.css +++ /dev/null @@ -1,128 +0,0 @@ -/* Agent Orchestrator — Colors & Type - Extracted from gitea-agent-orchestrator/ui (Tailwind config + index.css + usage). - Palette: slate neutrals + #2563eb blue accent, with pastel semantic chips. -*/ - -@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;700&family=IBM+Plex+Sans+JP:wght@400;500;600;700;800&display=swap'); - -:root { - /* —— Brand / Accent ———————————————————————— */ - --accent: #2563eb; /* blue-600 — primary action, active tab, focus ring */ - --accent-deep: #1d4ed8; /* blue-700 — hover on primary button */ - --accent-50: #eff6ff; - --accent-100: #dbeafe; - --accent-200: #bfdbfe; - --accent-500: #3b82f6; - --accent-700: #1d4ed8; - - /* —— Ink / Neutrals (slate scale) ————————————— */ - --ink: #0f172a; /* slate-900 — primary text */ - --muted: #64748b; /* slate-500 — secondary text */ - --slate-50: #f8fafc; /* body surface */ - --slate-100: #f1f5f9; /* scrollbar track, chip bg */ - --slate-200: #e2e8f0; /* default border */ - --slate-300: #cbd5e1; - --slate-400: #94a3b8; - --slate-500: #64748b; - --slate-600: #475569; - --slate-700: #334155; - --slate-800: #1e293b; - --slate-900: #0f172a; - --app-bg: #f3f6fb; /* root bg (index.html) */ - - /* —— Semantic status tones (from statusTone()) ———— - bg / fg pairs used in status pills and cards. */ - --status-running-bg: #dcfce7; --status-running-fg: #166534; /* green */ - --status-waiting-bg: #fef9c3; --status-waiting-fg: #854d0e; /* amber */ - --status-subtasks-bg: #e0e7ff; --status-subtasks-fg: #3730a3; /* indigo */ - --status-failed-bg: #fee2e2; --status-failed-fg: #b91c1c; /* red */ - --status-succeeded-bg: #dbeafe; --status-succeeded-fg: #1e40af; /* blue */ - --status-retry-bg: #fef3c7; --status-retry-fg: #92400e; /* amber-deep */ - --status-queued-bg: #e2e8f0; --status-queued-fg: #475569; /* slate */ - - /* Message bubbles (ChatMessage.tsx) */ - --bubble-user-bg: #2563eb; --bubble-user-fg: #ffffff; - --bubble-ask-bg: #fffbeb; --bubble-ask-border: #fde68a; /* amber-50/200 */ - --bubble-result-bg: #f0fdf4; --bubble-result-border: #bbf7d0; /* green-50/200 */ - - /* Log / terminal surface (ProgressTab) */ - --log-bg: #0f172a; - --log-fg: #f1f5f9; - - /* —— Typography ——————————————————————————— */ - --font-sans: 'IBM Plex Sans JP', 'Hiragino Sans', -apple-system, BlinkMacSystemFont, sans-serif; - --font-mono: 'IBM Plex Mono', ui-monospace, Menlo, monospace; - - /* UI base is small & dense — 13px body, mobile auto-zooms to 16. */ - --fs-10: 10px; /* micro labels, version tag */ - --fs-11: 11px; /* meta, pill labels, timestamps */ - --fs-12: 12px; /* secondary body, nav labels */ - --fs-13: 13px; /* DEFAULT body */ - --fs-14: 14px; /* chat bubble body */ - --fs-15: 15px; /* chat header */ - --fs-18: 18px; /* detail title */ - --fs-20: 20px; /* dialog title (xl) */ - - --fw-regular: 400; - --fw-medium: 500; - --fw-bold: 700; /* used aggressively — even small chips are bold */ - --fw-extra: 800; /* titles and headers */ - - /* —— Radii (very rounded) ————————————————————— */ - --radius-sm: 8px; /* rounded-lg — small buttons, selects, log surface */ - --radius-md: 12px; /* rounded-xl — DEFAULT card/button/input — everywhere */ - --radius-lg: 16px; /* rounded-2xl — dialogs, chat bubbles */ - --radius-pill: 9999px; /* status pills, filter tabs, avatar */ - - /* —— Shadow system ————————————————————————— */ - --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* card resting */ - --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25); /* modal */ - - /* —— Spacing scale (Tailwind units × 4) ————————— */ - --space-1: 4px; - --space-2: 8px; - --space-3: 12px; - --space-4: 16px; - --space-5: 20px; - --space-6: 24px; - --space-8: 32px; - - /* —— Borders ——————————————————————————————— */ - --border-default: 1px solid var(--slate-200); - --border-active: 1px solid var(--accent); - - /* —— Semantic aliases ———————————————————————— */ - --fg-1: var(--slate-900); - --fg-2: var(--slate-600); - --fg-3: var(--slate-500); - --fg-muted: var(--slate-400); - --bg-1: #ffffff; - --bg-2: var(--slate-50); - --bg-app: var(--app-bg); - --border: var(--slate-200); -} - -/* —— Base type roles ————————————————————————— */ -html, body { font-family: var(--font-sans); color: var(--fg-1); background: var(--bg-app); } -body { font-size: var(--fs-13); } - -.h1 { font-size: var(--fs-20); font-weight: var(--fw-extra); color: var(--fg-1); letter-spacing: -0.01em; } -.h2 { font-size: var(--fs-18); font-weight: var(--fw-extra); color: var(--fg-1); } -.h3 { font-size: var(--fs-15); font-weight: var(--fw-bold); color: var(--fg-1); } -.h4 { font-size: var(--fs-13); font-weight: var(--fw-bold); color: var(--fg-1); } -.p { font-size: var(--fs-13); color: var(--fg-2); line-height: 1.55; } -.meta { font-size: var(--fs-11); color: var(--fg-3); } -.micro { font-size: var(--fs-10); color: var(--fg-muted); text-transform: uppercase; letter-spacing: 0.08em; font-weight: var(--fw-bold); } -.mono { font-family: var(--font-mono); } -.code { font-family: var(--font-mono); font-size: var(--fs-12); background: var(--slate-100); padding: 2px 6px; border-radius: 6px; } - -/* The signature "Agent Orchestrator" wordmark style used in TopBar */ -.wordmark { - font-family: var(--font-mono); - font-size: var(--fs-11); - font-weight: var(--fw-bold); - color: var(--accent); - text-transform: uppercase; - letter-spacing: 0.16em; -} diff --git a/docs/design/ui_kits_reference/admin-legacy/ChatPane.jsx b/docs/design/ui_kits_reference/admin-legacy/ChatPane.jsx deleted file mode 100644 index fd8cd80..0000000 --- a/docs/design/ui_kits_reference/admin-legacy/ChatPane.jsx +++ /dev/null @@ -1,128 +0,0 @@ -// ChatPane — mirrors ui/src/components/chat/* with user/ask/result/progress bubbles -function Bubble({ role, children, footer }) { - const isUser = role === 'user'; - const style = { - maxWidth: '85%', - padding: '10px 14px', - borderRadius: 16, - fontSize: 13, - lineHeight: 1.55, - whiteSpace: 'pre-wrap', - wordBreak: 'break-word', - }; - if (isUser) { - Object.assign(style, { background: '#2563eb', color: '#fff', borderBottomRightRadius: 4, alignSelf: 'flex-end' }); - } else if (role === 'ask') { - Object.assign(style, { background: '#fef9c3', color: '#854d0e', border: '1px solid #fde68a', borderBottomLeftRadius: 4 }); - } else if (role === 'result') { - Object.assign(style, { background: '#ecfdf5', color: '#065f46', border: '1px solid #a7f3d0', borderBottomLeftRadius: 4 }); - } else { - Object.assign(style, { background: '#fff', color: '#0f172a', border: '1px solid #e2e8f0', borderBottomLeftRadius: 4 }); - } - return ( -
-
{children}
- {footer &&
{footer}
} -
- ); -} - -function ProgressBubble({ text }) { - return ( -
- - {text} -
- ); -} - -function ChatHeader({ task, onOpenDetail, detailOpen }) { - return ( -
-
-
- TASK #{task.id} -
-
- {task.title} -
-
-
- - -
-
- ); -} - -function Composer({ onSend }) { - const [text, setText] = React.useState(''); - const send = () => { if (!text.trim()) return; onSend(text.trim()); setText(''); }; - return ( -
-
- -