#
tokens: 49547/50000 79/223 files (page 1/15)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 1 of 15. Use http://codebase.md/pimzino/spec-workflow-mcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .dockerignore
├── .gitattributes
├── .github
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   ├── dashboard_issue.yml
│   │   ├── documentation.yml
│   │   ├── feature_request.yml
│   │   └── vscode_extension.yml
│   └── workflows
│       ├── claude-code-review.yml
│       └── claude.yml
├── .gitignore
├── CHANGELOG.md
├── containers
│   ├── .env.example
│   ├── DOCKER_USAGE.md
│   ├── docker-compose.yml
│   ├── Dockerfile
│   ├── example.mcp.json
│   └── README.md
├── docs
│   ├── CONFIGURATION.md
│   ├── DEVELOPMENT.md
│   ├── INTERFACES.md
│   ├── PROMPTING-GUIDE.md
│   ├── technical-documentation
│   │   ├── api-reference.md
│   │   ├── architecture.md
│   │   ├── context-management.md
│   │   ├── contributing.md
│   │   ├── dashboard.md
│   │   ├── developer-guide.md
│   │   ├── file-structure.md
│   │   ├── i18n-guide.md
│   │   ├── i18n-structure.md
│   │   ├── README.md
│   │   └── troubleshooting.md
│   ├── TOOLS-REFERENCE.md
│   ├── TROUBLESHOOTING.md
│   ├── USER-GUIDE.md
│   └── WORKFLOW.md
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── scripts
│   ├── copy-static.cjs
│   └── validate-i18n.js
├── src
│   ├── config.ts
│   ├── core
│   │   ├── archive-service.ts
│   │   ├── dashboard-session.ts
│   │   ├── implementation-log-migrator.ts
│   │   ├── parser.ts
│   │   ├── path-utils.ts
│   │   ├── project-registry.ts
│   │   ├── task-parser.ts
│   │   └── workspace-initializer.ts
│   ├── dashboard
│   │   ├── approval-storage.ts
│   │   ├── execution-history-manager.ts
│   │   ├── implementation-log-manager.ts
│   │   ├── job-scheduler.ts
│   │   ├── multi-server.ts
│   │   ├── parser.ts
│   │   ├── project-manager.ts
│   │   ├── public
│   │   │   ├── claude-icon-dark.svg
│   │   │   └── claude-icon.svg
│   │   ├── settings-manager.ts
│   │   ├── utils.ts
│   │   └── watcher.ts
│   ├── dashboard_frontend
│   │   ├── index.html
│   │   ├── src
│   │   │   ├── components
│   │   │   │   ├── I18nErrorBoundary.tsx
│   │   │   │   └── LanguageSelector.tsx
│   │   │   ├── i18n-dynamic.ts
│   │   │   ├── i18n.ts
│   │   │   ├── lib
│   │   │   │   └── utils.ts
│   │   │   ├── locales
│   │   │   │   ├── ar.json
│   │   │   │   ├── de.json
│   │   │   │   ├── en.json
│   │   │   │   ├── es.json
│   │   │   │   ├── fr.json
│   │   │   │   ├── it.json
│   │   │   │   ├── ja.json
│   │   │   │   ├── ko.json
│   │   │   │   ├── pt.json
│   │   │   │   ├── ru.json
│   │   │   │   └── zh.json
│   │   │   ├── main.tsx
│   │   │   ├── modules
│   │   │   │   ├── api
│   │   │   │   │   └── api.tsx
│   │   │   │   ├── app
│   │   │   │   │   └── App.tsx
│   │   │   │   ├── approvals
│   │   │   │   │   ├── ApprovalsAnnotator.tsx
│   │   │   │   │   └── colors.ts
│   │   │   │   ├── components
│   │   │   │   │   ├── KanbanBoard.tsx
│   │   │   │   │   ├── KanbanTaskCard.tsx
│   │   │   │   │   ├── PageNavigationSidebar.tsx
│   │   │   │   │   ├── ProjectDropdown.tsx
│   │   │   │   │   ├── SortDropdown.tsx
│   │   │   │   │   └── StatusFilterPills.tsx
│   │   │   │   ├── diff
│   │   │   │   │   ├── DiffStats.tsx
│   │   │   │   │   ├── DiffViewer.tsx
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── editor
│   │   │   │   │   └── MarkdownEditor.tsx
│   │   │   │   ├── markdown
│   │   │   │   │   └── Markdown.tsx
│   │   │   │   ├── modals
│   │   │   │   │   ├── AlertModal.tsx
│   │   │   │   │   ├── ChangelogModal.tsx
│   │   │   │   │   ├── ConfirmationModal.tsx
│   │   │   │   │   └── TextInputModal.tsx
│   │   │   │   ├── notifications
│   │   │   │   │   ├── NotificationProvider.tsx
│   │   │   │   │   ├── VolumeControl.module.css
│   │   │   │   │   └── VolumeControl.tsx
│   │   │   │   ├── pages
│   │   │   │   │   ├── ApprovalsPage.tsx
│   │   │   │   │   ├── DashboardStatistics.tsx
│   │   │   │   │   ├── JobExecutionHistory.tsx
│   │   │   │   │   ├── JobFormModal.tsx
│   │   │   │   │   ├── JobTemplates.ts
│   │   │   │   │   ├── LogsPage.tsx
│   │   │   │   │   ├── SettingsPage.tsx
│   │   │   │   │   ├── SpecsPage.tsx
│   │   │   │   │   ├── SpecViewerPage.tsx
│   │   │   │   │   ├── SteeringPage.tsx
│   │   │   │   │   └── TasksPage.tsx
│   │   │   │   ├── projects
│   │   │   │   │   └── ProjectProvider.tsx
│   │   │   │   ├── theme
│   │   │   │   │   ├── HighlightStyles.tsx
│   │   │   │   │   ├── tailwind.css
│   │   │   │   │   ├── theme.css
│   │   │   │   │   └── ThemeProvider.tsx
│   │   │   │   └── ws
│   │   │   │       └── WebSocketProvider.tsx
│   │   │   └── types.ts
│   │   └── vite.config.ts
│   ├── index.ts
│   ├── markdown
│   │   └── templates
│   │       ├── design-template.md
│   │       ├── product-template.md
│   │       ├── requirements-template.md
│   │       ├── structure-template.md
│   │       ├── tasks-template.md
│   │       └── tech-template.md
│   ├── prompts
│   │   ├── create-spec.ts
│   │   ├── create-steering-doc.ts
│   │   ├── implement-task.ts
│   │   ├── index.ts
│   │   ├── inject-spec-workflow-guide.ts
│   │   ├── inject-steering-guide.ts
│   │   ├── refresh-tasks.ts
│   │   ├── spec-status.ts
│   │   └── types.ts
│   ├── server.ts
│   ├── tools
│   │   ├── __tests__
│   │   │   └── projectPath.test.ts
│   │   ├── approvals.ts
│   │   ├── index.ts
│   │   ├── log-implementation.ts
│   │   ├── spec-status.ts
│   │   ├── spec-workflow-guide.ts
│   │   └── steering-guide.ts
│   └── types.ts
├── tsconfig.json
├── vitest.config.ts
└── vscode-extension
    ├── .gitignore
    ├── .vscode
    │   ├── extensions.json
    │   ├── launch.json
    │   ├── settings.json
    │   └── tasks.json
    ├── .vscode-test.mjs
    ├── .vscodeignore
    ├── CHANGELOG.md
    ├── components.json
    ├── esbuild.js
    ├── eslint.config.mjs
    ├── icon.png
    ├── icons
    │   ├── activity-bar-icon.svg
    │   └── spec-workflow.svg
    ├── LICENSE
    ├── package-lock.json
    ├── package.json
    ├── package.nls.ja.json
    ├── package.nls.json
    ├── package.nls.zh.json
    ├── README.md
    ├── src
    │   ├── extension
    │   │   ├── providers
    │   │   │   └── SidebarProvider.ts
    │   │   ├── services
    │   │   │   ├── ApprovalCommandService.ts
    │   │   │   ├── ApprovalEditorService.ts
    │   │   │   ├── ArchiveService.ts
    │   │   │   ├── CommentModalService.ts
    │   │   │   ├── FileWatcher.ts
    │   │   │   ├── ImplementationLogService.ts
    │   │   │   └── SpecWorkflowService.ts
    │   │   ├── types.ts
    │   │   └── utils
    │   │       ├── colorUtils.ts
    │   │       ├── logger.ts
    │   │       └── taskParser.ts
    │   ├── extension.ts
    │   ├── test
    │   │   ├── extension.test.ts
    │   │   └── pathResolution.test.ts
    │   └── webview
    │       ├── App.tsx
    │       ├── comment-modal.html
    │       ├── comment-modal.tsx
    │       ├── components
    │       │   ├── ArtifactSection.tsx
    │       │   ├── CommentModal.tsx
    │       │   ├── LogEntryCard.tsx
    │       │   ├── LogStatsPanel.tsx
    │       │   └── ui
    │       │       ├── accordion.tsx
    │       │       ├── badge.tsx
    │       │       ├── button.tsx
    │       │       ├── card.tsx
    │       │       ├── dropdown-menu.tsx
    │       │       ├── input.tsx
    │       │       ├── progress.tsx
    │       │       ├── select.tsx
    │       │       ├── separator.tsx
    │       │       └── tabs.tsx
    │       ├── globals.css
    │       ├── hooks
    │       │   ├── useSoundNotifications.ts
    │       │   └── useVSCodeTheme.ts
    │       ├── i18n.ts
    │       ├── index.html
    │       ├── lib
    │       │   ├── utils.ts
    │       │   └── vscode-api.ts
    │       ├── locales
    │       │   ├── ar.json
    │       │   ├── de.json
    │       │   ├── en.json
    │       │   ├── es.json
    │       │   ├── fr.json
    │       │   ├── it.json
    │       │   ├── ja.json
    │       │   ├── ko.json
    │       │   ├── pt.json
    │       │   ├── ru.json
    │       │   └── zh.json
    │       ├── main.tsx
    │       ├── pages
    │       │   └── LogsPage.tsx
    │       └── vite-env.d.ts
    ├── tailwind.config.js
    ├── tsconfig.app.json
    ├── tsconfig.extension.json
    ├── tsconfig.json
    ├── tsconfig.node.json
    ├── vite.config.ts
    ├── webview-assets
    │   └── sounds
    │       ├── approval-pending.wav
    │       └── task-completed.wav
    └── webview-dist
        ├── comment-modal.html
        ├── comment-modal.js
        ├── globals.css
        ├── i18n.js
        ├── index.html
        ├── locales
        │   ├── ar.json
        │   ├── de.json
        │   ├── en.json
        │   ├── es.json
        │   ├── fr.json
        │   ├── it.json
        │   ├── ja.json
        │   ├── ko.json
        │   ├── pt.json
        │   ├── ru.json
        │   └── zh.json
        ├── main.js
        └── sounds
            ├── approval-pending.wav
            └── task-completed.wav
```

# Files

--------------------------------------------------------------------------------
/vscode-extension/.gitignore:
--------------------------------------------------------------------------------

```
1 | out
2 | dist
3 | node_modules
4 | .vscode-test/
5 | *.vsix
6 | 
```

--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------

```
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 | 
```

--------------------------------------------------------------------------------
/vscode-extension/.vscode-test.mjs:
--------------------------------------------------------------------------------

```
1 | import { defineConfig } from '@vscode/test-cli';
2 | 
3 | export default defineConfig({
4 | 	files: 'out/test/**/*.test.js',
5 | });
6 | 
```

--------------------------------------------------------------------------------
/vscode-extension/.vscodeignore:
--------------------------------------------------------------------------------

```
 1 | .vscode/**
 2 | .vscode-test/**
 3 | out/**
 4 | node_modules/**
 5 | src/**
 6 | .gitignore
 7 | .yarnrc
 8 | esbuild.js
 9 | vsc-extension-quickstart.md
10 | **/tsconfig.json
11 | **/eslint.config.mjs
12 | **/*.map
13 | **/*.ts
14 | **/.vscode-test.*
15 | !webview-dist/**
16 | !package.nls.*.json
17 | 
```

--------------------------------------------------------------------------------
/containers/.env.example:
--------------------------------------------------------------------------------

```
1 | # Dashboard Configuration
2 | # Default port for the dashboard (change if 5000 is in use)
3 | DASHBOARD_PORT=5000
4 | 
5 | # Path to your project directory
6 | # This should be the directory containing (or where you want to create) .spec-workflow
7 | SPEC_WORKFLOW_PATH=./workspace
8 | 
```

--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------

```
 1 | # Dependencies
 2 | node_modules
 3 | npm-debug.log
 4 | 
 5 | # Build artifacts
 6 | dist
 7 | .next
 8 | out
 9 | 
10 | # IDE and editor files
11 | .vscode
12 | .idea
13 | *.swp
14 | *.swo
15 | *~
16 | 
17 | # OS files
18 | .DS_Store
19 | Thumbs.db
20 | 
21 | # Git
22 | .git
23 | .gitignore
24 | .gitattributes
25 | 
26 | # Testing
27 | coverage
28 | .nyc_output
29 | 
30 | # Documentation (not needed in container)
31 | docs
32 | *.md
33 | !containers/README.md
34 | 
35 | # CI/CD
36 | .github
37 | 
38 | # Environment files
39 | .env
40 | .env.*
41 | 
42 | # VSCode extension
43 | vscode-extension
44 | 
45 | # Temporary files
46 | tmp
47 | temp
48 | *.tmp
49 | .spec-workflow
50 | 
```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
  1 | # Logs
  2 | logs
  3 | *.log
  4 | npm-debug.log*
  5 | yarn-debug.log*
  6 | yarn-error.log*
  7 | lerna-debug.log*
  8 | .pnpm-debug.log*
  9 | 
 10 | # Diagnostic reports (https://nodejs.org/api/report.html)
 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
 12 | 
 13 | # Runtime data
 14 | pids
 15 | *.pid
 16 | *.seed
 17 | *.pid.lock
 18 | 
 19 | # Directory for instrumented libs generated by jscoverage/JSCover
 20 | lib-cov
 21 | 
 22 | # Coverage directory used by tools like istanbul
 23 | coverage
 24 | *.lcov
 25 | 
 26 | # nyc test coverage
 27 | .nyc_output
 28 | 
 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
 30 | .grunt
 31 | 
 32 | # Bower dependency directory (https://bower.io/)
 33 | bower_components
 34 | 
 35 | # node-waf configuration
 36 | .lock-wscript
 37 | 
 38 | # Compiled binary addons (https://nodejs.org/api/addons.html)
 39 | build/Release
 40 | 
 41 | # Dependency directories
 42 | node_modules/
 43 | jspm_packages/
 44 | 
 45 | # Snowpack dependency directory (https://snowpack.dev/)
 46 | web_modules/
 47 | 
 48 | # TypeScript cache
 49 | *.tsbuildinfo
 50 | 
 51 | # Optional npm cache directory
 52 | .npm
 53 | 
 54 | # Optional eslint cache
 55 | .eslintcache
 56 | 
 57 | # Optional stylelint cache
 58 | .stylelintcache
 59 | 
 60 | # Microbundle cache
 61 | .rpt2_cache/
 62 | .rts2_cache_cjs/
 63 | .rts2_cache_es/
 64 | .rts2_cache_umd/
 65 | 
 66 | # Optional REPL history
 67 | .node_repl_history
 68 | 
 69 | # Output of 'npm pack'
 70 | *.tgz
 71 | 
 72 | # Yarn Integrity file
 73 | .yarn-integrity
 74 | 
 75 | # dotenv environment variable files
 76 | .env
 77 | .env.development.local
 78 | .env.test.local
 79 | .env.production.local
 80 | .env.local
 81 | 
 82 | # parcel-bundler cache (https://parceljs.org/)
 83 | .cache
 84 | .parcel-cache
 85 | 
 86 | # Next.js build output
 87 | .next
 88 | out
 89 | 
 90 | # Nuxt.js build / generate output
 91 | .nuxt
 92 | dist
 93 | 
 94 | # Gatsby files
 95 | .cache/
 96 | # Comment in the public line in if your project uses Gatsby and not Next.js
 97 | # https://nextjs.org/blog/next-9-1#public-directory-support
 98 | # public
 99 | 
100 | # vuepress build output
101 | .vuepress/dist
102 | 
103 | # vuepress v2.x temp and cache directory
104 | .temp
105 | .cache
106 | 
107 | # vitepress build output
108 | **/.vitepress/dist
109 | 
110 | # vitepress cache directory
111 | **/.vitepress/cache
112 | 
113 | # Docusaurus cache and generated files
114 | .docusaurus
115 | 
116 | # Serverless directories
117 | .serverless/
118 | 
119 | # FuseBox cache
120 | .fusebox/
121 | 
122 | # DynamoDB Local files
123 | .dynamodb/
124 | 
125 | # TernJS port file
126 | .tern-port
127 | 
128 | # Stores VSCode versions used for testing VSCode extensions
129 | .vscode-test
130 | 
131 | # yarn v2
132 | .yarn/cache
133 | .yarn/unplugged
134 | .yarn/build-state.yml
135 | .yarn/install-state.gz
136 | .pnp.*
137 | 
138 | # AI
139 | CLAUDE.md
140 | .claude
141 | .serena
142 | AGENTS.md
143 | opencodetmp
144 | 
145 | # Spec Workflow MCP
146 | .specworkflow
```

--------------------------------------------------------------------------------
/vscode-extension/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Spec Workflow MCP Extension
 2 | 
 3 | A VSCode extension that provides an integrated dashboard for managing Spec-Workflow MCP projects directly in your workspace.
 4 | 
 5 | ## Features
 6 | 
 7 | - **Integrated Sidebar Dashboard**: Access all your spec workflow data without leaving VSCode
 8 | - **Real-time Updates**: File system watchers automatically update the dashboard when .spec-workflow files change
 9 | - **Project Overview**: Comprehensive statistics showing active vs archived specs, tasks, and approvals
10 | - **Spec Management**: Browse active and archived specifications with easy archiving/unarchiving
11 | - **Task Management**: View and update task statuses directly from the sidebar
12 | - **Approval Workflow**: Complete approval process with approve, reject, and revision requests
13 | - **Steering Documents**: Manage product, tech, and structure steering documents
14 | - **Sound Notifications**: Configurable audio alerts for approvals and task completions
15 | - **Editor Integration**: Context menu actions for approvals and comments directly in code
16 | - **React + Tailwind UI**: Modern, responsive interface built with React 19 and Tailwind CSS v4
17 | 
18 | ## Requirements
19 | 
20 | - VSCode 1.99.0 or higher
21 | - A workspace containing a `.spec-workflow` directory structure
22 | 
23 | ## Usage
24 | 
25 | 1. Open a workspace that contains a `.spec-workflow` directory
26 | 2. The Spec Workflow MCP icon will appear in the Activity Bar
27 | 3. Click the icon to open the dashboard sidebar
28 | 4. Use the tabbed interface to navigate between:
29 |    - **Overview**: Project statistics showing active/archived specs breakdown and recent activity
30 |    - **Steering**: Manage steering documents (product, tech, structure)
31 |    - **Specs**: Browse active and archived specifications with archive management
32 |    - **Tasks**: View and manage task progress for selected specifications
33 |    - **Approvals**: Handle pending approval requests with full workflow support
34 | 
35 | ## Archive Management
36 | 
37 | Specifications can be archived to keep dropdown menus clean and organized:
38 | - Switch between **Active** and **Archived** views in the Specs tab
39 | - Archive completed specifications to remove them from active dropdowns
40 | - Unarchive specifications when needed
41 | - Archive operations are blocked if pending approvals exist for the specification
42 | 
43 | ## Commands
44 | 
45 | - `Spec Workflow: Open Dashboard` - Opens the sidebar dashboard
46 | - `Spec Workflow: Refresh Data` - Manually refresh all data
47 | - `Spec Workflow: Open Spec` - Quick pick to open specific specifications
48 | - `Spec Workflow: Approve` - Approve current document (editor context)
49 | - `Spec Workflow: Reject` - Reject current document (editor context)
50 | - `Spec Workflow: Request Revision` - Request revision for current document
51 | - `Spec Workflow: Add Comment` - Add comment to selected text
52 | - `Spec Workflow: Approval Actions` - Show approval action menu
53 | 
54 | ## Extension Settings
55 | 
56 | - `specWorkflow.notifications.sounds.enabled` - Enable sound notifications (default: true)
57 | - `specWorkflow.notifications.sounds.volume` - Sound volume level 0.0-1.0 (default: 0.3)
58 | - `specWorkflow.notifications.sounds.approvalSound` - Play sound for approval requests (default: true)
59 | - `specWorkflow.notifications.sounds.taskCompletionSound` - Play sound for task completions (default: true)
60 | 
61 | ## Development
62 | 
63 | This extension is built with:
64 | - React 19 with TypeScript
65 | - Vite for webview bundling
66 | - Tailwind CSS v4 for styling
67 | - ShadCN UI components
68 | - VSCode Extension API
69 | 
70 | ## Release Notes
71 | 
72 | ### 0.0.1
73 | 
74 | Initial release of Spec Workflow MCP Extension:
75 | - **Dashboard Integration**: Complete sidebar dashboard with real-time updates
76 | - **Specification Management**: Active/archived spec organization with archive workflow
77 | - **Task Tracking**: Interactive task management with status updates
78 | - **Approval System**: Full approval workflow with approve/reject/revision capabilities
79 | - **Steering Documents**: Product, tech, and structure document management
80 | - **Sound Notifications**: Configurable audio alerts for key events
81 | - **Editor Integration**: Context menu actions and comment system
82 | - **Modern UI**: React 19 + Tailwind CSS v4 with responsive design
83 | 
84 | ## Support
85 | 
86 | If you find this extension helpful, consider supporting the development:
87 | 
88 | [☕ Buy Me a Coffee](https://buymeacoffee.com/pimzino)
89 | 
90 | ## License
91 | 
92 | This project is licensed under the GPL-3.0 License.
```

--------------------------------------------------------------------------------
/containers/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Spec-Workflow MCP Docker Setup
  2 | 
  3 | This directory contains Docker configuration files to run the Spec-Workflow MCP dashboard in a containerized environment. This setup provides isolation and easy deployment for the dashboard service.
  4 | 
  5 | ## 📋 Table of Contents
  6 | 
  7 | - [Prerequisites](#prerequisites)
  8 | - [Quick Start](#quick-start)
  9 | - [Building the Image](#building-the-image)
 10 | - [Running the Dashboard](#running-the-dashboard)
 11 | - [Using Docker Compose](#using-docker-compose)
 12 | - [Configuration Options](#configuration-options)
 13 | - [Troubleshooting](#troubleshooting)
 14 | 
 15 | ## Prerequisites
 16 | 
 17 | - Docker (version 20.10 or later)
 18 | - Docker Compose (optional, for simplified management)
 19 | - A project directory where you want to use spec-workflow
 20 | 
 21 | ## Quick Start
 22 | 
 23 | ### Option 1: Using Docker Compose (Recommended)
 24 | 
 25 | The easiest way to get started is with Docker Compose:
 26 | 
 27 | ```bash
 28 | # From the repository root
 29 | cd containers
 30 | docker-compose up --build
 31 | ```
 32 | 
 33 | The dashboard will be available at: http://localhost:5000
 34 | 
 35 | ### Option 2: Using Docker CLI
 36 | 
 37 | Build and run manually:
 38 | 
 39 | ```bash
 40 | # From the repository root
 41 | docker build -f containers/Dockerfile -t spec-workflow-mcp .
 42 | docker run -p 5000:5000 -v "./workspace/.spec-workflow:/workspace/.spec-workflow:rw" spec-workflow-mcp
 43 | ```
 44 | 
 45 | ## Building the Image
 46 | 
 47 | ### Build from Repository Root
 48 | 
 49 | **Important:** The Dockerfile must be built from the repository root directory, not from the `containers` directory, because it needs access to the source code.
 50 | 
 51 | ```bash
 52 | # From the repository root
 53 | docker build -f containers/Dockerfile -t spec-workflow-mcp .
 54 | ```
 55 | 
 56 | ### Build Arguments
 57 | 
 58 | The image is built in two stages:
 59 | 1. **Builder stage**: Installs dependencies and builds the TypeScript application
 60 | 2. **Runtime stage**: Creates a minimal production image with only necessary files
 61 | 
 62 | ## Running the Dashboard
 63 | 
 64 | ### Basic Usage
 65 | 
 66 | Run the dashboard on the default port (5000):
 67 | 
 68 | ```bash
 69 | docker run -p 5000:5000 \
 70 |   -v "./workspace/.spec-workflow:/workspace/.spec-workflow:rw" \
 71 |   spec-workflow-mcp
 72 | ```
 73 | 
 74 | ### Custom Port
 75 | 
 76 | Run the dashboard on a custom port (e.g., 8080):
 77 | 
 78 | ```bash
 79 | docker run -p 8080:8080 \
 80 |   -e DASHBOARD_PORT=8080 \
 81 |   -v "./workspace/.spec-workflow:/workspace/.spec-workflow:rw" \
 82 |   spec-workflow-mcp
 83 | ```
 84 | 
 85 | ### Using a Specific Project Path
 86 | 
 87 | Mount your project's `.spec-workflow` directory:
 88 | 
 89 | ```bash
 90 | docker run -p 5000:5000 \
 91 |   -v "/path/to/your/project/.spec-workflow:/workspace/.spec-workflow:rw" \
 92 |   spec-workflow-mcp
 93 | ```
 94 | 
 95 | ## Using Docker Compose
 96 | 
 97 | Docker Compose simplifies the management of the dashboard container.
 98 | 
 99 | ### Default Configuration
100 | 
101 | Create a `.env` file (optional):
102 | 
103 | ```bash
104 | # .env file
105 | DASHBOARD_PORT=5000
106 | SPEC_WORKFLOW_PATH=./workspace
107 | ```
108 | 
109 | Then start the dashboard:
110 | 
111 | ```bash
112 | cd containers
113 | docker-compose up -d
114 | ```
115 | 
116 | ### Custom Configuration
117 | 
118 | Override environment variables when starting:
119 | 
120 | ```bash
121 | DASHBOARD_PORT=8080 SPEC_WORKFLOW_PATH=/path/to/project docker-compose up -d
122 | ```
123 | 
124 | ### Managing the Service
125 | 
126 | ```bash
127 | # Start the dashboard
128 | docker-compose up -d
129 | 
130 | # View logs
131 | docker-compose logs -f
132 | 
133 | # Stop the dashboard
134 | docker-compose down
135 | 
136 | # Rebuild and restart
137 | docker-compose up --build
138 | ```
139 | 
140 | ## Configuration Options
141 | 
142 | ### Environment Variables
143 | 
144 | | Variable | Default | Description |
145 | |----------|---------|-------------|
146 | | `DASHBOARD_PORT` | `5000` | Port on which the dashboard runs |
147 | | `SPEC_WORKFLOW_PATH` | `/workspace` | Path to the project directory (inside container) |
148 | 
149 | ### Volume Mounts
150 | 
151 | The dashboard requires access to the `.spec-workflow` directory to function properly.
152 | 
153 | **Example:**
154 | ```bash
155 | -v "/path/to/project/.spec-workflow:/workspace/.spec-workflow:rw"
156 | ```
157 | 
158 | **Important Notes:**
159 | - The volume mount must be read-write (`:rw`) for the dashboard to function
160 | - Only the `.spec-workflow` directory needs to be mounted
161 | - The directory will be created automatically if it doesn't exist
162 | 
163 | ### Port Mapping
164 | 
165 | Map the container port to a host port:
166 | 
167 | ```bash
168 | -p <host-port>:<container-port>
169 | ```
170 | 
171 | **Examples:**
172 | - Default: `-p 5000:5000`
173 | - Custom: `-p 8080:8080` (remember to set `DASHBOARD_PORT=8080`)
174 | 
175 | ## MCP Server Configuration
176 | 
177 | The dashboard runs independently of MCP servers. To connect MCP servers to the dashboard:
178 | 
179 | ### For Claude Desktop
180 | 
181 | Add to your `claude_desktop_config.json`:
182 | 
183 | ```json
184 | {
185 |   "mcpServers": {
186 |     "spec-workflow": {
187 |       "command": "npx",
188 |       "args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/your/project"]
189 |     }
190 |   }
191 | }
192 | ```
193 | 
194 | **Note:** The MCP server runs on your host machine and connects to the Docker dashboard automatically via port 5000.
195 | 
196 | ### For Other MCP Clients
197 | 
198 | Use similar configuration with the appropriate MCP client settings. The MCP servers run independently and connect to the dashboard's WebSocket endpoint.
199 | 
200 | ## Troubleshooting
201 | 
202 | ### Common Issues
203 | 
204 | #### 1. Port Already in Use
205 | 
206 | **Error:** `Bind for 0.0.0.0:5000 failed: port is already allocated`
207 | 
208 | **Solution:** Use a different port:
209 | ```bash
210 | docker run -p 8080:8080 -e DASHBOARD_PORT=8080 ...
211 | # or with docker-compose
212 | DASHBOARD_PORT=8080 docker-compose up
213 | ```
214 | 
215 | #### 2. Permission Denied
216 | 
217 | **Error:** Permission issues with `.spec-workflow` directory
218 | 
219 | **Solutions:**
220 | - Ensure the directory has proper permissions: `chmod -R 755 .spec-workflow`
221 | - On SELinux systems, add `:z` to the volume mount: `-v "./workspace/.spec-workflow:/workspace/.spec-workflow:rw,z"`
222 | 
223 | #### 3. Dashboard Not Accessible
224 | 
225 | **Check:**
226 | - Container is running: `docker ps`
227 | - Port is properly mapped: `docker port <container-id>`
228 | - Firewall allows connections on the port
229 | - Access via: `http://localhost:5000` (or your custom port)
230 | 
231 | #### 4. Build Fails
232 | 
233 | **Error:** Build fails with COPY or dependency errors
234 | 
235 | **Solutions:**
236 | - Ensure you're building from the repository root: `docker build -f containers/Dockerfile -t spec-workflow-mcp .`
237 | - Check that all source files are present
238 | - Verify `package.json` and `package-lock.json` exist
239 | 
240 | ### Viewing Logs
241 | 
242 | #### Docker CLI
243 | ```bash
244 | docker logs <container-id>
245 | docker logs -f <container-id>  # Follow logs
246 | ```
247 | 
248 | #### Docker Compose
249 | ```bash
250 | docker-compose logs
251 | docker-compose logs -f  # Follow logs
252 | ```
253 | 
254 | ### Inspecting the Container
255 | 
256 | ```bash
257 | # View container details
258 | docker inspect <container-id>
259 | 
260 | # Access container shell
261 | docker exec -it <container-id> /bin/sh
262 | ```
263 | 
264 | ## Advanced Configuration
265 | 
266 | ### Running in Detached Mode
267 | 
268 | ```bash
269 | docker run -d \
270 |   --name spec-workflow-dashboard \
271 |   -p 5000:5000 \
272 |   -v "./workspace/.spec-workflow:/workspace/.spec-workflow:rw" \
273 |   spec-workflow-mcp
274 | ```
275 | 
276 | ### Auto-Restart on Failure
277 | 
278 | ```bash
279 | docker run -d \
280 |   --name spec-workflow-dashboard \
281 |   --restart unless-stopped \
282 |   -p 5000:5000 \
283 |   -v "./workspace/.spec-workflow:/workspace/.spec-workflow:rw" \
284 |   spec-workflow-mcp
285 | ```
286 | 
287 | ### Health Checks
288 | 
289 | The dashboard doesn't currently include health checks, but you can test connectivity:
290 | 
291 | ```bash
292 | curl http://localhost:5000
293 | ```
294 | 
295 | ## Security Considerations
296 | 
297 | - The container runs as a non-root user (`node`) for security
298 | - Only expose necessary ports
299 | - Use read-only volume mounts where possible (though `:rw` is required for `.spec-workflow`)
300 | - Keep the base image updated: `docker pull node:24-alpine`
301 | 
302 | ## Performance Tips
303 | 
304 | - The container is optimized for production with:
305 |   - Multi-stage builds to minimize image size
306 |   - Only production dependencies in final image
307 |   - Alpine Linux for small footprint
308 |   
309 | - Monitor resource usage:
310 |   ```bash
311 |   docker stats <container-id>
312 |   ```
313 | 
314 | ## Additional Resources
315 | 
316 | - [Main Documentation](../README.md)
317 | - [User Guide](../docs/USER-GUIDE.md)
318 | - [Troubleshooting Guide](../docs/TROUBLESHOOTING.md)
319 | - [GitHub Repository](https://github.com/Pimzino/spec-workflow-mcp)
320 | 
321 | ## Support
322 | 
323 | If you encounter issues:
324 | 1. Check the [Troubleshooting](#troubleshooting) section
325 | 2. Review logs: `docker logs <container-id>`
326 | 3. Open an issue on [GitHub](https://github.com/Pimzino/spec-workflow-mcp/issues)
327 | 4. Include:
328 |    - Docker version: `docker --version`
329 |    - Operating system
330 |    - Error messages
331 |    - Steps to reproduce
332 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Spec Workflow MCP
  2 | 
  3 | [![npm version](https://img.shields.io/npm/v/@pimzino/spec-workflow-mcp)](https://www.npmjs.com/package/@pimzino/spec-workflow-mcp)
  4 | [![VSCode Extension](https://badgen.net/vs-marketplace/v/Pimzino.spec-workflow-mcp)](https://marketplace.visualstudio.com/items?itemName=Pimzino.spec-workflow-mcp)
  5 | 
  6 | A Model Context Protocol (MCP) server for structured spec-driven development with real-time dashboard and VSCode extension.
  7 | 
  8 | ## ☕ Support This Project
  9 | 
 10 | <a href="https://buymeacoffee.com/Pimzino" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>
 11 | 
 12 | ## 📺 Showcase
 13 | 
 14 | ### 🔄 Approval System in Action
 15 | <a href="https://www.youtube.com/watch?v=C-uEa3mfxd0" target="_blank">
 16 |   <img src="https://img.youtube.com/vi/C-uEa3mfxd0/maxresdefault.jpg" alt="Approval System Demo" width="600">
 17 | </a>
 18 | 
 19 | *See how the approval system works: create documents, request approval through the dashboard, provide feedback, and track revisions.*
 20 | 
 21 | ### 📊 Dashboard & Spec Management
 22 | <a href="https://www.youtube.com/watch?v=g9qfvjLUWf8" target="_blank">
 23 |   <img src="https://img.youtube.com/vi/g9qfvjLUWf8/maxresdefault.jpg" alt="Dashboard Demo" width="600">
 24 | </a>
 25 | 
 26 | *Explore the real-time dashboard: view specs, track progress, navigate documents, and monitor your development workflow.*
 27 | 
 28 | ## ✨ Key Features
 29 | 
 30 | - **Structured Development Workflow** - Sequential spec creation (Requirements → Design → Tasks)
 31 | - **Real-Time Web Dashboard** - Monitor specs, tasks, and progress with live updates
 32 | - **VSCode Extension** - Integrated sidebar dashboard for VSCode users
 33 | - **Approval Workflow** - Complete approval process with revisions
 34 | - **Task Progress Tracking** - Visual progress bars and detailed status
 35 | - **Implementation Logs** - Searchable logs of all task implementations with code statistics
 36 | - **Multi-Language Support** - Available in 11 languages
 37 | 
 38 | ## 🌍 Supported Languages
 39 | 
 40 | 🇺🇸 English • 🇯🇵 日本語 • 🇨🇳 中文 • 🇪🇸 Español • 🇧🇷 Português • 🇩🇪 Deutsch • 🇫🇷 Français • 🇷🇺 Русский • 🇮🇹 Italiano • 🇰🇷 한국어 • 🇸🇦 العربية
 41 | 
 42 | ## 🚀 Quick Start
 43 | 
 44 | ### Step 1: Add to your AI tool
 45 | 
 46 | Add to your MCP configuration (see client-specific setup below):
 47 | 
 48 | ```json
 49 | {
 50 |   "mcpServers": {
 51 |     "spec-workflow": {
 52 |       "command": "npx",
 53 |       "args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/your/project"]
 54 |     }
 55 |   }
 56 | }
 57 | ```
 58 | 
 59 | ### Step 2: Choose your interface
 60 | 
 61 | **Option A: Web Dashboard** (Required for CLI users)
 62 | Start the dashboard (runs on port 5000 by default):
 63 | ```bash
 64 | npx -y @pimzino/spec-workflow-mcp@latest --dashboard
 65 | ```
 66 | 
 67 | The dashboard will be accessible at: http://localhost:5000
 68 | 
 69 | > **Note:** Only one dashboard instance is needed. All your projects will connect to the same dashboard.
 70 | 
 71 | **Option B: VSCode Extension** (Recommended for VSCode users)
 72 | 
 73 | Install [Spec Workflow MCP Extension](https://marketplace.visualstudio.com/items?itemName=Pimzino.spec-workflow-mcp) from the VSCode marketplace.
 74 | 
 75 | ## 📝 How to Use
 76 | 
 77 | Simply mention spec-workflow in your conversation:
 78 | 
 79 | - **"Create a spec for user authentication"** - Creates complete spec workflow
 80 | - **"List my specs"** - Shows all specs and their status
 81 | - **"Execute task 1.2 in spec user-auth"** - Runs a specific task
 82 | 
 83 | [See more examples →](docs/PROMPTING-GUIDE.md)
 84 | 
 85 | ## 🔧 MCP Client Setup
 86 | 
 87 | <details>
 88 | <summary><strong>Augment Code</strong></summary>
 89 | 
 90 | Configure in your Augment settings:
 91 | ```json
 92 | {
 93 |   "mcpServers": {
 94 |     "spec-workflow": {
 95 |       "command": "npx",
 96 |       "args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/your/project"]
 97 |     }
 98 |   }
 99 | }
100 | ```
101 | </details>
102 | 
103 | <details>
104 | <summary><strong>Claude Code CLI</strong></summary>
105 | 
106 | Add to your MCP configuration:
107 | ```bash
108 | claude mcp add spec-workflow npx @pimzino/spec-workflow-mcp@latest -- /path/to/your/project
109 | ```
110 | 
111 | **Important Notes:**
112 | - The `-y` flag bypasses npm prompts for smoother installation
113 | - The `--` separator ensures the path is passed to the spec-workflow script, not to npx
114 | - Replace `/path/to/your/project` with your actual project directory path
115 | 
116 | **Alternative for Windows (if the above doesn't work):**
117 | ```bash
118 | claude mcp add spec-workflow cmd.exe /c "npx @pimzino/spec-workflow-mcp@latest /path/to/your/project"
119 | ```
120 | </details>
121 | 
122 | <details>
123 | <summary><strong>Claude Desktop</strong></summary>
124 | 
125 | Add to `claude_desktop_config.json`:
126 | ```json
127 | {
128 |   "mcpServers": {
129 |     "spec-workflow": {
130 |       "command": "npx",
131 |       "args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/your/project"]
132 |     }
133 |   }
134 | }
135 | ```
136 | 
137 | > **Important:** Run the dashboard separately with `--dashboard` before starting the MCP server.
138 | 
139 | </details>
140 | 
141 | <details>
142 | <summary><strong>Cline/Claude Dev</strong></summary>
143 | 
144 | Add to your MCP server configuration:
145 | ```json
146 | {
147 |   "mcpServers": {
148 |     "spec-workflow": {
149 |       "command": "npx",
150 |       "args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/your/project"]
151 |     }
152 |   }
153 | }
154 | ```
155 | </details>
156 | 
157 | <details>
158 | <summary><strong>Continue IDE Extension</strong></summary>
159 | 
160 | Add to your Continue configuration:
161 | ```json
162 | {
163 |   "mcpServers": {
164 |     "spec-workflow": {
165 |       "command": "npx",
166 |       "args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/your/project"]
167 |     }
168 |   }
169 | }
170 | ```
171 | </details>
172 | 
173 | <details>
174 | <summary><strong>Cursor IDE</strong></summary>
175 | 
176 | Add to your Cursor settings (`settings.json`):
177 | ```json
178 | {
179 |   "mcpServers": {
180 |     "spec-workflow": {
181 |       "command": "npx",
182 |       "args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/your/project"]
183 |     }
184 |   }
185 | }
186 | ```
187 | </details>
188 | 
189 | <details>
190 | <summary><strong>OpenCode</strong></summary>
191 | 
192 | Add to your `opencode.json` configuration file:
193 | ```json
194 | {
195 |   "$schema": "https://opencode.ai/config.json",
196 |   "mcp": {
197 |     "spec-workflow": {
198 |       "type": "local",
199 |       "command": ["npx", "-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/your/project"],
200 |       "enabled": true
201 |     }
202 |   }
203 | }
204 | ```
205 | </details>
206 | 
207 | ## 🐳 Docker Deployment
208 | 
209 | Run the dashboard in a Docker container for isolated deployment:
210 | 
211 | ```bash
212 | # Using Docker Compose (recommended)
213 | cd containers
214 | docker-compose up --build
215 | 
216 | # Or using Docker CLI
217 | docker build -f containers/Dockerfile -t spec-workflow-mcp .
218 | docker run -p 5000:5000 -v "./workspace/.spec-workflow:/workspace/.spec-workflow:rw" spec-workflow-mcp
219 | ```
220 | 
221 | The dashboard will be available at: http://localhost:5000
222 | 
223 | [See Docker setup guide →](containers/README.md)
224 | 
225 | ## 📚 Documentation
226 | 
227 | - [Configuration Guide](docs/CONFIGURATION.md) - Command-line options, config files
228 | - [User Guide](docs/USER-GUIDE.md) - Comprehensive usage examples
229 | - [Workflow Process](docs/WORKFLOW.md) - Development workflow and best practices
230 | - [Interfaces Guide](docs/INTERFACES.md) - Dashboard and VSCode extension details
231 | - [Prompting Guide](docs/PROMPTING-GUIDE.md) - Advanced prompting examples
232 | - [Tools Reference](docs/TOOLS-REFERENCE.md) - Complete tools documentation
233 | - [Development](docs/DEVELOPMENT.md) - Contributing and development setup
234 | - [Troubleshooting](docs/TROUBLESHOOTING.md) - Common issues and solutions
235 | 
236 | ## 📁 Project Structure
237 | 
238 | ```
239 | your-project/
240 |   .spec-workflow/
241 |     approvals/
242 |     archive/
243 |     specs/
244 |     steering/
245 |     templates/
246 |     user-templates/
247 |     config.example.toml
248 | ```
249 | 
250 | ## 🛠️ Development
251 | 
252 | ```bash
253 | # Install dependencies
254 | npm install
255 | 
256 | # Build the project
257 | npm run build
258 | 
259 | # Run in development mode
260 | npm run dev
261 | ```
262 | 
263 | [See development guide →](docs/DEVELOPMENT.md)
264 | 
265 | ## 📄 License
266 | 
267 | GPL-3.0
268 | 
269 | ## ⭐ Star History
270 | 
271 | <a href="https://www.star-history.com/#Pimzino/spec-workflow-mcp&Date">
272 |  <picture>
273 |    <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Pimzino/spec-workflow-mcp&type=Date&theme=dark" />
274 |    <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Pimzino/spec-workflow-mcp&type=Date" />
275 |    <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Pimzino/spec-workflow-mcp&type=Date" />
276 |  </picture>
277 | </a>
```

--------------------------------------------------------------------------------
/docs/technical-documentation/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Technical Documentation
  2 | 
  3 | > **Quick Reference**: Jump to what you need most → [Tools API](api-reference.md) | [Architecture](architecture.md) | [Developer Guide](developer-guide.md) | [Troubleshooting](troubleshooting.md)
  4 | 
  5 | ## 📋 Table of Contents
  6 | 
  7 | ### Core Documentation
  8 | - **[Architecture Overview](architecture.md)** - System design, components, and data flow
  9 | - **[MCP Tools API Reference](api-reference.md)** - Complete tool documentation with examples
 10 | - **[Developer Workflow Guide](developer-guide.md)** - Step-by-step development workflows
 11 | - **[Context Management](context-management.md)** - How context switching and caching works
 12 | - **[File Structure](file-structure.md)** - Project organization and directory layout
 13 | - **[Dashboard System](dashboard.md)** - Web dashboard and real-time features
 14 | - **[Troubleshooting & FAQ](troubleshooting.md)** - Common issues and solutions
 15 | 
 16 | ### Quick Start Guides
 17 | - **[Setting Up Development Environment](setup.md)** - Get up and running quickly
 18 | - **[Contributing Guidelines](contributing.md)** - How to contribute to the project
 19 | - **[Testing Guide](testing.md)** - Running tests and writing new ones
 20 | 
 21 | ## 🚀 Quick Start
 22 | 
 23 | ### For AI Assistant Integration
 24 | ```json
 25 | {
 26 |   "mcpServers": {
 27 |     "spec-workflow": {
 28 |       "command": "npx",
 29 |       "args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/project", "--AutoStartDashboard"]
 30 |     }
 31 |   }
 32 | }
 33 | ```
 34 | 
 35 | ### For Local Development
 36 | ```bash
 37 | # Clone and setup
 38 | git clone <repository-url>
 39 | cd spec-workflow-mcp
 40 | npm install
 41 | 
 42 | # Start development server
 43 | npm run dev
 44 | 
 45 | # Build for production  
 46 | npm run build
 47 | ```
 48 | 
 49 | ## 🔍 Comprehensive Capability Analysis
 50 | 
 51 | ### Critical Questions Answered
 52 | 
 53 | Based on comprehensive codebase analysis, here are definitive answers to key technical questions:
 54 | 
 55 | #### **Question 1: Web Scraping & Research Capabilities**
 56 | **Answer: No independent web scraping - leverages LLM's built-in web search**
 57 | 
 58 | | Aspect | This MCP | Other AI Agents | Expansion Opportunity |
 59 | |--------|----------|----------------|---------------------|
 60 | | **Web Scraping** | ❌ No independent capability | ✅ Custom scrapers (Puppeteer, Playwright) | 🔮 Could add structured scraping tools |
 61 | | **API Research** | ❌ Relies on LLM's web search | ✅ Direct API integrations | 🔮 Could add GitHub, Stack Overflow APIs |
 62 | | **Research Caching** | ❌ No research persistence | ✅ Advanced caching systems | 🔮 Could cache LLM research results |
 63 | | **Data Sources** | ✅ LLM's vast training data + real-time web | ❌ Limited to configured sources | ✅ Best of both worlds |
 64 | 
 65 | #### **Question 2: AI Calls & Context Window Management**
 66 | **Answer: Pure MCP - uses only connected LLM, no independent AI calls**
 67 | 
 68 | | Aspect | This MCP | Other AI Agents | Expansion Opportunity |
 69 | |--------|----------|----------------|---------------------|
 70 | | **AI Service Calls** | ❌ No independent AI calls | ✅ Multiple AI model integration | 🔮 Could add specialized AI services |
 71 | | **Context Management** | ❌ No LLM context manipulation | ✅ Advanced context strategies | 🔮 Could add context optimization |
 72 | | **Memory Management** | ❌ File-based only | ✅ Vector databases, embeddings | 🔮 Could add persistent memory |
 73 | | **Multi-Model Usage** | ❌ Single LLM connection | ✅ GPT-4 + Claude + Gemini | 🔮 Could add model routing |
 74 | 
 75 | #### **Question 3: Document Planning Process**
 76 | **Answer: Template-guided LLM intelligence - no separate AI planning**
 77 | 
 78 | | Aspect | This MCP | Other AI Agents | Expansion Opportunity |
 79 | |--------|----------|----------------|---------------------|
 80 | | **Planning Intelligence** | ✅ LLM reasoning with templates | ✅ Dedicated planning AI | 🔮 Could add adaptive workflows |
 81 | | **Template System** | ✅ Static but comprehensive | ❌ Often no structured templates | ✅ Structured advantage |
 82 | | **Workflow Adaptation** | ❌ Fixed sequence | ✅ Dynamic workflow generation | 🔮 Could add LLM-powered workflows |
 83 | | **Project Analysis** | ✅ LLM analyzes project context | ✅ Specialized analysis tools | 🔮 Could add deep code analysis |
 84 | 
 85 | #### **Question 4: Auto Review Process**
 86 | **Answer: Human-only approval system - no automated AI review**
 87 | 
 88 | | Aspect | This MCP | Other AI Agents | Expansion Opportunity |
 89 | |--------|----------|----------------|---------------------|
 90 | | **Review Automation** | ❌ Human approval required | ✅ Multi-stage AI review | 🔮 Could add optional AI gates |
 91 | | **Quality Assurance** | ✅ LLM quality + Human oversight | ❌ AI-only (potential errors) | ✅ Best quality control |
 92 | | **Approval Workflows** | ✅ Dashboard/VS Code integration | ❌ Often CLI-only | ✅ Superior UX |
 93 | | **Review Intelligence** | ✅ LLM can suggest improvements | ✅ Specialized review models | 🔮 Could add review templates |
 94 | 
 95 | #### **Question 5: Best Practice Standards**
 96 | **Answer: LLM built-in knowledge - no external standards fetching**
 97 | 
 98 | | Aspect | This MCP | Other AI Agents | Expansion Opportunity |
 99 | |--------|----------|----------------|---------------------|
100 | | **Standards Source** | ✅ LLM's vast training knowledge | ✅ External standards APIs | 🔮 Could add standards integration |
101 | | **Currency** | ✅ LLM can web search for latest | ❌ Static configurations | ✅ Always current |
102 | | **Customization** | ❌ No project-specific standards | ✅ Custom rule engines | 🔮 Could add org standards |
103 | | **Best Practices** | ✅ Industry-wide via LLM | ❌ Limited to pre-configured | ✅ Comprehensive coverage |
104 | 
105 | ### Competitive Positioning Analysis
106 | 
107 | **Strengths vs Other AI Agents:**
108 | ```typescript
109 | interface CompetitiveAdvantages {
110 |   humanOversight: "Mandatory approval prevents runaway AI behavior";
111 |   llmLeverage: "Uses full power of connected LLM without limitations";
112 |   structuredOutput: "Templates ensure consistent, professional documentation";
113 |   realTimeUI: "Dashboard and VS Code integration for seamless workflow";
114 |   simplicity: "No complex setup or API key management required";
115 |   reliability: "Proven workflow sequence with validation and error handling";
116 | }
117 | ```
118 | 
119 | **Current Limitations vs Market Leaders:**
120 | ```typescript
121 | interface LimitationsAnalysis {
122 |   automationLevel: "Less automated than fully autonomous agents";
123 |   integrationEcosystem: "Limited external service integrations";
124 |   multiProject: "Single project scope vs enterprise-wide solutions";
125 |   aiDiversity: "Single LLM vs multi-model approaches";
126 |   workflowFlexibility: "Fixed sequence vs adaptive workflows";
127 | }
128 | ```
129 | 
130 | **Expansion Opportunities Identified:**
131 | ```typescript
132 | interface ExpansionRoadmap {
133 |   immediateWins: {
134 |     githubIntegration: "PR creation, issue sync, code analysis";
135 |     qualityGates: "Optional automated quality checks";
136 |     templateDynamism: "Project-type aware template selection";
137 |   };
138 |   
139 |   mediumTerm: {
140 |     multiProjectSupport: "Enterprise dashboard for multiple projects";
141 |     advancedIntegrations: "Jira, Confluence, Slack notifications";
142 |     workflowCustomization: "Configurable workflow sequences";
143 |   };
144 |   
145 |   longTerm: {
146 |     aiOrchestration: "Multi-agent coordination capabilities";
147 |     predictiveAnalytics: "Project success prediction and risk analysis";
148 |     enterpriseFeatures: "SSO, compliance, audit trails";
149 |   };
150 | }
151 | ```
152 | 
153 | ## ⚠️ Technical Limitations & Capabilities
154 | 
155 | ### What This MCP Does NOT Do
156 | 
157 | **No Independent External Calls**:
158 | - ❌ No separate web scraping or API calls by the MCP server
159 | - ❌ No independent external research by the MCP server
160 | - ❌ No direct calls to AI services from the MCP server
161 | - ✅ Leverages connected LLM's built-in web search and knowledge
162 | 
163 | **No Separate AI Service Integration**:
164 | - ❌ No additional calls to OpenAI, Anthropic, or other AI services
165 | - ❌ No independent AI processing outside the connected LLM
166 | - ❌ No separate AI models or services
167 | - ✅ Uses only the LLM provided through MCP connection
168 | 
169 | **No Context Window Management**:
170 | - ❌ Does not extend or manage AI client context windows
171 | - ❌ No conversation history or memory management
172 | - ❌ No cross-session AI context preservation
173 | - ✅ Provides structured project data for AI client consumption
174 | 
175 | **Human-Only Approval System**:
176 | - ❌ No automated AI-powered document review
177 | - ❌ No AI-based approval recommendations
178 | - ❌ Verbal approval not accepted
179 | - ✅ All approvals require dashboard or VS Code interaction
180 | 
181 | ### What This MCP Excels At
182 | 
183 | **Leveraging LLM Built-in Capabilities**:
184 | - ✅ Provides structured templates for LLM to fill with intelligent content
185 | - ✅ Supplies project context for LLM analysis and understanding
186 | - ✅ Enables LLM to use its built-in knowledge for best practices
187 | - ✅ Allows LLM to perform web research when generating content
188 | 
189 | **Structured Workflow Enforcement**:
190 | - ✅ Enforces spec-driven development sequence
191 | - ✅ Template-based document structure for consistent LLM output
192 | - ✅ Workflow validation and blocking
193 | - ✅ Human oversight integration for LLM-generated content
194 | 
195 | **Intelligent Project Data Management**:
196 | - ✅ Efficient context loading for LLM consumption
197 | - ✅ Real-time file watching and updates
198 | - ✅ Cross-platform path handling
199 | - ✅ Structured project organization that LLM can understand
200 | 
201 | **Enhanced Developer Experience**:
202 | - ✅ Web dashboard for reviewing LLM-generated content
203 | - ✅ VS Code extension integration
204 | - ✅ Real-time WebSocket updates
205 | - ✅ Comprehensive error handling
206 | 
207 | ## 🎯 Key Concepts
208 | 
209 | ### MCP Tools
210 | The server provides 12 MCP tools for spec-driven development:
211 | - **Workflow Tools**: `spec-workflow-guide`, `steering-guide`
212 | - **Content Tools**: `create-spec-doc`, `create-steering-doc`, `get-template-context`
213 | - **Search Tools**: `get-spec-context`, `get-steering-context`, `spec-list`
214 | - **Status Tools**: `spec-status`, `manage-tasks`
215 | - **Approval Tools**: `request-approval`, `get-approval-status`, `delete-approval`
216 | 
217 | ### File Organization
218 | ```
219 | .spec-workflow/
220 | ├── specs/           # Specification documents
221 | ├── steering/        # Project guidance documents
222 | ├── approvals/       # Approval workflow data
223 | └── archive/         # Archived specifications
224 | ```
225 | 
226 | ### Workflow Phases
227 | 1. **Requirements** → 2. **Design** → 3. **Tasks** → 4. **Implementation**
228 | 
229 | Each phase requires approval before proceeding to the next.
230 | 
231 | ## 🔧 Development Workflow
232 | 
233 | ### Adding a New MCP Tool
234 | 1. Create tool file in `src/tools/`
235 | 2. Export tool definition and handler
236 | 3. Register in `src/tools/index.ts`
237 | 4. Update API documentation
238 | 5. Add tests
239 | 
240 | ### Dashboard Development
241 | ```bash
242 | # Start dashboard in development mode
243 | npm run dev:dashboard
244 | 
245 | # Build dashboard assets
246 | npm run build:dashboard
247 | ```
248 | 
249 | ### VSCode Extension Development
250 | ```bash
251 | cd vscode-extension
252 | npm install
253 | npm run compile
254 | # Press F5 in VSCode to launch extension host
255 | ```
256 | 
257 | ## 📚 Documentation Standards
258 | 
259 | - **Code Examples**: Always include working examples
260 | - **Error Handling**: Document expected error conditions
261 | - **Performance**: Note any performance considerations
262 | - **Security**: Highlight security implications
263 | - **Breaking Changes**: Mark breaking changes clearly
264 | 
265 | ## 🤝 Getting Help
266 | 
267 | 1. **Check the [Troubleshooting Guide](troubleshooting.md)** first
268 | 2. **Search existing [GitHub Issues](https://github.com/Pimzino/spec-workflow-mcp/issues)**
269 | 3. **Create a new issue** with detailed reproduction steps
270 | 4. **Join the community** for real-time support
271 | 
272 | ---
273 | 
274 | ## 📊 Technical Architecture Summary
275 | 
276 | ### Pure MCP Server Design
277 | This project implements a **pure Model Context Protocol (MCP) server** that:
278 | 
279 | | Aspect | Implementation | Details |
280 | |--------|---------------|----------|
281 | | **AI Integration** | Pure MCP server | Leverages connected LLM's built-in capabilities |
282 | | **Web Research** | LLM built-in capability | LLM performs web search using its built-in features |
283 | | **Context Management** | File-based structure | No LLM context window management |
284 | | **Content Generation** | LLM-powered with templates | LLM fills templates using built-in knowledge & search |
285 | | **Planning Process** | LLM reasoning + workflow validation | LLM plans content, MCP enforces structure |
286 | | **Review System** | Human approval only | Dashboard/VS Code integration for LLM output |
287 | | **Best Practices** | LLM built-in knowledge | LLM applies best practices from its training |
288 | | **External Calls** | NPM version check only | All other capabilities through connected LLM |
289 | 
290 | ### Key Files & Implementation
291 | - **MCP Tools**: `src/tools/*.ts` - 13 tools for workflow management
292 | - **Templates**: `src/markdown/templates/*.md` - Static document structures  
293 | - **Approval System**: `src/dashboard/approval-storage.ts` - Human-only review
294 | - **Context Loading**: `src/core/*.ts` - File-based context structuring
295 | - **Web Dashboard**: `src/dashboard_frontend/` - React-based approval UI
296 | 
297 | ### Performance Characteristics
298 | - **Memory Usage**: 50KB templates + 10-100KB per spec context
299 | - **File System**: Local `.spec-workflow/` directory only
300 | - **Network**: Localhost dashboard + NPM version check
301 | - **Scaling**: Linear per project, 50-100 specs recommended
302 | - **Security**: Local-only, no external data transmission
303 | 
304 | ## 📊 Market Analysis & Strategic Insights
305 | 
306 | ### Competitive Landscape Analysis
307 | 
308 | **Category 1: Autonomous AI Agents (e.g., AutoGPT, LangChain Agents)**
309 | ```typescript
310 | interface AutonomousAgents {
311 |   capabilities: {
312 |     webScraping: "Advanced - Custom scrapers, API integrations";
313 |     aiCalls: "Multiple models, specialized AI services";
314 |     automation: "Fully autonomous operation";
315 |     integrations: "Extensive third-party ecosystem";
316 |   };
317 |   
318 |   limitations: {
319 |     humanOversight: "Limited or optional";
320 |     reliability: "Can go off-track or produce errors";
321 |     complexity: "Complex setup, API management";
322 |     cost: "High due to multiple AI calls";
323 |   };
324 |   
325 |   differentiator: "Full automation vs structured human-guided workflow";
326 | }
327 | ```
328 | 
329 | **Category 2: Development Workflow Tools (e.g., GitHub Copilot, Cursor)**
330 | ```typescript
331 | interface DevelopmentTools {
332 |   capabilities: {
333 |     codeGeneration: "Excellent within editors";
334 |     contextAwareness: "Good for code context";
335 |     realTimeAssistance: "Integrated development support";
336 |     aiPowered: "Built-in LLM capabilities";
337 |   };
338 |   
339 |   limitations: {
340 |     workflowStructure: "Limited structured spec processes";
341 |     documentationFocus: "Code-centric, not spec-driven";
342 |     approvalProcess: "No formal review workflows";
343 |     projectPlanning: "Limited high-level planning";
344 |   };
345 |   
346 |   differentiator: "Code-first vs spec-driven development approach";
347 | }
348 | ```
349 | 
350 | **Category 3: Project Management + AI (e.g., Notion AI, Linear)**
351 | ```typescript
352 | interface ProjectManagementAI {
353 |   capabilities: {
354 |     projectTracking: "Excellent project organization";
355 |     collaboration: "Team coordination features";
356 |     aiAssistance: "AI-powered content generation";
357 |     integration: "Extensive third-party connections";
358 |   };
359 |   
360 |   limitations: {
361 |     technicalDepth: "Limited technical specification focus";
362 |     workflowEnforcement: "Flexible but not enforced";
363 |     developerWorkflow: "Not developer-workflow optimized";
364 |     codeIntegration: "Limited code context understanding";
365 |   };
366 |   
367 |   differentiator: "General project management vs developer-specific workflows";
368 | }
369 | ```
370 | 
371 | ### Strategic Market Position
372 | 
373 | **Spec-Workflow-MCP's Unique Position:**
374 | ```typescript
375 | interface MarketPosition {
376 |   blueOcean: {
377 |     category: "LLM-Enhanced Structured Development Workflows";
378 |     uniqueValue: "Human-supervised LLM intelligence with enforced spec-driven process";
379 |     targetUser: "Development teams needing structured processes with AI assistance";
380 |   };
381 |   
382 |   competitiveAdvantages: {
383 |     llmLeverage: "Full LLM power without additional API costs";
384 |     humanOversight: "Prevents AI errors through mandatory approval";
385 |     structuredProcess: "Enforces proven development methodology";
386 |     simplicity: "No complex setup or API key management";
387 |     realTimeUI: "Superior user experience with dashboard";
388 |   };
389 |   
390 |   marketOpportunities: {
391 |     enterpriseAdoption: "Companies wanting AI benefits with human control";
392 |     consultingFirms: "Standardized processes across client projects";
393 |     startups: "Structured development without overhead";
394 |     education: "Teaching proper development workflows";
395 |   };
396 | }
397 | ```
398 | 
399 | ### Expansion Strategy Insights
400 | 
401 | **Phase 1: Leverage Core Strengths**
402 | ```typescript
403 | interface Phase1Strategy {
404 |   buildOnStrengths: {
405 |     enhanceHumanOversight: "Advanced approval workflows, review templates";
406 |     improveStructure: "Dynamic templates, adaptive workflows";
407 |     expandLLMUsage: "Better context utilization, smarter suggestions";
408 |   };
409 |   
410 |   addressGaps: {
411 |     basicIntegrations: "GitHub, GitLab, Bitbucket connections";
412 |     qualityGates: "Optional automated checks before human review";
413 |     teamFeatures: "Multi-developer coordination";
414 |   };
415 | }
416 | ```
417 | 
418 | **Phase 2: Strategic Differentiation**
419 | ```typescript
420 | interface Phase2Strategy {
421 |   uniqueCapabilities: {
422 |     hybridIntelligence: "Best of LLM automation + human oversight";
423 |     contextMastery: "Superior project context understanding";
424 |     processExcellence: "Industry-leading structured workflows";
425 |   };
426 |   
427 |   competitiveFeatures: {
428 |     multiModelSupport: "Support multiple LLM providers";
429 |     enterpriseFeatures: "SSO, compliance, audit trails";
430 |     aiOrchestration: "Multi-agent coordination while maintaining oversight";
431 |   };
432 | }
433 | ```
434 | 
435 | ### Strategic Recommendations for Creators
436 | 
437 | **Immediate Opportunities (0-6 months):**
438 | 1. **GitHub Integration**: Leverage LLM to create PRs, analyze codebases
439 | 2. **Quality Templates**: Add project-type detection for smarter templates  
440 | 3. **Team Coordination**: Multi-developer approval workflows
441 | 4. **Performance Analytics**: Track spec-to-delivery success rates
442 | 
443 | **Medium-term Differentiators (6-18 months):**
444 | 1. **Hybrid AI Workflows**: Optional automated gates with human oversight
445 | 2. **Enterprise Dashboard**: Multi-project management interface
446 | 3. **Advanced Integrations**: Jira, Slack, Confluence, CI/CD pipelines
447 | 4. **Predictive Analytics**: Project risk analysis using LLM insights
448 | 
449 | **Long-term Vision (18+ months):**
450 | 1. **AI Orchestration Platform**: Multi-agent coordination with human oversight
451 | 2. **Industry Templates**: Specialized workflows for different domains
452 | 3. **Compliance Integration**: SOX, GDPR, HIPAA workflow templates
453 | 4. **Educational Platform**: Teaching structured development at scale
454 | 
455 | ### Market Validation Insights
456 | 
457 | **This analysis reveals that Spec-Workflow-MCP occupies a unique market position:**
458 | - ✅ **Underserved Market**: Structured development workflows with AI enhancement
459 | - ✅ **Clear Differentiation**: Human oversight + LLM power combination
460 | - ✅ **Expansion Potential**: Multiple clear paths for feature enhancement
461 | - ✅ **Strategic Moat**: Proven workflow methodology that competitors would struggle to replicate
462 | 
463 | **Last Updated**: December 2024 | **Version**: 0.0.23
```

--------------------------------------------------------------------------------
/docs/technical-documentation/contributing.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Contributing Guidelines
  2 | 
  3 | > **Welcome!** This guide will help you contribute effectively to the Spec Workflow MCP project.
  4 | 
  5 | ## 🚀 Quick Start for Contributors
  6 | 
  7 | ### 1. Setup Development Environment
  8 | ```bash
  9 | # Fork and clone the repository
 10 | git clone https://github.com/your-username/spec-workflow-mcp.git
 11 | cd spec-workflow-mcp
 12 | 
 13 | # Install dependencies
 14 | npm install
 15 | 
 16 | # Install VS Code extension dependencies (optional)
 17 | cd vscode-extension
 18 | npm install
 19 | cd ..
 20 | 
 21 | # Build everything to verify setup
 22 | npm run build
 23 | ```
 24 | 
 25 | ### 2. Development Workflow
 26 | ```bash
 27 | # Start MCP server in development mode
 28 | npm run dev
 29 | 
 30 | # In another terminal, start dashboard
 31 | npm run dev:dashboard
 32 | 
 33 | # Make your changes
 34 | # Test thoroughly
 35 | # Create pull request
 36 | ```
 37 | 
 38 | ## 🎯 How to Contribute
 39 | 
 40 | ### Areas Where We Need Help
 41 | 
 42 | **🔧 Core Features**
 43 | - New MCP tools and functionality
 44 | - Performance optimizations
 45 | - Cross-platform compatibility improvements
 46 | 
 47 | **📱 Dashboard & UI**
 48 | - New dashboard features
 49 | - UI/UX improvements
 50 | - Accessibility enhancements
 51 | 
 52 | **📚 Documentation**
 53 | - Code examples and tutorials
 54 | - API documentation improvements
 55 | - Translation to other languages
 56 | 
 57 | **🧪 Testing**
 58 | - Unit test coverage
 59 | - Integration test scenarios  
 60 | - Manual testing on different platforms
 61 | 
 62 | **🐛 Bug Fixes**
 63 | - Reported issues in GitHub
 64 | - Edge cases and error handling
 65 | - Performance bottlenecks
 66 | 
 67 | ## 📋 Contribution Types
 68 | 
 69 | ### 1. Bug Reports
 70 | **Before Creating an Issue**:
 71 | - Search existing issues first
 72 | - Try the [troubleshooting guide](troubleshooting.md)
 73 | - Test with the latest version
 74 | 
 75 | **Good Bug Report Template**:
 76 | ```markdown
 77 | ## Bug Description
 78 | Brief description of the issue
 79 | 
 80 | ## Environment
 81 | - OS: [Windows 11 / macOS 14 / Ubuntu 22.04]
 82 | - Node.js: [version]
 83 | - MCP Client: [Claude Desktop / Cursor / etc.]
 84 | 
 85 | ## Steps to Reproduce
 86 | 1. Step one
 87 | 2. Step two
 88 | 3. Step three
 89 | 
 90 | ## Expected Behavior
 91 | What should happen
 92 | 
 93 | ## Actual Behavior  
 94 | What actually happens
 95 | 
 96 | ## Additional Context
 97 | - Error messages
 98 | - Screenshots
 99 | - Logs
100 | ```
101 | 
102 | ### 2. Feature Requests
103 | **Good Feature Request Template**:
104 | ```markdown
105 | ## Feature Description
106 | Clear description of the proposed feature
107 | 
108 | ## Problem It Solves
109 | What problem does this address?
110 | 
111 | ## Proposed Solution
112 | How should it work?
113 | 
114 | ## Alternatives Considered
115 | Other approaches you've considered
116 | 
117 | ## Implementation Ideas
118 | Any thoughts on how to implement this
119 | ```
120 | 
121 | ### 3. Code Contributions
122 | 
123 | #### Pull Request Process
124 | 1. **Fork** the repository
125 | 2. **Create** a feature branch: `git checkout -b feature/my-feature`
126 | 3. **Make** your changes following our coding standards
127 | 4. **Test** your changes thoroughly
128 | 5. **Document** new functionality
129 | 6. **Submit** a pull request with clear description
130 | 
131 | #### Pull Request Template
132 | ```markdown
133 | ## Description
134 | Brief description of changes
135 | 
136 | ## Type of Change
137 | - [ ] Bug fix
138 | - [ ] New feature  
139 | - [ ] Breaking change
140 | - [ ] Documentation update
141 | 
142 | ## Testing
143 | - [ ] Unit tests pass
144 | - [ ] Manual testing completed
145 | - [ ] Cross-platform tested (if applicable)
146 | 
147 | ## Documentation
148 | - [ ] Code is documented
149 | - [ ] README updated (if needed)
150 | - [ ] API docs updated (if needed)
151 | 
152 | ## Checklist
153 | - [ ] Code follows style guidelines
154 | - [ ] Self-review completed
155 | - [ ] No merge conflicts
156 | ```
157 | 
158 | ## 🎨 Coding Standards
159 | 
160 | ### TypeScript Guidelines
161 | 
162 | **File Organization**:
163 | ```typescript
164 | // 1. External library imports
165 | import { Tool } from '@modelcontextprotocol/sdk/types.js';
166 | import { readFile } from 'fs/promises';
167 | 
168 | // 2. Internal imports
169 | import { ToolContext, ToolResponse } from '../types.js';
170 | import { PathUtils } from '../core/path-utils.js';
171 | 
172 | // 3. Type definitions
173 | interface LocalInterface {
174 |   // ...
175 | }
176 | 
177 | // 4. Constants
178 | const CONSTANTS = {
179 |   // ...
180 | };
181 | 
182 | // 5. Main implementation
183 | export class MyClass {
184 |   // ...
185 | }
186 | ```
187 | 
188 | **Function Structure**:
189 | ```typescript
190 | /**
191 |  * Brief description of what the function does
192 |  * @param param1 Description of parameter
193 |  * @param param2 Description of parameter  
194 |  * @returns Description of return value
195 |  */
196 | export async function myFunction(
197 |   param1: string,
198 |   param2: number
199 | ): Promise<MyReturnType> {
200 |   // Input validation
201 |   if (!param1) {
202 |     throw new Error('param1 is required');
203 |   }
204 |   
205 |   try {
206 |     // Main logic
207 |     const result = await doSomething(param1, param2);
208 |     return result;
209 |   } catch (error: any) {
210 |     // Error handling
211 |     throw new Error(`Operation failed: ${error.message}`);
212 |   }
213 | }
214 | ```
215 | 
216 | **Error Handling Pattern**:
217 | ```typescript
218 | // MCP Tool error handling
219 | export async function myToolHandler(args: any, context: ToolContext): Promise<ToolResponse> {
220 |   try {
221 |     // Validation
222 |     const { requiredParam } = args;
223 |     if (!requiredParam) {
224 |       return {
225 |         success: false,
226 |         message: 'requiredParam is required',
227 |         nextSteps: ['Provide the required parameter']
228 |       };
229 |     }
230 |     
231 |     // Implementation
232 |     const result = await doWork(requiredParam);
233 |     
234 |     return {
235 |       success: true,
236 |       message: 'Operation completed successfully',
237 |       data: result,
238 |       nextSteps: ['Next recommended action']
239 |     };
240 |   } catch (error: any) {
241 |     return {
242 |       success: false,
243 |       message: `Operation failed: ${error.message}`,
244 |       nextSteps: [
245 |         'Check input parameters',
246 |         'Verify file permissions',
247 |         'Try again or contact support'
248 |       ]
249 |     };
250 |   }
251 | }
252 | ```
253 | 
254 | ### React Component Guidelines
255 | 
256 | **Component Structure**:
257 | ```typescript
258 | // src/dashboard_frontend/src/components/MyComponent.tsx
259 | import React, { useState, useEffect } from 'react';
260 | 
261 | interface MyComponentProps {
262 |   data: DataType[];
263 |   onAction: (item: DataType) => void;
264 |   className?: string;
265 | }
266 | 
267 | export default function MyComponent({ 
268 |   data, 
269 |   onAction, 
270 |   className = '' 
271 | }: MyComponentProps) {
272 |   const [localState, setLocalState] = useState<StateType>({});
273 |   
274 |   useEffect(() => {
275 |     // Side effects
276 |   }, [data]);
277 |   
278 |   const handleClick = (item: DataType) => {
279 |     // Event handlers
280 |     onAction(item);
281 |   };
282 |   
283 |   return (
284 |     <div className={`base-styles ${className}`}>
285 |       {data.map(item => (
286 |         <div key={item.id} onClick={() => handleClick(item)}>
287 |           {item.name}
288 |         </div>
289 |       ))}
290 |     </div>
291 |   );
292 | }
293 | ```
294 | 
295 | **Styling Guidelines**:
296 | ```typescript
297 | // Use Tailwind CSS classes
298 | <div className="p-4 bg-white dark:bg-gray-800 rounded-lg shadow-md">
299 |   <h2 className="text-xl font-semibold text-gray-900 dark:text-white">
300 |     Title
301 |   </h2>
302 | </div>
303 | 
304 | // Custom CSS only when Tailwind is insufficient
305 | // Add to src/modules/theme/theme.css
306 | ```
307 | 
308 | ### File and Directory Naming
309 | 
310 | ```
311 | // Files
312 | kebab-case.ts         ✅ Good
313 | PascalCase.ts         ❌ Avoid
314 | snake_case.ts         ❌ Avoid
315 | 
316 | // Directories  
317 | kebab-case/           ✅ Good
318 | PascalCase/          ❌ Avoid (except React components)
319 | snake_case/          ❌ Avoid
320 | 
321 | // React Components
322 | MyComponent.tsx       ✅ Good (PascalCase for components)
323 | my-component.tsx      ❌ Avoid
324 | 
325 | // MCP Tools
326 | my-tool.ts           ✅ Good
327 | myTool.ts            ❌ Avoid
328 | ```
329 | 
330 | ## 🧪 Testing Guidelines
331 | 
332 | ### Manual Testing Checklist
333 | 
334 | **Before Submitting PR**:
335 | - [ ] MCP server starts without errors
336 | - [ ] Dashboard loads and displays data
337 | - [ ] WebSocket connections work
338 | - [ ] File changes trigger updates
339 | - [ ] Approval workflow functions
340 | - [ ] Cross-platform compatibility (if applicable)
341 | 
342 | **Test Scenarios**:
343 | ```bash
344 | # 1. Basic MCP server functionality
345 | npm run dev
346 | # Connect AI client and test tools
347 | 
348 | # 2. Dashboard functionality
349 | npm run dev:dashboard
350 | # Test all pages and features
351 | 
352 | # 3. VS Code extension (if modified)
353 | cd vscode-extension
354 | # Press F5 in VS Code to test
355 | 
356 | # 4. Build process
357 | npm run clean
358 | npm run build
359 | # Verify dist/ contents
360 | 
361 | # 5. CLI interface
362 | node dist/index.js --help
363 | node dist/index.js --dashboard
364 | ```
365 | 
366 | ### Future Testing Framework
367 | 
368 | **Unit Tests** (planned):
369 | ```typescript
370 | // Example test structure
371 | describe('PathUtils', () => {
372 |   describe('getSpecPath', () => {
373 |     it('should create correct spec path', () => {
374 |       const result = PathUtils.getSpecPath('/project', 'my-spec');
375 |       expect(result).toBe('/project/.spec-workflow/specs/my-spec');
376 |     });
377 |     
378 |     it('should handle special characters', () => {
379 |       const result = PathUtils.getSpecPath('/project', 'user-auth');
380 |       expect(result).toContain('user-auth');
381 |     });
382 |   });
383 | });
384 | ```
385 | 
386 | ## 📖 Documentation Standards
387 | 
388 | ### Code Documentation
389 | 
390 | **JSDoc Comments**:
391 | ```typescript
392 | /**
393 |  * Creates a new specification document following the workflow sequence
394 |  * 
395 |  * @param projectPath - Absolute path to the project root
396 |  * @param specName - Feature name in kebab-case (e.g., 'user-authentication')  
397 |  * @param document - Which document to create: 'requirements' | 'design' | 'tasks'
398 |  * @param content - Complete markdown content for the document
399 |  * @returns Promise resolving to tool response with file path and next steps
400 |  * 
401 |  * @example
402 |  * ```typescript
403 |  * const response = await createSpecDoc({
404 |  *   projectPath: '/my/project',
405 |  *   specName: 'user-auth', 
406 |  *   document: 'requirements',
407 |  *   content: '# Requirements\n\n...'
408 |  * });
409 |  * ```
410 |  * 
411 |  * @throws {Error} When workflow order is violated (e.g., creating design before requirements)
412 |  */
413 | export async function createSpecDoc(...): Promise<ToolResponse> {
414 |   // Implementation
415 | }
416 | ```
417 | 
418 | **README Updates**:
419 | - Update main README.md for user-facing changes
420 | - Update technical documentation for developer changes
421 | - Include code examples for new features
422 | 
423 | ### API Documentation
424 | 
425 | **MCP Tool Documentation**:
426 | ```typescript
427 | export const myNewToolTool: Tool = {
428 |   name: 'my-new-tool',
429 |   description: `Brief description of what this tool does.
430 | 
431 | # Instructions  
432 | When to use this tool and how it fits in the workflow.
433 | 
434 | # Parameters
435 | - param1: Description and format
436 | - param2: Description and constraints
437 | 
438 | # Example Usage
439 | Concrete example of how to use this tool.`,
440 |   inputSchema: {
441 |     // JSON Schema
442 |   }
443 | };
444 | ```
445 | 
446 | ## 🔄 Development Workflow
447 | 
448 | ### Branch Strategy
449 | 
450 | ```bash
451 | # Main branches
452 | main                    # Stable release code
453 | develop                 # Integration branch for features
454 | 
455 | # Feature branches  
456 | feature/add-new-tool   # New features
457 | bugfix/fix-approval    # Bug fixes
458 | docs/update-api        # Documentation updates
459 | chore/update-deps      # Maintenance tasks
460 | ```
461 | 
462 | ### Commit Message Format
463 | 
464 | ```bash
465 | # Format: type(scope): description
466 | 
467 | feat(tools): add new spec validation tool
468 | fix(dashboard): resolve WebSocket connection issues  
469 | docs(api): update MCP tool documentation
470 | chore(deps): update TypeScript to 5.3.0
471 | refactor(parser): simplify task parsing logic
472 | 
473 | # Types: feat, fix, docs, style, refactor, test, chore
474 | # Scope: tools, dashboard, core, docs, extension
475 | ```
476 | 
477 | ### Release Process
478 | 
479 | **Version Bumping**:
480 | ```bash
481 | # Patch release (bug fixes)
482 | npm version patch
483 | 
484 | # Minor release (new features)  
485 | npm version minor
486 | 
487 | # Major release (breaking changes)
488 | npm version major
489 | ```
490 | 
491 | **Pre-release Checklist**:
492 | - [ ] All tests pass
493 | - [ ] Documentation updated
494 | - [ ] CHANGELOG.md updated  
495 | - [ ] Version bumped
496 | - [ ] Build successful
497 | - [ ] Manual testing completed
498 | 
499 | ## 🤝 Community Guidelines
500 | 
501 | ### Code of Conduct
502 | 
503 | **Our Standards**:
504 | - **Be Respectful** - Treat everyone with respect and kindness
505 | - **Be Inclusive** - Welcome contributors from all backgrounds
506 | - **Be Constructive** - Provide helpful feedback and suggestions
507 | - **Be Patient** - Remember that everyone is learning
508 | 
509 | **Unacceptable Behavior**:
510 | - Harassment or discrimination
511 | - Trolling or inflammatory comments
512 | - Personal attacks
513 | - Publishing private information
514 | 
515 | ### Getting Help
516 | 
517 | **For Contributors**:
518 | 1. **Read this guide** and linked documentation
519 | 2. **Search existing issues** and discussions
520 | 3. **Ask in GitHub Discussions** for general questions
521 | 4. **Create an issue** for specific problems
522 | 5. **Join community channels** (if available)
523 | 
524 | **For Maintainers**:
525 | - Respond to issues and PRs promptly
526 | - Provide constructive feedback
527 | - Help newcomers get started
528 | - Maintain welcoming environment
529 | 
530 | ## 🏆 Recognition
531 | 
532 | ### Contributors
533 | 
534 | Contributors are recognized in:
535 | - GitHub contributors list
536 | - CHANGELOG.md for significant contributions
537 | - README.md acknowledgments section
538 | 
539 | ### Types of Contributions
540 | 
541 | **All contributions are valued**:
542 | - 💻 **Code** - Features, bug fixes, improvements
543 | - 📖 **Documentation** - Guides, examples, translations  
544 | - 🐛 **Testing** - Bug reports, test cases, QA
545 | - 💡 **Ideas** - Feature requests, design feedback
546 | - 🎨 **Design** - UI/UX improvements, icons, graphics
547 | - 📢 **Community** - Helping other users, spreading the word
548 | 
549 | ---
550 | 
551 | **Thank you for contributing to Spec Workflow MCP!** 🎉
552 | 
553 | Every contribution, no matter how small, helps make this project better for everyone.
554 | 
555 | ---
556 | 
557 | **Next**: [Testing Guide →](testing.md)
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/vite-env.d.ts:
--------------------------------------------------------------------------------

```typescript
1 | /// <reference types="vite/client" />
2 | 
3 | declare module "*.css" {
4 |   const content: any;
5 |   export default content;
6 | }
```

--------------------------------------------------------------------------------
/vscode-extension/tsconfig.json:
--------------------------------------------------------------------------------

```json
1 | {
2 |   "files": [],
3 |   "references": [
4 |     { "path": "./tsconfig.app.json" },
5 |     { "path": "./tsconfig.node.json" },
6 |     { "path": "./tsconfig.extension.json" }
7 |   ]
8 | }
9 | 
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/src/lib/utils.ts:
--------------------------------------------------------------------------------

```typescript
1 | import { clsx, type ClassValue } from "clsx";
2 | import { twMerge } from "tailwind-merge";
3 | 
4 | export function cn(...inputs: ClassValue[]) {
5 |   return twMerge(clsx(inputs));
6 | }
```

--------------------------------------------------------------------------------
/containers/example.mcp.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "mcpServers": {
 3 |     "spec-workflow": {
 4 |       "command": "npx",
 5 |       "args": [
 6 |         "-y",
 7 |         "@pimzino/spec-workflow-mcp@latest",
 8 |         "/path/to/your/project"
 9 |       ]
10 |     }
11 |   }
12 | }
13 | 
14 | 
```

--------------------------------------------------------------------------------
/vscode-extension/.vscode/extensions.json:
--------------------------------------------------------------------------------

```json
1 | {
2 |   // See http://go.microsoft.com/fwlink/?LinkId=827846
3 |   // for the documentation about the extensions.json format
4 |   "recommendations": ["dbaeumer.vscode-eslint", "connor4312.esbuild-problem-matchers", "ms-vscode.extension-test-runner"]
5 | }
6 | 
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/index.html:
--------------------------------------------------------------------------------

```html
 1 | <!doctype html>
 2 | <html lang="en">
 3 |   <head>
 4 |     <meta charset="UTF-8" />
 5 |     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 6 |     <title>Spec Dashboard</title>
 7 |     <link rel="icon" href="/favicon.ico" />
 8 |   </head>
 9 |   <body>
10 |     <div id="root"></div>
11 |     <script type="module" src="/src/main.tsx"></script>
12 |   </body>
13 |   </html>
14 | 
15 | 
16 | 
```

--------------------------------------------------------------------------------
/containers/docker-compose.yml:
--------------------------------------------------------------------------------

```yaml
 1 | services:
 2 |   spec-workflow-mcp:
 3 |     build:
 4 |       context: ..
 5 |       dockerfile: containers/Dockerfile
 6 |     ports:
 7 |       - "${DASHBOARD_PORT:-5000}:${DASHBOARD_PORT:-5000}"
 8 |     volumes:
 9 |       - "${SPEC_WORKFLOW_PATH:-./workspace}/.spec-workflow:/workspace/.spec-workflow:rw"
10 |     environment:
11 |       - DASHBOARD_PORT=${DASHBOARD_PORT:-5000}
12 |     restart: unless-stopped
13 | 
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/src/modules/approvals/colors.ts:
--------------------------------------------------------------------------------

```typescript
 1 | export function hexToColorObject(hex: string) {
 2 |   const r = parseInt(hex.slice(1, 3), 16);
 3 |   const g = parseInt(hex.slice(3, 5), 16);
 4 |   const b = parseInt(hex.slice(5, 7), 16);
 5 |   const bg = `rgba(${r}, ${g}, ${b}, 0.3)`;
 6 |   const border = hex;
 7 |   const name = hex.toLowerCase();
 8 |   return { bg, border, name };
 9 | }
10 | 
11 | export function isValidHex(hex: string) {
12 |   return /^#[0-9A-Fa-f]{6}$/.test(hex);
13 | }
14 | 
15 | 
16 | 
```

--------------------------------------------------------------------------------
/src/prompts/types.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Prompt, PromptMessage, PromptArgument } from '@modelcontextprotocol/sdk/types.js';
 2 | import { ToolContext } from '../types.js';
 3 | 
 4 | export interface PromptHandler {
 5 |   (args: Record<string, any>, context: ToolContext): Promise<PromptMessage[]>;
 6 | }
 7 | 
 8 | export interface PromptDefinition {
 9 |   prompt: Prompt;
10 |   handler: PromptHandler;
11 | }
12 | 
13 | export interface PromptResponse {
14 |   messages: PromptMessage[];
15 | }
```

--------------------------------------------------------------------------------
/vscode-extension/components.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "$schema": "https://ui.shadcn.com/schema.json",
 3 |   "style": "new-york",
 4 |   "rsc": false,
 5 |   "tsx": true,
 6 |   "tailwind": {
 7 |     "config": "tailwind.config.js",
 8 |     "css": "src/webview/globals.css",
 9 |     "baseColor": "neutral",
10 |     "cssVariables": true,
11 |     "prefix": ""
12 |   },
13 |   "aliases": {
14 |     "components": "@/components",
15 |     "utils": "@/lib/utils",
16 |     "ui": "@/components/ui",
17 |     "lib": "@/lib",
18 |     "hooks": "@/hooks"
19 |   },
20 |   "iconLibrary": "lucide"
21 | }
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/index.html:
--------------------------------------------------------------------------------

```html
 1 | <!doctype html>
 2 | <html lang="en">
 3 |   <head>
 4 |     <meta charset="UTF-8" />
 5 |     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 6 |     <title>Spec Workflow Dashboard</title>
 7 |     <style>
 8 |       /* Prevent FOUC */
 9 |       body {
10 |         visibility: hidden;
11 |       }
12 |       body.loaded {
13 |         visibility: visible;
14 |       }
15 |     </style>
16 |   </head>
17 |   <body>
18 |     <div id="root"></div>
19 |     <script type="module" src="/main.tsx"></script>
20 |   </body>
21 | </html>
```

--------------------------------------------------------------------------------
/vitest.config.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { defineConfig } from 'vitest/config';
 2 | 
 3 | export default defineConfig({
 4 |   test: {
 5 |     environment: 'node',
 6 |     globals: true,
 7 |     include: ['src/**/*.{test,spec}.{js,ts}'],
 8 |     exclude: ['src/dashboard_frontend/**/*', 'node_modules/**/*'],
 9 |     coverage: {
10 |       reporter: ['text', 'json', 'html'],
11 |       exclude: [
12 |         'src/dashboard_frontend/**',
13 |         'dist/**',
14 |         '**/*.d.ts',
15 |         '**/*.config.*',
16 |         '**/test/**',
17 |         '**/__tests__/**',
18 |       ]
19 |     }
20 |   }
21 | });
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/main.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import React, { Suspense } from 'react';
 2 | import ReactDOM from 'react-dom/client';
 3 | import App from './App';
 4 | import './globals.css';
 5 | import './i18n';
 6 | 
 7 | // Create root and render app
 8 | const container = document.getElementById('root');
 9 | if (container) {
10 |   const root = ReactDOM.createRoot(container);
11 |   root.render(
12 |     <React.StrictMode>
13 |       <Suspense fallback="Loading...">
14 |         <App />
15 |       </Suspense>
16 |     </React.StrictMode>
17 |   );
18 |   
19 |   // Mark body as loaded to prevent FOUC
20 |   document.body.classList.add('loaded');
21 | }
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2022",
 4 |     "module": "node16",
 5 |     "moduleResolution": "node16",
 6 |     "lib": ["ES2022"],
 7 |     "outDir": "./dist",
 8 |     "rootDir": "./src",
 9 |     "strict": true,
10 |     "esModuleInterop": true,
11 |     "skipLibCheck": true,
12 |     "forceConsistentCasingInFileNames": true,
13 |     "resolveJsonModule": true,
14 |     "declaration": true,
15 |     "declarationMap": true,
16 |     "sourceMap": true,
17 |     "allowSyntheticDefaultImports": true
18 |   },
19 |   "include": ["src/**/*"],
20 |   "exclude": ["node_modules", "dist", "src/dashboard_frontend/**"]
21 | }
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/src/main.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import React, { Suspense } from 'react';
 2 | import { createRoot } from 'react-dom/client';
 3 | import { HashRouter } from 'react-router-dom';
 4 | import App from './modules/app/App';
 5 | import './modules/theme/tailwind.css';
 6 | import './modules/theme/theme.css';
 7 | import './i18n';
 8 | 
 9 | const container = document.getElementById('root');
10 | if (container) {
11 |   const root = createRoot(container);
12 |   root.render(
13 |     <React.StrictMode>
14 |       <Suspense fallback="loading">
15 |         <HashRouter>
16 |           <App />
17 |         </HashRouter>
18 |       </Suspense>
19 |     </React.StrictMode>
20 |   );
21 | }
22 | 
23 | 
24 | 
```

--------------------------------------------------------------------------------
/vscode-extension/tsconfig.extension.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "module": "Node16",
 4 |     "target": "ES2022",
 5 |     "lib": ["ES2022"],
 6 |     "allowJs": true,
 7 |     "skipLibCheck": true,
 8 |     "esModuleInterop": true,
 9 |     "allowSyntheticDefaultImports": true,
10 |     "strict": true,
11 |     "forceConsistentCasingInFileNames": true,
12 |     "moduleResolution": "Node16",
13 |     "resolveJsonModule": true,
14 |     "isolatedModules": true,
15 |     "noEmit": true,
16 |     "sourceMap": true,
17 |     "baseUrl": "."
18 |   },
19 |   "include": [
20 |     "src/extension",
21 |     "src/extension.ts",
22 |     "esbuild.js"
23 |   ],
24 |   "exclude": [
25 |     "node_modules"
26 |   ]
27 | }
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------

```yaml
 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-issue-config.json
 2 | 
 3 | blank_issues_enabled: false
 4 | contact_links:
 5 |   - name: 💬 Discussion
 6 |     url: https://github.com/anthropics/claude-code/issues
 7 |     about: Ask questions, share ideas, or discuss Claude Code and MCP projects
 8 |   - name: 📖 MCP Documentation
 9 |     url: https://modelcontextprotocol.io
10 |     about: Read about the Model Context Protocol specification and implementation guides
11 |   - name: ⚡ Claude Code
12 |     url: https://claude.ai/code
13 |     about: Official Claude Code documentation and resources
```

--------------------------------------------------------------------------------
/vscode-extension/.vscode/launch.json:
--------------------------------------------------------------------------------

```json
 1 | // A launch configuration that compiles the extension and then opens it inside a new window
 2 | // Use IntelliSense to learn about possible attributes.
 3 | // Hover to view descriptions of existing attributes.
 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
 5 | {
 6 | 	"version": "0.2.0",
 7 | 	"configurations": [
 8 | 		{
 9 | 			"name": "Run Extension",
10 | 			"type": "extensionHost",
11 | 			"request": "launch",
12 | 			"args": [
13 | 				"--extensionDevelopmentPath=${workspaceFolder}"
14 | 			],
15 | 			"outFiles": [
16 | 				"${workspaceFolder}/dist/**/*.js"
17 | 			],
18 | 			"preLaunchTask": "${defaultBuildTask}"
19 | 		}
20 | 	]
21 | }
22 | 
```

--------------------------------------------------------------------------------
/vscode-extension/webview-dist/index.html:
--------------------------------------------------------------------------------

```html
 1 | <!doctype html>
 2 | <html lang="en">
 3 |   <head>
 4 |     <meta charset="UTF-8" />
 5 |     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 6 |     <title>Spec Workflow Dashboard</title>
 7 |     <style>
 8 |       /* Prevent FOUC */
 9 |       body {
10 |         visibility: hidden;
11 |       }
12 |       body.loaded {
13 |         visibility: visible;
14 |       }
15 |     </style>
16 |     <script type="module" crossorigin src="/main.js"></script>
17 |     <link rel="modulepreload" crossorigin href="/i18n.js">
18 |     <link rel="stylesheet" crossorigin href="/globals.css">
19 |   </head>
20 |   <body>
21 |     <div id="root"></div>

22 |   </body>
23 | </html>
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/vite.config.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { defineConfig } from 'vite';
 2 | import { fileURLToPath } from 'url';
 3 | import { dirname } from 'path';
 4 | import react from '@vitejs/plugin-react';
 5 | 
 6 | // Dynamically import Tailwind CSS v4 plugin
 7 | async function createConfig() {
 8 |   const { default: tailwindcss } = await import('@tailwindcss/vite');
 9 | 
10 |   return {
11 |     plugins: [react(), tailwindcss()],
12 |     // Ensure Vite resolves index.html relative to this config file
13 |     root: dirname(fileURLToPath(new URL(import.meta.url))),
14 |     base: '/',
15 |     build: {
16 |       outDir: 'dist',
17 |       emptyOutDir: true,
18 |     },
19 |   };
20 | }
21 | 
22 | export default defineConfig(createConfig());
23 | 
24 | 
25 | 
```

--------------------------------------------------------------------------------
/vscode-extension/.vscode/settings.json:
--------------------------------------------------------------------------------

```json
 1 | // Place your settings in this file to overwrite default and user settings.
 2 | {
 3 |     "files.exclude": {
 4 |         "out": false, // set this to true to hide the "out" folder with the compiled JS files
 5 |         "dist": false // set this to true to hide the "dist" folder with the compiled JS files
 6 |     },
 7 |     "search.exclude": {
 8 |         "out": true, // set this to false to include "out" folder in search results
 9 |         "dist": true // set this to false to include "dist" folder in search results
10 |     },
11 |     // Turn off tsc task auto detection since we have the necessary tasks as npm scripts
12 |     "typescript.tsc.autoDetect": "off"
13 | }
```

--------------------------------------------------------------------------------
/vscode-extension/tsconfig.node.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
 4 |     "target": "ES2022",
 5 |     "lib": ["ES2022"],
 6 |     "module": "ESNext",
 7 |     "skipLibCheck": true,
 8 | 
 9 |     /* Bundler mode */
10 |     "moduleResolution": "bundler",
11 |     "allowImportingTsExtensions": true,
12 |     "verbatimModuleSyntax": true,
13 |     "moduleDetection": "force",
14 |     "noEmit": true,
15 | 
16 |     /* Linting */
17 |     "strict": true,
18 |     "noUnusedLocals": true,
19 |     "noUnusedParameters": true,
20 |     "erasableSyntaxOnly": true,
21 |     "noFallthroughCasesInSwitch": true,
22 |     "noUncheckedSideEffectImports": true
23 |   },
24 |   "include": ["vite.config.ts"]
25 | }
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/components/ui/separator.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import * as React from "react";
 2 | import * as SeparatorPrimitive from "@radix-ui/react-separator";
 3 | 
 4 | import { cn } from "@/lib/utils";
 5 | 
 6 | function Separator({
 7 |   className,
 8 |   orientation = "horizontal",
 9 |   decorative = true,
10 |   ...props
11 | }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
12 |   return (
13 |     <SeparatorPrimitive.Root
14 |       data-slot="separator"
15 |       decorative={decorative}
16 |       orientation={orientation}
17 |       className={cn(
18 |         "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
19 |         className
20 |       )}
21 |       {...props}
22 |     />
23 |   );
24 | }
25 | 
26 | export { Separator };
27 | 
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/components/ui/input.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import * as React from "react";
 2 | 
 3 | import { cn } from "@/lib/utils";
 4 | 
 5 | export interface InputProps
 6 |   extends React.InputHTMLAttributes<HTMLInputElement> {}
 7 | 
 8 | const Input = React.forwardRef<HTMLInputElement, InputProps>(
 9 |   ({ className, type, ...props }, ref) => (
10 |     <input
11 |       type={type}
12 |       className={cn(
13 |         "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
14 |         className
15 |       )}
16 |       ref={ref}
17 |       {...props}
18 |     />
19 |   )
20 | );
21 | Input.displayName = "Input";
22 | 
23 | export { Input };
24 | 
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/comment-modal.html:
--------------------------------------------------------------------------------

```html
 1 | <!DOCTYPE html>
 2 | <html lang="en">
 3 | <head>
 4 |   <meta charset="UTF-8">
 5 |   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6 |   <title>Add Comment</title>
 7 |   <link rel="stylesheet" href="./globals.css">
 8 |   <style>
 9 |     body {
10 |       margin: 0;
11 |       padding: 0;
12 |       font-family: var(--vscode-font-family), -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
13 |       font-size: var(--vscode-font-size, 13px);
14 |       line-height: 1.4;
15 |       color: var(--vscode-foreground);
16 |       background: var(--vscode-editor-background);
17 |     }
18 |     #root {
19 |       width: 100%;
20 |       height: 100vh;
21 |     }
22 |   </style>
23 | </head>
24 | <body>
25 |   <div id="root"></div>
26 |   <script type="module" src="./comment-modal.tsx"></script>
27 | </body>
28 | </html>
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/components/ui/progress.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | "use client";
 2 | 
 3 | import * as React from "react";
 4 | import * as ProgressPrimitive from "@radix-ui/react-progress";
 5 | 
 6 | import { cn } from "@/lib/utils";
 7 | 
 8 | function Progress({
 9 |   className,
10 |   value,
11 |   ...props
12 | }: React.ComponentProps<typeof ProgressPrimitive.Root>) {
13 |   return (
14 |     <ProgressPrimitive.Root
15 |       data-slot="progress"
16 |       className={cn(
17 |         "bg-primary/20 relative h-2 w-full overflow-hidden rounded-full",
18 |         className
19 |       )}
20 |       {...props}
21 |     >
22 |       <ProgressPrimitive.Indicator
23 |         data-slot="progress-indicator"
24 |         className="bg-primary h-full w-full flex-1 transition-all"
25 |         style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
26 |       />
27 |     </ProgressPrimitive.Root>
28 |   );
29 | }
30 | 
31 | export { Progress };
32 | 
```

--------------------------------------------------------------------------------
/vscode-extension/eslint.config.mjs:
--------------------------------------------------------------------------------

```
 1 | import typescriptEslint from "@typescript-eslint/eslint-plugin";
 2 | import tsParser from "@typescript-eslint/parser";
 3 | 
 4 | export default [{
 5 |     files: ["**/*.ts", "**/*.tsx"],
 6 |     ignores: ["node_modules/**", "webview-dist/**", "dist/**", "out/**", "**/*.d.ts", "**/webview-dist/**"],
 7 | }, {
 8 |     plugins: {
 9 |         "@typescript-eslint": typescriptEslint,
10 |     },
11 | 
12 |     languageOptions: {
13 |         parser: tsParser,
14 |         ecmaVersion: 2022,
15 |         sourceType: "module",
16 |     },
17 | 
18 |     rules: {
19 |         "@typescript-eslint/naming-convention": ["warn", {
20 |             selector: "import",
21 |             format: ["camelCase", "PascalCase"],
22 |         }],
23 | 
24 |         curly: "warn",
25 |         eqeqeq: "warn",
26 |         "no-throw-literal": "warn",
27 |         semi: "warn",
28 |     },
29 | }];
```

--------------------------------------------------------------------------------
/vscode-extension/tsconfig.app.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
 4 |     "target": "ES2022",
 5 |     "useDefineForClassFields": true,
 6 |     "lib": ["ES2022", "DOM", "DOM.Iterable"],
 7 |     "module": "ESNext",
 8 |     "skipLibCheck": true,
 9 | 
10 |     /* Bundler mode */
11 |     "moduleResolution": "bundler",
12 |     "allowImportingTsExtensions": true,
13 |     "verbatimModuleSyntax": true,
14 |     "moduleDetection": "force",
15 |     "noEmit": true,
16 |     "jsx": "react-jsx",
17 | 
18 |     /* Path mapping */
19 |     "baseUrl": ".",
20 |     "paths": {
21 |       "@/*": ["./src/webview/*"]
22 |     },
23 | 
24 |     /* Linting */
25 |     "strict": true,
26 |     "noUnusedLocals": true,
27 |     "noUnusedParameters": true,
28 |     "erasableSyntaxOnly": true,
29 |     "noFallthroughCasesInSwitch": true,
30 |     "noUncheckedSideEffectImports": true
31 |   },
32 |   "include": ["src/webview"]
33 | }
```

--------------------------------------------------------------------------------
/vscode-extension/webview-dist/comment-modal.html:
--------------------------------------------------------------------------------

```html
 1 | <!DOCTYPE html>
 2 | <html lang="en">
 3 | <head>
 4 |   <meta charset="UTF-8">
 5 |   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6 |   <title>Add Comment</title>

 7 |   <style>
 8 |     body {
 9 |       margin: 0;
10 |       padding: 0;
11 |       font-family: var(--vscode-font-family), -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
12 |       font-size: var(--vscode-font-size, 13px);
13 |       line-height: 1.4;
14 |       color: var(--vscode-foreground);
15 |       background: var(--vscode-editor-background);
16 |     }
17 |     #root {
18 |       width: 100%;
19 |       height: 100vh;
20 |     }
21 |   </style>
22 |   <script type="module" crossorigin src="/comment-modal.js"></script>
23 |   <link rel="modulepreload" crossorigin href="/i18n.js">
24 |   <link rel="stylesheet" crossorigin href="/globals.css">
25 | </head>
26 | <body>
27 |   <div id="root"></div>

28 | </body>
29 | </html>
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/lib/utils.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { clsx, type ClassValue } from "clsx";
 2 | import { twMerge } from "tailwind-merge";
 3 | 
 4 | export function cn(...inputs: ClassValue[]) {
 5 |   return twMerge(clsx(inputs));
 6 | }
 7 | 
 8 | export function formatDate(dateStr?: string) {
 9 |   if (!dateStr) {return 'Never';}
10 |   return new Date(dateStr).toLocaleDateString(undefined, { 
11 |     month: 'short', 
12 |     day: 'numeric', 
13 |     hour: '2-digit', 
14 |     minute: '2-digit' 
15 |   });
16 | }
17 | 
18 | export function formatDistanceToNow(dateStr: string) {
19 |   const date = new Date(dateStr);
20 |   const now = new Date();
21 |   const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
22 |   
23 |   if (diffInSeconds < 60) {return 'Just now';}
24 |   if (diffInSeconds < 3600) {return `${Math.floor(diffInSeconds / 60)}m ago`;}
25 |   if (diffInSeconds < 86400) {return `${Math.floor(diffInSeconds / 3600)}h ago`;}
26 |   return `${Math.floor(diffInSeconds / 86400)}d ago`;
27 | }
28 | 
```

--------------------------------------------------------------------------------
/containers/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | # Build stage
 2 | FROM node:24-alpine AS builder
 3 | WORKDIR /app
 4 | 
 5 | # Copy package files
 6 | COPY package*.json ./
 7 | 
 8 | # Install all dependencies (including devDependencies for build)
 9 | RUN npm ci
10 | 
11 | # Copy source files
12 | COPY src ./src
13 | COPY scripts ./scripts
14 | COPY tsconfig.json ./tsconfig.json
15 | COPY vitest.config.ts ./vitest.config.ts
16 | 
17 | # Build the application
18 | RUN npm run build
19 | 
20 | # Runtime stage
21 | FROM node:24-alpine
22 | WORKDIR /app
23 | 
24 | # Copy only production files
25 | COPY --from=builder /app/package*.json ./
26 | RUN npm ci --only=production
27 | 
28 | # Copy built application
29 | COPY --from=builder /app/dist ./dist
30 | 
31 | RUN mkdir -p /workspace
32 | 
33 | # Change ownership of the app directory to the node user (uid=1000)
34 | RUN chown -R node:node /app /workspace
35 | 
36 | # Switch to the node user to match host user permissions
37 | USER node
38 | 
39 | WORKDIR /workspace
40 | 
41 | EXPOSE 5000
42 | 
43 | CMD node /app/dist/index.js ${SPEC_WORKFLOW_PATH:-/workspace} --dashboard --port ${DASHBOARD_PORT:-5000}
44 | 
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/src/modules/theme/HighlightStyles.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import React, { useEffect } from 'react';
 2 | import { useTheme } from './ThemeProvider';
 3 | 
 4 | const LIGHT_ID = 'hljs-light-theme';
 5 | const DARK_ID = 'hljs-dark-theme';
 6 | const LIGHT_HREF = 'https://cdn.jsdelivr.net/npm/[email protected]/styles/github.min.css';
 7 | const DARK_HREF = 'https://cdn.jsdelivr.net/npm/[email protected]/styles/github-dark.min.css';
 8 | 
 9 | function ensureLink(id: string, href: string) {
10 |   let link = document.getElementById(id) as HTMLLinkElement | null;
11 |   if (!link) {
12 |     link = document.createElement('link');
13 |     link.id = id;
14 |     link.rel = 'stylesheet';
15 |     link.href = href;
16 |     document.head.appendChild(link);
17 |   }
18 |   return link;
19 | }
20 | 
21 | export function HighlightStyles() {
22 |   const { theme } = useTheme();
23 | 
24 |   useEffect(() => {
25 |     const light = ensureLink(LIGHT_ID, LIGHT_HREF);
26 |     const dark = ensureLink(DARK_ID, DARK_HREF);
27 |     if (theme === 'dark') {
28 |       light.disabled = true;
29 |       dark.disabled = false;
30 |     } else {
31 |       light.disabled = false;
32 |       dark.disabled = true;
33 |     }
34 |   }, [theme]);
35 | 
36 |   return null;
37 | }
38 | 
39 | 
40 | 
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/src/modules/theme/ThemeProvider.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
 2 | import './tailwind.css';
 3 | 
 4 | type Theme = 'light' | 'dark';
 5 | 
 6 | type ThemeContextType = {
 7 |   theme: Theme;
 8 |   toggleTheme: () => void;
 9 | };
10 | 
11 | const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
12 | 
13 | export function ThemeProvider({ children }: { children: React.ReactNode }) {
14 |   const [theme, setTheme] = useState<Theme>(() => {
15 |     const saved = localStorage.getItem('theme');
16 |     return (saved as Theme) || 'dark';
17 |   });
18 | 
19 |   useEffect(() => {
20 |     document.documentElement.classList.toggle('dark', theme === 'dark');
21 |     localStorage.setItem('theme', theme);
22 |   }, [theme]);
23 | 
24 |   const value = useMemo(
25 |     () => ({ theme, toggleTheme: () => setTheme((t) => (t === 'dark' ? 'light' : 'dark')) }),
26 |     [theme]
27 |   );
28 | 
29 |   return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
30 | }
31 | 
32 | export function useTheme(): ThemeContextType {
33 |   const ctx = useContext(ThemeContext);
34 |   if (!ctx) throw new Error('useTheme must be used within ThemeProvider');
35 |   return ctx;
36 | }
37 | 
38 | 
39 | 
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/src/modules/theme/tailwind.css:
--------------------------------------------------------------------------------

```css
 1 | @import "tailwindcss";
 2 | @plugin "@tailwindcss/typography";
 3 | 
 4 | @variant dark (.dark &);
 5 | 
 6 | :root {
 7 |   color-scheme: light dark;
 8 | }
 9 | 
10 | .card {
11 |   @apply bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-xl shadow-sm;
12 | }
13 | 
14 | .card-hover {
15 |   @apply transition-transform duration-200 hover:-translate-y-0.5 hover:shadow-md;
16 | }
17 | 
18 | .btn {
19 |   @apply inline-flex items-center gap-2 px-3 py-2 rounded-lg border border-transparent bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 transition;
20 | }
21 | 
22 | .btn-secondary {
23 |   @apply inline-flex items-center gap-2 px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 text-gray-700 dark:text-gray-300 text-sm hover:bg-gray-100 dark:hover:bg-gray-700 transition;
24 | }
25 | 
26 | .muted { @apply text-gray-500 dark:text-gray-400; }
27 | 
28 | /* Drag and Drop utilities */
29 | .draggable {
30 |   @apply touch-none select-none;
31 | }
32 | 
33 | .dragging {
34 |   @apply cursor-grabbing opacity-75 scale-105 rotate-1 z-50;
35 | }
36 | 
37 | .drag-overlay {
38 |   @apply pointer-events-none;
39 | }
40 | 
41 | .drop-zone {
42 |   @apply transition-colors duration-200;
43 | }
44 | 
45 | .drop-zone-active {
46 |   @apply ring-2 ring-blue-400 bg-blue-50 dark:bg-blue-900/10;
47 | }
```

--------------------------------------------------------------------------------
/vscode-extension/esbuild.js:
--------------------------------------------------------------------------------

```javascript
 1 | const esbuild = require("esbuild");
 2 | 
 3 | const production = process.argv.includes('--production');
 4 | const watch = process.argv.includes('--watch');
 5 | 
 6 | /**
 7 |  * @type {import('esbuild').Plugin}
 8 |  */
 9 | const esbuildProblemMatcherPlugin = {
10 | 	name: 'esbuild-problem-matcher',
11 | 
12 | 	setup(build) {
13 | 		build.onStart(() => {
14 | 			console.log('[watch] build started');
15 | 		});
16 | 		build.onEnd((result) => {
17 | 			result.errors.forEach(({ text, location }) => {
18 | 				console.error(`✘ [ERROR] ${text}`);
19 | 				console.error(`    ${location.file}:${location.line}:${location.column}:`);
20 | 			});
21 | 			console.log('[watch] build finished');
22 | 		});
23 | 	},
24 | };
25 | 
26 | async function main() {
27 | 	const ctx = await esbuild.context({
28 | 		entryPoints: [
29 | 			'src/extension.ts'
30 | 		],
31 | 		bundle: true,
32 | 		format: 'cjs',
33 | 		minify: production,
34 | 		sourcemap: !production,
35 | 		sourcesContent: false,
36 | 		platform: 'node',
37 | 		outfile: 'dist/extension.js',
38 | 		external: ['vscode'],
39 | 		logLevel: 'silent',
40 | 		plugins: [
41 | 			/* add to the end of plugins array */
42 | 			esbuildProblemMatcherPlugin,
43 | 		],
44 | 	});
45 | 	if (watch) {
46 | 		await ctx.watch();
47 | 	} else {
48 | 		await ctx.rebuild();
49 | 		await ctx.dispose();
50 | 	}
51 | }
52 | 
53 | main().catch(e => {
54 | 	console.error(e);
55 | 	process.exit(1);
56 | });
57 | 
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/src/modules/notifications/VolumeControl.module.css:
--------------------------------------------------------------------------------

```css
 1 | /* Slider styles for VolumeControl component */
 2 | .slider {
 3 |   -webkit-appearance: none;
 4 |   appearance: none;
 5 |   width: 80px;
 6 |   height: 4px;
 7 |   border-radius: 2px;
 8 |   background: #e5e7eb;
 9 |   outline: none;
10 |   cursor: pointer;
11 |   transition: background 0.3s;
12 | }
13 | 
14 | .dark .slider {
15 |   background: #4b5563;
16 | }
17 | 
18 | /* Webkit browsers (Chrome, Safari, Edge) */
19 | .slider::-webkit-slider-thumb {
20 |   -webkit-appearance: none;
21 |   appearance: none;
22 |   height: 16px;
23 |   width: 16px;
24 |   border-radius: 50%;
25 |   background: #2563eb;
26 |   cursor: pointer;
27 |   border: 2px solid #ffffff;
28 |   box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
29 |   transition: background 0.2s;
30 |   margin-top: -6px;
31 | }
32 | 
33 | .slider::-webkit-slider-thumb:hover {
34 |   background: #1d4ed8;
35 | }
36 | 
37 | /* Firefox */
38 | .slider::-moz-range-thumb {
39 |   height: 16px;
40 |   width: 16px;
41 |   border-radius: 50%;
42 |   background: #2563eb;
43 |   cursor: pointer;
44 |   border: 2px solid #ffffff;
45 |   box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
46 |   transition: background 0.2s;
47 | }
48 | 
49 | .slider::-moz-range-thumb:hover {
50 |   background: #1d4ed8;
51 | }
52 | 
53 | /* Track styles */
54 | .slider::-webkit-slider-runnable-track {
55 |   width: 100%;
56 |   height: 4px;
57 |   cursor: pointer;
58 |   border-radius: 2px;
59 | }
60 | 
61 | .slider::-moz-range-track {
62 |   width: 100%;
63 |   height: 4px;
64 |   cursor: pointer;
65 |   border-radius: 2px;
66 | }
```

--------------------------------------------------------------------------------
/src/markdown/templates/requirements-template.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Requirements Document
 2 | 
 3 | ## Introduction
 4 | 
 5 | [Provide a brief overview of the feature, its purpose, and its value to users]
 6 | 
 7 | ## Alignment with Product Vision
 8 | 
 9 | [Explain how this feature supports the goals outlined in product.md]
10 | 
11 | ## Requirements
12 | 
13 | ### Requirement 1
14 | 
15 | **User Story:** As a [role], I want [feature], so that [benefit]
16 | 
17 | #### Acceptance Criteria
18 | 
19 | 1. WHEN [event] THEN [system] SHALL [response]
20 | 2. IF [precondition] THEN [system] SHALL [response]
21 | 3. WHEN [event] AND [condition] THEN [system] SHALL [response]
22 | 
23 | ### Requirement 2
24 | 
25 | **User Story:** As a [role], I want [feature], so that [benefit]
26 | 
27 | #### Acceptance Criteria
28 | 
29 | 1. WHEN [event] THEN [system] SHALL [response]
30 | 2. IF [precondition] THEN [system] SHALL [response]
31 | 
32 | ## Non-Functional Requirements
33 | 
34 | ### Code Architecture and Modularity
35 | - **Single Responsibility Principle**: Each file should have a single, well-defined purpose
36 | - **Modular Design**: Components, utilities, and services should be isolated and reusable
37 | - **Dependency Management**: Minimize interdependencies between modules
38 | - **Clear Interfaces**: Define clean contracts between components and layers
39 | 
40 | ### Performance
41 | - [Performance requirements]
42 | 
43 | ### Security
44 | - [Security requirements]
45 | 
46 | ### Reliability
47 | - [Reliability requirements]
48 | 
49 | ### Usability
50 | - [Usability requirements]
51 | 
```

--------------------------------------------------------------------------------
/vscode-extension/package.nls.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "displayName": "Spec Workflow MCP",
 3 |   "description": "VSCode extension for Spec-Workflow-MCP with integrated dashboard",
 4 |   "command.openDashboard": "Open Spec Workflow Dashboard",
 5 |   "command.refreshData": "Refresh Data",
 6 |   "command.openSpec": "Open Spec",
 7 |   "command.approve": "Approve",
 8 |   "command.reject": "Reject",
 9 |   "command.requestRevision": "Request Revision",
10 |   "command.addComment": "Add Comment",
11 |   "command.editComment": "Edit Comment",
12 |   "command.deleteComment": "Delete Comment",
13 |   "command.showApprovalActions": "Approval Actions",
14 |   "view.dashboard": "Dashboard",
15 |   "view.containerTitle": "Spec Workflow",
16 |   "config.title": "Spec Workflow",
17 |   "config.sounds.enabled.description": "Enable sound notifications for spec workflow events",
18 |   "config.sounds.volume.description": "Volume level for sound notifications (0.0 to 1.0)",
19 |   "config.sounds.approvalSound.description": "Play sound when new approval requests are pending",
20 |   "config.sounds.taskCompletionSound.description": "Play sound when tasks are completed",
21 |   "config.language.description": "Language for the extension interface",
22 |   "config.language.auto.description": "Auto-detect based on VS Code settings",
23 |   "config.language.en.description": "English",
24 |   "config.language.ja.description": "Japanese (日本語)",
25 |   "config.language.zh.description": "Chinese (中文)"
26 | }
27 | 
```

--------------------------------------------------------------------------------
/src/dashboard_frontend/src/types.ts:
--------------------------------------------------------------------------------

```typescript
 1 | export interface AutomationJob {
 2 |   id: string;
 3 |   name: string;
 4 |   type: 'cleanup-approvals' | 'cleanup-specs' | 'cleanup-archived-specs';
 5 |   enabled: boolean;
 6 |   config: {
 7 |     daysOld: number;
 8 |   };
 9 |   schedule: string;
10 |   lastRun?: string;
11 |   nextRun?: string;
12 |   createdAt: string;
13 | }
14 | 
15 | export interface ImplementationLogEntry {
16 |   id: string;
17 |   taskId: string;
18 |   timestamp: string;
19 |   summary: string;
20 |   filesModified: string[];
21 |   filesCreated: string[];
22 |   statistics: {
23 |     linesAdded: number;
24 |     linesRemoved: number;
25 |     filesChanged: number;
26 |   };
27 |   artifacts: {
28 |     apiEndpoints?: Array<{
29 |       method: string;
30 |       path: string;
31 |       purpose: string;
32 |       requestFormat?: string;
33 |       responseFormat?: string;
34 |       location: string;
35 |     }>;
36 |     components?: Array<{
37 |       name: string;
38 |       type: string;
39 |       purpose: string;
40 |       location: string;
41 |       props?: string;
42 |       exports?: string[];
43 |     }>;
44 |     functions?: Array<{
45 |       name: string;
46 |       purpose: string;
47 |       location: string;
48 |       signature?: string;
49 |       isExported: boolean;
50 |     }>;
51 |     classes?: Array<{
52 |       name: string;
53 |       purpose: string;
54 |       location: string;
55 |       methods?: string[];
56 |       isExported: boolean;
57 |     }>;
58 |     integrations?: Array<{
59 |       description: string;
60 |       frontendComponent: string;
61 |       backendEndpoint: string;
62 |       dataFlow: string;
63 |     }>;
64 |   };
65 | }
66 | 
```

--------------------------------------------------------------------------------
/vscode-extension/.vscode/tasks.json:
--------------------------------------------------------------------------------

```json
 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558
 2 | // for the documentation about the tasks.json format
 3 | {
 4 | 	"version": "2.0.0",
 5 | 	"tasks": [
 6 | 		{
 7 |             "label": "watch",
 8 |             "dependsOn": [
 9 |                 "npm: watch:tsc",
10 |                 "npm: watch:esbuild"
11 |             ],
12 |             "presentation": {
13 |                 "reveal": "never"
14 |             },
15 |             "group": {
16 |                 "kind": "build",
17 |                 "isDefault": true
18 |             }
19 |         },
20 |         {
21 |             "type": "npm",
22 |             "script": "watch:esbuild",
23 |             "group": "build",
24 |             "problemMatcher": "$esbuild-watch",
25 |             "isBackground": true,
26 |             "label": "npm: watch:esbuild",
27 |             "presentation": {
28 |                 "group": "watch",
29 |                 "reveal": "never"
30 |             }
31 |         },
32 | 		{
33 |             "type": "npm",
34 |             "script": "watch:tsc",
35 |             "group": "build",
36 |             "problemMatcher": "$tsc-watch",
37 |             "isBackground": true,
38 |             "label": "npm: watch:tsc",
39 |             "presentation": {
40 |                 "group": "watch",
41 |                 "reveal": "never"
42 |             }
43 |         },
44 | 		{
45 | 			"type": "npm",
46 | 			"script": "watch-tests",
47 | 			"problemMatcher": "$tsc-watch",
48 | 			"isBackground": true,
49 | 			"presentation": {
50 | 				"reveal": "never",
51 | 				"group": "watchers"
52 | 			},
53 | 			"group": "build"
54 | 		},
55 | 		{
56 | 			"label": "tasks: watch-tests",
57 | 			"dependsOn": [
58 | 				"npm: watch",
59 | 				"npm: watch-tests"
60 | 			],
61 | 			"problemMatcher": []
62 | 		}
63 | 	]
64 | }
65 | 
```

--------------------------------------------------------------------------------
/src/markdown/templates/product-template.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Product Overview
 2 | 
 3 | ## Product Purpose
 4 | [Describe the core purpose of this product/project. What problem does it solve?]
 5 | 
 6 | ## Target Users
 7 | [Who are the primary users of this product? What are their needs and pain points?]
 8 | 
 9 | ## Key Features
10 | [List the main features that deliver value to users]
11 | 
12 | 1. **Feature 1**: [Description]
13 | 2. **Feature 2**: [Description]
14 | 3. **Feature 3**: [Description]
15 | 
16 | ## Business Objectives
17 | [What are the business goals this product aims to achieve?]
18 | 
19 | - [Objective 1]
20 | - [Objective 2]
21 | - [Objective 3]
22 | 
23 | ## Success Metrics
24 | [How will we measure the success of this product?]
25 | 
26 | - [Metric 1]: [Target]
27 | - [Metric 2]: [Target]
28 | - [Metric 3]: [Target]
29 | 
30 | ## Product Principles
31 | [Core principles that guide product decisions]
32 | 
33 | 1. **[Principle 1]**: [Explanation]
34 | 2. **[Principle 2]**: [Explanation]
35 | 3. **[Principle 3]**: [Explanation]
36 | 
37 | ## Monitoring & Visibility (if applicable)
38 | [How do users track progress and monitor the system?]
39 | 
40 | - **Dashboard Type**: [e.g., Web-based, CLI, Desktop app]
41 | - **Real-time Updates**: [e.g., WebSocket, polling, push notifications]
42 | - **Key Metrics Displayed**: [What information is most important to surface]
43 | - **Sharing Capabilities**: [e.g., read-only links, exports, reports]
44 | 
45 | ## Future Vision
46 | [Where do we see this product evolving in the future?]
47 | 
48 | ### Potential Enhancements
49 | - **Remote Access**: [e.g., Tunnel features for sharing dashboards with stakeholders]
50 | - **Analytics**: [e.g., Historical trends, performance metrics]
51 | - **Collaboration**: [e.g., Multi-user support, commenting]
52 | 
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/components/LogStatsPanel.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { useTranslation } from 'react-i18next';
 2 | import { Card, CardContent } from './ui/card';
 3 | 
 4 | interface LogStatsPanelProps {
 5 |   stats: {
 6 |     totalEntries: number;
 7 |     totalLinesAdded: number;
 8 |     totalLinesRemoved: number;
 9 |     totalFilesChanged: number;
10 |   } | null;
11 | }
12 | 
13 | export function LogStatsPanel({ stats }: LogStatsPanelProps) {
14 |   const { t } = useTranslation();
15 | 
16 |   if (!stats) {
17 |     return null;
18 |   }
19 | 
20 |   return (
21 |     <Card className="mb-6">
22 |       <CardContent className="p-4">
23 |         <div className="grid grid-cols-4 gap-4">
24 |           <div className="text-center">
25 |             <div className="text-2xl font-bold">{stats.totalEntries}</div>
26 |             <div className="text-xs text-muted-foreground">{t('logs.stats.totalEntries')}</div>
27 |           </div>
28 |           <div className="text-center">
29 |             <div className="text-2xl font-bold text-green-600">{stats.totalLinesAdded}</div>
30 |             <div className="text-xs text-muted-foreground">{t('logs.stats.linesAdded')}</div>
31 |           </div>
32 |           <div className="text-center">
33 |             <div className="text-2xl font-bold text-red-600">{stats.totalLinesRemoved}</div>
34 |             <div className="text-xs text-muted-foreground">{t('logs.stats.linesRemoved')}</div>
35 |           </div>
36 |           <div className="text-center">
37 |             <div className="text-2xl font-bold text-purple-600">{stats.totalFilesChanged}</div>
38 |             <div className="text-xs text-muted-foreground">{t('logs.stats.filesChanged')}</div>
39 |           </div>
40 |         </div>
41 |       </CardContent>
42 |     </Card>
43 |   );
44 | }
45 | 
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/documentation.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: 📚 Documentation
 2 | description: Report issues with documentation or suggest improvements
 3 | title: "[Docs]: "
 4 | labels: ["documentation", "needs-triage"]
 5 | body:
 6 |   - type: markdown
 7 |     attributes:
 8 |       value: |
 9 |         Help us improve the documentation!
10 | 
11 |   - type: dropdown
12 |     id: issue-type
13 |     attributes:
14 |       label: Issue Type
15 |       description: What kind of documentation issue is this?
16 |       options:
17 |         - "Error or typo"
18 |         - "Unclear explanation"
19 |         - "Missing information"
20 |         - "Outdated information"
21 |         - "New documentation needed"
22 |         - "Better examples needed"
23 |         - "Other"
24 |     validations:
25 |       required: true
26 | 
27 |   - type: textarea
28 |     id: location
29 |     attributes:
30 |       label: Where is the issue?
31 |       description: Which documentation has the issue?
32 |       placeholder: |
33 |         - File: README.md, etc.
34 |         - Section: Installation, Usage, etc.
35 |         - URL: If online documentation
36 |     validations:
37 |       required: true
38 | 
39 |   - type: textarea
40 |     id: issue-description
41 |     attributes:
42 |       label: What's the problem?
43 |       description: Describe the documentation issue
44 |       placeholder: What's wrong or missing?
45 |     validations:
46 |       required: true
47 | 
48 |   - type: textarea
49 |     id: suggested-improvement
50 |     attributes:
51 |       label: How should it be improved?
52 |       description: What would make it better?
53 |       placeholder: Your suggested improvement...
54 |     validations:
55 |       required: true
56 | 
57 |   - type: textarea
58 |     id: additional-context
59 |     attributes:
60 |       label: Additional Context
61 |       description: Any other details that would help?
62 |       placeholder: Add any other context here...
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/components/ui/badge.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import * as React from "react";
 2 | import { Slot } from "@radix-ui/react-slot";
 3 | import { cva, type VariantProps } from "class-variance-authority";
 4 | 
 5 | import { cn } from "@/lib/utils";
 6 | 
 7 | const badgeVariants = cva(
 8 |   "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
 9 |   {
10 |     variants: {
11 |       variant: {
12 |         default:
13 |           "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
14 |         secondary:
15 |           "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
16 |         destructive:
17 |           "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
18 |         outline:
19 |           "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
20 |       },
21 |     },
22 |     defaultVariants: {
23 |       variant: "default",
24 |     },
25 |   }
26 | );
27 | 
28 | function Badge({
29 |   className,
30 |   variant,
31 |   asChild = false,
32 |   ...props
33 | }: React.ComponentProps<"span"> &
34 |   VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
35 |   const Comp = asChild ? Slot : "span";
36 | 
37 |   return (
38 |     <Comp
39 |       data-slot="badge"
40 |       className={cn(badgeVariants({ variant }), className)}
41 |       {...props}
42 |     />
43 |   );
44 | }
45 | 
46 | export { Badge, badgeVariants };
47 | 
```

--------------------------------------------------------------------------------
/vscode-extension/src/extension/utils/logger.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import * as vscode from 'vscode';
 2 | 
 3 | export class Logger {
 4 |   private outputChannel: vscode.OutputChannel;
 5 | 
 6 |   constructor(outputChannel: vscode.OutputChannel) {
 7 |     this.outputChannel = outputChannel;
 8 |   }
 9 | 
10 |   private formatMessage(level: string, message: string, data?: any): string {
11 |     const timestamp = new Date().toISOString();
12 |     let formatted = `[${timestamp}] ${level}: ${message}`;
13 |     
14 |     if (data !== undefined) {
15 |       if (typeof data === 'object') {
16 |         formatted += `\n${JSON.stringify(data, null, 2)}`;
17 |       } else {
18 |         formatted += ` ${data}`;
19 |       }
20 |     }
21 |     
22 |     return formatted;
23 |   }
24 | 
25 |   log(message: string, data?: any) {
26 |     const formatted = this.formatMessage('INFO', message, data);
27 |     this.outputChannel.appendLine(formatted);
28 |   }
29 | 
30 |   error(message: string, data?: any) {
31 |     const formatted = this.formatMessage('ERROR', message, data);
32 |     this.outputChannel.appendLine(formatted);
33 |   }
34 | 
35 |   warn(message: string, data?: any) {
36 |     const formatted = this.formatMessage('WARN', message, data);
37 |     this.outputChannel.appendLine(formatted);
38 |   }
39 | 
40 |   debug(message: string, data?: any) {
41 |     const formatted = this.formatMessage('DEBUG', message, data);
42 |     this.outputChannel.appendLine(formatted);
43 |   }
44 | 
45 |   separator(title?: string) {
46 |     const line = '='.repeat(60);
47 |     if (title) {
48 |       const padding = Math.max(0, 60 - title.length - 4);
49 |       const leftPad = Math.floor(padding / 2);
50 |       const rightPad = padding - leftPad;
51 |       this.outputChannel.appendLine(`${'='.repeat(leftPad)} ${title} ${'='.repeat(rightPad)}`);
52 |     } else {
53 |       this.outputChannel.appendLine(line);
54 |     }
55 |   }
56 | 
57 |   show() {
58 |     this.outputChannel.show();
59 |   }
60 | }
```

--------------------------------------------------------------------------------
/src/dashboard/public/claude-icon-dark.svg:
--------------------------------------------------------------------------------

```
1 | <svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#F4A971" fill-rule="nonzero"></path></svg>
```

--------------------------------------------------------------------------------
/src/dashboard/public/claude-icon.svg:
--------------------------------------------------------------------------------

```
1 | <svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#D97757" fill-rule="nonzero"></path></svg>
```

--------------------------------------------------------------------------------
/containers/DOCKER_USAGE.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Example MCP Configuration with Docker Dashboard
 2 | 
 3 | This directory contains an example MCP server configuration (`example.mcp.json`) 
 4 | for use with the Docker-hosted dashboard.
 5 | 
 6 | ## Architecture
 7 | 
 8 | The recommended setup is:
 9 | - **Dashboard**: Runs in Docker (using docker-compose.yml)
10 | - **MCP Servers**: Run on host machine via npx (using example.mcp.json)
11 | 
12 | ## Quick Start
13 | 
14 | 1. **Start the Dashboard in Docker:**
15 |    ```bash
16 |    cd containers
17 |    docker-compose up -d
18 |    ```
19 |    Dashboard will be at: http://localhost:5000
20 | 
21 | 2. **Configure MCP Servers:**
22 |    Use the configuration from `example.mcp.json` in your MCP client config:
23 |    ```json
24 |    {
25 |      "mcpServers": {
26 |        "spec-workflow": {
27 |          "command": "npx",
28 |          "args": ["-y", "@pimzino/spec-workflow-mcp@latest", "/path/to/your/project"]
29 |        }
30 |      }
31 |    }
32 |    ```
33 | 
34 | 3. **Start Your MCP Client:**
35 |    The MCP servers will automatically connect to the dashboard at port 5000.
36 | 
37 | ## Why This Architecture?
38 | 
39 | - **Dashboard in Docker**: Provides isolation and easy deployment
40 | - **MCP Servers on Host**: Allows direct file system access to your projects
41 | - **Automatic Connection**: MCP servers auto-detect and connect to dashboard
42 | 
43 | ## Alternative: Everything in Docker
44 | 
45 | If you need to run MCP servers in Docker (not recommended for most users):
46 | - You'll need to create a custom setup with network bridges
47 | - File system access becomes more complex
48 | - The current setup (dashboard in Docker, MCP on host) is simpler and more flexible
49 | 
50 | ## See Also
51 | 
52 | - [Docker Setup Guide](README.md) - Complete Docker documentation
53 | - [Main README](../README.md) - General setup and usage
54 | - [Configuration Guide](../docs/CONFIGURATION.md) - Advanced configuration options
55 | 
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/hooks/useVSCodeTheme.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { useState, useEffect } from 'react';
 2 | 
 3 | type VSCodeTheme = 'light' | 'dark' | 'high-contrast';
 4 | 
 5 | /**
 6 |  * Custom hook to detect and track VS Code theme changes
 7 |  * VS Code automatically adds theme classes to the body element:
 8 |  * - 'vscode-light' for light themes
 9 |  * - 'vscode-dark' for dark themes  
10 |  * - 'vscode-high-contrast' for high contrast themes
11 |  */
12 | export function useVSCodeTheme(): VSCodeTheme {
13 |   const [theme, setTheme] = useState<VSCodeTheme>(() => {
14 |     // Initial theme detection
15 |     const body = document.body;
16 |     if (body.classList.contains('vscode-high-contrast')) {
17 |       return 'high-contrast';
18 |     }
19 |     if (body.classList.contains('vscode-dark')) {
20 |       return 'dark';
21 |     }
22 |     return 'light';
23 |   });
24 | 
25 |   useEffect(() => {
26 |     const detectTheme = (): VSCodeTheme => {
27 |       const body = document.body;
28 |       if (body.classList.contains('vscode-high-contrast')) {
29 |         return 'high-contrast';
30 |       }
31 |       if (body.classList.contains('vscode-dark')) {
32 |         return 'dark';
33 |       }
34 |       return 'light';
35 |     };
36 | 
37 |     // Update theme on initial mount
38 |     setTheme(detectTheme());
39 | 
40 |     // Create observer to watch for theme changes
41 |     const observer = new MutationObserver((mutations) => {
42 |       mutations.forEach((mutation) => {
43 |         if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
44 |           const newTheme = detectTheme();
45 |           setTheme(newTheme);
46 |         }
47 |       });
48 |     });
49 | 
50 |     // Start observing body class changes
51 |     observer.observe(document.body, {
52 |       attributes: true,
53 |       attributeFilter: ['class']
54 |     });
55 | 
56 |     // Cleanup observer on unmount
57 |     return () => {
58 |       observer.disconnect();
59 |     };
60 |   }, []);
61 | 
62 |   return theme;
63 | }
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: ✨ Feature Request
 2 | description: Suggest a new feature or enhancement for the Spec-Driven Workflow MCP Server
 3 | title: "[Feature]: "
 4 | labels: ["enhancement", "needs-triage"]
 5 | body:
 6 |   - type: markdown
 7 |     attributes:
 8 |       value: |
 9 |         Thanks for suggesting a feature! Help us understand what you'd like to see.
10 | 
11 |   - type: textarea
12 |     id: feature-description
13 |     attributes:
14 |       label: Feature Description
15 |       description: What feature would you like to see?
16 |       placeholder: Describe the feature you'd like...
17 |     validations:
18 |       required: true
19 | 
20 |   - type: textarea
21 |     id: problem-statement
22 |     attributes:
23 |       label: Problem or Use Case
24 |       description: What problem would this solve or what would you use it for?
25 |       placeholder: |
26 |         Describe the problem or use case:
27 |         - What are you trying to accomplish?
28 |         - What's currently difficult or missing?
29 |     validations:
30 |       required: true
31 | 
32 |   - type: textarea
33 |     id: proposed-solution
34 |     attributes:
35 |       label: How should it work?
36 |       description: Describe how you envision this feature working
37 |       placeholder: How would you like this feature to work?
38 | 
39 |   - type: dropdown
40 |     id: feature-area
41 |     attributes:
42 |       label: Feature Area
43 |       description: Which area would this affect?
44 |       options:
45 |         - MCP Tools
46 |         - Web Dashboard
47 |         - VSCode Extension
48 |         - Spec Workflow
49 |         - Bug Workflow
50 |         - Templates
51 |         - Documentation
52 |         - Other
53 | 
54 |   - type: textarea
55 |     id: additional-context
56 |     attributes:
57 |       label: Additional Context
58 |       description: Anything else that would help us understand this request?
59 |       placeholder: Add any other details, examples, or context here...
```

--------------------------------------------------------------------------------
/vscode-extension/icons/activity-bar-icon.svg:
--------------------------------------------------------------------------------

```
 1 | <svg xmlns="http://www.w3.org/2000/svg"
 2 |      width="96" height="96" viewBox="0 0 96 96"
 3 |      preserveAspectRatio="xMidYMid meet"
 4 |      fill="none" stroke="currentColor" stroke-width="0.75"
 5 |      stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
 6 |   <title>Flow diagram on a page</title>
 7 | 
 8 |   <style>*{vector-effect:non-scaling-stroke}</style>
 9 |   <g transform="scale(4)">
10 | 
11 | 
12 |   <!-- Page with folded corner -->
13 |   <path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2z"/>
14 |   <path d="M14 2v6h6"/>
15 | 
16 |   <!-- Nodes (precisely aligned) -->
17 |   <!-- Start: circle center (9,7.5), r=1.6 -> bottom tangent at y=9.1 -->
18 |   <circle cx="9" cy="7.5" r="1.6"/>
19 | 
20 |   <!-- Process: rect from (6,11.5) size 6x3.5; center y=13.25; right mid at (12,13.25) -->
21 |   <rect x="6" y="11.5" width="6" height="3.5" rx="0.6"/>
22 | 
23 |   <!-- Decision: diamond centered at (16.25,13.25), touching (16.25,11.5) top,
24 |        (18,13.25) right, (16.25,15) bottom, (14.5,13.25) left -->
25 |   <polygon points="16.25,11.5 18,13.25 16.25,15 14.5,13.25"/>
26 | 
27 |   <!-- Connectors (end exactly at tangents/edges) -->
28 |   <!-- From circle bottom (9,9.1) to process top center (9,11.5) -->
29 |   <line x1="9" y1="9.1" x2="9" y2="11.5"/>
30 |   <!-- Arrowhead into the process box -->
31 |   <polyline points="8.55,11.0 9,11.5 9.45,11.0"/>
32 | 
33 |   <!-- From process right mid (12,13.25) to diamond left point (14.5,13.25) -->
34 |   <line x1="12" y1="13.25" x2="14.5" y2="13.25"/>
35 |   <!-- Arrowhead into the diamond -->
36 |   <polyline points="14.0,12.8 14.5,13.25 14.0,13.7"/>
37 | 
38 |   <!-- Optional: from diamond bottom point (16.25,15) down a bit to imply continuation -->
39 |   <line x1="16.25" y1="15" x2="16.25" y2="16.75"/>
40 |   <polyline points="15.8,16.25 16.25,16.75 16.7,16.25"/>
41 | 
42 |   </g>
43 | </svg>
44 | 
```

--------------------------------------------------------------------------------
/src/prompts/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Prompt, PromptMessage, ListPromptsResult, GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
 2 | import { ToolContext } from '../types.js';
 3 | import { PromptDefinition, PromptHandler } from './types.js';
 4 | 
 5 | // Import individual prompt definitions
 6 | import { createSpecPrompt } from './create-spec.js';
 7 | import { createSteeringDocPrompt } from './create-steering-doc.js';
 8 | import { implementTaskPrompt } from './implement-task.js';
 9 | import { specStatusPrompt } from './spec-status.js';
10 | import { injectSpecWorkflowGuidePrompt } from './inject-spec-workflow-guide.js';
11 | import { injectSteeringGuidePrompt } from './inject-steering-guide.js';
12 | import { refreshTasksPrompt } from './refresh-tasks.js';
13 | 
14 | // Registry of all prompts
15 | const promptDefinitions: PromptDefinition[] = [
16 |   createSpecPrompt,
17 |   createSteeringDocPrompt,
18 |   implementTaskPrompt,
19 |   specStatusPrompt,
20 |   injectSpecWorkflowGuidePrompt,
21 |   injectSteeringGuidePrompt,
22 |   refreshTasksPrompt
23 | ];
24 | 
25 | /**
26 |  * Get all registered prompts
27 |  */
28 | export function registerPrompts(): Prompt[] {
29 |   return promptDefinitions.map(def => def.prompt);
30 | }
31 | 
32 | /**
33 |  * Handle prompts/list request
34 |  */
35 | export async function handlePromptList(): Promise<ListPromptsResult> {
36 |   return {
37 |     prompts: registerPrompts()
38 |   };
39 | }
40 | 
41 | /**
42 |  * Handle prompts/get request
43 |  */
44 | export async function handlePromptGet(
45 |   name: string, 
46 |   args: Record<string, any> = {}, 
47 |   context: ToolContext
48 | ): Promise<GetPromptResult> {
49 |   const promptDef = promptDefinitions.find(def => def.prompt.name === name);
50 |   
51 |   if (!promptDef) {
52 |     throw new Error(`Prompt not found: ${name}`);
53 |   }
54 | 
55 |   try {
56 |     const messages = await promptDef.handler(args, context);
57 |     return { messages };
58 |   } catch (error: any) {
59 |     throw new Error(`Failed to generate prompt messages: ${error.message}`);
60 |   }
61 | }
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/i18n.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import i18n from 'i18next';
 2 | import { initReactI18next } from 'react-i18next';
 3 | import LanguageDetector from 'i18next-browser-languagedetector';
 4 | import enTranslation from './locales/en.json';
 5 | import jaTranslation from './locales/ja.json';
 6 | import zhTranslation from './locales/zh.json';
 7 | import esTranslation from './locales/es.json';
 8 | import ptTranslation from './locales/pt.json';
 9 | import deTranslation from './locales/de.json';
10 | import frTranslation from './locales/fr.json';
11 | import ruTranslation from './locales/ru.json';
12 | import itTranslation from './locales/it.json';
13 | import koTranslation from './locales/ko.json';
14 | import arTranslation from './locales/ar.json';
15 | 
16 | i18n
17 |   .use(LanguageDetector)
18 |   .use(initReactI18next)
19 |   .init({
20 |     resources: {
21 |       en: {
22 |         translation: enTranslation,
23 |       },
24 |       ja: {
25 |         translation: jaTranslation,
26 |       },
27 |       zh: {
28 |         translation: zhTranslation,
29 |       },
30 |       es: {
31 |         translation: esTranslation,
32 |       },
33 |       pt: {
34 |         translation: ptTranslation,
35 |       },
36 |       de: {
37 |         translation: deTranslation,
38 |       },
39 |       fr: {
40 |         translation: frTranslation,
41 |       },
42 |       ru: {
43 |         translation: ruTranslation,
44 |       },
45 |       it: {
46 |         translation: itTranslation,
47 |       },
48 |       ko: {
49 |         translation: koTranslation,
50 |       },
51 |       ar: {
52 |         translation: arTranslation,
53 |       },
54 |     },
55 |     fallbackLng: 'en',
56 |     interpolation: {
57 |       escapeValue: false, // react already safes from xss
58 |     },
59 |     debug: true, // Enable debug mode for webview
60 |     detection: {
61 |       // Configure language detector to check for manual preference first
62 |       order: ['localStorage', 'navigator', 'htmlTag'],
63 |       lookupLocalStorage: 'spec-workflow-language',
64 |       caches: ['localStorage'],
65 |     },
66 |   });
67 | 
68 | export default i18n;
69 | 
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/comment-modal.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import ReactDOM from 'react-dom/client';
 2 | import { CommentModal } from '@/components/CommentModal';
 3 | import { I18nextProvider } from 'react-i18next';
 4 | import i18n from './i18n';
 5 | import '@/globals.css';
 6 | 
 7 | interface SaveCommentMessage {
 8 |   command: 'save';
 9 |   comment: string;
10 |   color: string;
11 | }
12 | 
13 | interface CancelMessage {
14 |   command: 'cancel';
15 | }
16 | 
17 | // Type for webview communication  
18 | // type WebviewMessage = SaveCommentMessage | CancelMessage;
19 | 
20 | // Extend the existing VSCode API interface
21 | declare global {
22 |   interface Window {
23 |     initialState?: {
24 |       selectedText: string;
25 |       existingComment?: {
26 |         id: string;
27 |         text: string;
28 |         highlightColor?: {
29 |           bg: string;
30 |           border: string;
31 |           name: string;
32 |         };
33 |         timestamp: string;
34 |       } | null;
35 |     };
36 |   }
37 | }
38 | 
39 | const vscode = window.acquireVsCodeApi?.();
40 | 
41 | function CommentModalApp() {
42 |   // Get initial data from webview  
43 |   const selectedText = window.initialState?.selectedText || i18n.t('commentModal.noTextSelected');
44 |   const existingComment = window.initialState?.existingComment || null;
45 | 
46 |   const handleSave = (comment: string, color: string) => {
47 |     const message: SaveCommentMessage = {
48 |       command: 'save',
49 |       comment,
50 |       color
51 |     };
52 |     vscode?.postMessage(message);
53 |   };
54 | 
55 |   const handleCancel = () => {
56 |     const message: CancelMessage = {
57 |       command: 'cancel'
58 |     };
59 |     vscode?.postMessage(message);
60 |   };
61 | 
62 |   return (
63 |     <I18nextProvider i18n={i18n}>
64 |       <CommentModal
65 |         selectedText={selectedText}
66 |         existingComment={existingComment}
67 |         onSave={handleSave}
68 |         onCancel={handleCancel}
69 |       />
70 |     </I18nextProvider>
71 |   );
72 | }
73 | 
74 | // Mount the React app
75 | const container = document.getElementById('root');
76 | if (container) {
77 |   const root = ReactDOM.createRoot(container);
78 |   root.render(<CommentModalApp />);
79 | }
```

--------------------------------------------------------------------------------
/src/tools/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Tool } from '@modelcontextprotocol/sdk/types.js';
 2 | import { specWorkflowGuideTool, specWorkflowGuideHandler } from './spec-workflow-guide.js';
 3 | import { specStatusTool, specStatusHandler } from './spec-status.js';
 4 | import { steeringGuideTool, steeringGuideHandler } from './steering-guide.js';
 5 | import { approvalsTool, approvalsHandler } from './approvals.js';
 6 | import { logImplementationTool, logImplementationHandler } from './log-implementation.js';
 7 | import { ToolContext, ToolResponse, MCPToolResponse, toMCPResponse } from '../types.js';
 8 | 
 9 | export function registerTools(): Tool[] {
10 |   return [
11 |     specWorkflowGuideTool,
12 |     steeringGuideTool,
13 |     specStatusTool,
14 |     approvalsTool,
15 |     logImplementationTool
16 |   ];
17 | }
18 | 
19 | export async function handleToolCall(name: string, args: any, context: ToolContext): Promise<MCPToolResponse> {
20 |   let response: ToolResponse;
21 |   let isError = false;
22 | 
23 |   try {
24 |     switch (name) {
25 |       case 'spec-workflow-guide':
26 |         response = await specWorkflowGuideHandler(args, context);
27 |         break;
28 |       case 'steering-guide':
29 |         response = await steeringGuideHandler(args, context);
30 |         break;
31 |       case 'spec-status':
32 |         response = await specStatusHandler(args, context);
33 |         break;
34 |       case 'approvals':
35 |         response = await approvalsHandler(args, context);
36 |         break;
37 |       case 'log-implementation':
38 |         response = await logImplementationHandler(args, context);
39 |         break;
40 |       default:
41 |         throw new Error(`Unknown tool: ${name}`);
42 |     }
43 | 
44 |     // Check if the response indicates an error
45 |     isError = !response.success;
46 | 
47 |   } catch (error) {
48 |     const errorMessage = error instanceof Error ? error.message : String(error);
49 |     response = {
50 |       success: false,
51 |       message: `Tool execution failed: ${errorMessage}`
52 |     };
53 |     isError = true;
54 |   }
55 | 
56 |   return toMCPResponse(response, isError);
57 | }
```

--------------------------------------------------------------------------------
/.github/workflows/claude-code-review.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Claude Code Review
 2 | 
 3 | on:
 4 |   pull_request:
 5 |     types: [opened, synchronize]
 6 |     # Optional: Only run on specific file changes
 7 |     # paths:
 8 |     #   - "src/**/*.ts"
 9 |     #   - "src/**/*.tsx"
10 |     #   - "src/**/*.js"
11 |     #   - "src/**/*.jsx"
12 | 
13 | jobs:
14 |   claude-review:
15 |     # Optional: Filter by PR author
16 |     # if: |
17 |     #   github.event.pull_request.user.login == 'external-contributor' ||
18 |     #   github.event.pull_request.user.login == 'new-developer' ||
19 |     #   github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20 |     
21 |     runs-on: ubuntu-latest
22 |     permissions:
23 |       contents: read
24 |       pull-requests: read
25 |       issues: read
26 |       id-token: write
27 |     
28 |     steps:
29 |       - name: Checkout repository
30 |         uses: actions/checkout@v4
31 |         with:
32 |           fetch-depth: 1
33 | 
34 |       - name: Run Claude Code Review
35 |         id: claude-review
36 |         uses: anthropics/claude-code-action@v1
37 |         with:
38 |           claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39 |           prompt: |
40 |             Please review this pull request and provide feedback on:
41 |             - Code quality and best practices
42 |             - Potential bugs or issues
43 |             - Performance considerations
44 |             - Security concerns
45 |             - Test coverage
46 |             
47 |             Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
48 | 
49 |             Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
50 |           
51 |           # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
52 |           # or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options
53 |           claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
54 | 
55 | 
```

--------------------------------------------------------------------------------
/.github/workflows/claude.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Claude Code
 2 | 
 3 | on:
 4 |   issue_comment:
 5 |     types: [created]
 6 |   pull_request_review_comment:
 7 |     types: [created]
 8 |   issues:
 9 |     types: [opened, assigned]
10 |   pull_request_review:
11 |     types: [submitted]
12 | 
13 | jobs:
14 |   claude:
15 |     if: |
16 |       (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17 |       (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18 |       (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19 |       (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20 |     runs-on: ubuntu-latest
21 |     permissions:
22 |       contents: read
23 |       pull-requests: read
24 |       issues: read
25 |       id-token: write
26 |       actions: read # Required for Claude to read CI results on PRs
27 |     steps:
28 |       - name: Checkout repository
29 |         uses: actions/checkout@v4
30 |         with:
31 |           fetch-depth: 1
32 | 
33 |       - name: Run Claude Code
34 |         id: claude
35 |         uses: anthropics/claude-code-action@v1
36 |         with:
37 |           claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38 |           
39 |           # This is an optional setting that allows Claude to read CI results on PRs
40 |           additional_permissions: |
41 |             actions: read
42 | 
43 |           # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
44 |           # prompt: 'Update the pull request description to include a summary of changes.'
45 | 
46 |           # Optional: Add claude_args to customize behavior and configuration
47 |           # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
48 |           # or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options
49 |           # claude_args: '--model claude-opus-4-1-20250805 --allowed-tools Bash(gh pr:*)'
50 | 
51 | 
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/dashboard_issue.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: 📊 Dashboard/Extension Issue
 2 | description: Report an issue with the web dashboard or VSCode extension dashboard
 3 | title: "[Dashboard]: "
 4 | labels: ["dashboard", "needs-triage"]
 5 | body:
 6 |   - type: markdown
 7 |     attributes:
 8 |       value: |
 9 |         Report issues with the web dashboard or VSCode extension dashboard.
10 | 
11 |   - type: dropdown
12 |     id: dashboard-type
13 |     attributes:
14 |       label: Dashboard Type
15 |       description: Which dashboard are you using?
16 |       options:
17 |         - "Web Dashboard"
18 |         - "VSCode Extension Dashboard"
19 |     validations:
20 |       required: true
21 | 
22 |   - type: dropdown
23 |     id: issue-type
24 |     attributes:
25 |       label: Issue Type
26 |       description: What type of dashboard issue is this?
27 |       options:
28 |         - "Bug - Dashboard not loading"
29 |         - "Bug - Display/UI issues"
30 |         - "Bug - Updates not showing"
31 |         - "Feature request"
32 |         - "Performance issue"
33 |         - "Other"
34 |     validations:
35 |       required: true
36 | 
37 |   - type: textarea
38 |     id: issue-description
39 |     attributes:
40 |       label: What's happening?
41 |       description: Describe the issue or feature request
42 |       placeholder: Tell us what's wrong or what you'd like to see...
43 |     validations:
44 |       required: true
45 | 
46 |   - type: textarea
47 |     id: steps-to-reproduce
48 |     attributes:
49 |       label: Steps to Reproduce
50 |       description: How can we reproduce this issue?
51 |       placeholder: |
52 |         1. Start dashboard with...
53 |         2. Do this...
54 |         3. See issue
55 |     validations:
56 |       required: true
57 | 
58 |   - type: textarea
59 |     id: command-used
60 |     attributes:
61 |       label: Command or Setup Used
62 |       description: How did you start the MCP server/dashboard or what VSCode version are you using?
63 |       render: shell
64 |       placeholder: npx @pimzino/spec-workflow-mcp@latest --dashboard
65 | 
66 |   - type: textarea
67 |     id: additional-context
68 |     attributes:
69 |       label: Additional Context
70 |       description: Any other details, error messages, or screenshots?
71 |       placeholder: Add any other context here...
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/components/ui/card.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import * as React from "react";
 2 | 
 3 | import { cn } from "@/lib/utils";
 4 | 
 5 | function Card({ className, ...props }: React.ComponentProps<"div">) {
 6 |   return (
 7 |     <div
 8 |       data-slot="card"
 9 |       className={cn(
10 |         "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
11 |         className
12 |       )}
13 |       {...props}
14 |     />
15 |   );
16 | }
17 | 
18 | function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19 |   return (
20 |     <div
21 |       data-slot="card-header"
22 |       className={cn(
23 |         "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
24 |         className
25 |       )}
26 |       {...props}
27 |     />
28 |   );
29 | }
30 | 
31 | function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32 |   return (
33 |     <div
34 |       data-slot="card-title"
35 |       className={cn("leading-none font-semibold", className)}
36 |       {...props}
37 |     />
38 |   );
39 | }
40 | 
41 | function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
42 |   return (
43 |     <div
44 |       data-slot="card-description"
45 |       className={cn("text-muted-foreground text-sm", className)}
46 |       {...props}
47 |     />
48 |   );
49 | }
50 | 
51 | function CardAction({ className, ...props }: React.ComponentProps<"div">) {
52 |   return (
53 |     <div
54 |       data-slot="card-action"
55 |       className={cn(
56 |         "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
57 |         className
58 |       )}
59 |       {...props}
60 |     />
61 |   );
62 | }
63 | 
64 | function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65 |   return (
66 |     <div
67 |       data-slot="card-content"
68 |       className={cn("px-6", className)}
69 |       {...props}
70 |     />
71 |   );
72 | }
73 | 
74 | function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75 |   return (
76 |     <div
77 |       data-slot="card-footer"
78 |       className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
79 |       {...props}
80 |     />
81 |   );
82 | }
83 | 
84 | export {
85 |   Card,
86 |   CardHeader,
87 |   CardFooter,
88 |   CardTitle,
89 |   CardAction,
90 |   CardDescription,
91 |   CardContent,
92 | };
93 | 
```

--------------------------------------------------------------------------------
/vscode-extension/icons/spec-workflow.svg:
--------------------------------------------------------------------------------

```
 1 | <svg xmlns="http://www.w3.org/2000/svg"
 2 |      width="96" height="96" viewBox="0 0 96 96"
 3 |      preserveAspectRatio="xMidYMid meet"
 4 |      fill="none" stroke="currentColor" stroke-width="0.75"
 5 |      stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
 6 |   <title>Spec Workflow Icon</title>
 7 | 
 8 |   <style>*{vector-effect:non-scaling-stroke}</style>
 9 | 
10 |   <!-- Background circle -->
11 |   <circle cx="48" cy="48" r="48" fill="#ffffff"/>
12 | 
13 |   <!-- Icon copied from activity-bar-icon.svg -->
14 |   <!-- Centered 24x24 icon with padding: translate to center, scale, translate back -->
15 |   <g transform="translate(48,48) scale(3.5) translate(-12,-12)">
16 |     <!-- Page with folded corner -->
17 |     <path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2z"/>
18 |     <path d="M14 2v6h6"/>
19 | 
20 |     <!-- Nodes (precisely aligned) -->
21 |     <!-- Start: circle center (9,7.5), r=1.6 -> bottom tangent at y=9.1 -->
22 |     <circle cx="9" cy="7.5" r="1.6"/>
23 | 
24 |     <!-- Process: rect from (6,11.5) size 6x3.5; center y=13.25; right mid at (12,13.25) -->
25 |     <rect x="6" y="11.5" width="6" height="3.5" rx="0.6"/>
26 | 
27 |     <!-- Decision: diamond centered at (16.25,13.25), touching (16.25,11.5) top,
28 |          (18,13.25) right, (16.25,15) bottom, (14.5,13.25) left -->
29 |     <polygon points="16.25,11.5 18,13.25 16.25,15 14.5,13.25"/>
30 | 
31 |     <!-- Connectors (end exactly at tangents/edges) -->
32 |     <!-- From circle bottom (9,9.1) to process top center (9,11.5) -->
33 |     <line x1="9" y1="9.1" x2="9" y2="11.5"/>
34 |     <!-- Arrowhead into the process box -->
35 |     <polyline points="8.55,11.0 9,11.5 9.45,11.0"/>
36 | 
37 |     <!-- From process right mid (12,13.25) to diamond left point (14.5,13.25) -->
38 |     <line x1="12" y1="13.25" x2="14.5" y2="13.25"/>
39 |     <!-- Arrowhead into the diamond -->
40 |     <polyline points="14.0,12.8 14.5,13.25 14.0,13.7"/>
41 | 
42 |     <!-- Optional: from diamond bottom point (16.25,15) down a bit to imply continuation -->
43 |     <line x1="16.25" y1="15" x2="16.25" y2="16.75"/>
44 |     <polyline points="15.8,16.25 16.25,16.75 16.7,16.25"/>
45 |   </g>
46 | </svg>
47 | 
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/components/ui/accordion.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | "use client";
 2 | 
 3 | import * as React from "react";
 4 | import * as AccordionPrimitive from "@radix-ui/react-accordion";
 5 | import { ChevronDownIcon } from "lucide-react";
 6 | 
 7 | import { cn } from "@/lib/utils";
 8 | 
 9 | function Accordion({
10 |   ...props
11 | }: React.ComponentProps<typeof AccordionPrimitive.Root>) {
12 |   return <AccordionPrimitive.Root data-slot="accordion" {...props} />;
13 | }
14 | 
15 | function AccordionItem({
16 |   className,
17 |   ...props
18 | }: React.ComponentProps<typeof AccordionPrimitive.Item>) {
19 |   return (
20 |     <AccordionPrimitive.Item
21 |       data-slot="accordion-item"
22 |       className={cn("border-b last:border-b-0", className)}
23 |       {...props}
24 |     />
25 |   );
26 | }
27 | 
28 | function AccordionTrigger({
29 |   className,
30 |   children,
31 |   ...props
32 | }: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
33 |   return (
34 |     <AccordionPrimitive.Header className="flex">
35 |       <AccordionPrimitive.Trigger
36 |         data-slot="accordion-trigger"
37 |         className={cn(
38 |           "focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
39 |           className
40 |         )}
41 |         {...props}
42 |       >
43 |         {children}
44 |         <ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
45 |       </AccordionPrimitive.Trigger>
46 |     </AccordionPrimitive.Header>
47 |   );
48 | }
49 | 
50 | function AccordionContent({
51 |   className,
52 |   children,
53 |   ...props
54 | }: React.ComponentProps<typeof AccordionPrimitive.Content>) {
55 |   return (
56 |     <AccordionPrimitive.Content
57 |       data-slot="accordion-content"
58 |       className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
59 |       {...props}
60 |     >
61 |       <div className={cn("pt-0 pb-4", className)}>{children}</div>
62 |     </AccordionPrimitive.Content>
63 |   );
64 | }
65 | 
66 | export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
67 | 
```

--------------------------------------------------------------------------------
/vscode-extension/tailwind.config.js:
--------------------------------------------------------------------------------

```javascript
 1 | /** @type {import('tailwindcss').Config} */
 2 | module.exports = {
 3 |   darkMode: ["class"],
 4 |   content: [
 5 |     './src/webview/**/*.{ts,tsx,js,jsx}',
 6 |     './src/webview/index.html',
 7 |   ],
 8 |   prefix: "",
 9 |   theme: {
10 |     container: {
11 |       center: true,
12 |       padding: "2rem",
13 |       screens: {
14 |         "2xl": "1400px",
15 |       },
16 |     },
17 |     extend: {
18 |       colors: {
19 |         border: "hsl(var(--border))",
20 |         input: "hsl(var(--input))",
21 |         ring: "hsl(var(--ring))",
22 |         background: "hsl(var(--background))",
23 |         foreground: "hsl(var(--foreground))",
24 |         primary: {
25 |           DEFAULT: "hsl(var(--primary))",
26 |           foreground: "hsl(var(--primary-foreground))",
27 |         },
28 |         secondary: {
29 |           DEFAULT: "hsl(var(--secondary))",
30 |           foreground: "hsl(var(--secondary-foreground))",
31 |         },
32 |         destructive: {
33 |           DEFAULT: "hsl(var(--destructive))",
34 |           foreground: "hsl(var(--destructive-foreground))",
35 |         },
36 |         muted: {
37 |           DEFAULT: "hsl(var(--muted))",
38 |           foreground: "hsl(var(--muted-foreground))",
39 |         },
40 |         accent: {
41 |           DEFAULT: "hsl(var(--accent))",
42 |           foreground: "hsl(var(--accent-foreground))",
43 |         },
44 |         popover: {
45 |           DEFAULT: "hsl(var(--popover))",
46 |           foreground: "hsl(var(--popover-foreground))",
47 |         },
48 |         card: {
49 |           DEFAULT: "hsl(var(--card))",
50 |           foreground: "hsl(var(--card-foreground))",
51 |         },
52 |       },
53 |       borderRadius: {
54 |         lg: "var(--radius)",
55 |         md: "calc(var(--radius) - 2px)",
56 |         sm: "calc(var(--radius) - 4px)",
57 |       },
58 |       keyframes: {
59 |         "accordion-down": {
60 |           from: { height: "0" },
61 |           to: { height: "var(--radix-accordion-content-height)" },
62 |         },
63 |         "accordion-up": {
64 |           from: { height: "var(--radix-accordion-content-height)" },
65 |           to: { height: "0" },
66 |         },
67 |       },
68 |       animation: {
69 |         "accordion-down": "accordion-down 0.2s ease-out",
70 |         "accordion-up": "accordion-up 0.2s ease-out",
71 |       },
72 |     },
73 |   },
74 |   plugins: [],
75 | }
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/components/ui/tabs.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import * as React from "react";
 2 | import * as TabsPrimitive from "@radix-ui/react-tabs";
 3 | 
 4 | import { cn } from "@/lib/utils";
 5 | 
 6 | function Tabs({
 7 |   className,
 8 |   ...props
 9 | }: React.ComponentProps<typeof TabsPrimitive.Root>) {
10 |   return (
11 |     <TabsPrimitive.Root
12 |       data-slot="tabs"
13 |       className={cn("flex flex-col gap-2", className)}
14 |       {...props}
15 |     />
16 |   );
17 | }
18 | 
19 | function TabsList({
20 |   className,
21 |   ...props
22 | }: React.ComponentProps<typeof TabsPrimitive.List>) {
23 |   return (
24 |     <TabsPrimitive.List
25 |       data-slot="tabs-list"
26 |       className={cn(
27 |         "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
28 |         "[body.vscode-light_&]:border [body.vscode-light_&]:border-border/20 [body.vscode-light_&]:shadow-sm",
29 |         className
30 |       )}
31 |       {...props}
32 |     />
33 |   );
34 | }
35 | 
36 | function TabsTrigger({
37 |   className,
38 |   ...props
39 | }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
40 |   return (
41 |     <TabsPrimitive.Trigger
42 |       data-slot="tabs-trigger"
43 |       className={cn(
44 |         "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
45 |         className
46 |       )}
47 |       {...props}
48 |     />
49 |   );
50 | }
51 | 
52 | function TabsContent({
53 |   className,
54 |   ...props
55 | }: React.ComponentProps<typeof TabsPrimitive.Content>) {
56 |   return (
57 |     <TabsPrimitive.Content
58 |       data-slot="tabs-content"
59 |       className={cn("flex-1 outline-none", className)}
60 |       {...props}
61 |     />
62 |   );
63 | }
64 | 
65 | export { Tabs, TabsList, TabsTrigger, TabsContent };
66 | 
```

--------------------------------------------------------------------------------
/scripts/copy-static.cjs:
--------------------------------------------------------------------------------

```
 1 | #!/usr/bin/env node
 2 | 
 3 | const fs = require('fs');
 4 | const path = require('path');
 5 | 
 6 | function copyDir(src, dest) {
 7 |   if (!fs.existsSync(dest)) {
 8 |     fs.mkdirSync(dest, { recursive: true });
 9 |   }
10 | 
11 |   const entries = fs.readdirSync(src, { withFileTypes: true });
12 | 
13 |   for (const entry of entries) {
14 |     const srcPath = path.join(src, entry.name);
15 |     const destPath = path.join(dest, entry.name);
16 | 
17 |     if (entry.isDirectory()) {
18 |       copyDir(srcPath, destPath);
19 |     } else {
20 |       fs.copyFileSync(srcPath, destPath);
21 |     }
22 |   }
23 | }
24 | 
25 | // Copy markdown directory
26 | const markdownSrc = path.join(__dirname, '..', 'src', 'markdown');
27 | const markdownDest = path.join(__dirname, '..', 'dist', 'markdown');
28 | 
29 | if (fs.existsSync(markdownSrc)) {
30 |   copyDir(markdownSrc, markdownDest);
31 |   console.log('✓ Copied markdown files');
32 | }
33 | 
34 | // Copy locales directory
35 | const localesSrc = path.join(__dirname, '..', 'src', 'locales');
36 | const localesDest = path.join(__dirname, '..', 'dist', 'locales');
37 | 
38 | if (fs.existsSync(localesSrc)) {
39 |   copyDir(localesSrc, localesDest);
40 |   console.log('✓ Copied locale files');
41 | }
42 | 
43 | // Copy icons from old dashboard (we still need these)
44 | const iconsSrc = path.join(__dirname, '..', 'src', 'dashboard', 'public');
45 | const publicDest = path.join(__dirname, '..', 'dist', 'dashboard', 'public');
46 | 
47 | // Ensure public directory exists
48 | if (!fs.existsSync(publicDest)) {
49 |   fs.mkdirSync(publicDest, { recursive: true });
50 | }
51 | 
52 | // Copy only the icon files from old dashboard
53 | const iconFiles = ['claude-icon.svg', 'claude-icon-dark.svg'];
54 | if (fs.existsSync(iconsSrc)) {
55 |   for (const iconFile of iconFiles) {
56 |     const srcPath = path.join(iconsSrc, iconFile);
57 |     const destPath = path.join(publicDest, iconFile);
58 |     if (fs.existsSync(srcPath)) {
59 |       fs.copyFileSync(srcPath, destPath);
60 |     }
61 |   }
62 |   console.log('✓ Copied dashboard icon files');
63 | }
64 | 
65 | // Copy dashboard build as the main dashboard
66 | const newDashSrc = path.join(__dirname, '..', 'src', 'dashboard_frontend', 'dist');
67 | 
68 | if (fs.existsSync(newDashSrc)) {
69 |   // Copy all files from new dashboard to public root
70 |   copyDir(newDashSrc, publicDest);
71 |   console.log('✓ Copied dashboard as main dashboard');
72 | }
```

--------------------------------------------------------------------------------
/vscode-extension/src/webview/components/ui/button.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import * as React from "react";
 2 | import { Slot } from "@radix-ui/react-slot";
 3 | import { cva, type VariantProps } from "class-variance-authority";
 4 | 
 5 | import { cn } from "@/lib/utils";
 6 | 
 7 | const buttonVariants = cva(
 8 |   "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
 9 |   {
10 |     variants: {
11 |       variant: {
12 |         default:
13 |           "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
14 |         destructive:
15 |           "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
16 |         outline:
17 |           "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
18 |         secondary:
19 |           "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
20 |         ghost:
21 |           "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
22 |         link: "text-primary underline-offset-4 hover:underline",
23 |       },
24 |       size: {
25 |         default: "h-9 px-4 py-2 has-[>svg]:px-3",
26 |         sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
27 |         lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
28 |         icon: "size-9",
29 |       },
30 |     },
31 |     defaultVariants: {
32 |       variant: "default",
33 |       size: "default",
34 |     },
35 |   }
36 | );
37 | 
38 | function Button({
39 |   className,
40 |   variant,
41 |   size,
42 |   asChild = false,
43 |   ...props
44 | }: React.ComponentProps<"button"> &
45 |   VariantProps<typeof buttonVariants> & {
46 |     asChild?: boolean
47 |   }) {
48 |   const Comp = asChild ? Slot : "button";
49 | 
50 |   return (
51 |     <Comp
52 |       data-slot="button"
53 |       className={cn(buttonVariants({ variant, size, className }))}
54 |       {...props}
55 |     />
56 |   );
57 | }
58 | 
59 | export { Button, buttonVariants };
60 | 
```

--------------------------------------------------------------------------------
/src/prompts/inject-spec-workflow-guide.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { Prompt, PromptMessage } from '@modelcontextprotocol/sdk/types.js';
 2 | import { PromptDefinition } from './types.js';
 3 | import { ToolContext } from '../types.js';
 4 | import { specWorkflowGuideHandler } from '../tools/spec-workflow-guide.js';
 5 | 
 6 | const prompt: Prompt = {
 7 |   name: 'inject-spec-workflow-guide',
 8 |   title: 'Inject Spec Workflow Guide into Context',
 9 |   description: 'Injects the complete spec-driven development workflow guide into the conversation context. This provides immediate access to all workflow phases, tools, and best practices without requiring separate tool calls.'
10 | };
11 | 
12 | async function handler(args: Record<string, any>, context: ToolContext): Promise<PromptMessage[]> {
13 |   // Call the spec-workflow-guide tool to get the full guide
14 |   const toolResponse = await specWorkflowGuideHandler({}, context);
15 |   
16 |   // Extract the guide content from the tool response
17 |   const guide = toolResponse.data?.guide || '';
18 |   const dashboardUrl = toolResponse.data?.dashboardUrl;
19 |   const nextSteps = toolResponse.nextSteps || [];
20 | 
21 |   const messages: PromptMessage[] = [
22 |     {
23 |       role: 'user',
24 |       content: {
25 |         type: 'text',
26 |         text: `Please review and follow this comprehensive spec-driven development workflow guide:
27 | 
28 | ${guide}
29 | 
30 | **Current Context:**
31 | - Project: ${context.projectPath}
32 | ${dashboardUrl ? `- Dashboard: ${dashboardUrl}` : '- Dashboard: Please start the dashboard or use VS Code extension "Spec Workflow MCP"'}
33 | 
34 | **Next Steps:**
35 | ${nextSteps.map(step => `- ${step}`).join('\n')}
36 | 
37 | **Important Instructions:**
38 | 1. This guide has been injected into your context for immediate reference
39 | 2. Follow the workflow sequence exactly: Requirements → Design → Tasks → Implementation
40 | 3. Use the MCP tools mentioned in the guide to execute each phase
41 | 4. Always request approval between phases using the approvals tool
42 | 5. Never proceed to the next phase without successful approval cleanup
43 | 
44 | Please acknowledge that you've reviewed this workflow guide and are ready to help with spec-driven development.`
45 |       }
46 |     }
47 |   ];
48 | 
49 |   return messages;
50 | }
51 | 
52 | export const injectSpecWorkflowGuidePrompt: PromptDefinition = {
53 |   prompt,
54 |   handler
55 | };
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: 🐛 Bug Report
 2 | description: Report a bug or issue with the Spec-Driven Workflow MCP Server
 3 | title: "[Bug]: "
 4 | labels: ["bug", "needs-triage"]
 5 | body:
 6 |   - type: markdown
 7 |     attributes:
 8 |       value: |
 9 |         Thanks for reporting a bug! Please provide the essential details below to help us fix the issue quickly.
10 | 
11 |   - type: textarea
12 |     id: what-happened
13 |     attributes:
14 |       label: What happened?
15 |       description: Describe the bug clearly and concisely
16 |       placeholder: Tell us what went wrong...
17 |     validations:
18 |       required: true
19 | 
20 |   - type: dropdown
21 |     id: component
22 |     attributes:
23 |       label: Component
24 |       description: Which component is affected?
25 |       options:
26 |         - MCP Server
27 |         - Web Dashboard
28 |         - VSCode Extension
29 |     validations:
30 |       required: true
31 | 
32 |   - type: textarea
33 |     id: steps-to-reproduce
34 |     attributes:
35 |       label: Steps to Reproduce
36 |       description: How can we reproduce this issue?
37 |       placeholder: |
38 |         1. Run MCP server with '...'
39 |         2. Use tool '...'
40 |         3. See error
41 |     validations:
42 |       required: true
43 | 
44 |   - type: textarea
45 |     id: expected-behavior
46 |     attributes:
47 |       label: Expected Behavior
48 |       description: What should have happened instead?
49 |       placeholder: Describe what you expected to happen...
50 |     validations:
51 |       required: true
52 | 
53 |   - type: textarea
54 |     id: error-output
55 |     attributes:
56 |       label: Error Output (if any)
57 |       description: Paste any error messages or logs
58 |       render: shell
59 |       placeholder: Paste error messages here...
60 | 
61 |   - type: input
62 |     id: version
63 |     attributes:
64 |       label: Version
65 |       description: What version are you using? (MCP server, dashboard, or extension version)
66 |       placeholder: "0.0.19"
67 |     validations:
68 |       required: true
69 | 
70 |   - type: dropdown
71 |     id: os
72 |     attributes:
73 |       label: Operating System
74 |       options:
75 |         - Windows
76 |         - macOS
77 |         - Linux
78 |         - Other
79 | 
80 |   - type: textarea
81 |     id: additional-context
82 |     attributes:
83 |       label: Additional Context
84 |       description: Anything else that might help us understand the issue?
85 |       placeholder: Add any other details, screenshots, or context here...
```
Page 1/15FirstPrevNextLast