diff --git a/docs/operations/guide.css b/docs/operations/guide.css new file mode 100644 index 0000000..5cfa17c --- /dev/null +++ b/docs/operations/guide.css @@ -0,0 +1,76 @@ +/* MAESTRO 運用ガイド 共通スタイル + 段階バッジ: 設計=青 / 実装=黄 / 完成=緑 */ +:root { + --bg: #f8fafc; + --surface: #ffffff; + --text: #0f172a; + --muted: #64748b; + --border: #e2e8f0; + --accent: #4f46e5; + --code-bg: #0f172a; + --code-text: #e2e8f0; + --stage-design: #2563eb; + --stage-impl: #d97706; + --stage-done: #16a34a; +} +@media (prefers-color-scheme: dark) { + :root { + --bg: #0b1120; --surface: #111827; --text: #e2e8f0; --muted: #94a3b8; + --border: #1f2937; --accent: #818cf8; --code-bg: #000; --code-text: #e5e7eb; + } +} +* { box-sizing: border-box; } +html { scroll-behavior: smooth; } +body { + margin: 0; background: var(--bg); color: var(--text); + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Hiragino Sans', 'Noto Sans JP', Roboto, sans-serif; + line-height: 1.75; font-size: 15px; +} +.wrap { max-width: 860px; margin: 0 auto; padding: 32px 24px 80px; } +header.doc { border-bottom: 1px solid var(--border); padding-bottom: 20px; margin-bottom: 32px; } +.crumbs { font-size: 13px; color: var(--muted); margin-bottom: 12px; } +.crumbs a { color: var(--accent); text-decoration: none; } +.crumbs a:hover { text-decoration: underline; } +h1 { font-size: 1.85rem; line-height: 1.3; margin: 6px 0 10px; letter-spacing: -0.01em; } +h2 { font-size: 1.3rem; margin: 40px 0 12px; padding-top: 8px; border-top: 1px solid var(--border); } +h2:first-of-type { border-top: none; } +h3 { font-size: 1.05rem; margin: 24px 0 8px; } +p, li { color: var(--text); } +.meta { color: var(--muted); font-size: 13px; margin-top: 8px; } +.badge { + display: inline-block; font-size: 12px; font-weight: 700; letter-spacing: .04em; + padding: 3px 10px; border-radius: 999px; color: #fff; vertical-align: middle; +} +.badge.design { background: var(--stage-design); } +.badge.impl { background: var(--stage-impl); } +.badge.done { background: var(--stage-done); } +code { + font-family: 'SF Mono', ui-monospace, Menlo, Consolas, monospace; font-size: 0.88em; + background: rgba(99,102,241,.12); color: var(--accent); padding: 1px 6px; border-radius: 5px; +} +pre { + background: var(--code-bg); color: var(--code-text); padding: 16px 18px; border-radius: 10px; + overflow-x: auto; font-size: 13px; line-height: 1.6; border: 1px solid var(--border); +} +pre code { background: none; color: inherit; padding: 0; } +table { border-collapse: collapse; width: 100%; margin: 16px 0; font-size: 14px; } +th, td { border: 1px solid var(--border); padding: 9px 12px; text-align: left; vertical-align: top; } +th { background: rgba(99,102,241,.08); font-weight: 600; } +tr:nth-child(even) td { background: rgba(148,163,184,.06); } +.note, .warn, .tip { + border-left: 4px solid var(--accent); background: var(--surface); + padding: 12px 16px; border-radius: 0 8px 8px 0; margin: 16px 0; font-size: 14px; +} +.warn { border-left-color: #dc2626; } +.tip { border-left-color: var(--stage-done); } +.note b, .warn b, .tip b { display: inline-block; margin-bottom: 2px; } +.steps { counter-reset: step; list-style: none; padding-left: 0; } +.steps > li { position: relative; padding-left: 42px; margin: 18px 0; } +.steps > li::before { + counter-increment: step; content: counter(step); + position: absolute; left: 0; top: 0; width: 28px; height: 28px; + background: var(--accent); color: #fff; border-radius: 50%; + display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; +} +a { color: var(--accent); } +footer.doc { margin-top: 56px; padding-top: 16px; border-top: 1px solid var(--border); color: var(--muted); font-size: 13px; } diff --git a/docs/operations/index.html b/docs/operations/index.html new file mode 100644 index 0000000..f254ff7 --- /dev/null +++ b/docs/operations/index.html @@ -0,0 +1,44 @@ + + +
+ + +| 資料 | 段階 | 更新日 | 概要 |
|---|---|---|---|
| 初期セットアップ(認証・初回管理者) | +完成 | +2026-06-10 | +ローカル認証を有効化し、初回管理者アカウントを起動時 seed で作る手順。ログインID 運用も。 | +
docs/ 配下に Markdown で置いています。
+ 本ディレクトリは「セットアップ・運用の手順書」を段階別 HTML で集約する場所です。
+ + MAESTRO は認証なし(no-auth)でも動きますが、複数人で使う・外部に出す場合はログインを有効にします。 + その際に最初に詰まるのが「まだ誰もログインできない状態で、どうやって最初の管理者を作るか」です。 + 本ガイドはローカル認証(ID + パスワード)を前提に、その初回ブートストラップ手順をまとめます。 +
+npm run setup のセットアップウィザードは LLM 接続先の設定だけが対象で、認証・初期管理者は対象外です。
+ 認証まわりは本ガイドで手動設定します。
+ config.yaml が存在すること(無ければ config.yaml.example をコピー)。scripts/server.sh start 等)。
+ 初回管理者は「セルフ登録」ではなく、config.yaml に書いておくと起動時に自動作成(seed)される方式です。
+ auth: ブロックに次を追加します。
+
auth:
+ session_secret: "ランダムな長い文字列" # 未設定だと再起動ごとにセッション失効
+ local:
+ enabled: true
+ allow_signup: false # 後述。true で他ユーザーのセルフ登録を許可
+ bootstrap_admin: # 起動時に id='local' の管理者を冪等 seed
+ email: "admin" # ← ログインID(メール形式でなくてOK)
+ password: "強いパスワードを設定" # ← 平文で config に入る。初回ログイン後に変更推奨
+
+ | キー | 意味 |
|---|---|
auth.session_secret | セッション署名鍵。未設定だとプロセスごとのランダム値になり、再起動でログインが切れる。安定運用では必ず設定。 |
auth.local.enabled | true でローカル(ID+パスワード)ログインを有効化。これだけで認証が有効になり、OAuth 無しでも保護される。 |
auth.local.bootstrap_admin.email | 初回管理者のログインID。後述の通りメール形式は不要。 |
auth.local.bootstrap_admin.password | 初回管理者のパスワード。config に平文で保存されるため、初回ログイン後に Settings から変更を推奨。 |
auth.local.allow_signup | true で 2人目以降のセルフ登録を許可(作成されるのは承認待ち状態)。 |
local で作られます。これは no-auth 時代にデータの所有者として使われていた ID と同じなので、
+ 認証なしで溜めたタスクやファイルを、そのまま初回 admin が引き継ぎます。
+ [auth] seeded local system admin id=local email=... が出ることを確認する(seed は冪等。再起動のたびに config の値でパスワードが更新される)。/auth/login を開き、ステップ1で設定した ID とパスワードでログインする。そのまま管理者として入れる。
+ ローカル認証の識別子は内部的に「email」という名前のフィールドですが、メール形式の検証はしていません。
+ admin や team-taro のような自由な文字列をログインID として使えます。
+ ログイン/登録フォームの入力欄も type="text"・ラベル「ログインID」になっており、
+ ブラウザのメール形式チェックは外れています。
+
auth.admin_emails のメール一致で判定されます。
+ ローカル認証だけなら自由ID で問題ありません。
+ 方法は2通りです。
+auth.local.allow_signup: true にすると、ログイン画面に登録フォームが出る。登録されたユーザーは承認待ち(pending)になり、そのままではアプリを使えない。管理者が Settings → ユーザー管理 で承認すると有効化される。| 症状 | 原因 / 対処 |
|---|---|
起動時に Cannot read properties of undefined (reading 'google') で落ちる |
+ 古いビルドで auth.providers 未設定だと発生した既知不具合(修正済み)。最新を pull・再ビルドすれば解消。暫定回避は auth: 直下に providers: {} を1行足す。 |
+
| 再起動のたびにログインが切れる | +auth.session_secret 未設定。安定した値を設定する。 |
+
| 初回 admin でログインできない | +入力した ID/パスワードが bootstrap_admin の値と一致しているか確認。値を変えて再起動すればパスワードは上書き更新される(seed は冪等)。 |
+
| UI 変更が反映されない | +サーバー再起動だけでは UI は更新されない。npm run build:ui を実行してから再起動する。 |
+
config.yaml.example の auth: ブロックのコメント参照。npm run setup)が担当。本ガイドの認証はウィザードの対象外。auth.providers 未設定クラッシュ修正(PR #447)。