@prmichaelsen/task-mcp 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/.env.example +19 -0
  2. package/AGENT.md +1165 -0
  3. package/CHANGELOG.md +72 -0
  4. package/agent/commands/acp.commit.md +511 -0
  5. package/agent/commands/acp.init.md +376 -0
  6. package/agent/commands/acp.package-install.md +347 -0
  7. package/agent/commands/acp.proceed.md +311 -0
  8. package/agent/commands/acp.report.md +392 -0
  9. package/agent/commands/acp.status.md +280 -0
  10. package/agent/commands/acp.sync.md +323 -0
  11. package/agent/commands/acp.update.md +301 -0
  12. package/agent/commands/acp.validate.md +385 -0
  13. package/agent/commands/acp.version-check-for-updates.md +275 -0
  14. package/agent/commands/acp.version-check.md +190 -0
  15. package/agent/commands/acp.version-update.md +288 -0
  16. package/agent/commands/command.template.md +273 -0
  17. package/agent/commands/git.commit.md +511 -0
  18. package/agent/commands/git.init.md +513 -0
  19. package/agent/design/.gitkeep +0 -0
  20. package/agent/design/acp-task-execution-requirements.md +555 -0
  21. package/agent/design/api-dto-design.md +394 -0
  22. package/agent/design/code-extraction-guide.md +827 -0
  23. package/agent/design/design.template.md +136 -0
  24. package/agent/design/requirements.template.md +387 -0
  25. package/agent/design/rest-api-integration.md +489 -0
  26. package/agent/design/sdk-export-requirements.md +549 -0
  27. package/agent/milestones/.gitkeep +0 -0
  28. package/agent/milestones/milestone-1-{title}.template.md +206 -0
  29. package/agent/milestones/milestone-2-task-infrastructure.md +232 -0
  30. package/agent/milestones/milestone-4-autonomous-execution.md +235 -0
  31. package/agent/patterns/.gitkeep +0 -0
  32. package/agent/patterns/bootstrap.md +1271 -0
  33. package/agent/patterns/bootstrap.template.md +1237 -0
  34. package/agent/patterns/pattern.template.md +364 -0
  35. package/agent/progress.template.yaml +158 -0
  36. package/agent/progress.yaml +375 -0
  37. package/agent/scripts/check-for-updates.sh +88 -0
  38. package/agent/scripts/install.sh +157 -0
  39. package/agent/scripts/uninstall.sh +75 -0
  40. package/agent/scripts/update.sh +139 -0
  41. package/agent/scripts/version.sh +35 -0
  42. package/agent/tasks/.gitkeep +0 -0
  43. package/agent/tasks/task-1-{title}.template.md +225 -0
  44. package/agent/tasks/task-86-task-data-model-schemas.md +143 -0
  45. package/agent/tasks/task-87-task-database-service.md +220 -0
  46. package/agent/tasks/task-88-firebase-client-wrapper.md +139 -0
  47. package/agent/tasks/task-88-task-execution-engine.md +277 -0
  48. package/agent/tasks/task-89-mcp-server-implementation.md +197 -0
  49. package/agent/tasks/task-90-build-configuration.md +146 -0
  50. package/agent/tasks/task-91-deployment-configuration.md +128 -0
  51. package/coverage/base.css +224 -0
  52. package/coverage/block-navigation.js +87 -0
  53. package/coverage/favicon.png +0 -0
  54. package/coverage/index.html +191 -0
  55. package/coverage/lcov-report/base.css +224 -0
  56. package/coverage/lcov-report/block-navigation.js +87 -0
  57. package/coverage/lcov-report/favicon.png +0 -0
  58. package/coverage/lcov-report/index.html +191 -0
  59. package/coverage/lcov-report/prettify.css +1 -0
  60. package/coverage/lcov-report/prettify.js +2 -0
  61. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  62. package/coverage/lcov-report/sorter.js +210 -0
  63. package/coverage/lcov-report/src/client.ts.html +1030 -0
  64. package/coverage/lcov-report/src/constant/collections.ts.html +469 -0
  65. package/coverage/lcov-report/src/constant/index.html +116 -0
  66. package/coverage/lcov-report/src/dto/index.html +116 -0
  67. package/coverage/lcov-report/src/dto/transformers.ts.html +568 -0
  68. package/coverage/lcov-report/src/index.html +146 -0
  69. package/coverage/lcov-report/src/schemas/index.html +116 -0
  70. package/coverage/lcov-report/src/schemas/task.ts.html +547 -0
  71. package/coverage/lcov-report/src/server-factory.ts.html +418 -0
  72. package/coverage/lcov-report/src/server.ts.html +289 -0
  73. package/coverage/lcov-report/src/services/index.html +116 -0
  74. package/coverage/lcov-report/src/services/task-database.service.ts.html +1495 -0
  75. package/coverage/lcov-report/src/tools/index.html +236 -0
  76. package/coverage/lcov-report/src/tools/index.ts.html +292 -0
  77. package/coverage/lcov-report/src/tools/task-add-message.ts.html +277 -0
  78. package/coverage/lcov-report/src/tools/task-complete-task-item.ts.html +343 -0
  79. package/coverage/lcov-report/src/tools/task-create-milestone.ts.html +286 -0
  80. package/coverage/lcov-report/src/tools/task-create-task-item.ts.html +358 -0
  81. package/coverage/lcov-report/src/tools/task-get-next-step.ts.html +460 -0
  82. package/coverage/lcov-report/src/tools/task-get-status.ts.html +316 -0
  83. package/coverage/lcov-report/src/tools/task-report-completion.ts.html +343 -0
  84. package/coverage/lcov-report/src/tools/task-update-progress.ts.html +232 -0
  85. package/coverage/lcov.info +974 -0
  86. package/coverage/prettify.css +1 -0
  87. package/coverage/prettify.js +2 -0
  88. package/coverage/sort-arrow-sprite.png +0 -0
  89. package/coverage/sorter.js +210 -0
  90. package/coverage/src/client.ts.html +1030 -0
  91. package/coverage/src/constant/collections.ts.html +469 -0
  92. package/coverage/src/constant/index.html +116 -0
  93. package/coverage/src/dto/index.html +116 -0
  94. package/coverage/src/dto/transformers.ts.html +568 -0
  95. package/coverage/src/index.html +146 -0
  96. package/coverage/src/schemas/index.html +116 -0
  97. package/coverage/src/schemas/task.ts.html +547 -0
  98. package/coverage/src/server-factory.ts.html +418 -0
  99. package/coverage/src/server.ts.html +289 -0
  100. package/coverage/src/services/index.html +116 -0
  101. package/coverage/src/services/task-database.service.ts.html +1495 -0
  102. package/coverage/src/tools/index.html +236 -0
  103. package/coverage/src/tools/index.ts.html +292 -0
  104. package/coverage/src/tools/task-add-message.ts.html +277 -0
  105. package/coverage/src/tools/task-complete-task-item.ts.html +343 -0
  106. package/coverage/src/tools/task-create-milestone.ts.html +286 -0
  107. package/coverage/src/tools/task-create-task-item.ts.html +358 -0
  108. package/coverage/src/tools/task-get-next-step.ts.html +460 -0
  109. package/coverage/src/tools/task-get-status.ts.html +316 -0
  110. package/coverage/src/tools/task-report-completion.ts.html +343 -0
  111. package/coverage/src/tools/task-update-progress.ts.html +232 -0
  112. package/firestore.rules +95 -0
  113. package/jest.config.js +31 -0
  114. package/package.json +67 -0
  115. package/src/client.spec.ts +199 -0
  116. package/src/client.ts +315 -0
  117. package/src/constant/collections.ts +128 -0
  118. package/src/dto/index.ts +47 -0
  119. package/src/dto/task-api.dto.ts +219 -0
  120. package/src/dto/transformers.spec.ts +462 -0
  121. package/src/dto/transformers.ts +161 -0
  122. package/src/schemas/task.ts +154 -0
  123. package/src/server-factory.spec.ts +70 -0
  124. package/src/server-factory.ts +111 -0
  125. package/src/server.ts +68 -0
  126. package/src/services/task-database.service.e2e.ts +116 -0
  127. package/src/services/task-database.service.spec.ts +479 -0
  128. package/src/services/task-database.service.ts +470 -0
  129. package/src/test-schemas.ts +161 -0
  130. package/src/tools/index.ts +69 -0
  131. package/src/tools/task-add-message.ts +64 -0
  132. package/src/tools/task-complete-task-item.ts +86 -0
  133. package/src/tools/task-create-milestone.ts +67 -0
  134. package/src/tools/task-create-task-item.ts +91 -0
  135. package/src/tools/task-get-next-step.spec.ts +136 -0
  136. package/src/tools/task-get-next-step.ts +125 -0
  137. package/src/tools/task-get-status.spec.ts +213 -0
  138. package/src/tools/task-get-status.ts +77 -0
  139. package/src/tools/task-report-completion.ts +86 -0
  140. package/src/tools/task-update-progress.ts +49 -0
  141. package/src/tools/tools.spec.ts +194 -0
  142. package/tsconfig.json +31 -0
@@ -0,0 +1,197 @@
1
+ # Task 90: MCP Server Implementation
2
+
3
+ **Milestone**: Milestone 2 - MCP Server Foundation
4
+ **Estimated Time**: 8 hours
5
+ **Dependencies**: Task 89 (Core MCP Tools)
6
+ **Status**: Not Started
7
+
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ Create the MCP server implementation that exposes task management tools via MCP protocol. Implement both standalone server (stdio transport) and server factory (multi-tenant) following the MCP Server Bootstrap Pattern.
13
+
14
+ ## Steps
15
+
16
+ ### 1. Install MCP SDK
17
+
18
+ Install dependencies:
19
+ ```bash
20
+ npm install @modelcontextprotocol/sdk
21
+ ```
22
+
23
+ ### 2. Create Server Factory
24
+
25
+ Create `src/server-factory.ts`:
26
+ - Export `createServer(userId, options)` function
27
+ - Initialize FirebaseClient with userId
28
+ - Create MCP Server instance
29
+ - Register all tools from `src/tools/`
30
+ - Handle `list_tools` requests
31
+ - Handle `call_tool` requests
32
+ - Return configured Server instance
33
+
34
+ ### 3. Create Standalone Server
35
+
36
+ Create `src/server.ts`:
37
+ - CLI entry point for stdio transport
38
+ - Load userId from environment or args
39
+ - Use server factory to create instance
40
+ - Connect with StdioServerTransport
41
+ - Handle graceful shutdown
42
+
43
+ ### 4. Create CLI Entry Point
44
+
45
+ Create `src/index.ts`:
46
+ - Parse command line arguments
47
+ - Load environment variables
48
+ - Start standalone server
49
+ - Handle errors
50
+
51
+ ### 5. Create Types
52
+
53
+ Create `src/types.ts`:
54
+ - MCP-specific type definitions
55
+ - Server options interface
56
+ - Tool handler types
57
+ - Export shared types
58
+
59
+ ### 6. Write Unit Tests
60
+
61
+ Create tests:
62
+ - `src/server-factory.spec.ts` - Test factory function
63
+ - `src/server.spec.ts` - Test server initialization
64
+ - Test tool registration
65
+ - Test request handling
66
+
67
+ ## Verification
68
+
69
+ - [ ] Server factory creates isolated instances
70
+ - [ ] Standalone server starts with stdio
71
+ - [ ] All tools registered correctly
72
+ - [ ] list_tools returns all 8 tools
73
+ - [ ] call_tool executes tools correctly
74
+ - [ ] Error handling works
75
+ - [ ] Unit tests pass
76
+ - [ ] TypeScript compiles without errors
77
+
78
+ ## Example Server Factory
79
+
80
+ ```typescript
81
+ // src/server-factory.ts
82
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js'
83
+ import {
84
+ CallToolRequestSchema,
85
+ ListToolsRequestSchema,
86
+ ErrorCode,
87
+ McpError
88
+ } from '@modelcontextprotocol/sdk/types.js'
89
+ import { FirebaseClient } from './client.js'
90
+ import {
91
+ taskGetStatusTool,
92
+ handleTaskGetStatus,
93
+ taskGetNextStepTool,
94
+ handleTaskGetNextStep,
95
+ // ... import all tools
96
+ } from './tools/index.js'
97
+
98
+ export interface ServerOptions {
99
+ name?: string
100
+ version?: string
101
+ }
102
+
103
+ export function createServer(
104
+ userId: string,
105
+ options: ServerOptions = {}
106
+ ): Server {
107
+ if (!userId) {
108
+ throw new Error('userId is required')
109
+ }
110
+
111
+ // Initialize Firebase client for this user
112
+ const client = new FirebaseClient(userId)
113
+
114
+ // Create MCP server
115
+ const server = new Server(
116
+ {
117
+ name: options.name || 'task-mcp',
118
+ version: options.version || '0.1.0'
119
+ },
120
+ {
121
+ capabilities: {
122
+ tools: {}
123
+ }
124
+ }
125
+ )
126
+
127
+ // Register list_tools handler
128
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
129
+ return {
130
+ tools: [
131
+ taskGetStatusTool,
132
+ taskGetNextStepTool,
133
+ // ... all tool definitions
134
+ ]
135
+ }
136
+ })
137
+
138
+ // Register call_tool handler
139
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
140
+ const { name, arguments: args } = request.params
141
+
142
+ try {
143
+ let result: string
144
+
145
+ switch (name) {
146
+ case 'task_get_status':
147
+ result = await handleTaskGetStatus(client, args)
148
+ break
149
+
150
+ case 'task_get_next_step':
151
+ result = await handleTaskGetNextStep(client, args)
152
+ break
153
+
154
+ // ... all tool handlers
155
+
156
+ default:
157
+ throw new McpError(
158
+ ErrorCode.MethodNotFound,
159
+ `Unknown tool: ${name}`
160
+ )
161
+ }
162
+
163
+ return {
164
+ content: [
165
+ {
166
+ type: 'text',
167
+ text: result
168
+ }
169
+ ]
170
+ }
171
+ } catch (error) {
172
+ if (error instanceof McpError) {
173
+ throw error
174
+ }
175
+
176
+ throw new McpError(
177
+ ErrorCode.InternalError,
178
+ `Tool execution failed: ${error instanceof Error ? error.message : String(error)}`
179
+ )
180
+ }
181
+ })
182
+
183
+ return server
184
+ }
185
+ ```
186
+
187
+ ## Files to Create
188
+
189
+ - `src/server-factory.ts`
190
+ - `src/server-factory.spec.ts`
191
+ - `src/server.ts`
192
+ - `src/index.ts`
193
+ - `src/types.ts`
194
+
195
+ ---
196
+
197
+ **Next Task**: [Task 91: Build Configuration](task-91-build-configuration.md)
@@ -0,0 +1,146 @@
1
+ # Task 91: Build Configuration
2
+
3
+ **Milestone**: Milestone 2 - MCP Server Foundation
4
+ **Estimated Time**: 4 hours
5
+ **Dependencies**: Task 90 (MCP Server Implementation)
6
+ **Status**: Not Started
7
+
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ Create esbuild configuration for bundling the MCP server for deployment. Set up both build and watch modes following the MCP Server Bootstrap Pattern.
13
+
14
+ ## Steps
15
+
16
+ ### 1. Install esbuild
17
+
18
+ ```bash
19
+ npm install --save-dev esbuild
20
+ ```
21
+
22
+ ### 2. Create Build Script
23
+
24
+ Create `esbuild.build.js`:
25
+ - Bundle `src/server.ts` for standalone deployment
26
+ - Bundle `src/server-factory.ts` for library usage
27
+ - Target Node.js 20
28
+ - ESM format
29
+ - External dependencies: firebase-admin, @modelcontextprotocol/sdk
30
+ - Generate source maps
31
+ - Generate TypeScript declarations
32
+
33
+ ### 3. Create Watch Script
34
+
35
+ Create `esbuild.watch.js`:
36
+ - Same configuration as build script
37
+ - Enable watch mode for development
38
+ - Auto-rebuild on file changes
39
+
40
+ ### 4. Update package.json Scripts
41
+
42
+ Add build scripts:
43
+ ```json
44
+ {
45
+ "scripts": {
46
+ "build": "node esbuild.build.js",
47
+ "build:watch": "node esbuild.watch.js",
48
+ "clean": "rm -rf dist",
49
+ "dev": "npm run build:watch"
50
+ }
51
+ }
52
+ ```
53
+
54
+ ### 5. Test Build
55
+
56
+ Run build and verify:
57
+ - `npm run build` succeeds
58
+ - `dist/server.js` created
59
+ - `dist/server-factory.js` created
60
+ - Type declarations generated
61
+ - No build errors
62
+
63
+ ## Verification
64
+
65
+ - [ ] esbuild.build.js created
66
+ - [ ] esbuild.watch.js created
67
+ - [ ] Build succeeds without errors
68
+ - [ ] dist/ directory contains bundled files
69
+ - [ ] TypeScript declarations generated
70
+ - [ ] Source maps generated
71
+ - [ ] Watch mode works for development
72
+ - [ ] Bundle size is reasonable
73
+
74
+ ## Example Build Script
75
+
76
+ ```javascript
77
+ // esbuild.build.js
78
+ import * as esbuild from 'esbuild';
79
+ import { execSync } from 'child_process';
80
+
81
+ // Build standalone server
82
+ await esbuild.build({
83
+ entryPoints: ['src/server.ts'],
84
+ bundle: true,
85
+ platform: 'node',
86
+ target: 'node20',
87
+ format: 'esm',
88
+ outfile: 'dist/server.js',
89
+ sourcemap: true,
90
+ external: [
91
+ 'firebase-admin',
92
+ '@modelcontextprotocol/sdk'
93
+ ],
94
+ banner: {
95
+ js: "import { createRequire } from 'module'; const require = createRequire(import.meta.url);"
96
+ },
97
+ alias: {
98
+ '@': './src'
99
+ }
100
+ });
101
+
102
+ // Build server factory
103
+ await esbuild.build({
104
+ entryPoints: ['src/server-factory.ts'],
105
+ bundle: true,
106
+ platform: 'node',
107
+ target: 'node20',
108
+ format: 'esm',
109
+ outfile: 'dist/server-factory.js',
110
+ sourcemap: true,
111
+ external: [
112
+ 'firebase-admin',
113
+ '@modelcontextprotocol/sdk'
114
+ ],
115
+ banner: {
116
+ js: "import { createRequire } from 'module'; const require = createRequire(import.meta.url);"
117
+ },
118
+ alias: {
119
+ '@': './src'
120
+ }
121
+ });
122
+
123
+ console.log('✓ JavaScript bundles built');
124
+
125
+ // Generate TypeScript declarations
126
+ console.log('Generating TypeScript declarations...');
127
+ try {
128
+ execSync('tsc --emitDeclarationOnly --outDir dist', { stdio: 'inherit' });
129
+ console.log('✓ TypeScript declarations generated');
130
+ } catch (error) {
131
+ console.error('✗ Failed to generate TypeScript declarations');
132
+ process.exit(1);
133
+ }
134
+
135
+ console.log('✓ Build complete');
136
+ ```
137
+
138
+ ## Files to Create
139
+
140
+ - `esbuild.build.js`
141
+ - `esbuild.watch.js`
142
+ - Update `package.json` scripts
143
+
144
+ ---
145
+
146
+ **Next Task**: [Task 92: Deployment Configuration](task-92-deployment-configuration.md)
@@ -0,0 +1,128 @@
1
+ # Task 92: Deployment Configuration
2
+
3
+ **Milestone**: Milestone 2 - MCP Server Foundation
4
+ **Estimated Time**: 4 hours
5
+ **Dependencies**: Task 91 (Build Configuration)
6
+ **Status**: Not Started
7
+
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ Create deployment configuration for running task-mcp MCP server on Cloud Run or other platforms. Set up environment variables, service account configuration, and deployment scripts.
13
+
14
+ ## Steps
15
+
16
+ ### 1. Create Environment Configuration
17
+
18
+ Create `.env.example`:
19
+ ```bash
20
+ # Firebase Configuration
21
+ FIREBASE_PROJECT_ID=your-project-id
22
+ FIREBASE_SERVICE_ACCOUNT_PATH=./service-account.json
23
+ # Or use JSON directly:
24
+ # FIREBASE_SERVICE_ACCOUNT_JSON={"type":"service_account",...}
25
+
26
+ # Server Configuration
27
+ NODE_ENV=production
28
+ LOG_LEVEL=info
29
+ ```
30
+
31
+ ### 2. Create Dockerfile
32
+
33
+ Create `Dockerfile`:
34
+ - Use Node.js 20 base image
35
+ - Copy package files and install dependencies
36
+ - Copy source code
37
+ - Build the project
38
+ - Set up entrypoint for server
39
+ - Expose necessary ports (if using SSE)
40
+
41
+ ### 3. Create Cloud Run Configuration
42
+
43
+ Create `cloudrun.yaml`:
44
+ - Service name: task-mcp
45
+ - Region: us-central1
46
+ - Memory: 512Mi
47
+ - CPU: 1
48
+ - Min instances: 0
49
+ - Max instances: 10
50
+ - Environment variables
51
+ - Service account
52
+
53
+ ### 4. Create Deployment Script
54
+
55
+ Create `scripts/deploy.sh`:
56
+ - Build Docker image
57
+ - Push to Google Container Registry
58
+ - Deploy to Cloud Run
59
+ - Set environment variables
60
+ - Configure service account
61
+
62
+ ### 5. Update .gitignore
63
+
64
+ Add to `.gitignore`:
65
+ - `service-account.json`
66
+ - `.env`
67
+ - `.env.local`
68
+ - `dist/`
69
+ - `coverage/`
70
+
71
+ ### 6. Create README
72
+
73
+ Create `README.md`:
74
+ - Project description
75
+ - Installation instructions
76
+ - Configuration guide
77
+ - Deployment guide
78
+ - Usage examples
79
+
80
+ ## Verification
81
+
82
+ - [ ] .env.example created
83
+ - [ ] Dockerfile builds successfully
84
+ - [ ] Cloud Run configuration valid
85
+ - [ ] Deployment script works
86
+ - [ ] .gitignore updated
87
+ - [ ] README.md complete
88
+ - [ ] Service account not in git
89
+ - [ ] Environment variables documented
90
+
91
+ ## Example Dockerfile
92
+
93
+ ```dockerfile
94
+ FROM node:20-alpine
95
+
96
+ WORKDIR /app
97
+
98
+ # Copy package files
99
+ COPY package*.json ./
100
+
101
+ # Install dependencies
102
+ RUN npm ci --only=production
103
+
104
+ # Copy source code
105
+ COPY . .
106
+
107
+ # Build the project
108
+ RUN npm run build
109
+
110
+ # Set environment
111
+ ENV NODE_ENV=production
112
+
113
+ # Run the server
114
+ CMD ["node", "dist/server.js"]
115
+ ```
116
+
117
+ ## Files to Create
118
+
119
+ - `Dockerfile`
120
+ - `.env.example`
121
+ - `cloudrun.yaml`
122
+ - `scripts/deploy.sh`
123
+ - `README.md`
124
+ - Update `.gitignore`
125
+
126
+ ---
127
+
128
+ **Next Task**: Milestone 2 Complete! → [Milestone 3: agentbase.me Integration](../milestones/milestone-3-agentbase-integration.md)
@@ -0,0 +1,224 @@
1
+ body, html {
2
+ margin:0; padding: 0;
3
+ height: 100%;
4
+ }
5
+ body {
6
+ font-family: Helvetica Neue, Helvetica, Arial;
7
+ font-size: 14px;
8
+ color:#333;
9
+ }
10
+ .small { font-size: 12px; }
11
+ *, *:after, *:before {
12
+ -webkit-box-sizing:border-box;
13
+ -moz-box-sizing:border-box;
14
+ box-sizing:border-box;
15
+ }
16
+ h1 { font-size: 20px; margin: 0;}
17
+ h2 { font-size: 14px; }
18
+ pre {
19
+ font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
20
+ margin: 0;
21
+ padding: 0;
22
+ -moz-tab-size: 2;
23
+ -o-tab-size: 2;
24
+ tab-size: 2;
25
+ }
26
+ a { color:#0074D9; text-decoration:none; }
27
+ a:hover { text-decoration:underline; }
28
+ .strong { font-weight: bold; }
29
+ .space-top1 { padding: 10px 0 0 0; }
30
+ .pad2y { padding: 20px 0; }
31
+ .pad1y { padding: 10px 0; }
32
+ .pad2x { padding: 0 20px; }
33
+ .pad2 { padding: 20px; }
34
+ .pad1 { padding: 10px; }
35
+ .space-left2 { padding-left:55px; }
36
+ .space-right2 { padding-right:20px; }
37
+ .center { text-align:center; }
38
+ .clearfix { display:block; }
39
+ .clearfix:after {
40
+ content:'';
41
+ display:block;
42
+ height:0;
43
+ clear:both;
44
+ visibility:hidden;
45
+ }
46
+ .fl { float: left; }
47
+ @media only screen and (max-width:640px) {
48
+ .col3 { width:100%; max-width:100%; }
49
+ .hide-mobile { display:none!important; }
50
+ }
51
+
52
+ .quiet {
53
+ color: #7f7f7f;
54
+ color: rgba(0,0,0,0.5);
55
+ }
56
+ .quiet a { opacity: 0.7; }
57
+
58
+ .fraction {
59
+ font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
60
+ font-size: 10px;
61
+ color: #555;
62
+ background: #E8E8E8;
63
+ padding: 4px 5px;
64
+ border-radius: 3px;
65
+ vertical-align: middle;
66
+ }
67
+
68
+ div.path a:link, div.path a:visited { color: #333; }
69
+ table.coverage {
70
+ border-collapse: collapse;
71
+ margin: 10px 0 0 0;
72
+ padding: 0;
73
+ }
74
+
75
+ table.coverage td {
76
+ margin: 0;
77
+ padding: 0;
78
+ vertical-align: top;
79
+ }
80
+ table.coverage td.line-count {
81
+ text-align: right;
82
+ padding: 0 5px 0 20px;
83
+ }
84
+ table.coverage td.line-coverage {
85
+ text-align: right;
86
+ padding-right: 10px;
87
+ min-width:20px;
88
+ }
89
+
90
+ table.coverage td span.cline-any {
91
+ display: inline-block;
92
+ padding: 0 5px;
93
+ width: 100%;
94
+ }
95
+ .missing-if-branch {
96
+ display: inline-block;
97
+ margin-right: 5px;
98
+ border-radius: 3px;
99
+ position: relative;
100
+ padding: 0 4px;
101
+ background: #333;
102
+ color: yellow;
103
+ }
104
+
105
+ .skip-if-branch {
106
+ display: none;
107
+ margin-right: 10px;
108
+ position: relative;
109
+ padding: 0 4px;
110
+ background: #ccc;
111
+ color: white;
112
+ }
113
+ .missing-if-branch .typ, .skip-if-branch .typ {
114
+ color: inherit !important;
115
+ }
116
+ .coverage-summary {
117
+ border-collapse: collapse;
118
+ width: 100%;
119
+ }
120
+ .coverage-summary tr { border-bottom: 1px solid #bbb; }
121
+ .keyline-all { border: 1px solid #ddd; }
122
+ .coverage-summary td, .coverage-summary th { padding: 10px; }
123
+ .coverage-summary tbody { border: 1px solid #bbb; }
124
+ .coverage-summary td { border-right: 1px solid #bbb; }
125
+ .coverage-summary td:last-child { border-right: none; }
126
+ .coverage-summary th {
127
+ text-align: left;
128
+ font-weight: normal;
129
+ white-space: nowrap;
130
+ }
131
+ .coverage-summary th.file { border-right: none !important; }
132
+ .coverage-summary th.pct { }
133
+ .coverage-summary th.pic,
134
+ .coverage-summary th.abs,
135
+ .coverage-summary td.pct,
136
+ .coverage-summary td.abs { text-align: right; }
137
+ .coverage-summary td.file { white-space: nowrap; }
138
+ .coverage-summary td.pic { min-width: 120px !important; }
139
+ .coverage-summary tfoot td { }
140
+
141
+ .coverage-summary .sorter {
142
+ height: 10px;
143
+ width: 7px;
144
+ display: inline-block;
145
+ margin-left: 0.5em;
146
+ background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
147
+ }
148
+ .coverage-summary .sorted .sorter {
149
+ background-position: 0 -20px;
150
+ }
151
+ .coverage-summary .sorted-desc .sorter {
152
+ background-position: 0 -10px;
153
+ }
154
+ .status-line { height: 10px; }
155
+ /* yellow */
156
+ .cbranch-no { background: yellow !important; color: #111; }
157
+ /* dark red */
158
+ .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
159
+ .low .chart { border:1px solid #C21F39 }
160
+ .highlighted,
161
+ .highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
162
+ background: #C21F39 !important;
163
+ }
164
+ /* medium red */
165
+ .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
166
+ /* light red */
167
+ .low, .cline-no { background:#FCE1E5 }
168
+ /* light green */
169
+ .high, .cline-yes { background:rgb(230,245,208) }
170
+ /* medium green */
171
+ .cstat-yes { background:rgb(161,215,106) }
172
+ /* dark green */
173
+ .status-line.high, .high .cover-fill { background:rgb(77,146,33) }
174
+ .high .chart { border:1px solid rgb(77,146,33) }
175
+ /* dark yellow (gold) */
176
+ .status-line.medium, .medium .cover-fill { background: #f9cd0b; }
177
+ .medium .chart { border:1px solid #f9cd0b; }
178
+ /* light yellow */
179
+ .medium { background: #fff4c2; }
180
+
181
+ .cstat-skip { background: #ddd; color: #111; }
182
+ .fstat-skip { background: #ddd; color: #111 !important; }
183
+ .cbranch-skip { background: #ddd !important; color: #111; }
184
+
185
+ span.cline-neutral { background: #eaeaea; }
186
+
187
+ .coverage-summary td.empty {
188
+ opacity: .5;
189
+ padding-top: 4px;
190
+ padding-bottom: 4px;
191
+ line-height: 1;
192
+ color: #888;
193
+ }
194
+
195
+ .cover-fill, .cover-empty {
196
+ display:inline-block;
197
+ height: 12px;
198
+ }
199
+ .chart {
200
+ line-height: 0;
201
+ }
202
+ .cover-empty {
203
+ background: white;
204
+ }
205
+ .cover-full {
206
+ border-right: none !important;
207
+ }
208
+ pre.prettyprint {
209
+ border: none !important;
210
+ padding: 0 !important;
211
+ margin: 0 !important;
212
+ }
213
+ .com { color: #999 !important; }
214
+ .ignore-none { color: #999; font-weight: normal; }
215
+
216
+ .wrapper {
217
+ min-height: 100%;
218
+ height: auto !important;
219
+ height: 100%;
220
+ margin: 0 auto -48px;
221
+ }
222
+ .footer, .push {
223
+ height: 48px;
224
+ }