client-handover 1.0.5 → 1.1.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.
Potentially problematic release.
This version of client-handover might be problematic. Click here for more details.
- package/README.md +11 -0
- package/cli.js +87 -90
- package/generator.js +289 -104
- package/license.js +3 -2
- package/package.json +5 -8
- package/postinstall.js +63 -32
- package/prompts.js +185 -0
- package/scanner.js +250 -0
- package/credentials.js +0 -50
- package/deploy.js +0 -34
- package/handover.js +0 -96
- package/setup.js +0 -31
package/prompts.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
export function technicalHandoverPrompt(projectInfo, developerInfo) {
|
|
2
|
+
const { name, company, email, phone } = developerInfo
|
|
3
|
+
const date = new Date().toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' })
|
|
4
|
+
|
|
5
|
+
return `
|
|
6
|
+
You are an expert technical writer generating a TECHNICAL HANDOVER DOCUMENT for a developer taking over a client website project.
|
|
7
|
+
|
|
8
|
+
This document is written for a DEVELOPER (future maintainer) — be precise, thorough, and technically complete. They need to be able to pick this project up cold with no prior knowledge.
|
|
9
|
+
|
|
10
|
+
Developer who built this project:
|
|
11
|
+
- Name: ${name || '[Developer Name]'}
|
|
12
|
+
${company ? `- Company: ${company}` : ''}
|
|
13
|
+
- Email: ${email || '[Developer Email]'}
|
|
14
|
+
${phone ? `- Phone: ${phone}` : ''}
|
|
15
|
+
- Handover date: ${date}
|
|
16
|
+
|
|
17
|
+
The following context has been automatically scanned from the project files (package.json, config files, folder structure, environment variable keys, deploy configs, README, CSS colors, etc.). Use this to generate a document specific to THIS project. Do not invent or use generic placeholders — if a specific detail is not in the scanned data, note it as "[to be confirmed]".
|
|
18
|
+
|
|
19
|
+
${projectInfo || '[No project data available]'}
|
|
20
|
+
|
|
21
|
+
Generate a complete technical handover document with ALL of the following sections:
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# [Project Name] — Technical Handover Document
|
|
26
|
+
|
|
27
|
+
**Prepared by:** ${name || '[Developer Name]'}${company ? ` · ${company}` : ''}${email ? ` · ${email}` : ''}${phone ? ` · ${phone}` : ''}
|
|
28
|
+
**Handover Date:** ${date}
|
|
29
|
+
**Project URL:** [Live URL — to be confirmed]
|
|
30
|
+
**Repository:** [Repo URL — to be confirmed]
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 1. Tech Stack
|
|
35
|
+
- List every technology, framework, library, and tool used
|
|
36
|
+
- Include versions where known
|
|
37
|
+
- Briefly explain the role of each in the project
|
|
38
|
+
|
|
39
|
+
## 2. Project Structure
|
|
40
|
+
- Full folder/file structure with explanations of what each directory contains
|
|
41
|
+
- Location of key config files and what they control
|
|
42
|
+
- Entry points and routing overview
|
|
43
|
+
|
|
44
|
+
## 3. Local Development Setup
|
|
45
|
+
- Prerequisites (Node version, package manager, etc.)
|
|
46
|
+
- Step-by-step install and run instructions using exact terminal commands in code blocks
|
|
47
|
+
- All environment variables required (keys only, no values) — what each one does
|
|
48
|
+
|
|
49
|
+
## 4. Build & Deployment
|
|
50
|
+
- Build command and output directory
|
|
51
|
+
- Hosting provider and deployment method
|
|
52
|
+
- CI/CD pipeline if applicable
|
|
53
|
+
- Domain, DNS, and SSL details
|
|
54
|
+
- How to roll back a broken deployment
|
|
55
|
+
|
|
56
|
+
## 5. Third-Party Integrations & Services
|
|
57
|
+
- Every external service, API, or plugin used
|
|
58
|
+
- What each one does and where it is configured
|
|
59
|
+
- Which accounts own these services
|
|
60
|
+
|
|
61
|
+
## 6. Credentials & Access
|
|
62
|
+
- Table of all accounts needed (service, URL, account owner, how to request access)
|
|
63
|
+
- Environment variable names and their purpose
|
|
64
|
+
- Access transfer checklist
|
|
65
|
+
|
|
66
|
+
## 7. Known Issues & Technical Debt
|
|
67
|
+
- Any bugs, limitations, or workarounds in the current codebase
|
|
68
|
+
- TODO items or deferred improvements
|
|
69
|
+
- Performance or SEO considerations
|
|
70
|
+
|
|
71
|
+
## 8. Maintenance Guide
|
|
72
|
+
- How to update npm dependencies safely
|
|
73
|
+
- What to check after deploying changes
|
|
74
|
+
- Renewal dates for domain, hosting, or licences if known
|
|
75
|
+
|
|
76
|
+
## 9. Developer Handover Checklist
|
|
77
|
+
- [ ] Repository access transferred or shared
|
|
78
|
+
- [ ] All environment variables documented
|
|
79
|
+
- [ ] Hosting and domain access transferred
|
|
80
|
+
- [ ] Third-party service accounts handed over
|
|
81
|
+
- [ ] Local dev environment tested and documented
|
|
82
|
+
- [ ] Live site tested across browsers and devices
|
|
83
|
+
- [ ] Analytics verified working
|
|
84
|
+
- [ ] README updated
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
Format the entire document in clean, well-structured Markdown.
|
|
89
|
+
Use code blocks for all terminal commands and code snippets.
|
|
90
|
+
Use tables where appropriate (especially for credentials and dependencies).
|
|
91
|
+
Be thorough and precise — this document is the sole reference for the incoming developer.
|
|
92
|
+
`.trim()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function nonTechnicalHandoverPrompt(projectInfo, developerInfo) {
|
|
96
|
+
const { name, company, email, phone } = developerInfo
|
|
97
|
+
const date = new Date().toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' })
|
|
98
|
+
|
|
99
|
+
return `
|
|
100
|
+
You are an expert writer generating a NON-TECHNICAL HANDOVER DOCUMENT for a CLIENT receiving their completed website.
|
|
101
|
+
|
|
102
|
+
This document is written for the BUSINESS OWNER or CLIENT — use plain English, a warm and reassuring tone, and absolutely no technical jargon. The client should feel confident and informed about what they own.
|
|
103
|
+
|
|
104
|
+
Developer contact details:
|
|
105
|
+
- Name: ${name || '[Developer Name]'}
|
|
106
|
+
${company ? `- Company: ${company}` : ''}
|
|
107
|
+
- Email: ${email || '[Developer Email]'}
|
|
108
|
+
${phone ? `- Phone: ${phone}` : ''}
|
|
109
|
+
- Handover date: ${date}
|
|
110
|
+
|
|
111
|
+
The following context has been automatically scanned from the project files. Use this to generate a document specific to THIS project. Focus on what the client needs to know — not how it was built. If a specific detail is not available, note it as "[to be confirmed]".
|
|
112
|
+
|
|
113
|
+
${projectInfo || '[No project data available]'}
|
|
114
|
+
|
|
115
|
+
Generate a complete non-technical handover document with ALL of the following sections:
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
# [Project Name] — Your Website Handover Guide
|
|
120
|
+
|
|
121
|
+
**Prepared by:** ${name || '[Developer Name]'}${company ? ` · ${company}` : ''}${email ? ` · ${email}` : ''}${phone ? ` · ${phone}` : ''}
|
|
122
|
+
**Date:** ${date}
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 1. About Your Website
|
|
127
|
+
- What your website does and who it is for (1–2 paragraphs, plain English)
|
|
128
|
+
- The main pages or sections and what each one is for
|
|
129
|
+
- Any special features the site has (contact forms, booking, e-commerce, blog, etc.)
|
|
130
|
+
|
|
131
|
+
## 2. Your Website's Look & Feel
|
|
132
|
+
- The overall design style and visual identity
|
|
133
|
+
- Colours used on the site (mention specific colours by name and hex code if detected in the project)
|
|
134
|
+
- Fonts used
|
|
135
|
+
- Any branding guidelines to keep in mind when making future updates
|
|
136
|
+
|
|
137
|
+
## 3. What You Own
|
|
138
|
+
- A plain-English summary of everything handed over: the website, domain, hosting, code, and content
|
|
139
|
+
- Who owns what and what that means for you
|
|
140
|
+
|
|
141
|
+
## 4. Logging Into Your Website
|
|
142
|
+
- How to access and log in to any admin area or CMS (plain steps, no jargon)
|
|
143
|
+
- What you can safely update yourself
|
|
144
|
+
- What you should NOT change without speaking to a developer first
|
|
145
|
+
|
|
146
|
+
## 5. How to Update Your Content
|
|
147
|
+
- Step-by-step instructions for common tasks (e.g. updating text, adding images, publishing a blog post)
|
|
148
|
+
- Keep instructions simple and numbered
|
|
149
|
+
- Include a note about backing up before making changes
|
|
150
|
+
|
|
151
|
+
## 6. Your Accounts & Passwords
|
|
152
|
+
- List of all accounts the client now owns (hosting, domain, CMS, email, analytics, etc.)
|
|
153
|
+
- Reminder to store passwords securely and change them after handover
|
|
154
|
+
- Note: actual passwords should be shared separately and securely — not in this document
|
|
155
|
+
|
|
156
|
+
## 7. Keeping Your Website Healthy
|
|
157
|
+
- What needs renewing and approximately when (domain name, hosting plan, SSL certificate, any paid plugins)
|
|
158
|
+
- How to tell if something on the site is broken
|
|
159
|
+
- Simple monthly and yearly maintenance checklist
|
|
160
|
+
|
|
161
|
+
## 8. Getting Help
|
|
162
|
+
- When and how to contact your developer: ${name || '[Developer Name]'}${company ? ` (${company})` : ''}${email ? `, ${email}` : ''}${phone ? `, ${phone}` : ''}
|
|
163
|
+
- What kinds of changes require a developer
|
|
164
|
+
- Recommended process for requesting future updates
|
|
165
|
+
|
|
166
|
+
## 9. Handover Sign-Off
|
|
167
|
+
### Developer confirms:
|
|
168
|
+
- [ ] All accounts and login details have been transferred
|
|
169
|
+
- [ ] The live site has been reviewed and approved
|
|
170
|
+
- [ ] This document has been discussed with the client
|
|
171
|
+
|
|
172
|
+
### Client acknowledges:
|
|
173
|
+
- [ ] I have received all login credentials securely
|
|
174
|
+
- [ ] I understand how to update my website content
|
|
175
|
+
- [ ] I know what I should not change without developer help
|
|
176
|
+
- [ ] I know how to contact my developer for support
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
Write the entire document in plain, friendly English. Use short sentences and simple words.
|
|
181
|
+
Avoid ALL technical jargon — if a technical term must be used, explain it in brackets immediately after.
|
|
182
|
+
Use numbered lists for any step-by-step instructions.
|
|
183
|
+
The tone should be warm, professional, and reassuring — the client should feel proud of their new website.
|
|
184
|
+
`.trim()
|
|
185
|
+
}
|
package/scanner.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
|
|
4
|
+
const CONFIG_FILES = [
|
|
5
|
+
'vite.config.js', 'vite.config.ts',
|
|
6
|
+
'next.config.js', 'next.config.ts', 'next.config.mjs',
|
|
7
|
+
'nuxt.config.js', 'nuxt.config.ts',
|
|
8
|
+
'astro.config.js', 'astro.config.ts', 'astro.config.mjs',
|
|
9
|
+
'svelte.config.js',
|
|
10
|
+
'remix.config.js',
|
|
11
|
+
'tailwind.config.js', 'tailwind.config.ts',
|
|
12
|
+
'postcss.config.js',
|
|
13
|
+
'netlify.toml',
|
|
14
|
+
'vercel.json',
|
|
15
|
+
'render.yaml',
|
|
16
|
+
'railway.json',
|
|
17
|
+
'.htaccess',
|
|
18
|
+
'Dockerfile',
|
|
19
|
+
'docker-compose.yml',
|
|
20
|
+
'firebase.json',
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
const DEPLOY_WORKFLOW_DIR = '.github/workflows'
|
|
24
|
+
|
|
25
|
+
function readFileSafe(filePath) {
|
|
26
|
+
try {
|
|
27
|
+
return fs.readFileSync(filePath, 'utf-8')
|
|
28
|
+
} catch {
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getEnvKeys(filePath) {
|
|
34
|
+
const content = readFileSafe(filePath)
|
|
35
|
+
if (!content) return []
|
|
36
|
+
return content
|
|
37
|
+
.split('\n')
|
|
38
|
+
.map(l => l.trim())
|
|
39
|
+
.filter(l => l && !l.startsWith('#') && l.includes('='))
|
|
40
|
+
.map(l => l.split('=')[0].trim())
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getFolderStructure(dir, depth = 0, maxDepth = 2) {
|
|
44
|
+
if (depth > maxDepth) return []
|
|
45
|
+
const ignore = new Set(['node_modules', '.git', '.next', '.nuxt', 'dist', 'build', '.cache', 'coverage', '.turbo'])
|
|
46
|
+
let entries = []
|
|
47
|
+
try {
|
|
48
|
+
const items = fs.readdirSync(dir, { withFileTypes: true })
|
|
49
|
+
for (const item of items) {
|
|
50
|
+
if (ignore.has(item.name) || item.name.startsWith('.')) continue
|
|
51
|
+
const indent = ' '.repeat(depth)
|
|
52
|
+
if (item.isDirectory()) {
|
|
53
|
+
entries.push(`${indent}${item.name}/`)
|
|
54
|
+
entries.push(...getFolderStructure(path.join(dir, item.name), depth + 1, maxDepth))
|
|
55
|
+
} else {
|
|
56
|
+
entries.push(`${indent}${item.name}`)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} catch {}
|
|
60
|
+
return entries
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function detectFramework(deps = {}, devDeps = {}) {
|
|
64
|
+
const all = { ...deps, ...devDeps }
|
|
65
|
+
if (all['next']) return 'Next.js'
|
|
66
|
+
if (all['nuxt'] || all['nuxt3']) return 'Nuxt'
|
|
67
|
+
if (all['@astrojs/core'] || all['astro']) return 'Astro'
|
|
68
|
+
if (all['@sveltejs/kit']) return 'SvelteKit'
|
|
69
|
+
if (all['svelte']) return 'Svelte'
|
|
70
|
+
if (all['@remix-run/react']) return 'Remix'
|
|
71
|
+
if (all['gatsby']) return 'Gatsby'
|
|
72
|
+
if (all['react']) return 'React'
|
|
73
|
+
if (all['vue']) return 'Vue'
|
|
74
|
+
if (all['angular']) return 'Angular'
|
|
75
|
+
return null
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function scanProject(dir = process.cwd()) {
|
|
79
|
+
const sections = []
|
|
80
|
+
|
|
81
|
+
// --- package.json ---
|
|
82
|
+
const pkgPath = path.join(dir, 'package.json')
|
|
83
|
+
let pkg = null
|
|
84
|
+
if (fs.existsSync(pkgPath)) {
|
|
85
|
+
try {
|
|
86
|
+
pkg = JSON.parse(readFileSafe(pkgPath))
|
|
87
|
+
const framework = detectFramework(pkg.dependencies, pkg.devDependencies)
|
|
88
|
+
sections.push(`## package.json`)
|
|
89
|
+
sections.push(`Name: ${pkg.name || 'unknown'}`)
|
|
90
|
+
if (pkg.description) sections.push(`Description: ${pkg.description}`)
|
|
91
|
+
if (pkg.version) sections.push(`Version: ${pkg.version}`)
|
|
92
|
+
if (framework) sections.push(`Detected framework: ${framework}`)
|
|
93
|
+
if (pkg.engines?.node) sections.push(`Node requirement: ${pkg.engines.node}`)
|
|
94
|
+
|
|
95
|
+
if (pkg.scripts && Object.keys(pkg.scripts).length) {
|
|
96
|
+
sections.push(`\nScripts:`)
|
|
97
|
+
for (const [k, v] of Object.entries(pkg.scripts)) {
|
|
98
|
+
sections.push(` ${k}: ${v}`)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const deps = Object.keys(pkg.dependencies || {})
|
|
103
|
+
const devDeps = Object.keys(pkg.devDependencies || {})
|
|
104
|
+
if (deps.length) sections.push(`\nDependencies: ${deps.join(', ')}`)
|
|
105
|
+
if (devDeps.length) sections.push(`Dev dependencies: ${devDeps.join(', ')}`)
|
|
106
|
+
} catch {}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// --- Package manager ---
|
|
110
|
+
let pm = 'npm'
|
|
111
|
+
if (fs.existsSync(path.join(dir, 'yarn.lock'))) pm = 'yarn'
|
|
112
|
+
else if (fs.existsSync(path.join(dir, 'pnpm-lock.yaml'))) pm = 'pnpm'
|
|
113
|
+
else if (fs.existsSync(path.join(dir, 'bun.lockb'))) pm = 'bun'
|
|
114
|
+
sections.push(`\nPackage manager: ${pm}`)
|
|
115
|
+
|
|
116
|
+
// --- Environment variables ---
|
|
117
|
+
const envExampleKeys = getEnvKeys(path.join(dir, '.env.example'))
|
|
118
|
+
const envLocalKeys = getEnvKeys(path.join(dir, '.env.local'))
|
|
119
|
+
const envKeys = getEnvKeys(path.join(dir, '.env'))
|
|
120
|
+
const allEnvKeys = [...new Set([...envExampleKeys, ...envLocalKeys, ...envKeys])]
|
|
121
|
+
if (allEnvKeys.length) {
|
|
122
|
+
sections.push(`\n## Environment Variables (keys only)`)
|
|
123
|
+
allEnvKeys.forEach(k => sections.push(` ${k}`))
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// --- Config files ---
|
|
127
|
+
for (const file of CONFIG_FILES) {
|
|
128
|
+
const filePath = path.join(dir, file)
|
|
129
|
+
if (fs.existsSync(filePath)) {
|
|
130
|
+
const content = readFileSafe(filePath)
|
|
131
|
+
if (content && content.length < 4000) {
|
|
132
|
+
sections.push(`\n## ${file}`)
|
|
133
|
+
sections.push('```')
|
|
134
|
+
sections.push(content.trim())
|
|
135
|
+
sections.push('```')
|
|
136
|
+
} else if (content) {
|
|
137
|
+
sections.push(`\n## ${file} (truncated)`)
|
|
138
|
+
sections.push('```')
|
|
139
|
+
sections.push(content.trim().slice(0, 4000) + '\n...')
|
|
140
|
+
sections.push('```')
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// --- GitHub Actions workflows ---
|
|
146
|
+
const workflowDir = path.join(dir, DEPLOY_WORKFLOW_DIR)
|
|
147
|
+
if (fs.existsSync(workflowDir)) {
|
|
148
|
+
try {
|
|
149
|
+
const files = fs.readdirSync(workflowDir).filter(f => f.endsWith('.yml') || f.endsWith('.yaml'))
|
|
150
|
+
for (const file of files) {
|
|
151
|
+
const content = readFileSafe(path.join(workflowDir, file))
|
|
152
|
+
if (content) {
|
|
153
|
+
sections.push(`\n## .github/workflows/${file}`)
|
|
154
|
+
sections.push('```yaml')
|
|
155
|
+
sections.push(content.trim().slice(0, 3000))
|
|
156
|
+
sections.push('```')
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} catch {}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// --- README ---
|
|
163
|
+
const readmePath = path.join(dir, 'README.md')
|
|
164
|
+
if (fs.existsSync(readmePath)) {
|
|
165
|
+
const content = readFileSafe(readmePath)
|
|
166
|
+
if (content) {
|
|
167
|
+
sections.push(`\n## README.md`)
|
|
168
|
+
sections.push(content.trim().slice(0, 3000))
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// --- License ---
|
|
173
|
+
for (const f of ['LICENSE', 'LICENSE.md', 'LICENSE.txt']) {
|
|
174
|
+
const p = path.join(dir, f)
|
|
175
|
+
if (fs.existsSync(p)) {
|
|
176
|
+
const content = readFileSafe(p)
|
|
177
|
+
if (content) {
|
|
178
|
+
sections.push(`\n## ${f}`)
|
|
179
|
+
sections.push(content.trim().slice(0, 500))
|
|
180
|
+
}
|
|
181
|
+
break
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// --- CSS color detection ---
|
|
186
|
+
const cssColors = extractColors(dir)
|
|
187
|
+
if (cssColors.length) {
|
|
188
|
+
sections.push(`\n## Detected colours (from CSS/config files)`)
|
|
189
|
+
cssColors.forEach(c => sections.push(` ${c}`))
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// --- Folder structure ---
|
|
193
|
+
const structure = getFolderStructure(dir)
|
|
194
|
+
if (structure.length) {
|
|
195
|
+
sections.push(`\n## Project folder structure`)
|
|
196
|
+
sections.push(structure.join('\n'))
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return sections.join('\n')
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function extractColors(dir) {
|
|
203
|
+
const colors = new Set()
|
|
204
|
+
const hexPattern = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})\b/g
|
|
205
|
+
const cssVarColorPattern = /(--[\w-]*color[\w-]*|--[\w-]*bg[\w-]*|--[\w-]*primary[\w-]*|--[\w-]*secondary[\w-]*):\s*([^;}\n]+)/gi
|
|
206
|
+
const cssExtensions = ['.css', '.scss', '.sass', '.less']
|
|
207
|
+
|
|
208
|
+
function scanFile(filePath) {
|
|
209
|
+
const content = readFileSafe(filePath)
|
|
210
|
+
if (!content) return
|
|
211
|
+
let match
|
|
212
|
+
while ((match = hexPattern.exec(content)) !== null) {
|
|
213
|
+
colors.add(`#${match[1].toUpperCase()}`)
|
|
214
|
+
}
|
|
215
|
+
while ((match = cssVarColorPattern.exec(content)) !== null) {
|
|
216
|
+
colors.add(`${match[1].trim()}: ${match[2].trim()}`)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function walkDir(d, depth = 0) {
|
|
221
|
+
if (depth > 3) return
|
|
222
|
+
const ignore = new Set(['node_modules', '.git', '.next', '.nuxt', 'dist', 'build', '.cache'])
|
|
223
|
+
try {
|
|
224
|
+
const items = fs.readdirSync(d, { withFileTypes: true })
|
|
225
|
+
for (const item of items) {
|
|
226
|
+
if (ignore.has(item.name) || item.name.startsWith('.')) continue
|
|
227
|
+
const full = path.join(d, item.name)
|
|
228
|
+
if (item.isDirectory()) {
|
|
229
|
+
walkDir(full, depth + 1)
|
|
230
|
+
} else if (cssExtensions.includes(path.extname(item.name).toLowerCase())) {
|
|
231
|
+
scanFile(full)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} catch {}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
walkDir(dir)
|
|
238
|
+
|
|
239
|
+
// Also check tailwind config for color definitions
|
|
240
|
+
for (const twConfig of ['tailwind.config.js', 'tailwind.config.ts']) {
|
|
241
|
+
const content = readFileSafe(path.join(dir, twConfig))
|
|
242
|
+
if (!content) continue
|
|
243
|
+
let match
|
|
244
|
+
while ((match = hexPattern.exec(content)) !== null) {
|
|
245
|
+
colors.add(`#${match[1].toUpperCase()}`)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return [...colors].slice(0, 40) // cap at 40 to avoid flooding context
|
|
250
|
+
}
|
package/credentials.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export function credentials(projectInfo = '') {
|
|
2
|
-
return `
|
|
3
|
-
You are a technical documentation writer creating a CREDENTIALS section for a frontend website handover document.
|
|
4
|
-
|
|
5
|
-
⚠️ IMPORTANT: Never include real passwords, keys, or secrets. All sensitive values must use placeholder format: YOUR_VALUE_HERE or [REPLACE_WITH_ACTUAL_VALUE]
|
|
6
|
-
|
|
7
|
-
Using the following project information:
|
|
8
|
-
${projectInfo || '[No project info provided — use placeholder examples]'}
|
|
9
|
-
|
|
10
|
-
Generate a CREDENTIALS & ACCESS section that includes:
|
|
11
|
-
|
|
12
|
-
## Credentials & Access
|
|
13
|
-
|
|
14
|
-
### For the Client (Plain English)
|
|
15
|
-
- What accounts exist and what each one is for
|
|
16
|
-
- Who currently has admin access
|
|
17
|
-
- How to reset a password if they get locked out
|
|
18
|
-
- Reminder to store credentials in a password manager (suggest 1Password, Bitwarden, etc.)
|
|
19
|
-
- What NOT to share over email
|
|
20
|
-
|
|
21
|
-
### For the Developer (Technical)
|
|
22
|
-
Generate a credentials table template with these categories (use placeholders for all values):
|
|
23
|
-
|
|
24
|
-
| Service | Purpose | URL | Username/Email | Notes |
|
|
25
|
-
|---------|---------|-----|----------------|-------|
|
|
26
|
-
|
|
27
|
-
Include rows for:
|
|
28
|
-
- Hosting provider (e.g. Vercel, Netlify, cPanel)
|
|
29
|
-
- Domain registrar
|
|
30
|
-
- CMS or admin panel (if applicable)
|
|
31
|
-
- Database access (if applicable)
|
|
32
|
-
- Third-party APIs (list each one)
|
|
33
|
-
- Email/SMTP service
|
|
34
|
-
- Analytics (e.g. Google Analytics)
|
|
35
|
-
- Version control (GitHub/GitLab repo URL)
|
|
36
|
-
- Any other relevant service
|
|
37
|
-
|
|
38
|
-
### API Keys & Environment Variables
|
|
39
|
-
List all .env variables used with placeholder values and a description of each.
|
|
40
|
-
|
|
41
|
-
### Access Transfer Checklist
|
|
42
|
-
- [ ] Client has been added as admin to hosting
|
|
43
|
-
- [ ] Client has been added to domain registrar
|
|
44
|
-
- [ ] Developer has been removed or downgraded after handover
|
|
45
|
-
- [ ] 2FA has been set up for client accounts
|
|
46
|
-
- [ ] All credentials have been shared via secure method (not email)
|
|
47
|
-
|
|
48
|
-
Format as clean Markdown with tables.
|
|
49
|
-
`.trim()
|
|
50
|
-
}
|
package/deploy.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
export function deploy(projectInfo = '') {
|
|
2
|
-
return `
|
|
3
|
-
You are a technical documentation writer creating a DEPLOYMENT section for a frontend website handover document.
|
|
4
|
-
|
|
5
|
-
The audience is TWO types of readers:
|
|
6
|
-
1. A NON-TECHNICAL CLIENT — plain English, no jargon
|
|
7
|
-
2. A DEVELOPER — exact technical steps
|
|
8
|
-
|
|
9
|
-
Using the following project information:
|
|
10
|
-
${projectInfo || '[No project info provided — use placeholder examples]'}
|
|
11
|
-
|
|
12
|
-
Generate a DEPLOYMENT section that includes:
|
|
13
|
-
|
|
14
|
-
## Deployment & Hosting
|
|
15
|
-
|
|
16
|
-
### For the Client (Plain English)
|
|
17
|
-
- Where the website is hosted and what that means
|
|
18
|
-
- How updates get published (automatic or manual?)
|
|
19
|
-
- What happens if the site goes down — who to call, what to check
|
|
20
|
-
- Estimated monthly/yearly hosting costs if known
|
|
21
|
-
|
|
22
|
-
### For the Developer (Technical)
|
|
23
|
-
- Hosting provider and account details (use placeholders for sensitive info)
|
|
24
|
-
- Deployment method (e.g. Vercel push-to-deploy, FTP, CI/CD pipeline)
|
|
25
|
-
- Step-by-step deploy process with exact commands
|
|
26
|
-
- Domain/DNS setup and where it's managed
|
|
27
|
-
- SSL certificate info
|
|
28
|
-
- Build command and output directory
|
|
29
|
-
- Any environment-specific configs (staging vs production)
|
|
30
|
-
- Rollback procedure if a deployment fails
|
|
31
|
-
|
|
32
|
-
Format as clean Markdown. Use code blocks for terminal commands.
|
|
33
|
-
`.trim()
|
|
34
|
-
}
|
package/handover.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
export function handover(projectInfo = '') {
|
|
2
|
-
return `
|
|
3
|
-
You are an expert technical writer generating a COMPLETE CLIENT WEBSITE HANDOVER DOCUMENT.
|
|
4
|
-
|
|
5
|
-
This document is for TWO audiences:
|
|
6
|
-
1. NON-TECHNICAL CLIENT — plain English, reassuring tone, no jargon. They need to feel confident owning this site.
|
|
7
|
-
2. DEVELOPER (future maintainer) — precise, technical, complete. They need to be able to pick this up cold.
|
|
8
|
-
|
|
9
|
-
Using the following project information from the developer:
|
|
10
|
-
${projectInfo || '[No project info provided — use placeholder examples throughout]'}
|
|
11
|
-
|
|
12
|
-
Generate a full handover document with ALL of the following sections:
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
# [Project Name] — Website Handover Document
|
|
17
|
-
**Prepared by:** [Developer Name]
|
|
18
|
-
**Handover Date:** [Date]
|
|
19
|
-
**Project URL:** [Live URL]
|
|
20
|
-
**Repository:** [Repo URL]
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## 1. Project Overview
|
|
25
|
-
- What the site does (1 paragraph, plain English)
|
|
26
|
-
- Tech stack summary (with one-line plain English explanation of each)
|
|
27
|
-
- Key contacts (developer, hosting support, etc.)
|
|
28
|
-
|
|
29
|
-
## 2. Project Setup & Dependencies
|
|
30
|
-
*(Follow the dual-audience format: client section + developer section)*
|
|
31
|
-
- Prerequisites, install steps, local dev commands, environment variables
|
|
32
|
-
|
|
33
|
-
## 3. Deployment & Hosting
|
|
34
|
-
*(Dual-audience format)*
|
|
35
|
-
- Hosting provider, deploy method, domain/DNS, SSL, build config, rollback steps
|
|
36
|
-
|
|
37
|
-
## 4. Credentials & Access
|
|
38
|
-
*(Dual-audience format)*
|
|
39
|
-
- All accounts, credentials table with placeholders, .env variables, access transfer checklist
|
|
40
|
-
|
|
41
|
-
## 5. Site Structure & Content Management
|
|
42
|
-
### For the Client
|
|
43
|
-
- How to update content (CMS, direct file edits, or contact developer)
|
|
44
|
-
- What they should NEVER touch without developer help
|
|
45
|
-
- How to add new pages or blog posts (if applicable)
|
|
46
|
-
|
|
47
|
-
### For the Developer
|
|
48
|
-
- Folder structure overview
|
|
49
|
-
- Where key config files live
|
|
50
|
-
- Component/template structure
|
|
51
|
-
- Any custom hooks, stores, or utilities worth knowing about
|
|
52
|
-
|
|
53
|
-
## 6. Maintenance & Updates
|
|
54
|
-
### For the Client
|
|
55
|
-
- What needs renewing and when (domain, hosting, licences)
|
|
56
|
-
- How to know if something is broken
|
|
57
|
-
- Recommended monthly/yearly maintenance tasks
|
|
58
|
-
|
|
59
|
-
### For the Developer
|
|
60
|
-
- How to update npm dependencies safely
|
|
61
|
-
- Any known technical debt or TODO items
|
|
62
|
-
- Performance and SEO considerations
|
|
63
|
-
|
|
64
|
-
## 7. Licensing & Attribution
|
|
65
|
-
*(Dual-audience format)*
|
|
66
|
-
- Ownership summary, third-party licences table, attribution requirements, portfolio rights
|
|
67
|
-
|
|
68
|
-
## 8. Handover Checklist
|
|
69
|
-
A final sign-off checklist for both parties:
|
|
70
|
-
|
|
71
|
-
### Developer Checklist (before handover)
|
|
72
|
-
- [ ] All credentials transferred securely
|
|
73
|
-
- [ ] Client added to hosting & domain accounts
|
|
74
|
-
- [ ] Repository access transferred or shared
|
|
75
|
-
- [ ] Live site tested across browsers and devices
|
|
76
|
-
- [ ] Analytics verified working
|
|
77
|
-
- [ ] All placeholder content replaced
|
|
78
|
-
- [ ] .env.example file committed to repo
|
|
79
|
-
- [ ] README updated
|
|
80
|
-
- [ ] Handover document reviewed with client
|
|
81
|
-
|
|
82
|
-
### Client Acknowledgement
|
|
83
|
-
- [ ] I have received all login credentials
|
|
84
|
-
- [ ] I understand how to update content
|
|
85
|
-
- [ ] I know who to contact for technical support
|
|
86
|
-
- [ ] I have been shown the live site and approve it
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
Format the entire document in clean, well-structured Markdown.
|
|
91
|
-
Use code blocks for all terminal commands.
|
|
92
|
-
Use tables where appropriate.
|
|
93
|
-
Keep client sections warm, clear, and jargon-free.
|
|
94
|
-
Keep developer sections precise and thorough.
|
|
95
|
-
`.trim()
|
|
96
|
-
}
|
package/setup.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export function setup(projectInfo = '') {
|
|
2
|
-
return `
|
|
3
|
-
You are a technical documentation writer creating a SETUP section for a frontend website handover document.
|
|
4
|
-
|
|
5
|
-
The audience is TWO types of readers:
|
|
6
|
-
1. A NON-TECHNICAL CLIENT — who needs plain-English explanations of what everything is and why it matters
|
|
7
|
-
2. A DEVELOPER — who needs exact commands, file paths, and technical detail
|
|
8
|
-
|
|
9
|
-
Using the following project information provided by the developer:
|
|
10
|
-
${projectInfo || '[No project info provided — use placeholder examples]'}
|
|
11
|
-
|
|
12
|
-
Generate a SETUP section that includes:
|
|
13
|
-
|
|
14
|
-
## Project Setup & Dependencies
|
|
15
|
-
|
|
16
|
-
### For the Client (Plain English)
|
|
17
|
-
- What tech stack is used and a simple one-line explanation of each part
|
|
18
|
-
- What they'll need to pay for or maintain (hosting, domain, licences)
|
|
19
|
-
- Who to contact if something breaks
|
|
20
|
-
|
|
21
|
-
### For the Developer (Technical)
|
|
22
|
-
- Prerequisites (Node version, package manager, etc.)
|
|
23
|
-
- Step-by-step install instructions with exact terminal commands
|
|
24
|
-
- Environment variables needed (use placeholder values like YOUR_VALUE_HERE)
|
|
25
|
-
- How to run locally (dev server command, expected URL)
|
|
26
|
-
- Any known gotchas or first-time setup issues
|
|
27
|
-
|
|
28
|
-
Format this as clean, well-structured Markdown with clear headings.
|
|
29
|
-
Keep the client section jargon-free. Keep the developer section precise.
|
|
30
|
-
`.trim()
|
|
31
|
-
}
|