@vfarcic/dot-ai 0.143.0 → 0.145.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/tools/remediate.d.ts.map +1 -1
- package/dist/tools/remediate.js +23 -1
- package/package.json +1 -1
- package/prompts/remediate-system.md +1 -0
- package/scripts/cnpg.nu +14 -0
- package/shared-prompts/generate-dockerfile.md +580 -0
- package/shared-prompts/prd-next.md +19 -1
- package/shared-prompts/prd-update-progress.md +21 -0
- package/dist/tools/platform/discover-operations.tool.d.ts +0 -35
- package/dist/tools/platform/discover-operations.tool.d.ts.map +0 -1
- package/dist/tools/platform/discover-operations.tool.js +0 -88
- package/shared-prompts/tests-reminder.md +0 -40
package/README.md
CHANGED
|
@@ -73,7 +73,10 @@ Generate 25+ governance, legal, and automation files (LICENSE, CODE_OF_CONDUCT,
|
|
|
73
73
|
📖 [Learn more →](./docs/mcp-project-setup-guide.md)
|
|
74
74
|
|
|
75
75
|
### 💬 Shared Prompts Library
|
|
76
|
-
Access curated prompts as native slash commands (`/dot-ai:prompt-name`) in your coding agent for consistent workflows across projects
|
|
76
|
+
Access curated prompts as native slash commands (`/dot-ai:prompt-name`) in your coding agent for consistent workflows across projects:
|
|
77
|
+
- **PRD Management**: Create, track, and complete Product Requirements Documents (`prd-create`, `prd-next`, `prd-done`, etc.)
|
|
78
|
+
- **Dockerfile Generation**: Generate production-ready, secure multi-stage Dockerfiles for any project (`generate-dockerfile`)
|
|
79
|
+
|
|
77
80
|
📖 [Learn more →](./docs/mcp-prompts-guide.md)
|
|
78
81
|
|
|
79
82
|
### ⚡ AI Integration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remediate.d.ts","sourceRoot":"","sources":["../../src/tools/remediate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAC/C,eAAO,MAAM,0BAA0B,yfAAwf,CAAC;AAIhiB,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;CASvC,CAAC;AAGF,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAGD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,MAAM,EAAE,eAAe,GAAG,mBAAmB,GAAG,QAAQ,GAAG,uBAAuB,GAAG,sBAAsB,GAAG,WAAW,CAAC;IAC1H,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;CACtC;AAGD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,oBAAoB,CAAC;CAC5B,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,wBAAwB,CAAC;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IACF,QAAQ,EAAE;QACR,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,WAAW,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,iBAAiB,EAAE,CAAC;QAC7B,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;KACjC,CAAC;IAEF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;CAC/B;AAqJD;;GAEG;AACH,UAAU,uBAAuB;IAC/B,WAAW,EAAE,QAAQ,GAAG,UAAU,GAAG,cAAc,CAAC;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,iBAAiB,EAAE,CAAC;QAC7B,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;KACjC,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,uBAAuB,CAmGhF;
|
|
1
|
+
{"version":3,"file":"remediate.d.ts","sourceRoot":"","sources":["../../src/tools/remediate.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/remediate.js
CHANGED
|
@@ -392,15 +392,37 @@ async function executeRemediationCommands(session, sessionManager, logger, reque
|
|
|
392
392
|
if (overallSuccess && finalAnalysis.validationIntent) {
|
|
393
393
|
const validationIntent = finalAnalysis.validationIntent;
|
|
394
394
|
try {
|
|
395
|
+
// In automatic mode, wait for Kubernetes to apply changes before validating
|
|
396
|
+
// This gives time for deployments to roll out new pods, operators to reconcile, etc.
|
|
397
|
+
// Manual mode skips this delay since the user can verify interactively
|
|
398
|
+
if (session.data.mode === 'automatic') {
|
|
399
|
+
logger.info('Waiting for Kubernetes to apply changes before validation', {
|
|
400
|
+
requestId,
|
|
401
|
+
sessionId: session.sessionId,
|
|
402
|
+
delayMs: 15000
|
|
403
|
+
});
|
|
404
|
+
await new Promise(resolve => setTimeout(resolve, 15000));
|
|
405
|
+
}
|
|
395
406
|
logger.info('Running post-execution validation', {
|
|
396
407
|
requestId,
|
|
397
408
|
sessionId: session.sessionId,
|
|
398
409
|
validationIntent: validationIntent
|
|
399
410
|
});
|
|
400
411
|
// Run validation by calling main function recursively with validation intent
|
|
412
|
+
// Include original issue context so the AI understands what was fixed
|
|
401
413
|
const executedCommands = results.map(r => r.action);
|
|
414
|
+
const validationIssue = `POST-REMEDIATION VALIDATION
|
|
415
|
+
|
|
416
|
+
Original issue that was remediated: ${session.data.issue}
|
|
417
|
+
|
|
418
|
+
Commands that were executed to fix the issue:
|
|
419
|
+
${executedCommands.map((cmd, i) => `${i + 1}. ${cmd}`).join('\n')}
|
|
420
|
+
|
|
421
|
+
Validation task: ${validationIntent}
|
|
422
|
+
|
|
423
|
+
IMPORTANT: You MUST respond with the final JSON analysis format as specified in your instructions. Verify the remediation was successful and return your analysis as JSON with issueStatus set to "resolved" if fixed, or "active" if issues remain.`;
|
|
402
424
|
const validationInput = {
|
|
403
|
-
issue:
|
|
425
|
+
issue: validationIssue,
|
|
404
426
|
executedCommands: executedCommands,
|
|
405
427
|
interaction_id: currentInteractionId || session.data.interaction_id // Use current interaction_id for validation
|
|
406
428
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vfarcic/dot-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.145.1",
|
|
4
4
|
"description": "AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance",
|
|
5
5
|
"mcpName": "io.github.vfarcic/dot-ai",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,6 +19,7 @@ You are an expert Kubernetes troubleshooting agent that investigates issues and
|
|
|
19
19
|
- **Build incrementally**: Each tool call should advance understanding
|
|
20
20
|
- **Think holistically**: Consider relationships between resources
|
|
21
21
|
- **Use cluster resources only**: Never suggest installing new CRDs or operators - work with what's already in the cluster
|
|
22
|
+
- **Respect namespace scope**: If the issue specifies a namespace, focus your investigation and remediation on that namespace. Only expand to other namespaces if you deduce the root cause involves cross-namespace dependencies (e.g., cluster-wide operators, shared services)
|
|
22
23
|
|
|
23
24
|
## Solution Validation Requirement
|
|
24
25
|
|
package/scripts/cnpg.nu
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env nu
|
|
2
|
+
|
|
3
|
+
# Installs Cloud-Native PostgreSQL (CNPG) operator
|
|
4
|
+
def "main apply cnpg" [] {
|
|
5
|
+
|
|
6
|
+
print $"\nInstalling (ansi yellow_bold)Cloud-Native PostgreSQL \(CNPG\)(ansi reset)...\n"
|
|
7
|
+
|
|
8
|
+
(
|
|
9
|
+
helm upgrade --install cnpg cloudnative-pg
|
|
10
|
+
--repo https://cloudnative-pg.github.io/charts
|
|
11
|
+
--namespace cnpg-system --create-namespace --wait
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
}
|
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: generate-dockerfile
|
|
3
|
+
description: Generate production-ready, secure, multi-stage Dockerfile and .dockerignore for any project
|
|
4
|
+
category: development
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Generate Production-Ready Dockerfile
|
|
8
|
+
|
|
9
|
+
Generate an optimized, secure, multi-stage Dockerfile and .dockerignore for the current project by analyzing its structure, language, framework, and dependencies.
|
|
10
|
+
|
|
11
|
+
## Instructions
|
|
12
|
+
|
|
13
|
+
You are helping a developer containerize their application for production deployment. Your task is to analyze the project structure and generate two files:
|
|
14
|
+
|
|
15
|
+
1. **Dockerfile**: Production-ready, multi-stage build with security best practices
|
|
16
|
+
2. **.dockerignore**: Optimized build context configuration
|
|
17
|
+
|
|
18
|
+
## Critical Principles
|
|
19
|
+
|
|
20
|
+
These are non-negotiable rules that override all other guidance.
|
|
21
|
+
|
|
22
|
+
### Verify Everything Before Adding It
|
|
23
|
+
|
|
24
|
+
**ABSOLUTE RULE**: Before adding ANY instruction, configuration, or feature to the Dockerfile, verify it by examining the actual codebase.
|
|
25
|
+
|
|
26
|
+
**Required Process**:
|
|
27
|
+
1. **Identify** what you think should be added
|
|
28
|
+
2. **Search the codebase** to verify it exists or is actually needed
|
|
29
|
+
3. **Only add if verified** - if you can't find evidence in the code, don't add it
|
|
30
|
+
4. **When uncertain, ask the user** - if you cannot deduce something from the codebase analysis, ask the user rather than guessing
|
|
31
|
+
|
|
32
|
+
**Never assume. Always verify. Ask when uncertain. Evidence-based Dockerfiles only.**
|
|
33
|
+
|
|
34
|
+
**Thoroughness over speed**: Shallow analysis leads to broken Dockerfiles. Before generating anything:
|
|
35
|
+
- Read the actual source files, not just file names or directory listings
|
|
36
|
+
- Search for patterns multiple times with different queries if needed
|
|
37
|
+
- Trace the application entry point through its imports and dependencies
|
|
38
|
+
- Don't stop at the first search result - investigate thoroughly
|
|
39
|
+
- If analysis feels quick, you probably missed something
|
|
40
|
+
|
|
41
|
+
A correct Dockerfile that took longer to generate is far better than a fast but broken one. Spend the time upfront.
|
|
42
|
+
|
|
43
|
+
### Multi-Architecture Support
|
|
44
|
+
|
|
45
|
+
**REQUIREMENT**: Ensure all Dockerfile instructions support multiple architectures (amd64, arm64, etc.).
|
|
46
|
+
|
|
47
|
+
**Apply to**:
|
|
48
|
+
- Base image selection: Use multi-arch official images
|
|
49
|
+
- Binary downloads: Detect architecture dynamically, never hardcode (amd64, x86_64, etc.)
|
|
50
|
+
- System package installation: Use package manager (automatically handles architecture)
|
|
51
|
+
- Build commands: Ensure cross-platform compatibility
|
|
52
|
+
|
|
53
|
+
**The Dockerfile must build successfully on different CPU architectures without modification.**
|
|
54
|
+
|
|
55
|
+
### NEVER Add HEALTHCHECK
|
|
56
|
+
|
|
57
|
+
**ABSOLUTE PROHIBITION**: DO NOT add HEALTHCHECK instruction under ANY circumstances.
|
|
58
|
+
|
|
59
|
+
**Why**:
|
|
60
|
+
- Health endpoints are application-specific and cannot be verified from codebase analysis
|
|
61
|
+
- Adding unverified health checks will cause containers to be marked unhealthy incorrectly
|
|
62
|
+
- Users will add their own HEALTHCHECK if their application has health endpoints
|
|
63
|
+
|
|
64
|
+
**If you add HEALTHCHECK, you are violating the "verify everything" principle.**
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Best Practices Reference
|
|
69
|
+
|
|
70
|
+
These are best practices to consider when generating the Dockerfile. **Apply them when relevant to the project** - not every practice applies to every situation:
|
|
71
|
+
|
|
72
|
+
- Package manager flags depend on which package manager is used (apt-get vs apk vs others)
|
|
73
|
+
- Language-specific guidance applies only to that language
|
|
74
|
+
- The "verify everything" principle overrides all: if a practice doesn't fit the project, skip it
|
|
75
|
+
|
|
76
|
+
Use this section as guidance during generation and a reference for validation.
|
|
77
|
+
|
|
78
|
+
### Security
|
|
79
|
+
|
|
80
|
+
| Practice | Description |
|
|
81
|
+
|----------|-------------|
|
|
82
|
+
| **Non-root user** | Create and run as a dedicated user (UID 10001+), never run as root |
|
|
83
|
+
| **Pin image versions** | Use specific tags like `node:20-alpine`, never `:latest` |
|
|
84
|
+
| **Official images** | Prefer Docker Official Images or Verified Publishers from trusted sources |
|
|
85
|
+
| **No secrets in image** | Never embed credentials, API keys, or passwords in Dockerfile or ENV instructions |
|
|
86
|
+
| **No sudo** | Don't use sudo in containers; switch USER explicitly when root access is needed |
|
|
87
|
+
| **Minimal packages** | Only install packages that are actually required for the application |
|
|
88
|
+
| **--no-install-recommends** | Use this flag with apt-get to prevent installing optional packages |
|
|
89
|
+
| **COPY over ADD** | Always use COPY unless you specifically need ADD's tar extraction; never use ADD with URLs |
|
|
90
|
+
| **No debugging tools** | Avoid installing curl, wget, vim, netcat in production images unless required by the application |
|
|
91
|
+
| **Clean in same layer** | Remove package manager caches in the same RUN command as installation |
|
|
92
|
+
| **Executables owned by root** | Application binaries should be owned by root but executed by non-root user |
|
|
93
|
+
|
|
94
|
+
### Image Selection
|
|
95
|
+
|
|
96
|
+
| Practice | Description |
|
|
97
|
+
|----------|-------------|
|
|
98
|
+
| **Minimal base images** | Prefer alpine, slim, distroless, or scratch over full distribution images |
|
|
99
|
+
| **Multi-stage builds** | Always separate build dependencies from runtime; build stage → runtime stage |
|
|
100
|
+
| **Match language needs** | Compiled languages → distroless/scratch; Interpreted → slim/alpine with runtime |
|
|
101
|
+
| **Derive version from project** | Get language version from project files (package.json engines, go.mod, etc.) |
|
|
102
|
+
|
|
103
|
+
### Build Optimization
|
|
104
|
+
|
|
105
|
+
| Practice | Description |
|
|
106
|
+
|----------|-------------|
|
|
107
|
+
| **Layer caching** | Copy dependency manifests (package.json, go.mod) before source code |
|
|
108
|
+
| **Combine RUN commands** | Chain related commands with `&&` to reduce layers and enable cleanup |
|
|
109
|
+
| **Explicit COPY** | Never use `COPY . .`; explicitly copy only required files and directories |
|
|
110
|
+
| **Order by change frequency** | Place stable instructions first (base image, deps) and volatile ones last (source code) |
|
|
111
|
+
| **Production dependencies only** | Install only production dependencies, not devDependencies |
|
|
112
|
+
|
|
113
|
+
### Maintainability
|
|
114
|
+
|
|
115
|
+
| Practice | Description |
|
|
116
|
+
|----------|-------------|
|
|
117
|
+
| **Sort arguments** | Alphabetize multi-line package lists for easier maintenance and review |
|
|
118
|
+
| **Use WORKDIR** | Always use WORKDIR to change directories, never `RUN cd` |
|
|
119
|
+
| **Exec form for CMD** | Use JSON array format: `CMD ["executable", "arg1"]` for proper signal handling |
|
|
120
|
+
| **Comment non-obvious decisions** | Explain why certain choices were made, not what the command does |
|
|
121
|
+
| **OCI labels** (optional) | Add metadata labels for image management (org.opencontainers.image.*) |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Process
|
|
126
|
+
|
|
127
|
+
### Step 0: Check for Existing Dockerfile
|
|
128
|
+
|
|
129
|
+
**Before generating anything, check if the project already has a Dockerfile.**
|
|
130
|
+
|
|
131
|
+
1. Look for `Dockerfile` in the project root (also check for variants like `Dockerfile.prod`)
|
|
132
|
+
2. If found, read and store its contents for Step 2
|
|
133
|
+
3. Similarly, check for `.dockerignore` and read it if present
|
|
134
|
+
|
|
135
|
+
This determines whether Step 2 will generate new files or improve existing ones.
|
|
136
|
+
|
|
137
|
+
### Step 1: Analyze Project Structure
|
|
138
|
+
|
|
139
|
+
**Identify the project characteristics through exploration, not pattern matching.**
|
|
140
|
+
|
|
141
|
+
These are analysis goals, not lookup tables. The examples below are illustrative - apply the same analytical approach to ANY language, framework, or toolchain you encounter.
|
|
142
|
+
|
|
143
|
+
1. **Language Detection**: Explore the project to identify its programming language(s).
|
|
144
|
+
- Look for dependency manifest files (e.g., `package.json`, `go.mod`, `requirements.txt`, `Cargo.toml`, `Gemfile`, `composer.json`, `mix.exs`, `build.sbt`, etc.)
|
|
145
|
+
- Examine source file extensions
|
|
146
|
+
- Read manifest contents to understand the ecosystem
|
|
147
|
+
- **Principle**: Every language has some form of dependency declaration - find it and read it
|
|
148
|
+
|
|
149
|
+
2. **Version Detection**: Find the required language/runtime version.
|
|
150
|
+
- Search manifest files for version constraints or engine requirements
|
|
151
|
+
- Look for version files (e.g., `.node-version`, `.python-version`, `.ruby-version`, `.tool-versions`)
|
|
152
|
+
- Check CI configuration files which often specify versions
|
|
153
|
+
- **If project specifies a version** → use that exact version
|
|
154
|
+
- **If no version specified** → search online for the current LTS/stable version of that language/runtime
|
|
155
|
+
- **Principle**: Use the project's required version if specified, otherwise look up the current recommended version - never guess
|
|
156
|
+
|
|
157
|
+
3. **Framework Detection**: Identify frameworks from dependencies and project structure.
|
|
158
|
+
- Read the dependency list in manifest files
|
|
159
|
+
- Look for framework-specific configuration files
|
|
160
|
+
- Examine the project structure for framework conventions
|
|
161
|
+
- **Principle**: Frameworks leave fingerprints - configuration files, directory structures, dependencies
|
|
162
|
+
|
|
163
|
+
4. **Application Type**: Determine what kind of application this is by examining entry points and configuration.
|
|
164
|
+
- Web server/API: Look for HTTP server setup, route definitions, port binding
|
|
165
|
+
- CLI tool: Look for argument parsing, command definitions, bin entries
|
|
166
|
+
- Worker/background job: Look for queue consumers, scheduled tasks
|
|
167
|
+
- Static site: Look for build output configuration, no server code
|
|
168
|
+
- **Principle**: The entry point and its imports reveal the application's purpose
|
|
169
|
+
|
|
170
|
+
5. **Port Detection**: Search for port configuration in source code and configuration files.
|
|
171
|
+
- Look for environment variable usage (e.g., `PORT`, `HTTP_PORT`)
|
|
172
|
+
- Search for hardcoded port numbers in server initialization
|
|
173
|
+
- Check configuration files for port settings
|
|
174
|
+
- **Only add EXPOSE if you find concrete evidence**
|
|
175
|
+
|
|
176
|
+
6. **Build Requirements**: Identify how the project is built.
|
|
177
|
+
- Read the manifest file for build scripts/commands
|
|
178
|
+
- Identify the build tool (could be language-standard or third-party)
|
|
179
|
+
- Determine build outputs (compiled binaries, transpiled code, bundled assets)
|
|
180
|
+
- **Principle**: Every project that needs building has build instructions - find them
|
|
181
|
+
|
|
182
|
+
7. **System Dependencies**: Critical step - missing runtime binaries cause silent failures.
|
|
183
|
+
- Search the codebase for code that executes external commands or binaries
|
|
184
|
+
- Common patterns: shell execution, subprocess calls, exec functions, system calls
|
|
185
|
+
- For each binary found, verify it's needed at runtime (not just build time)
|
|
186
|
+
- Consider what the application actually does - does it need CLI tools, database clients, image processors?
|
|
187
|
+
- **When uncertain whether something is a runtime dependency, ask the user**
|
|
188
|
+
|
|
189
|
+
8. **Environment Variable Detection**: Critical step - missing env vars cause runtime failures.
|
|
190
|
+
- Search the codebase for environment variable access (every language has a way to read env vars)
|
|
191
|
+
- Look for `.env.example`, `.env.sample`, or similar files that document required variables
|
|
192
|
+
- Check configuration and startup code for env var usage
|
|
193
|
+
- Determine which vars are required (no default, app fails without) vs optional (has default)
|
|
194
|
+
- For required vars, set sensible defaults in the Dockerfile
|
|
195
|
+
- **Principle**: If the code reads an env var, the container probably needs it configured
|
|
196
|
+
|
|
197
|
+
### Step 2: Generate or Improve Dockerfile
|
|
198
|
+
|
|
199
|
+
**If no existing Dockerfile** → Generate a new multi-stage Dockerfile using the patterns below.
|
|
200
|
+
|
|
201
|
+
**If existing Dockerfile found** → Analyze it against the best practices and checklists below, then improve:
|
|
202
|
+
|
|
203
|
+
1. **Evaluate against checklists** - Check each item in the Builder and Runtime checklists
|
|
204
|
+
2. **Identify issues** - Security problems (running as root, :latest tags), missing optimizations (no multi-stage, COPY . .), maintainability issues
|
|
205
|
+
3. **Preserve intentional customizations** - Comments explaining decisions, custom configurations, environment-specific settings
|
|
206
|
+
4. **Edit to fix issues** - Apply best practices while keeping the existing structure where it's already correct
|
|
207
|
+
5. **Explain changes** - When presenting the improved Dockerfile, briefly note what was changed and why
|
|
208
|
+
|
|
209
|
+
Use the patterns and checklists below for both generation and validation.
|
|
210
|
+
|
|
211
|
+
**The examples below show structural patterns, not copy-paste templates.** Adapt the pattern to whatever language, package manager, and build tool the project uses.
|
|
212
|
+
|
|
213
|
+
#### Stage 1: Builder
|
|
214
|
+
|
|
215
|
+
```dockerfile
|
|
216
|
+
# Build stage - use an image with build tools for this language
|
|
217
|
+
FROM <language-image>:<version>-<variant> AS builder
|
|
218
|
+
|
|
219
|
+
WORKDIR /app
|
|
220
|
+
|
|
221
|
+
# PATTERN: Copy dependency manifests FIRST for layer caching
|
|
222
|
+
# Examples: package.json, go.mod, requirements.txt, Gemfile, Cargo.toml, pom.xml
|
|
223
|
+
COPY <dependency-manifest-files> ./
|
|
224
|
+
|
|
225
|
+
# PATTERN: Install dependencies, clean cache in same layer
|
|
226
|
+
# Use whatever package manager the project uses
|
|
227
|
+
RUN <install-dependencies-command> && \
|
|
228
|
+
<clean-cache-command>
|
|
229
|
+
|
|
230
|
+
# PATTERN: Copy only the source files needed for build
|
|
231
|
+
# Never use "COPY . ." - be explicit about what's needed
|
|
232
|
+
COPY <source-directories> ./
|
|
233
|
+
COPY <config-files-needed-for-build> ./
|
|
234
|
+
|
|
235
|
+
# PATTERN: Run the project's build command
|
|
236
|
+
RUN <build-command>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Builder stage checklist**:
|
|
240
|
+
- [ ] Named stage (`AS builder`)
|
|
241
|
+
- [ ] Base image appropriate for the language (with build tools)
|
|
242
|
+
- [ ] Version derived from project files (not assumed)
|
|
243
|
+
- [ ] Dependency manifests copied before source code
|
|
244
|
+
- [ ] Dependencies installed with cache cleanup in same RUN
|
|
245
|
+
- [ ] Only required files copied (never `COPY . .`)
|
|
246
|
+
- [ ] Build command matches what the project actually uses
|
|
247
|
+
|
|
248
|
+
#### Stage 2: Runtime
|
|
249
|
+
|
|
250
|
+
```dockerfile
|
|
251
|
+
# Runtime stage - use minimal image appropriate for the language
|
|
252
|
+
# Compiled languages: consider distroless, scratch, or alpine
|
|
253
|
+
# Interpreted languages: use slim or alpine variant with runtime only
|
|
254
|
+
FROM <minimal-runtime-image>:<version>
|
|
255
|
+
|
|
256
|
+
WORKDIR /app
|
|
257
|
+
|
|
258
|
+
# PATTERN: Create non-root user (syntax varies by base image)
|
|
259
|
+
# Alpine uses addgroup/adduser, Debian uses groupadd/useradd
|
|
260
|
+
RUN <create-group-command> && \
|
|
261
|
+
<create-user-command>
|
|
262
|
+
|
|
263
|
+
# PATTERN: Copy ONLY runtime artifacts from builder
|
|
264
|
+
# What you copy depends on the language:
|
|
265
|
+
# - Compiled: just the binary
|
|
266
|
+
# - Interpreted: built output + runtime dependencies + minimal config
|
|
267
|
+
COPY --from=builder <build-outputs> ./
|
|
268
|
+
COPY --from=builder <runtime-dependencies> ./
|
|
269
|
+
|
|
270
|
+
# PATTERN: Set ownership to non-root user
|
|
271
|
+
RUN chown -R <user>:<group> /app
|
|
272
|
+
|
|
273
|
+
# Switch to non-root user BEFORE exposing ports or setting CMD
|
|
274
|
+
USER <non-root-user>
|
|
275
|
+
|
|
276
|
+
# Only if port was verified during analysis
|
|
277
|
+
EXPOSE <port>
|
|
278
|
+
|
|
279
|
+
# PATTERN: Use exec form for proper signal handling
|
|
280
|
+
# The command depends on how this application runs
|
|
281
|
+
CMD ["<executable>", "<args>"]
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Runtime stage checklist**:
|
|
285
|
+
- [ ] Minimal base image (alpine/slim/distroless/scratch as appropriate)
|
|
286
|
+
- [ ] Non-root user created (UID 10001+)
|
|
287
|
+
- [ ] Only runtime artifacts copied from builder
|
|
288
|
+
- [ ] No source code, tests, build tools, or dev dependencies
|
|
289
|
+
- [ ] Proper ownership set
|
|
290
|
+
- [ ] USER directive before CMD
|
|
291
|
+
- [ ] EXPOSE only if port was verified in analysis
|
|
292
|
+
- [ ] CMD in exec form (JSON array)
|
|
293
|
+
|
|
294
|
+
#### System Package Installation Pattern
|
|
295
|
+
|
|
296
|
+
When system packages are required, use the package manager appropriate for your base image. The principle is always the same: **install only what's needed and clean the cache in the same layer**.
|
|
297
|
+
|
|
298
|
+
Common examples (adapt to your base image's package manager):
|
|
299
|
+
|
|
300
|
+
```dockerfile
|
|
301
|
+
# apt-get (Debian, Ubuntu)
|
|
302
|
+
RUN apt-get update && \
|
|
303
|
+
apt-get install -y --no-install-recommends \
|
|
304
|
+
package1 \
|
|
305
|
+
package2 && \
|
|
306
|
+
rm -rf /var/lib/apt/lists/*
|
|
307
|
+
|
|
308
|
+
# apk (Alpine)
|
|
309
|
+
RUN apk add --no-cache \
|
|
310
|
+
package1 \
|
|
311
|
+
package2
|
|
312
|
+
|
|
313
|
+
# yum/dnf (RHEL, Fedora, CentOS)
|
|
314
|
+
RUN yum install -y \
|
|
315
|
+
package1 \
|
|
316
|
+
package2 && \
|
|
317
|
+
yum clean all && \
|
|
318
|
+
rm -rf /var/cache/yum
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Package installation checklist**:
|
|
322
|
+
- [ ] Used the correct package manager for the base image
|
|
323
|
+
- [ ] Used flags to skip optional/recommended packages where available
|
|
324
|
+
- [ ] Packages sorted alphabetically for maintainability
|
|
325
|
+
- [ ] Cache cleaned in same RUN command
|
|
326
|
+
- [ ] Only packages actually required by the application
|
|
327
|
+
|
|
328
|
+
### Step 3: Create or Improve .dockerignore
|
|
329
|
+
|
|
330
|
+
**If no existing .dockerignore** → Generate a minimal one based on the Dockerfile.
|
|
331
|
+
|
|
332
|
+
**If existing .dockerignore found** → Review it against the Dockerfile's COPY commands:
|
|
333
|
+
1. Remove redundant exclusions (directories not copied by Dockerfile anyway)
|
|
334
|
+
2. Add missing security exclusions (secrets inside copied directories)
|
|
335
|
+
3. Keep it minimal (~10-15 lines)
|
|
336
|
+
|
|
337
|
+
**Generate a MINIMAL .dockerignore file based on the Dockerfile.**
|
|
338
|
+
|
|
339
|
+
Since the Dockerfile uses **explicit COPY commands** (not `COPY . .`), .dockerignore serves a limited purpose:
|
|
340
|
+
|
|
341
|
+
1. **Security** - Exclude secret patterns that could exist INSIDE directories being copied
|
|
342
|
+
2. **Performance** - Exclude large directories that slow down build context transfer
|
|
343
|
+
|
|
344
|
+
#### Process
|
|
345
|
+
|
|
346
|
+
1. Review your Dockerfile's COPY commands - what directories does it copy?
|
|
347
|
+
2. Identify security risks inside those directories (secret files that could accidentally exist)
|
|
348
|
+
3. Identify large directories in the project (>1MB) that slow context transfer
|
|
349
|
+
4. Exclude ONLY those items
|
|
350
|
+
|
|
351
|
+
#### What NOT To Exclude
|
|
352
|
+
|
|
353
|
+
**DO NOT exclude directories that aren't copied by your Dockerfile!**
|
|
354
|
+
|
|
355
|
+
If your Dockerfile doesn't copy a directory, excluding it in .dockerignore is pointless redundancy.
|
|
356
|
+
|
|
357
|
+
#### Target Size
|
|
358
|
+
|
|
359
|
+
**~10-15 lines maximum.** If your .dockerignore exceeds 20 lines, you're likely adding unnecessary exclusions.
|
|
360
|
+
|
|
361
|
+
### Step 4: Build, Test, and Iterate
|
|
362
|
+
|
|
363
|
+
**Purpose**: Verify the Dockerfile works before presenting to user. A Dockerfile isn't done until it's validated.
|
|
364
|
+
|
|
365
|
+
#### 4.1 Build
|
|
366
|
+
|
|
367
|
+
Build the image to verify the Dockerfile syntax and instructions are correct:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
docker build -t [project-name]-validation .
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
- If build succeeds → proceed to run
|
|
374
|
+
- If build fails → analyze the error, fix Dockerfile, retry
|
|
375
|
+
|
|
376
|
+
#### 4.2 Run
|
|
377
|
+
|
|
378
|
+
Start a container to verify the application runs:
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
docker run -d --name [project-name]-test [project-name]-validation
|
|
382
|
+
sleep 5 # Allow startup time
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Check container state:
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
docker inspect --format='{{.State.Status}}' [project-name]-test
|
|
389
|
+
docker inspect --format='{{.State.ExitCode}}' [project-name]-test
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**Expected behavior depends on application type** (determined in Step 1):
|
|
393
|
+
- **Services** (web servers, APIs, workers): Container should still be running
|
|
394
|
+
- **CLI tools / one-shot commands**: Container should have exited with code 0
|
|
395
|
+
|
|
396
|
+
If container crashed or exited unexpectedly → proceed to log analysis to understand why.
|
|
397
|
+
|
|
398
|
+
#### 4.3 Log Analysis
|
|
399
|
+
|
|
400
|
+
Capture and analyze container logs:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
docker logs [project-name]-test 2>&1
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**Analyze logs using your knowledge of the project from Step 1.** You know:
|
|
407
|
+
- What language and framework this is
|
|
408
|
+
- What the application is supposed to do
|
|
409
|
+
- What dependencies it requires
|
|
410
|
+
- What a successful startup looks like for this type of application
|
|
411
|
+
|
|
412
|
+
Use this context to determine if the logs indicate:
|
|
413
|
+
- The application started correctly, OR
|
|
414
|
+
- Something is wrong (errors, crashes, missing dependencies, permission issues, etc.)
|
|
415
|
+
|
|
416
|
+
If logs indicate a problem → identify root cause, fix Dockerfile or .dockerignore, retry.
|
|
417
|
+
|
|
418
|
+
#### 4.4 Linting (if available)
|
|
419
|
+
|
|
420
|
+
If `hadolint` is installed, run it to catch Dockerfile best practice issues:
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
hadolint Dockerfile
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
- If hadolint is not installed → skip this check
|
|
427
|
+
- If hadolint reports issues → evaluate each issue, fix if appropriate, retry
|
|
428
|
+
- Some hadolint warnings may be intentional (use judgment based on project context)
|
|
429
|
+
|
|
430
|
+
#### 4.5 Security Scan (if available)
|
|
431
|
+
|
|
432
|
+
If `trivy` is installed, scan the built image for vulnerabilities:
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
trivy image --severity HIGH,CRITICAL [project-name]-validation
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
- If trivy is not installed → skip this check
|
|
439
|
+
- If trivy reports HIGH/CRITICAL vulnerabilities in the base image → consider if a different base image version or variant would help
|
|
440
|
+
- If vulnerabilities are in application dependencies → note them for the user but don't block (dependency updates are outside Dockerfile scope)
|
|
441
|
+
|
|
442
|
+
#### 4.6 Iterate
|
|
443
|
+
|
|
444
|
+
If any validation step fails:
|
|
445
|
+
|
|
446
|
+
1. **Analyze** the specific error message or behavior
|
|
447
|
+
2. **Identify root cause** - common issues include:
|
|
448
|
+
- Missing file → incorrect COPY command or overly aggressive .dockerignore
|
|
449
|
+
- Missing dependency → system package not installed
|
|
450
|
+
- Permission denied → ownership or USER directive issue
|
|
451
|
+
- Module not found → build step incomplete or wrong files copied
|
|
452
|
+
- Hadolint warning → Dockerfile best practice issue
|
|
453
|
+
3. **Fix** the appropriate file (Dockerfile or .dockerignore)
|
|
454
|
+
4. **Retry** from step 4.1
|
|
455
|
+
|
|
456
|
+
**Maximum 5 iterations.** If still failing after 5 attempts:
|
|
457
|
+
- Stop and present current state to user
|
|
458
|
+
- Explain what's failing and what fixes were attempted
|
|
459
|
+
- Ask for guidance
|
|
460
|
+
|
|
461
|
+
#### 4.7 Cleanup
|
|
462
|
+
|
|
463
|
+
**Always clean up after validation**, whether successful or not:
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
docker stop [project-name]-test 2>/dev/null || true
|
|
467
|
+
docker rm [project-name]-test 2>/dev/null || true
|
|
468
|
+
docker rmi [project-name]-validation 2>/dev/null || true
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
Only proceed to present the Dockerfile to user after:
|
|
472
|
+
- All validation steps pass, AND
|
|
473
|
+
- Cleanup is complete
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## Output Format
|
|
478
|
+
|
|
479
|
+
### For New Dockerfiles (no existing file)
|
|
480
|
+
|
|
481
|
+
**Present both files to the user:**
|
|
482
|
+
|
|
483
|
+
1. **Dockerfile** with clear comments explaining each section
|
|
484
|
+
2. **.dockerignore** with organized sections
|
|
485
|
+
|
|
486
|
+
**After generating, provide:**
|
|
487
|
+
- Brief explanation of design choices (base images, build stages, security measures)
|
|
488
|
+
- Build command: `docker build -t [project-name] .`
|
|
489
|
+
- Run command: `docker run -p [port]:[port] [project-name]`
|
|
490
|
+
- Image size expectations
|
|
491
|
+
|
|
492
|
+
### For Improved Dockerfiles (existing file found)
|
|
493
|
+
|
|
494
|
+
**Present the improved files with a summary of changes:**
|
|
495
|
+
|
|
496
|
+
1. **Dockerfile** - the improved version
|
|
497
|
+
2. **Changes made** - brief list of what was changed and why:
|
|
498
|
+
- Security fixes (e.g., "Added non-root user - was running as root")
|
|
499
|
+
- Optimization improvements (e.g., "Added multi-stage build to reduce image size")
|
|
500
|
+
- Best practice updates (e.g., "Changed CMD to exec form for signal handling")
|
|
501
|
+
3. **Preserved** - note any intentional customizations that were kept
|
|
502
|
+
4. **.dockerignore** - improved version if changes were needed
|
|
503
|
+
|
|
504
|
+
### For Both Cases
|
|
505
|
+
|
|
506
|
+
**Recommended next steps** (the Dockerfile has already been validated):
|
|
507
|
+
- Integrate into CI/CD pipeline
|
|
508
|
+
- Commit to version control
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## Success Criteria
|
|
513
|
+
|
|
514
|
+
### Dockerfile Checklist
|
|
515
|
+
|
|
516
|
+
- [ ] Builds successfully without errors
|
|
517
|
+
- [ ] Uses multi-stage build (builder → runtime)
|
|
518
|
+
- [ ] Runs as non-root user (UID 10001+)
|
|
519
|
+
- [ ] Uses pinned version tags (no `:latest`)
|
|
520
|
+
- [ ] Uses minimal base images (alpine/slim/distroless)
|
|
521
|
+
- [ ] Copies dependency manifests before source (layer caching)
|
|
522
|
+
- [ ] Uses explicit COPY (no `COPY . .`)
|
|
523
|
+
- [ ] Combines RUN commands with `&&`
|
|
524
|
+
- [ ] Cleans package manager caches in same layer
|
|
525
|
+
- [ ] Uses `--no-install-recommends` (if apt-get used)
|
|
526
|
+
- [ ] Uses exec form for CMD (`["executable", "arg"]`)
|
|
527
|
+
- [ ] No debugging tools unless required
|
|
528
|
+
- [ ] No secrets or credentials embedded
|
|
529
|
+
|
|
530
|
+
### .dockerignore Checklist
|
|
531
|
+
|
|
532
|
+
- [ ] Minimal size (~10-15 lines)
|
|
533
|
+
- [ ] Excludes secrets inside copied directories
|
|
534
|
+
- [ ] Excludes large unnecessary directories
|
|
535
|
+
- [ ] Does NOT exclude directories not copied by Dockerfile
|
|
536
|
+
|
|
537
|
+
### Validation Checklist (Step 4)
|
|
538
|
+
|
|
539
|
+
- [ ] Image builds successfully
|
|
540
|
+
- [ ] Container starts without crashing
|
|
541
|
+
- [ ] Logs show no errors indicating application failure
|
|
542
|
+
- [ ] Hadolint passes (if installed)
|
|
543
|
+
- [ ] Trivy shows no critical base image vulnerabilities (if installed)
|
|
544
|
+
- [ ] Test container and image cleaned up
|
|
545
|
+
|
|
546
|
+
**Do not present Dockerfile to user until all validation checks pass.**
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## Example Workflows
|
|
551
|
+
|
|
552
|
+
### New Dockerfile (no existing file)
|
|
553
|
+
|
|
554
|
+
1. **Check**: "No existing Dockerfile found. Will generate new one."
|
|
555
|
+
2. **Explore**: "Let me find the dependency manifest... found `<manifest-file>`. Reading it to understand the ecosystem."
|
|
556
|
+
3. **Identify**: "This is a `<language>` project using `<framework/tool>`. The manifest indicates version `<X>`."
|
|
557
|
+
4. **Trace**: "The entry point is `<file>`. Following imports to understand runtime needs."
|
|
558
|
+
5. **Structure**: "Multi-stage build: builder stage needs `<build-tools>`, runtime stage needs only `<runtime-artifacts>`."
|
|
559
|
+
6. **Dependencies**: "Searching for external binary usage... found `<binary>`. This needs to be in the runtime image."
|
|
560
|
+
7. **Generate**: "Create Dockerfile and .dockerignore. Check against best practices checklists."
|
|
561
|
+
8. **Build & Test**: "Building image... Running container... Checking logs..."
|
|
562
|
+
9. **Iterate** (if needed): "Build failed due to missing package. Adding to Dockerfile and retrying..."
|
|
563
|
+
10. **Cleanup & Present**: "Validation passed. Removing test artifacts. Here's your Dockerfile."
|
|
564
|
+
|
|
565
|
+
### Improving Existing Dockerfile
|
|
566
|
+
|
|
567
|
+
1. **Check**: "Found existing Dockerfile. Reading it to analyze..."
|
|
568
|
+
2. **Analyze project**: Same exploration as above to understand what the Dockerfile should do.
|
|
569
|
+
3. **Evaluate**: "Checking existing Dockerfile against best practices checklists..."
|
|
570
|
+
- "❌ Running as root - no USER directive"
|
|
571
|
+
- "❌ Using :latest tag instead of pinned version"
|
|
572
|
+
- "✅ Multi-stage build already in place"
|
|
573
|
+
- "✅ Dependency manifests copied first"
|
|
574
|
+
4. **Preserve**: "Keeping custom ENV variables and the specific port configuration - these appear intentional."
|
|
575
|
+
5. **Improve**: "Adding non-root user, pinning image version to match project requirements."
|
|
576
|
+
6. **Build & Test**: "Building improved image... Running container... Checking logs..."
|
|
577
|
+
7. **Iterate** (if needed): "Container crashed - logs show permission error. Fixing ownership and retrying..."
|
|
578
|
+
8. **Cleanup & Present**: "Validation passed. Removing test artifacts. Here are the improvements."
|
|
579
|
+
|
|
580
|
+
**Key mindset**: Investigate the actual project rather than matching against templates. Every project is unique. Don't present until validated.
|
|
@@ -18,6 +18,8 @@ You are helping analyze an existing Product Requirements Document (PRD) to sugge
|
|
|
18
18
|
4. **Identify the Single Best Next Task** - Find the one task that should be worked on next
|
|
19
19
|
5. **Present Recommendation** - Give clear rationale and wait for confirmation
|
|
20
20
|
6. **Design Discussion** - If confirmed, dive into implementation design details
|
|
21
|
+
7. **Implementation** - User implements the task
|
|
22
|
+
8. **Update Progress** - Prompt user to run /prd-update-progress
|
|
21
23
|
|
|
22
24
|
## Step 0: Context Awareness Check
|
|
23
25
|
|
|
@@ -242,4 +244,20 @@ This command should:
|
|
|
242
244
|
- ✅ Wait for user confirmation before proceeding
|
|
243
245
|
- ✅ If confirmed, provide detailed implementation design guidance
|
|
244
246
|
- ✅ Keep teams focused on the most important work rather than overwhelming them with options
|
|
245
|
-
- ✅ Enable immediate action by transitioning from recommendation to design discussion
|
|
247
|
+
- ✅ Enable immediate action by transitioning from recommendation to design discussion
|
|
248
|
+
|
|
249
|
+
## Step 8: Update Progress After Completion
|
|
250
|
+
|
|
251
|
+
After the user completes the task implementation, prompt them to update PRD progress:
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
**Task implementation complete.**
|
|
256
|
+
|
|
257
|
+
To update PRD progress and commit your work, run the `prd-update-progress` prompt.
|
|
258
|
+
|
|
259
|
+
*Note: Different agents/clients may have different syntax for executing commands and prompts (e.g., `/prd-update-progress` in Claude Code, or other syntax in different MCP clients).*
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
This ensures a smooth workflow from task selection → implementation → progress tracking → next task.
|
|
@@ -20,6 +20,7 @@ You are helping update an existing Product Requirements Document (PRD) based on
|
|
|
20
20
|
6. **Update PRD** - Apply changes and add work log entry
|
|
21
21
|
7. **Flag Divergences** - Alert when actual work differs from planned work
|
|
22
22
|
8. **Commit Progress Updates** - Preserve progress checkpoint
|
|
23
|
+
9. **Continue to Next Task** - Prompt user to run /prd-next
|
|
23
24
|
|
|
24
25
|
## Step 1: Smart PRD Identification
|
|
25
26
|
|
|
@@ -310,3 +311,23 @@ Progress: X% complete - [next major milestone]"
|
|
|
310
311
|
- **Evidence-based**: Only commit when there's actual implementation progress
|
|
311
312
|
|
|
312
313
|
**Note**: Do NOT push commits unless explicitly requested by the user. Commits preserve local progress checkpoints without affecting remote branches.
|
|
314
|
+
|
|
315
|
+
## Step 9: Continue to Next Task
|
|
316
|
+
|
|
317
|
+
After completing the PRD update and committing changes, prompt the user to continue working:
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
**PRD progress updated and committed.**
|
|
322
|
+
|
|
323
|
+
**Recommended**: Clear the context before starting the next task to ensure a fresh start without clutter from the previous work session.
|
|
324
|
+
|
|
325
|
+
To continue working on the next task:
|
|
326
|
+
1. Clear/reset the conversation context
|
|
327
|
+
2. Run the `prd-next` prompt to get the next task recommendation
|
|
328
|
+
|
|
329
|
+
*Note: Different agents/clients may have different syntax for executing commands and prompts (e.g., `/clear`, `/prd-next` in Claude Code, or other syntax in different MCP clients).*
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
This ensures a smooth workflow from completing work → updating progress → fresh context → starting the next task.
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Discover Operations Tool
|
|
3
|
-
*
|
|
4
|
-
* Self-contained tool that fetches raw Nu shell script help output.
|
|
5
|
-
* Returns unprocessed data for AI to parse.
|
|
6
|
-
*/
|
|
7
|
-
import { AITool, AIProvider } from '../../core/ai-provider.interface';
|
|
8
|
-
import { Logger } from '../../core/error-handling';
|
|
9
|
-
/**
|
|
10
|
-
* Operation interfaces (re-export for tool consumers)
|
|
11
|
-
*/
|
|
12
|
-
export interface OperationCommand {
|
|
13
|
-
name: string;
|
|
14
|
-
command: string[];
|
|
15
|
-
}
|
|
16
|
-
export interface Operation {
|
|
17
|
-
name: string;
|
|
18
|
-
description: string;
|
|
19
|
-
operations: OperationCommand[];
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Tool schema for getting Nu script help output
|
|
23
|
-
*/
|
|
24
|
-
export declare const discoverOperationsTool: AITool;
|
|
25
|
-
/**
|
|
26
|
-
* Execute get_nu_help_output tool
|
|
27
|
-
*
|
|
28
|
-
* Simple data fetcher - returns raw Nu script help output
|
|
29
|
-
*/
|
|
30
|
-
export declare function executeDiscoverOperations(input: any, aiProvider: AIProvider, logger: Logger): Promise<{
|
|
31
|
-
success: boolean;
|
|
32
|
-
helpOutput?: string;
|
|
33
|
-
error?: string;
|
|
34
|
-
}>;
|
|
35
|
-
//# sourceMappingURL=discover-operations.tool.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"discover-operations.tool.d.ts","sourceRoot":"","sources":["../../../src/tools/platform/discover-operations.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAGnD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAUpC,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,GAAG,EACV,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAyBpE"}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Discover Operations Tool
|
|
4
|
-
*
|
|
5
|
-
* Self-contained tool that fetches raw Nu shell script help output.
|
|
6
|
-
* Returns unprocessed data for AI to parse.
|
|
7
|
-
*/
|
|
8
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
-
if (k2 === undefined) k2 = k;
|
|
10
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
-
}
|
|
14
|
-
Object.defineProperty(o, k2, desc);
|
|
15
|
-
}) : (function(o, m, k, k2) {
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
o[k2] = m[k];
|
|
18
|
-
}));
|
|
19
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
-
}) : function(o, v) {
|
|
22
|
-
o["default"] = v;
|
|
23
|
-
});
|
|
24
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
-
var ownKeys = function(o) {
|
|
26
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
-
var ar = [];
|
|
28
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
-
return ar;
|
|
30
|
-
};
|
|
31
|
-
return ownKeys(o);
|
|
32
|
-
};
|
|
33
|
-
return function (mod) {
|
|
34
|
-
if (mod && mod.__esModule) return mod;
|
|
35
|
-
var result = {};
|
|
36
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
-
__setModuleDefault(result, mod);
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
})();
|
|
41
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.discoverOperationsTool = void 0;
|
|
43
|
-
exports.executeDiscoverOperations = executeDiscoverOperations;
|
|
44
|
-
const path = __importStar(require("path"));
|
|
45
|
-
const platform_utils_1 = require("../../core/platform-utils");
|
|
46
|
-
/**
|
|
47
|
-
* Tool schema for getting Nu script help output
|
|
48
|
-
*/
|
|
49
|
-
exports.discoverOperationsTool = {
|
|
50
|
-
name: "get_nu_help_output",
|
|
51
|
-
description: `Executes 'nu ./dot.nu --help' and returns the raw help output text.
|
|
52
|
-
|
|
53
|
-
Returns the complete help documentation that lists all available platform
|
|
54
|
-
operations with their commands and descriptions.`,
|
|
55
|
-
inputSchema: {
|
|
56
|
-
type: "object",
|
|
57
|
-
properties: {} // No input needed
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* Execute get_nu_help_output tool
|
|
62
|
-
*
|
|
63
|
-
* Simple data fetcher - returns raw Nu script help output
|
|
64
|
-
*/
|
|
65
|
-
async function executeDiscoverOperations(input, aiProvider, logger) {
|
|
66
|
-
try {
|
|
67
|
-
// Execute Nu script help command
|
|
68
|
-
const scriptPath = path.join((0, platform_utils_1.getScriptsDir)(), 'dot.nu');
|
|
69
|
-
const { stdout, stderr } = await (0, platform_utils_1.execAsync)(`nu "${scriptPath}" --help`);
|
|
70
|
-
if (stderr) {
|
|
71
|
-
logger.warn?.('Nu script help command produced stderr', { stderr });
|
|
72
|
-
}
|
|
73
|
-
logger.info?.('Tool fetched Nu help output', {
|
|
74
|
-
length: stdout.length
|
|
75
|
-
});
|
|
76
|
-
return {
|
|
77
|
-
success: true,
|
|
78
|
-
helpOutput: stdout
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
logger.error?.('Tool failed to get Nu help output', error);
|
|
83
|
-
return {
|
|
84
|
-
success: false,
|
|
85
|
-
error: error instanceof Error ? error.message : String(error)
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: tests-reminder
|
|
3
|
-
description: Remind about testing requirements when making code changes
|
|
4
|
-
category: development
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Testing Requirements Reminder
|
|
8
|
-
|
|
9
|
-
⚠️ **MANDATORY TESTING CHECKLIST** ⚠️
|
|
10
|
-
|
|
11
|
-
Before marking any task or implementation as complete, you MUST:
|
|
12
|
-
|
|
13
|
-
## 1. Write Tests
|
|
14
|
-
- [ ] Unit tests for new functions/methods
|
|
15
|
-
- [ ] Integration tests for new features
|
|
16
|
-
- [ ] End-to-end tests for user workflows
|
|
17
|
-
- [ ] Error handling tests for edge cases
|
|
18
|
-
|
|
19
|
-
## 2. Run All Tests
|
|
20
|
-
```bash
|
|
21
|
-
npm test
|
|
22
|
-
```
|
|
23
|
-
**ALL tests must pass** - no exceptions.
|
|
24
|
-
|
|
25
|
-
## 3. Test Coverage
|
|
26
|
-
- [ ] New code has appropriate test coverage
|
|
27
|
-
- [ ] Tests validate the actual functionality
|
|
28
|
-
- [ ] Tests cover both success and failure scenarios
|
|
29
|
-
|
|
30
|
-
## 4. Update CLAUDE.md
|
|
31
|
-
- [ ] Update project instructions if new patterns/standards introduced
|
|
32
|
-
- [ ] Document any new testing approaches or requirements
|
|
33
|
-
|
|
34
|
-
## ❌ TASK IS NOT COMPLETE IF:
|
|
35
|
-
- Any tests are failing
|
|
36
|
-
- New code lacks test coverage
|
|
37
|
-
- You haven't run `npm test` to verify
|
|
38
|
-
- Tests don't actually validate the intended functionality
|
|
39
|
-
|
|
40
|
-
**Remember: Code without tests is not production-ready code.**
|