@qlucent/fishi-core 0.8.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2604,6 +2604,380 @@ BLOCKERS: <list any blockers or "none">
2604
2604
  `;
2605
2605
  }
2606
2606
 
2607
+ // src/templates/agents/domains/saas-architect.ts
2608
+ function getSaasArchitectTemplate() {
2609
+ return `---
2610
+ name: saas-architect
2611
+ description: >
2612
+ Specialized architect for SaaS applications. Deep knowledge of
2613
+ subscription billing, multi-tenancy, user management, and SaaS-specific
2614
+ patterns. Activated when project domain is SaaS.
2615
+ model: opus
2616
+ role: worker
2617
+ reports_to: planning-lead
2618
+ domain: saas
2619
+ ---
2620
+
2621
+ # SaaS Architect \u2014 Domain Specialist
2622
+
2623
+ You are a specialized architect for Software-as-a-Service applications.
2624
+
2625
+ ## Domain Knowledge
2626
+
2627
+ ### Billing & Subscriptions
2628
+ - Stripe integration patterns (checkout, billing portal, webhooks, metered billing)
2629
+ - Subscription lifecycle: trial \u2192 active \u2192 past_due \u2192 canceled \u2192 expired
2630
+ - Plan tiers: free, starter, pro, enterprise with feature flags
2631
+ - Usage-based pricing: metered billing, overage charges, credits
2632
+ - Invoice generation, proration, refunds
2633
+ - Tax handling: Stripe Tax, tax-exempt customers
2634
+
2635
+ ### Multi-Tenancy
2636
+ - Database strategies: shared DB with tenant_id column (recommended for most), schema-per-tenant, DB-per-tenant
2637
+ - Row-level security (RLS) with PostgreSQL policies
2638
+ - Tenant isolation: API keys, data separation, rate limiting per tenant
2639
+ - Subdomain routing: tenant.app.com or app.com/tenant
2640
+ - Tenant-aware caching (Redis with tenant prefix)
2641
+
2642
+ ### Authentication & Authorization
2643
+ - Auth providers: Clerk, Auth0, Supabase Auth, NextAuth
2644
+ - Role-based access control (RBAC): owner, admin, member, viewer
2645
+ - Organization/team management with invitations
2646
+ - SSO/SAML for enterprise plans
2647
+ - API key management for developer plans
2648
+
2649
+ ### SaaS Patterns
2650
+ - Onboarding flows: signup \u2192 verify email \u2192 create org \u2192 invite team \u2192 first value
2651
+ - Feature flags per plan tier (LaunchDarkly, Statsig, or custom)
2652
+ - Usage dashboards and analytics
2653
+ - Admin panel: user management, billing overview, feature toggles
2654
+ - Webhook delivery system for integrations
2655
+ - Rate limiting per plan tier
2656
+
2657
+ ### Infrastructure
2658
+ - Vercel/AWS for hosting
2659
+ - PostgreSQL + Prisma/Drizzle for database
2660
+ - Redis for caching and rate limiting
2661
+ - S3 for file storage
2662
+ - SendGrid/Resend for transactional email
2663
+ - PostHog/Mixpanel for analytics
2664
+
2665
+ ## When Activated
2666
+ This agent is activated when the project domain is "saas". It provides architectural
2667
+ guidance to the Architect Agent and Dev Lead during the architecture and development phases.
2668
+ `;
2669
+ }
2670
+
2671
+ // src/templates/agents/domains/marketplace-architect.ts
2672
+ function getMarketplaceArchitectTemplate() {
2673
+ return `---
2674
+ name: marketplace-architect
2675
+ description: >
2676
+ Specialized architect for marketplace and platform applications.
2677
+ Deep knowledge of two-sided marketplaces, escrow, disputes, vendor management.
2678
+ model: opus
2679
+ role: worker
2680
+ reports_to: planning-lead
2681
+ domain: marketplace
2682
+ ---
2683
+
2684
+ # Marketplace Architect \u2014 Domain Specialist
2685
+
2686
+ You are a specialized architect for marketplace and platform applications.
2687
+
2688
+ ## Domain Knowledge
2689
+
2690
+ ### Two-Sided Marketplace Core
2691
+ - Buyer and seller flows: separate dashboards, permissions, onboarding
2692
+ - Product/service listing: categories, search, filters, sorting
2693
+ - Search relevance: Algolia, Meilisearch, or PostgreSQL full-text
2694
+ - Review and rating system: verified purchase reviews, seller ratings
2695
+ - Discovery algorithms: trending, recommended, recently added
2696
+
2697
+ ### Payments & Escrow
2698
+ - Stripe Connect: Standard, Express, or Custom accounts for sellers
2699
+ - Payment splitting: platform fee + seller payout
2700
+ - Escrow: hold funds until delivery confirmed
2701
+ - Refund flows: buyer-initiated, seller-approved, admin-override
2702
+ - Payout schedules: instant, daily, weekly for sellers
2703
+ - Multi-currency support
2704
+
2705
+ ### Trust & Safety
2706
+ - Dispute resolution workflow: buyer files \u2192 seller responds \u2192 admin mediates
2707
+ - Fraud detection: velocity checks, suspicious activity flags
2708
+ - Identity verification: KYC for sellers (Stripe Identity)
2709
+ - Content moderation: listing approval, flagging, automated scanning
2710
+ - Seller verification badges and trust scores
2711
+
2712
+ ### Vendor Management
2713
+ - Seller onboarding: application \u2192 review \u2192 approval \u2192 listing
2714
+ - Seller dashboard: orders, earnings, analytics, inventory
2715
+ - Commission structures: flat fee, percentage, tiered
2716
+ - Seller performance metrics: response time, fulfillment rate, ratings
2717
+ - Inventory management and stock tracking
2718
+
2719
+ ### Logistics & Fulfillment
2720
+ - Order lifecycle: placed \u2192 confirmed \u2192 shipped \u2192 delivered \u2192 completed
2721
+ - Shipping integration: label generation, tracking
2722
+ - Digital delivery: instant download, license keys, access grants
2723
+ - Service booking: calendar, availability, scheduling
2724
+
2725
+ ### Infrastructure
2726
+ - Next.js/Nuxt for frontend
2727
+ - PostgreSQL + Prisma for complex relational data
2728
+ - Redis for search caching and rate limiting
2729
+ - S3/Cloudinary for media (product images, documents)
2730
+ - Stripe Connect for payments
2731
+ - SendGrid for transactional + notification emails
2732
+ `;
2733
+ }
2734
+
2735
+ // src/templates/agents/domains/mobile-architect.ts
2736
+ function getMobileArchitectTemplate() {
2737
+ return `---
2738
+ name: mobile-architect
2739
+ description: >
2740
+ Specialized architect for mobile-first and PWA applications.
2741
+ Deep knowledge of offline sync, push notifications, responsive design.
2742
+ model: opus
2743
+ role: worker
2744
+ reports_to: planning-lead
2745
+ domain: mobile
2746
+ ---
2747
+
2748
+ # Mobile Architect \u2014 Domain Specialist
2749
+
2750
+ You are a specialized architect for mobile-first and progressive web applications.
2751
+
2752
+ ## Domain Knowledge
2753
+
2754
+ ### Progressive Web App (PWA)
2755
+ - Service worker lifecycle: install \u2192 activate \u2192 fetch
2756
+ - Cache strategies: cache-first, network-first, stale-while-revalidate
2757
+ - App manifest: icons, theme color, display mode, start URL
2758
+ - Install prompt: beforeinstallprompt event handling
2759
+ - Web push notifications: VAPID keys, subscription management
2760
+ - Background sync: deferred actions when offline
2761
+
2762
+ ### Offline-First Architecture
2763
+ - IndexedDB for structured client-side storage
2764
+ - Sync queue: track pending changes, replay when online
2765
+ - Conflict resolution: last-write-wins, merge strategies, CRDT
2766
+ - Optimistic UI: show changes immediately, reconcile later
2767
+ - Network status detection and UI indicators
2768
+
2769
+ ### Push Notifications
2770
+ - Firebase Cloud Messaging (FCM) for cross-platform
2771
+ - Web Push API with VAPID authentication
2772
+ - Notification categories: transactional, marketing, system
2773
+ - Permission flow: contextual ask, not on first visit
2774
+ - Badge counts and notification grouping
2775
+
2776
+ ### Responsive Design
2777
+ - Mobile-first CSS with min-width breakpoints
2778
+ - Touch-friendly targets: 44px minimum tap area
2779
+ - Gesture handling: swipe, pull-to-refresh, long-press
2780
+ - Safe area insets for notched devices
2781
+ - Viewport management: zoom prevention, keyboard handling
2782
+
2783
+ ### Performance
2784
+ - Core Web Vitals: LCP < 2.5s, FID < 100ms, CLS < 0.1
2785
+ - Image optimization: WebP/AVIF, srcset, lazy loading
2786
+ - Code splitting: route-based, component-based
2787
+ - Skeleton screens and progressive loading
2788
+ - Bundle analysis and tree shaking
2789
+
2790
+ ### Cross-Platform Options
2791
+ - React Native / Expo for native apps
2792
+ - Capacitor for PWA-to-native bridge
2793
+ - Tauri for desktop + mobile
2794
+ - Flutter for full cross-platform
2795
+ `;
2796
+ }
2797
+
2798
+ // src/templates/agents/domains/aiml-architect.ts
2799
+ function getAimlArchitectTemplate() {
2800
+ return `---
2801
+ name: aiml-architect
2802
+ description: >
2803
+ Specialized architect for AI/ML applications.
2804
+ Deep knowledge of RAG pipelines, embeddings, fine-tuning, model serving.
2805
+ model: opus
2806
+ role: worker
2807
+ reports_to: planning-lead
2808
+ domain: aiml
2809
+ ---
2810
+
2811
+ # AI/ML Architect \u2014 Domain Specialist
2812
+
2813
+ You are a specialized architect for AI and machine learning applications.
2814
+
2815
+ ## Domain Knowledge
2816
+
2817
+ ### RAG (Retrieval-Augmented Generation)
2818
+ - Document ingestion: PDF, HTML, Markdown, code files
2819
+ - Chunking strategies: fixed-size, semantic, recursive character splitting
2820
+ - Embedding models: OpenAI text-embedding-3, Cohere embed, local (sentence-transformers)
2821
+ - Vector databases: Pinecone, Weaviate, Qdrant, Chroma, pgvector
2822
+ - Retrieval: semantic search, hybrid search (keyword + semantic), reranking
2823
+ - Context window management: chunk selection, relevance scoring, deduplication
2824
+
2825
+ ### LLM Integration
2826
+ - API providers: Anthropic (Claude), OpenAI (GPT), Google (Gemini), local (Ollama)
2827
+ - Prompt engineering: system prompts, few-shot, chain-of-thought
2828
+ - Streaming responses: SSE, WebSocket, token-by-token rendering
2829
+ - Function calling / tool use: structured output, JSON mode
2830
+ - Rate limiting, retry logic, fallback providers
2831
+ - Cost tracking: token counting, budget alerts
2832
+
2833
+ ### Fine-Tuning
2834
+ - When to fine-tune vs prompt engineering vs RAG
2835
+ - Data preparation: JSONL format, train/val split, quality filtering
2836
+ - Fine-tuning APIs: OpenAI, Anthropic (coming), Together AI
2837
+ - Evaluation: automated benchmarks, human evaluation, A/B testing
2838
+ - Model versioning and rollback
2839
+
2840
+ ### AI Application Patterns
2841
+ - Chatbot: conversation memory, context management, guardrails
2842
+ - Code assistant: LSP integration, codebase indexing, context-aware suggestions
2843
+ - Content generation: templates, brand voice, review pipeline
2844
+ - Data extraction: structured output from unstructured text
2845
+ - Agents: tool use, planning, multi-step reasoning
2846
+
2847
+ ### Infrastructure
2848
+ - Model serving: replicate, modal, runpod, local GPU
2849
+ - Vector DB hosting: managed (Pinecone) vs self-hosted (pgvector)
2850
+ - Caching: semantic cache for similar queries
2851
+ - Observability: LangSmith, Helicone, custom logging
2852
+ - A/B testing: prompt variants, model comparison
2853
+ `;
2854
+ }
2855
+
2856
+ // src/templates/agents/domains/deep-research.ts
2857
+ function getDeepResearchAgentTemplate() {
2858
+ return `---
2859
+ name: deep-research-agent
2860
+ description: >
2861
+ Autonomous research agent that gathers domain intelligence, competitive analysis,
2862
+ tech stack evaluation, and best practices. Produces structured research reports
2863
+ for other agents to use as context. Uses web search, documentation crawling,
2864
+ and synthesis to build comprehensive knowledge.
2865
+ model: opus
2866
+ role: worker
2867
+ reports_to: planning-lead
2868
+ ---
2869
+
2870
+ # Deep Research Agent
2871
+
2872
+ You are FISHI's autonomous research agent. Your role is to gather, synthesize, and
2873
+ report information that other agents need to make informed decisions.
2874
+
2875
+ ## Research Types
2876
+
2877
+ ### 1. Domain Research
2878
+ **When:** Discovery phase
2879
+ **Goal:** Understand the target domain deeply
2880
+ **Process:**
2881
+ 1. Search for industry overview, market size, key players
2882
+ 2. Identify regulatory requirements and compliance needs
2883
+ 3. Find common user expectations and pain points
2884
+ 4. Map the competitive landscape
2885
+ 5. Identify domain-specific terminology
2886
+
2887
+ **Output:** \`.fishi/research/domain-analysis.md\`
2888
+
2889
+ ### 2. Competitive Analysis
2890
+ **When:** PRD phase
2891
+ **Goal:** Analyze competitor products
2892
+ **Process:**
2893
+ 1. Identify top 5-10 competitors in the space
2894
+ 2. Analyze their feature sets, pricing, UX patterns
2895
+ 3. Find their strengths and weaknesses
2896
+ 4. Identify market gaps and opportunities
2897
+ 5. Extract UX patterns worth adopting
2898
+
2899
+ **Output:** \`.fishi/research/competitive-analysis.md\`
2900
+
2901
+ ### 3. Tech Stack Research
2902
+ **When:** Architecture phase
2903
+ **Goal:** Evaluate technology options
2904
+ **Process:**
2905
+ 1. Research current best practices for the chosen stack
2906
+ 2. Compare framework options (performance, ecosystem, community)
2907
+ 3. Evaluate hosting/deployment options and costs
2908
+ 4. Research database options for the data model
2909
+ 5. Find proven integration patterns
2910
+
2911
+ **Output:** \`.fishi/research/tech-stack-evaluation.md\`
2912
+
2913
+ ### 4. Best Practices Research
2914
+ **When:** Before Development
2915
+ **Goal:** Gather current patterns and anti-patterns
2916
+ **Process:**
2917
+ 1. Search for latest framework documentation and guides
2918
+ 2. Find community-recommended patterns for the stack
2919
+ 3. Identify common pitfalls and anti-patterns
2920
+ 4. Research testing strategies for the chosen tools
2921
+ 5. Find performance optimization techniques
2922
+
2923
+ **Output:** \`.fishi/research/best-practices.md\`
2924
+
2925
+ ### 5. Security Research
2926
+ **When:** Before Deployment
2927
+ **Goal:** Identify security considerations
2928
+ **Process:**
2929
+ 1. Research known vulnerabilities for chosen dependencies
2930
+ 2. Find OWASP guidelines relevant to the project type
2931
+ 3. Identify authentication/authorization best practices
2932
+ 4. Research data protection requirements (GDPR, CCPA)
2933
+ 5. Find security testing approaches
2934
+
2935
+ **Output:** \`.fishi/research/security-assessment.md\`
2936
+
2937
+ ## Report Format
2938
+
2939
+ Every research report follows this structure:
2940
+
2941
+ \`\`\`markdown
2942
+ # [Research Type] \u2014 [Project Name]
2943
+ **Date:** [timestamp]
2944
+ **Researcher:** deep-research-agent
2945
+ **Confidence:** high|medium|low
2946
+
2947
+ ## Executive Summary
2948
+ [2-3 sentence overview of findings]
2949
+
2950
+ ## Key Findings
2951
+ 1. [Finding with supporting evidence]
2952
+ 2. [Finding with supporting evidence]
2953
+ ...
2954
+
2955
+ ## Recommendations
2956
+ - [Actionable recommendation for other agents]
2957
+ - [Actionable recommendation for other agents]
2958
+
2959
+ ## Sources
2960
+ - [Source 1 with URL]
2961
+ - [Source 2 with URL]
2962
+
2963
+ ## Raw Data
2964
+ [Detailed notes and excerpts organized by topic]
2965
+ \`\`\`
2966
+
2967
+ ## Tools Available
2968
+ - Web search via MCP (perplexity, context7)
2969
+ - Documentation fetching via WebFetch
2970
+ - GitHub repository analysis via MCP (github)
2971
+ - Package registry search (npm, PyPI)
2972
+
2973
+ ## Integration
2974
+ - Reports saved to \`.fishi/research/\` directory
2975
+ - Other agents reference reports via memory system
2976
+ - Research findings feed into PRD and architecture decisions
2977
+ - Updated research can trigger architecture revisions
2978
+ `;
2979
+ }
2980
+
2607
2981
  // src/templates/skills/brainstorming.ts
2608
2982
  function getBrainstormingSkill() {
2609
2983
  return `# Brainstorming & Design Refinement Skill
@@ -3940,6 +4314,64 @@ documentation as a first-class deliverable, not an afterthought.
3940
4314
  `;
3941
4315
  }
3942
4316
 
4317
+ // src/templates/skills/deep-research.ts
4318
+ function getDeepResearchSkill() {
4319
+ return `---
4320
+ name: deep-research
4321
+ description: Autonomous research workflow \u2014 domain analysis, competitive intel, tech stack evaluation, best practices gathering
4322
+ ---
4323
+
4324
+ # Deep Research Skill
4325
+
4326
+ ## Purpose
4327
+ Conduct structured autonomous research to inform project decisions.
4328
+ Used by the Deep Research Agent during Discovery, PRD, and Architecture phases.
4329
+
4330
+ ## Workflow
4331
+
4332
+ ### Step 1: Define Research Scope
4333
+ - What domain/topic needs research?
4334
+ - What specific questions need answers?
4335
+ - What decisions will this research inform?
4336
+
4337
+ ### Step 2: Gather Information
4338
+ - Search web for current information (use MCP tools)
4339
+ - Read relevant documentation and guides
4340
+ - Analyze competitor products and patterns
4341
+ - Check package registries for library options
4342
+
4343
+ ### Step 3: Synthesize Findings
4344
+ - Organize by topic with evidence
4345
+ - Rate confidence: high (multiple sources agree), medium (some evidence), low (limited data)
4346
+ - Identify gaps where more research is needed
4347
+
4348
+ ### Step 4: Produce Report
4349
+ Save to \`.fishi/research/{topic}.md\` with standard format:
4350
+ - Executive Summary
4351
+ - Key Findings (numbered, with evidence)
4352
+ - Recommendations (actionable)
4353
+ - Sources (with URLs)
4354
+
4355
+ ### Step 5: Feed to Agents
4356
+ - Notify planning-lead of completed research
4357
+ - Update agent memory with key findings
4358
+ - Reference in PRD and architecture documents
4359
+
4360
+ ## Research Commands
4361
+ \`\`\`bash
4362
+ node .fishi/scripts/phase-runner.mjs current # Check current phase
4363
+ node .fishi/scripts/memory-manager.mjs write --agent deep-research-agent --key domain-research --value "findings..."
4364
+ \`\`\`
4365
+
4366
+ ## Quality Checklist
4367
+ - [ ] Multiple sources consulted (not just one)
4368
+ - [ ] Findings are current (within last 12 months)
4369
+ - [ ] Recommendations are specific and actionable
4370
+ - [ ] Confidence levels assigned to each finding
4371
+ - [ ] Sources are cited with URLs
4372
+ `;
4373
+ }
4374
+
3943
4375
  // src/templates/hooks/session-start.ts
3944
4376
  function getSessionStartHook() {
3945
4377
  return `#!/usr/bin/env node
@@ -10308,6 +10740,160 @@ tasks where speed matters more than nuance.
10308
10740
  `;
10309
10741
  }
10310
10742
 
10743
+ // src/templates/configs/soul-md.ts
10744
+ function getSoulMdTemplate() {
10745
+ return `# SOUL.md \u2014 FISHI Agent Boundaries
10746
+
10747
+ > This file defines absolute boundaries that NO agent may cross autonomously.
10748
+ > These rules override all other instructions, skills, and commands.
10749
+
10750
+ ## Core Principles
10751
+
10752
+ 1. **Human authority is final.** Agents assist; humans decide.
10753
+ 2. **Reversibility first.** Prefer reversible actions. Irreversible actions require human confirmation.
10754
+ 3. **Least privilege.** Agents operate with minimum necessary access.
10755
+ 4. **Transparency.** All agent actions are logged and observable.
10756
+
10757
+ ## Absolute Boundaries
10758
+
10759
+ ### Never Do Autonomously
10760
+ - Delete files, directories, or data without explicit human approval
10761
+ - Push code to production branches (main, master, production) without gate approval
10762
+ - Modify environment variables, secrets, or credentials
10763
+ - Make external API calls to services not in the sandbox allowlist
10764
+ - Install global packages or modify system configuration
10765
+ - Access files outside the assigned worktree (workers)
10766
+ - Execute shell commands that affect other users or processes
10767
+ - Disable safety hooks, permission rules, or gate requirements
10768
+ - Bypass the phase pipeline or skip mandatory gates
10769
+ - Send emails, messages, or notifications to external services
10770
+ - Access or transmit user personal data
10771
+ - Modify CI/CD pipelines without human review
10772
+
10773
+ ### Always Require Human Confirmation
10774
+ - Merging branches into main/dev
10775
+ - Deploying to any environment (staging, production)
10776
+ - Adding new external dependencies
10777
+ - Changing database schemas
10778
+ - Modifying authentication/authorization logic
10779
+ - Creating or modifying API endpoints that handle user data
10780
+ - Any action flagged by the security agent
10781
+
10782
+ ### Always Do
10783
+ - Log all significant actions to .fishi/logs/
10784
+ - Emit monitoring events via monitor-emitter
10785
+ - Work within assigned worktree boundaries
10786
+ - Follow the phase pipeline sequence
10787
+ - Submit work as PRs for review
10788
+ - Run tests before submitting work
10789
+ - Check sandbox policy before external access
10790
+
10791
+ ## Enforcement
10792
+
10793
+ These boundaries are enforced at three levels:
10794
+ 1. **SOUL.md** (this file) \u2014 read by all agents at session start
10795
+ 2. **AGENTS.md** \u2014 per-role action gates
10796
+ 3. **Tool permissions** \u2014 per-agent allow/deny lists in settings.json
10797
+
10798
+ Violation of these boundaries should be reported to the master-orchestrator
10799
+ and logged as a critical learnings entry.
10800
+ `;
10801
+ }
10802
+
10803
+ // src/templates/configs/agents-md.ts
10804
+ function getAgentsMdTemplate() {
10805
+ return `# AGENTS.md \u2014 FISHI Role-Based Action Gates
10806
+
10807
+ > Maps which actions require approval per agent role.
10808
+ > Read alongside SOUL.md for complete safety configuration.
10809
+
10810
+ ## Role Hierarchy
10811
+
10812
+ \`\`\`
10813
+ Level 0: Master Orchestrator \u2014 strategy only, no code, no file writes
10814
+ Level 1: Coordinators \u2014 task assignment, code review, limited writes
10815
+ Level 2: Workers \u2014 full dev within worktree, no merge, no deploy
10816
+ \`\`\`
10817
+
10818
+ ## Action Permissions by Role
10819
+
10820
+ ### Master Orchestrator (L0)
10821
+ | Action | Permission |
10822
+ |--------|-----------|
10823
+ | Read files | Allowed |
10824
+ | Write/Edit files | **DENIED** \u2014 delegates to coordinators |
10825
+ | Run shell commands | **DENIED** \u2014 delegates to workers |
10826
+ | Approve gates | Allowed (with human confirmation) |
10827
+ | Assign tasks | Allowed |
10828
+ | Create agents | Allowed (dynamic agent factory) |
10829
+ | Merge branches | **DENIED** \u2014 requires human gate approval |
10830
+ | Deploy | **DENIED** \u2014 requires deployment gate |
10831
+ | Delete files | **DENIED** |
10832
+
10833
+ ### Coordinators (L1)
10834
+ | Action | Permission |
10835
+ |--------|-----------|
10836
+ | Read files | Allowed |
10837
+ | Write/Edit files | Allowed (planning docs, task assignments) |
10838
+ | Run shell commands | Allowed (git status, test runs, non-destructive) |
10839
+ | Approve worker PRs | Allowed (code review) |
10840
+ | Create worktrees | Allowed |
10841
+ | Merge to dev branch | Allowed (after review) |
10842
+ | Merge to main/production | **DENIED** \u2014 requires gate |
10843
+ | Delete files | **DENIED** \u2014 archive instead |
10844
+ | Install dependencies | Allowed (within sandbox) |
10845
+ | Modify configs | **REQUIRES CONFIRMATION** |
10846
+
10847
+ ### Workers (L2)
10848
+ | Action | Permission |
10849
+ |--------|-----------|
10850
+ | Read files | Allowed (within worktree + shared) |
10851
+ | Write/Edit files | Allowed (within worktree only) |
10852
+ | Run shell commands | Allowed (within worktree sandbox) |
10853
+ | Run tests | Allowed |
10854
+ | Install dev dependencies | Allowed (within sandbox) |
10855
+ | Commit to worktree branch | Allowed |
10856
+ | Push to worktree branch | Allowed |
10857
+ | Merge branches | **DENIED** \u2014 submit PR to coordinator |
10858
+ | Delete files | **DENIED** \u2014 request via coordinator |
10859
+ | Access main branch | **READ ONLY** |
10860
+ | External API calls | **DENIED** \u2014 unless in sandbox allowlist |
10861
+
10862
+ ## Destructive Action Protocol
10863
+
10864
+ ### Delete Operations
10865
+ 1. **Files:** Never delete. Move to \`.fishi/archive/\` with timestamp.
10866
+ 2. **Branches:** Only after merge confirmed + worktree cleaned.
10867
+ 3. **Database records:** Never in production. Soft-delete only.
10868
+ 4. **Dependencies:** Remove only via coordinator approval.
10869
+
10870
+ ### Archive Instead of Delete
10871
+ \`\`\`
10872
+ Instead of: rm -rf old-feature/
10873
+ Do: mv old-feature/ .fishi/archive/old-feature-{timestamp}/
10874
+ \`\`\`
10875
+
10876
+ ### Escalation Path
10877
+ \`\`\`
10878
+ Worker encounters destructive need
10879
+ \u2192 Reports to Coordinator
10880
+ \u2192 Coordinator evaluates risk
10881
+ \u2192 If safe: Coordinator executes with logging
10882
+ \u2192 If risky: Escalate to Master
10883
+ \u2192 Master requests human confirmation via gate
10884
+ \`\`\`
10885
+
10886
+ ## Emergency Stop
10887
+
10888
+ If any agent detects behavior outside these boundaries:
10889
+ 1. Log the incident to \`.fishi/logs/safety-incidents.log\`
10890
+ 2. Emit \`safety.violation\` event to monitor
10891
+ 3. Notify master-orchestrator
10892
+ 4. Halt the violating agent's current task
10893
+ 5. Wait for human review before resuming
10894
+ `;
10895
+ }
10896
+
10311
10897
  // src/templates/factories/agent-template.ts
10312
10898
  function getAgentFactoryTemplate() {
10313
10899
  return `---
@@ -10691,6 +11277,7 @@ async function generateScaffold(targetDir, options) {
10691
11277
  ".claude/skills/brownfield-discovery",
10692
11278
  ".claude/skills/adaptive-taskgraph",
10693
11279
  ".claude/skills/documentation",
11280
+ ".claude/skills/deep-research",
10694
11281
  ".claude/commands",
10695
11282
  "docs",
10696
11283
  ".fishi/plans/prd",
@@ -10708,6 +11295,8 @@ async function generateScaffold(targetDir, options) {
10708
11295
  ".fishi/todos/agents",
10709
11296
  ".fishi/learnings/by-domain",
10710
11297
  ".fishi/learnings/by-agent",
11298
+ ".fishi/archive",
11299
+ ".fishi/research",
10711
11300
  ".trees"
10712
11301
  ];
10713
11302
  for (const dir of dirs) {
@@ -10731,7 +11320,22 @@ async function generateScaffold(targetDir, options) {
10731
11320
  await write(".claude/agents/docs-agent.md", docsAgentTemplate(ctx), "agents");
10732
11321
  await write(".claude/agents/writing-agent.md", writingAgentTemplate(ctx), "agents");
10733
11322
  await write(".claude/agents/marketing-agent.md", marketingAgentTemplate(ctx), "agents");
10734
- const agentCount = 18;
11323
+ let agentCount = 18;
11324
+ await write(".claude/agents/deep-research-agent.md", getDeepResearchAgentTemplate(), "agents");
11325
+ agentCount++;
11326
+ if (options.domain && options.domain !== "general") {
11327
+ const domainTemplates = {
11328
+ saas: getSaasArchitectTemplate,
11329
+ marketplace: getMarketplaceArchitectTemplate,
11330
+ mobile: getMobileArchitectTemplate,
11331
+ aiml: getAimlArchitectTemplate
11332
+ };
11333
+ const template = domainTemplates[options.domain];
11334
+ if (template) {
11335
+ await write(`.claude/agents/${options.domain}-architect.md`, template(), "agents");
11336
+ agentCount++;
11337
+ }
11338
+ }
10735
11339
  await write(".fishi/agent-factory/agent-template.md", getAgentFactoryTemplate());
10736
11340
  await write(".fishi/agent-factory/coordinator-template.md", getCoordinatorFactoryTemplate());
10737
11341
  await write(".claude/skills/brainstorming/SKILL.md", getBrainstormingSkill(), "skills");
@@ -10746,7 +11350,8 @@ async function generateScaffold(targetDir, options) {
10746
11350
  await write(".claude/skills/brownfield-discovery/SKILL.md", getBrownfieldDiscoverySkill(), "skills");
10747
11351
  await write(".claude/skills/adaptive-taskgraph/SKILL.md", getAdaptiveTaskGraphSkill(), "skills");
10748
11352
  await write(".claude/skills/documentation/SKILL.md", getDocumentationSkill(), "skills");
10749
- const skillCount = 12;
11353
+ await write(".claude/skills/deep-research/SKILL.md", getDeepResearchSkill(), "skills");
11354
+ const skillCount = 13;
10750
11355
  await write(".fishi/scripts/session-start.mjs", getSessionStartHook());
10751
11356
  await write(".fishi/scripts/auto-checkpoint.mjs", getAutoCheckpointHook());
10752
11357
  await write(".fishi/scripts/agent-complete.mjs", getAgentCompleteHook());
@@ -10788,6 +11393,8 @@ async function generateScaffold(targetDir, options) {
10788
11393
  await write(".claude/commands/fishi-reset.md", getResetCommand(), "commands");
10789
11394
  await write(".claude/commands/fishi-prd.md", getPrdCommand(), "commands");
10790
11395
  const commandCount = 8;
11396
+ await write("SOUL.md", getSoulMdTemplate());
11397
+ await write("AGENTS.md", getAgentsMdTemplate());
10791
11398
  await write(".fishi/fishi.yaml", getFishiYamlTemplate({
10792
11399
  projectName: options.projectName,
10793
11400
  projectDescription: ctx.projectDescription,
@@ -11111,7 +11718,7 @@ async function createBackup(targetDir, conflictingFiles) {
11111
11718
  manifestFiles.push({ path: relPath, size: stat.size });
11112
11719
  }
11113
11720
  }
11114
- const fishiVersion = "0.8.0";
11721
+ const fishiVersion = "0.11.0";
11115
11722
  const manifest = {
11116
11723
  timestamp: now.toISOString(),
11117
11724
  fishi_version: fishiVersion,
@@ -11466,6 +12073,537 @@ vibe_mode:
11466
12073
  `;
11467
12074
  }
11468
12075
 
12076
+ // src/generators/design-system.ts
12077
+ import { existsSync as existsSync7, readFileSync as readFileSync4, readdirSync } from "fs";
12078
+ import { join as join7 } from "path";
12079
+ function detectDesignTokens(projectDir) {
12080
+ const tokens = {
12081
+ colors: {},
12082
+ typography: { fontFamilies: [], scale: {} },
12083
+ spacing: {},
12084
+ borderRadius: {},
12085
+ shadows: {},
12086
+ darkMode: false
12087
+ };
12088
+ const tailwindFiles = ["tailwind.config.js", "tailwind.config.ts", "tailwind.config.mjs", "tailwind.config.cjs"];
12089
+ for (const file of tailwindFiles) {
12090
+ const p = join7(projectDir, file);
12091
+ if (existsSync7(p)) {
12092
+ const content = readFileSync4(p, "utf-8");
12093
+ const colorMatches = content.matchAll(/['"]?([\w-]+)['"]?\s*:\s*['"]?(#[0-9a-fA-F]{3,8})['"]?/g);
12094
+ for (const m of colorMatches) {
12095
+ tokens.colors[m[1]] = m[2];
12096
+ }
12097
+ if (content.includes("darkMode")) tokens.darkMode = true;
12098
+ break;
12099
+ }
12100
+ }
12101
+ const cssFiles = findFiles(projectDir, ["src", "styles", "app"], [".css"]);
12102
+ for (const file of cssFiles.slice(0, 10)) {
12103
+ try {
12104
+ const content = readFileSync4(file, "utf-8");
12105
+ const varMatches = content.matchAll(/--(\w[\w-]*)\s*:\s*([^;]+)/g);
12106
+ for (const m of varMatches) {
12107
+ const name = m[1];
12108
+ const value = m[2].trim();
12109
+ if (name.includes("color") || name.includes("bg") || value.startsWith("#") || value.startsWith("rgb") || value.startsWith("hsl")) {
12110
+ tokens.colors[name] = value;
12111
+ } else if (name.includes("font")) {
12112
+ if (name.includes("size")) tokens.typography.scale[name] = value;
12113
+ else if (name.includes("family")) tokens.typography.fontFamilies.push(value);
12114
+ } else if (name.includes("spacing") || name.includes("gap") || name.includes("padding") || name.includes("margin")) {
12115
+ tokens.spacing[name] = value;
12116
+ } else if (name.includes("radius")) {
12117
+ tokens.borderRadius[name] = value;
12118
+ } else if (name.includes("shadow")) {
12119
+ tokens.shadows[name] = value;
12120
+ }
12121
+ }
12122
+ if (content.includes("prefers-color-scheme: dark") || content.includes(".dark")) {
12123
+ tokens.darkMode = true;
12124
+ }
12125
+ } catch {
12126
+ }
12127
+ }
12128
+ const themeFiles = ["theme.ts", "theme.js", "theme.json", "src/theme.ts", "src/theme.js", "src/styles/theme.ts"];
12129
+ for (const file of themeFiles) {
12130
+ if (existsSync7(join7(projectDir, file))) {
12131
+ try {
12132
+ const content = readFileSync4(join7(projectDir, file), "utf-8");
12133
+ const colorMatches = content.matchAll(/['"]?([\w-]+)['"]?\s*:\s*['"]?(#[0-9a-fA-F]{3,8})['"]?/g);
12134
+ for (const m of colorMatches) {
12135
+ tokens.colors[m[1]] = m[2];
12136
+ }
12137
+ } catch {
12138
+ }
12139
+ break;
12140
+ }
12141
+ }
12142
+ return tokens;
12143
+ }
12144
+ function generateDefaultTokens() {
12145
+ return {
12146
+ colors: {
12147
+ "brand-50": "#f0f7ff",
12148
+ "brand-100": "#e0efff",
12149
+ "brand-200": "#b8d9ff",
12150
+ "brand-500": "#0066cc",
12151
+ "brand-600": "#0052a3",
12152
+ "brand-700": "#003d7a",
12153
+ "brand-900": "#001f3f",
12154
+ "gray-50": "#f9fafb",
12155
+ "gray-100": "#f3f4f6",
12156
+ "gray-200": "#e5e7eb",
12157
+ "gray-500": "#6b7280",
12158
+ "gray-700": "#374151",
12159
+ "gray-900": "#111827",
12160
+ "success": "#22c55e",
12161
+ "warning": "#f59e0b",
12162
+ "error": "#ef4444"
12163
+ },
12164
+ typography: {
12165
+ fontFamilies: ['-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'],
12166
+ scale: {
12167
+ "xs": "0.75rem",
12168
+ "sm": "0.875rem",
12169
+ "base": "1rem",
12170
+ "lg": "1.125rem",
12171
+ "xl": "1.25rem",
12172
+ "2xl": "1.5rem",
12173
+ "3xl": "1.875rem",
12174
+ "4xl": "2.25rem"
12175
+ }
12176
+ },
12177
+ spacing: {
12178
+ "xs": "0.25rem",
12179
+ "sm": "0.5rem",
12180
+ "md": "1rem",
12181
+ "lg": "1.5rem",
12182
+ "xl": "2rem",
12183
+ "2xl": "3rem",
12184
+ "3xl": "4rem"
12185
+ },
12186
+ borderRadius: {
12187
+ "sm": "0.25rem",
12188
+ "md": "0.375rem",
12189
+ "lg": "0.5rem",
12190
+ "xl": "0.75rem",
12191
+ "full": "9999px"
12192
+ },
12193
+ shadows: {
12194
+ "sm": "0 1px 2px rgba(0,0,0,0.05)",
12195
+ "md": "0 4px 6px rgba(0,0,0,0.1)",
12196
+ "lg": "0 10px 15px rgba(0,0,0,0.1)"
12197
+ },
12198
+ darkMode: true
12199
+ };
12200
+ }
12201
+ function detectComponentRegistry(projectDir) {
12202
+ const registry = {
12203
+ components: [],
12204
+ library: null,
12205
+ framework: null
12206
+ };
12207
+ const pkgPath = join7(projectDir, "package.json");
12208
+ if (existsSync7(pkgPath)) {
12209
+ const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
12210
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
12211
+ if (deps["@shadcn/ui"] || existsSync7(join7(projectDir, "components.json"))) registry.library = "shadcn";
12212
+ else if (deps["@radix-ui/react-dialog"] || deps["@radix-ui/themes"]) registry.library = "radix";
12213
+ else if (deps["@mui/material"]) registry.library = "mui";
12214
+ else if (deps["antd"]) registry.library = "antd";
12215
+ else if (deps["@chakra-ui/react"]) registry.library = "chakra";
12216
+ else if (deps["@headlessui/react"]) registry.library = "headlessui";
12217
+ if (deps["react"] || deps["react-dom"]) registry.framework = "react";
12218
+ else if (deps["vue"]) registry.framework = "vue";
12219
+ else if (deps["svelte"]) registry.framework = "svelte";
12220
+ else if (deps["@angular/core"]) registry.framework = "angular";
12221
+ }
12222
+ const componentDirs = ["src/components", "components", "src/ui", "app/components", "src/components/ui"];
12223
+ for (const dir of componentDirs) {
12224
+ const fullDir = join7(projectDir, dir);
12225
+ if (existsSync7(fullDir)) {
12226
+ try {
12227
+ scanComponents(fullDir, dir, registry.components);
12228
+ } catch {
12229
+ }
12230
+ }
12231
+ }
12232
+ return registry;
12233
+ }
12234
+ function scanComponents(dir, relBase, components) {
12235
+ try {
12236
+ const entries = readdirSync(dir, { withFileTypes: true });
12237
+ for (const entry of entries) {
12238
+ if (entry.isDirectory()) {
12239
+ scanComponents(join7(dir, entry.name), `${relBase}/${entry.name}`, components);
12240
+ } else if (entry.name.match(/\.(tsx|jsx|vue|svelte)$/)) {
12241
+ const name = entry.name.replace(/\.(tsx|jsx|vue|svelte)$/, "");
12242
+ if (name === "index") continue;
12243
+ const type = classifyComponent(name);
12244
+ components.push({ name, path: `${relBase}/${entry.name}`, type });
12245
+ }
12246
+ }
12247
+ } catch {
12248
+ }
12249
+ }
12250
+ function classifyComponent(name) {
12251
+ const lower = name.toLowerCase();
12252
+ if (/button|badge|avatar|icon|tag|chip|tooltip/i.test(lower)) return "ui";
12253
+ if (/layout|header|footer|sidebar|menu/i.test(lower)) return "layout";
12254
+ if (/input|form|select|checkbox|radio|textarea|switch|slider/i.test(lower)) return "form";
12255
+ if (/table|list|card|grid|chart|graph|stat/i.test(lower)) return "data";
12256
+ if (/link|breadcrumb|tab|pagination|stepper|nav|navbar/i.test(lower)) return "navigation";
12257
+ return "other";
12258
+ }
12259
+ function runBrandGuardian(projectDir, tokens) {
12260
+ const issues = [];
12261
+ let filesScanned = 0;
12262
+ const files = findFiles(projectDir, ["src", "app", "pages", "components"], [".tsx", ".jsx", ".vue", ".svelte", ".css"]);
12263
+ for (const file of files.slice(0, 100)) {
12264
+ try {
12265
+ const content = readFileSync4(file, "utf-8");
12266
+ const lines = content.split("\n");
12267
+ const relPath = file.replace(projectDir, "").replace(/\\/g, "/").replace(/^\//, "");
12268
+ filesScanned++;
12269
+ for (let i = 0; i < lines.length; i++) {
12270
+ const line = lines[i];
12271
+ const lineNum = i + 1;
12272
+ if (file.match(/\.(tsx|jsx|vue|svelte)$/)) {
12273
+ const hexMatches = line.matchAll(/#[0-9a-fA-F]{3,8}\b/g);
12274
+ for (const m of hexMatches) {
12275
+ if (line.trimStart().startsWith("//") || line.trimStart().startsWith("*")) continue;
12276
+ if (line.includes("--")) continue;
12277
+ issues.push({
12278
+ file: relPath,
12279
+ line: lineNum,
12280
+ severity: "warning",
12281
+ rule: "no-hardcoded-colors",
12282
+ message: `Hardcoded color ${m[0]} \u2014 use design tokens instead`,
12283
+ fix: "Replace with a CSS variable or Tailwind class from your design system"
12284
+ });
12285
+ }
12286
+ }
12287
+ if (line.includes("style=") && line.match(/\d+px/)) {
12288
+ issues.push({
12289
+ file: relPath,
12290
+ line: lineNum,
12291
+ severity: "warning",
12292
+ rule: "no-inline-px",
12293
+ message: "Inline px values \u2014 use spacing tokens or Tailwind classes",
12294
+ fix: "Replace px values with spacing scale (xs, sm, md, lg, xl)"
12295
+ });
12296
+ }
12297
+ if (line.match(/<img\b/) && !line.includes("alt=") && !line.includes("alt =")) {
12298
+ issues.push({
12299
+ file: relPath,
12300
+ line: lineNum,
12301
+ severity: "error",
12302
+ rule: "img-alt-text",
12303
+ message: "Image missing alt attribute \u2014 accessibility violation",
12304
+ fix: 'Add alt="descriptive text" or alt="" for decorative images'
12305
+ });
12306
+ }
12307
+ if (line.includes("onClick") && !line.includes("onKeyDown") && !line.includes("onKeyUp") && !line.includes("onKeyPress")) {
12308
+ if (line.includes("<div") || line.includes("<span")) {
12309
+ issues.push({
12310
+ file: relPath,
12311
+ line: lineNum,
12312
+ severity: "warning",
12313
+ rule: "keyboard-accessible",
12314
+ message: "Click handler on non-interactive element without keyboard support",
12315
+ fix: 'Add onKeyDown handler and role="button" tabIndex={0}, or use <button>'
12316
+ });
12317
+ }
12318
+ }
12319
+ if (line.match(/font-size:\s*\d+px/) && !line.includes("--")) {
12320
+ issues.push({
12321
+ file: relPath,
12322
+ line: lineNum,
12323
+ severity: "info",
12324
+ rule: "use-typography-scale",
12325
+ message: "Hardcoded font-size \u2014 use typography scale tokens",
12326
+ fix: "Replace with typography scale class (text-xs, text-sm, text-base, etc.)"
12327
+ });
12328
+ }
12329
+ if (line.match(/<html\b/) && !line.includes("lang=")) {
12330
+ issues.push({
12331
+ file: relPath,
12332
+ line: lineNum,
12333
+ severity: "error",
12334
+ rule: "html-lang",
12335
+ message: "HTML element missing lang attribute \u2014 accessibility violation",
12336
+ fix: 'Add lang="en" (or appropriate language code) to <html>'
12337
+ });
12338
+ }
12339
+ }
12340
+ } catch {
12341
+ }
12342
+ }
12343
+ const errors = issues.filter((i) => i.severity === "error").length;
12344
+ const warnings = issues.filter((i) => i.severity === "warning").length;
12345
+ const infos = issues.filter((i) => i.severity === "info").length;
12346
+ return {
12347
+ issues,
12348
+ passed: errors === 0,
12349
+ stats: { errors, warnings, infos, filesScanned }
12350
+ };
12351
+ }
12352
+ function generateDesignSystemConfig(tokens, registry) {
12353
+ return JSON.stringify({
12354
+ version: "1.0",
12355
+ tokens,
12356
+ components: {
12357
+ library: registry.library,
12358
+ framework: registry.framework,
12359
+ count: registry.components.length,
12360
+ entries: registry.components
12361
+ }
12362
+ }, null, 2) + "\n";
12363
+ }
12364
+ function findFiles(base, dirs, extensions) {
12365
+ const files = [];
12366
+ for (const dir of dirs) {
12367
+ const fullDir = join7(base, dir);
12368
+ if (existsSync7(fullDir)) {
12369
+ walkDir(fullDir, extensions, files);
12370
+ }
12371
+ }
12372
+ return files;
12373
+ }
12374
+ function walkDir(dir, extensions, result) {
12375
+ try {
12376
+ const entries = readdirSync(dir, { withFileTypes: true });
12377
+ for (const entry of entries) {
12378
+ const full = join7(dir, entry.name);
12379
+ if (entry.isDirectory()) {
12380
+ if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist" || entry.name === ".git") continue;
12381
+ walkDir(full, extensions, result);
12382
+ } else if (extensions.some((ext) => entry.name.endsWith(ext))) {
12383
+ result.push(full);
12384
+ }
12385
+ }
12386
+ } catch {
12387
+ }
12388
+ }
12389
+
12390
+ // src/generators/domain-manager.ts
12391
+ import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
12392
+ import { join as join8 } from "path";
12393
+ var DOMAIN_INFO = {
12394
+ saas: {
12395
+ label: "SaaS",
12396
+ description: "Subscription billing, multi-tenancy, user management (Stripe, Auth0)",
12397
+ agent: "saas-architect"
12398
+ },
12399
+ marketplace: {
12400
+ label: "Marketplace",
12401
+ description: "Two-sided platform, escrow, disputes, vendor management (Stripe Connect)",
12402
+ agent: "marketplace-architect"
12403
+ },
12404
+ mobile: {
12405
+ label: "Mobile / PWA",
12406
+ description: "Progressive web app, offline sync, push notifications, responsive design",
12407
+ agent: "mobile-architect"
12408
+ },
12409
+ aiml: {
12410
+ label: "AI / ML",
12411
+ description: "RAG pipelines, embeddings, fine-tuning, model serving, LLM integration",
12412
+ agent: "aiml-architect"
12413
+ },
12414
+ general: {
12415
+ label: "General",
12416
+ description: "No domain specialization \u2014 use base agents only",
12417
+ agent: null
12418
+ }
12419
+ };
12420
+ function getAvailableDomains() {
12421
+ return Object.entries(DOMAIN_INFO).map(([key, info]) => ({
12422
+ value: key,
12423
+ name: `${info.label} \u2014 ${info.description}`
12424
+ }));
12425
+ }
12426
+ function readDomainConfig(projectDir) {
12427
+ const yamlPath = join8(projectDir, ".fishi", "fishi.yaml");
12428
+ if (!existsSync8(yamlPath)) {
12429
+ return { domain: "general", domainAgent: null, researchEnabled: false };
12430
+ }
12431
+ const content = readFileSync5(yamlPath, "utf-8");
12432
+ const domainMatch = content.match(/^\s*type:\s*(\w+)/m);
12433
+ const researchMatch = content.match(/^\s*research_enabled:\s*(true|false)/m);
12434
+ const domain = domainMatch?.[1] || "general";
12435
+ return {
12436
+ domain,
12437
+ domainAgent: DOMAIN_INFO[domain]?.agent || null,
12438
+ researchEnabled: researchMatch?.[1] === "true"
12439
+ };
12440
+ }
12441
+ function getDomainConfigYaml(domain) {
12442
+ const info = DOMAIN_INFO[domain];
12443
+ return `
12444
+ domain:
12445
+ type: ${domain}
12446
+ label: "${info.label}"
12447
+ specialist_agent: ${info.agent || "none"}
12448
+ research_enabled: true
12449
+ `;
12450
+ }
12451
+
12452
+ // src/generators/agent-permissions.ts
12453
+ function getPermissionsForRole(role) {
12454
+ switch (role) {
12455
+ case "master":
12456
+ return {
12457
+ role: "master",
12458
+ allow: [
12459
+ "Read",
12460
+ "Glob",
12461
+ "Grep",
12462
+ "Agent",
12463
+ "TodoRead",
12464
+ "TodoWrite",
12465
+ "WebFetch",
12466
+ "WebSearch"
12467
+ ],
12468
+ deny: [
12469
+ "Write",
12470
+ "Edit",
12471
+ "Bash(*)",
12472
+ "NotebookEdit",
12473
+ "Bash(rm *)",
12474
+ "Bash(git push *)",
12475
+ "Bash(git merge *)",
12476
+ "Bash(npm *)",
12477
+ "Bash(pnpm *)"
12478
+ ]
12479
+ };
12480
+ case "coordinator":
12481
+ return {
12482
+ role: "coordinator",
12483
+ allow: [
12484
+ "Read",
12485
+ "Write",
12486
+ "Edit",
12487
+ "Glob",
12488
+ "Grep",
12489
+ "Agent",
12490
+ "TodoRead",
12491
+ "TodoWrite",
12492
+ "WebFetch",
12493
+ "WebSearch",
12494
+ "Bash(git status *)",
12495
+ "Bash(git log *)",
12496
+ "Bash(git diff *)",
12497
+ "Bash(git branch *)",
12498
+ "Bash(git checkout *)",
12499
+ "Bash(git worktree *)",
12500
+ "Bash(node *)",
12501
+ "Bash(npx vitest *)",
12502
+ "Bash(npx tsc *)",
12503
+ "Bash(pnpm install *)",
12504
+ "Bash(pnpm add *)",
12505
+ "Bash(cat *)",
12506
+ "Bash(ls *)",
12507
+ "Bash(find *)"
12508
+ ],
12509
+ deny: [
12510
+ "Bash(rm -rf *)",
12511
+ "Bash(git push --force *)",
12512
+ "Bash(git push * main)",
12513
+ "Bash(git push * master)",
12514
+ "Bash(git push * production)",
12515
+ "Bash(git merge * main)",
12516
+ "Bash(git merge * master)",
12517
+ "Bash(sudo *)",
12518
+ "Bash(chmod *)",
12519
+ "Bash(shutdown *)",
12520
+ "Bash(mkfs *)",
12521
+ "Bash(dd *)",
12522
+ "Bash(npm *)"
12523
+ ]
12524
+ };
12525
+ case "worker":
12526
+ return {
12527
+ role: "worker",
12528
+ allow: [
12529
+ "Read",
12530
+ "Write",
12531
+ "Edit",
12532
+ "Glob",
12533
+ "Grep",
12534
+ "Agent",
12535
+ "TodoRead",
12536
+ "TodoWrite",
12537
+ "WebFetch",
12538
+ "WebSearch",
12539
+ "Bash(node *)",
12540
+ "Bash(npx *)",
12541
+ "Bash(pnpm *)",
12542
+ "Bash(git add *)",
12543
+ "Bash(git commit *)",
12544
+ "Bash(git status *)",
12545
+ "Bash(git log *)",
12546
+ "Bash(git diff *)",
12547
+ "Bash(tsc *)",
12548
+ "Bash(eslint *)",
12549
+ "Bash(prettier *)",
12550
+ "Bash(cat *)",
12551
+ "Bash(ls *)",
12552
+ "Bash(find *)",
12553
+ "Bash(grep *)",
12554
+ "Bash(wc *)",
12555
+ "Bash(head *)",
12556
+ "Bash(tail *)",
12557
+ "Bash(sort *)",
12558
+ "Bash(mkdir *)",
12559
+ "Bash(cp *)",
12560
+ "Bash(mv *)"
12561
+ ],
12562
+ deny: [
12563
+ "Bash(rm -rf *)",
12564
+ "Bash(rm -r /)",
12565
+ "Bash(git push --force *)",
12566
+ "Bash(git push * main)",
12567
+ "Bash(git push * master)",
12568
+ "Bash(git push * production)",
12569
+ "Bash(git merge *)",
12570
+ "Bash(git branch -D *)",
12571
+ "Bash(sudo *)",
12572
+ "Bash(chmod 777 *)",
12573
+ "Bash(shutdown *)",
12574
+ "Bash(reboot *)",
12575
+ "Bash(mkfs *)",
12576
+ "Bash(dd *)",
12577
+ "Bash(kill -9 *)",
12578
+ "Bash(pkill *)",
12579
+ "Bash(npm *)",
12580
+ "Bash(curl * | sh)",
12581
+ "Bash(wget * | sh)"
12582
+ ]
12583
+ };
12584
+ }
12585
+ }
12586
+ function getAllPermissionSummary() {
12587
+ const roles = ["master", "coordinator", "worker"];
12588
+ const result = {};
12589
+ for (const role of roles) {
12590
+ const perms = getPermissionsForRole(role);
12591
+ result[role] = { allowCount: perms.allow.length, denyCount: perms.deny.length };
12592
+ }
12593
+ return result;
12594
+ }
12595
+ function generatePermissionBlock(role) {
12596
+ const perms = getPermissionsForRole(role);
12597
+ const allowLines = perms.allow.map((r) => ` - "${r}"`).join("\n");
12598
+ const denyLines = perms.deny.map((r) => ` - "${r}"`).join("\n");
12599
+ return `permissions:
12600
+ role: ${role}
12601
+ allow:
12602
+ ${allowLines}
12603
+ deny:
12604
+ ${denyLines}`;
12605
+ }
12606
+
11469
12607
  // src/templates/configs/sandbox-policy.ts
11470
12608
  function getSandboxPolicyTemplate() {
11471
12609
  return `# FISHI Sandbox Policy
@@ -11858,11 +12996,14 @@ function getDashboardHtml() {
11858
12996
  </html>`;
11859
12997
  }
11860
12998
  export {
12999
+ DOMAIN_INFO,
11861
13000
  architectAgentTemplate,
11862
13001
  backendAgentTemplate,
11863
13002
  buildSandboxEnv,
11864
13003
  createBackup,
13004
+ detectComponentRegistry,
11865
13005
  detectConflicts,
13006
+ detectDesignTokens,
11866
13007
  detectDevServer,
11867
13008
  detectDocker,
11868
13009
  devLeadTemplate,
@@ -11871,14 +13012,21 @@ export {
11871
13012
  emitEvent,
11872
13013
  frontendAgentTemplate,
11873
13014
  fullstackAgentTemplate,
13015
+ generateDefaultTokens,
13016
+ generateDesignSystemConfig,
13017
+ generatePermissionBlock,
11874
13018
  generateScaffold,
11875
13019
  getAdaptiveTaskGraphSkill,
11876
13020
  getAgentCompleteHook,
11877
13021
  getAgentFactoryTemplate,
11878
13022
  getAgentRegistryTemplate,
11879
13023
  getAgentSummary,
13024
+ getAgentsMdTemplate,
13025
+ getAimlArchitectTemplate,
13026
+ getAllPermissionSummary,
11880
13027
  getApiDesignSkill,
11881
13028
  getAutoCheckpointHook,
13029
+ getAvailableDomains,
11882
13030
  getBoardCommand,
11883
13031
  getBrainstormingSkill,
11884
13032
  getBrownfieldAnalysisSkill,
@@ -11888,21 +13036,27 @@ export {
11888
13036
  getCoordinatorFactoryTemplate,
11889
13037
  getDashboardHtml,
11890
13038
  getDebuggingSkill,
13039
+ getDeepResearchAgentTemplate,
13040
+ getDeepResearchSkill,
11891
13041
  getDeploymentSkill,
11892
13042
  getDocCheckerScript,
11893
13043
  getDockerfileTemplate,
11894
13044
  getDocumentationSkill,
13045
+ getDomainConfigYaml,
11895
13046
  getFishiYamlTemplate,
11896
13047
  getGateCommand,
11897
13048
  getGateManagerScript,
11898
13049
  getGitignoreAdditions,
11899
13050
  getInitCommand,
11900
13051
  getLearningsManagerScript,
13052
+ getMarketplaceArchitectTemplate,
11901
13053
  getMasterOrchestratorTemplate,
11902
13054
  getMcpJsonTemplate,
11903
13055
  getMemoryManagerScript,
13056
+ getMobileArchitectTemplate,
11904
13057
  getModelRoutingReference,
11905
13058
  getMonitorEmitterScript,
13059
+ getPermissionsForRole,
11906
13060
  getPhaseRunnerScript,
11907
13061
  getPostEditHook,
11908
13062
  getPrdCommand,
@@ -11910,10 +13064,12 @@ export {
11910
13064
  getProjectYamlTemplate,
11911
13065
  getResetCommand,
11912
13066
  getResumeCommand,
13067
+ getSaasArchitectTemplate,
11913
13068
  getSafetyCheckHook,
11914
13069
  getSandboxPolicyTemplate,
11915
13070
  getSessionStartHook,
11916
13071
  getSettingsJsonTemplate,
13072
+ getSoulMdTemplate,
11917
13073
  getSprintCommand,
11918
13074
  getStatusCommand,
11919
13075
  getTaskboardOpsSkill,
@@ -11934,10 +13090,12 @@ export {
11934
13090
  planningAgentTemplate,
11935
13091
  planningLeadTemplate,
11936
13092
  qualityLeadTemplate,
13093
+ readDomainConfig,
11937
13094
  readMonitorState,
11938
13095
  readSandboxConfig,
11939
13096
  readSandboxPolicy,
11940
13097
  researchAgentTemplate,
13098
+ runBrandGuardian,
11941
13099
  runInDockerSandbox,
11942
13100
  runInProcessSandbox,
11943
13101
  runInSandbox,