prizmkit 1.1.78 → 1.1.79
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/bundled/VERSION.json +3 -3
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills-windows/prizm-kit/SKILL.md +81 -0
- package/bundled/skills-windows/prizmkit-code-review/SKILL.md +225 -0
- package/bundled/skills-windows/prizmkit-committer/SKILL.md +81 -0
- package/bundled/skills-windows/prizmkit-deploy/SKILL.md +468 -0
- package/bundled/skills-windows/prizmkit-deploy/references/ci-cd-workflows.md +115 -0
- package/bundled/skills-windows/prizmkit-deploy/references/cloud-platform-deploy.md +93 -0
- package/bundled/skills-windows/prizmkit-deploy/references/database-setup.md +46 -0
- package/bundled/skills-windows/prizmkit-deploy/references/deploy-config-schema.md +148 -0
- package/bundled/skills-windows/prizmkit-deploy/references/deploy-history-schema.md +62 -0
- package/bundled/skills-windows/prizmkit-deploy/references/deployment-modes.md +50 -0
- package/bundled/skills-windows/prizmkit-deploy/references/direct-upload.md +26 -0
- package/bundled/skills-windows/prizmkit-deploy/references/dns-setup.md +42 -0
- package/bundled/skills-windows/prizmkit-deploy/references/docker-deploy.md +31 -0
- package/bundled/skills-windows/prizmkit-deploy/references/firewall-setup.md +37 -0
- package/bundled/skills-windows/prizmkit-deploy/references/live-validation-notes.md +21 -0
- package/bundled/skills-windows/prizmkit-deploy/references/nginx-blue-green.md +59 -0
- package/bundled/skills-windows/prizmkit-deploy/references/ssl-setup.md +56 -0
- package/bundled/skills-windows/prizmkit-implement/SKILL.md +65 -0
- package/bundled/skills-windows/prizmkit-plan/SKILL.md +184 -0
- package/bundled/skills-windows/prizmkit-plan/assets/plan-template.md +115 -0
- package/bundled/skills-windows/prizmkit-plan/assets/spec-template.md +73 -0
- package/bundled/skills-windows/prizmkit-plan/references/clarify-guide.md +67 -0
- package/bundled/skills-windows/prizmkit-plan/references/verification-checklist.md +60 -0
- package/bundled/skills-windows/prizmkit-prizm-docs/SKILL.md +115 -0
- package/bundled/skills-windows/prizmkit-prizm-docs/assets/prizm-docs-format.md +613 -0
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-init.md +45 -0
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-rebuild.md +15 -0
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-status.md +14 -0
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-update.md +19 -0
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-validate.md +17 -0
- package/bundled/skills-windows/prizmkit-retrospective/SKILL.md +87 -0
- package/bundled/skills-windows/prizmkit-retrospective/references/knowledge-injection-steps.md +50 -0
- package/bundled/skills-windows/prizmkit-retrospective/references/structural-sync-steps.md +43 -0
- package/bundled/skills-windows/prizmkit-test/SKILL.md +281 -0
- package/package.json +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Database Setup
|
|
2
|
+
|
|
3
|
+
Read this file when Discovery detected a database driver and the user wants AI-assisted database installation on the server.
|
|
4
|
+
|
|
5
|
+
## Entry condition
|
|
6
|
+
|
|
7
|
+
During Discovery Step 1 (Project Detection), database drivers were already scanned. If a driver was detected, ask after bootstrap tools are installed:
|
|
8
|
+
|
|
9
|
+
> "检测到项目使用了 <PostgreSQL/MySQL/Redis>,需要帮你在服务器上安装配置吗?"
|
|
10
|
+
> - **需要** → 继续数据库安装
|
|
11
|
+
> - **不需要** → 跳过,记录到 deploy.md,标注"数据库需用户自行配置"
|
|
12
|
+
|
|
13
|
+
## PostgreSQL setup
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
apt-get install -y postgresql postgresql-contrib
|
|
17
|
+
sudo -u postgres psql -c "CREATE DATABASE <project>;"
|
|
18
|
+
sudo -u postgres psql -c "CREATE USER <project> WITH PASSWORD '<random-password>';"
|
|
19
|
+
sudo -u postgres psql -c "GRANT ALL ON DATABASE <project> TO <project>;"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- Generate a secure random password (32 chars, alphanumeric + symbols).
|
|
23
|
+
- Write the connection string to `.prizmkit/deploy/secrets.local.json`: `DATABASE_URL=postgresql://<project>:<password>@localhost:5432/<project>`.
|
|
24
|
+
- In deploy.md, write: "PostgreSQL 已安装,连接信息已记录到 `.prizmkit/deploy/secrets.local.json`(不提交到 git)".
|
|
25
|
+
|
|
26
|
+
## MySQL setup (future)
|
|
27
|
+
|
|
28
|
+
Similar flow. Not implemented in first version — if project uses MySQL, direct user to documentation fallback.
|
|
29
|
+
|
|
30
|
+
## Redis setup
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
apt-get install -y redis-server
|
|
34
|
+
redis-cli CONFIG SET requirepass "<random-password>"
|
|
35
|
+
redis-cli CONFIG REWRITE
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- Bind to localhost only (modify `/etc/redis/redis.conf` if needed).
|
|
39
|
+
- Write `REDIS_URL=redis://:<password>@localhost:6379` to `.prizmkit/deploy/secrets.local.json`.
|
|
40
|
+
|
|
41
|
+
## Security notes
|
|
42
|
+
|
|
43
|
+
- Never write database passwords to deploy.md, because deploy.md may be committed to git and passwords would leak.
|
|
44
|
+
- Passwords stored in `.prizmkit/deploy/secrets.local.json` (gitignored).
|
|
45
|
+
- Default: database binds to localhost, no external access, because most indie projects only need local connections.
|
|
46
|
+
- Record a `"database-setup"` event in deploy history (presence metadata only, no passwords).
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# deploy.config.json Schema
|
|
2
|
+
|
|
3
|
+
This file is the machine-readable deployment configuration. Always read it before executing any deploy operation.
|
|
4
|
+
|
|
5
|
+
## Top-Level Structure
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"version": 1,
|
|
10
|
+
"project": "project-name",
|
|
11
|
+
"deploymentMode": "ssh",
|
|
12
|
+
"deployStrategy": "direct-upload|ci-cd-push|ci-cd-pull",
|
|
13
|
+
"defaults": { ... },
|
|
14
|
+
"environments": { ... },
|
|
15
|
+
"servers": [ ... ],
|
|
16
|
+
"repository": { ... },
|
|
17
|
+
"apps": [ ... ],
|
|
18
|
+
"nginx": { ... },
|
|
19
|
+
"env": { ... }
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## defaults
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"releaseRetention": 5,
|
|
28
|
+
"credentialMode": "ai-assisted|user-managed",
|
|
29
|
+
"secretStorage": "ask-every-time|encrypted-local|plaintext-local|user-managed-on-server-only",
|
|
30
|
+
"rollbackOnFailure": true,
|
|
31
|
+
"headlessDefaultEnvironment": "test"
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## environments
|
|
36
|
+
|
|
37
|
+
Keyed by environment name. Each entry:
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"dev": {
|
|
41
|
+
"server": "server-id",
|
|
42
|
+
"allowHeadless": true,
|
|
43
|
+
"confirmBeforeDeploy": false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## servers
|
|
49
|
+
|
|
50
|
+
Array of server objects:
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"id": "prod-1",
|
|
54
|
+
"host": "IP or hostname",
|
|
55
|
+
"port": 22,
|
|
56
|
+
"bootstrapUser": "root",
|
|
57
|
+
"runtimeUser": "deploy",
|
|
58
|
+
"roles": ["web"],
|
|
59
|
+
"validated": {
|
|
60
|
+
"ssh": true|false,
|
|
61
|
+
"bootstrap": true|false,
|
|
62
|
+
"runtimeUser": true|false,
|
|
63
|
+
"tools": {
|
|
64
|
+
"node": "version",
|
|
65
|
+
"npm": "version",
|
|
66
|
+
"pm2": "version",
|
|
67
|
+
"nginx": "version",
|
|
68
|
+
"git": "version"
|
|
69
|
+
},
|
|
70
|
+
"directories": true|false,
|
|
71
|
+
"deployKey": true|false
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## repository
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"url": "git@github.com:owner/repo.git",
|
|
81
|
+
"branch": "master",
|
|
82
|
+
"auth": "deploy-key|ssh-agent|token",
|
|
83
|
+
"validated": {
|
|
84
|
+
"clone": true|false
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## apps
|
|
90
|
+
|
|
91
|
+
Array of app objects:
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"id": "web",
|
|
95
|
+
"path": ".",
|
|
96
|
+
"runtime": "pm2",
|
|
97
|
+
"packageManager": "npm",
|
|
98
|
+
"installCommand": "npm ci",
|
|
99
|
+
"buildCommand": "npm run build",
|
|
100
|
+
"startCommand": "npm run start",
|
|
101
|
+
"ports": {
|
|
102
|
+
"blue": 3101,
|
|
103
|
+
"green": 3102
|
|
104
|
+
},
|
|
105
|
+
"healthChecks": [
|
|
106
|
+
{ "name": "home", "url": "/", "expectedStatus": [200] },
|
|
107
|
+
{ "name": "login", "url": "/login", "expectedStatus": [200, 302] }
|
|
108
|
+
],
|
|
109
|
+
"activeColor": "blue",
|
|
110
|
+
"pm2Process": "prizm-ideas-blue"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## nginx
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"enabled": true,
|
|
119
|
+
"managed": true,
|
|
120
|
+
"firstChangeRequiresConfirmation": true,
|
|
121
|
+
"domain": null,
|
|
122
|
+
"ipFallback": true,
|
|
123
|
+
"currentUpstream": "127.0.0.1:3101"
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## env
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"strategy": "ai-assisted|user-managed",
|
|
132
|
+
"required": ["VAR_NAME"],
|
|
133
|
+
"secrets": ["SECRET_NAME"],
|
|
134
|
+
"validated": {
|
|
135
|
+
"allRequiredPresent": true|false
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Validation Rules
|
|
141
|
+
|
|
142
|
+
- `version` must be present (always 1 for first version)
|
|
143
|
+
- `servers` must have at least one entry with host and bootstrapUser
|
|
144
|
+
- `repository.url` must be present
|
|
145
|
+
- `apps` must have at least one entry
|
|
146
|
+
- `apps[*].ports.blue` and `apps[*].ports.green` must differ
|
|
147
|
+
- `apps[*].healthChecks` should have at least one entry
|
|
148
|
+
- Environment referenced in `environments` must have a matching server in `servers`
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Deploy History Record Schema
|
|
2
|
+
|
|
3
|
+
Each event in `.prizmkit/deploy/deploy-history/<id>.json` follows this schema:
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
{
|
|
7
|
+
"eventId": "<releaseId or event id>",
|
|
8
|
+
"eventType": "deploy|rollback|status|validation|failed-deploy|user-aborted|takeover|adapter-gap",
|
|
9
|
+
"timestamp": "<ISO 8601>",
|
|
10
|
+
"serverId": "<server id from deploy.config.json>",
|
|
11
|
+
"appIds": ["<app ids involved>"],
|
|
12
|
+
"branch": "<git branch>",
|
|
13
|
+
"commitSha": "<full or short commit SHA>",
|
|
14
|
+
"releasePath": "<full server path, e.g. /var/www/prizm-ideas/releases/20260430-22783a3>",
|
|
15
|
+
"previousReleasePath": "<previous release path or null for first deploy>",
|
|
16
|
+
"targetPort": 3101,
|
|
17
|
+
"targetColor": "blue|green",
|
|
18
|
+
"previousPort": 3102,
|
|
19
|
+
"phases": {
|
|
20
|
+
"preflight": "success|failed|skipped",
|
|
21
|
+
"prepareRelease": "success|failed|skipped",
|
|
22
|
+
"fetchCode": "success|failed|skipped",
|
|
23
|
+
"installDependencies": "success|failed|skipped",
|
|
24
|
+
"build": "success|failed|skipped",
|
|
25
|
+
"stageRuntime": "success|failed|skipped",
|
|
26
|
+
"healthCheck": "success|failed|skipped",
|
|
27
|
+
"switchTraffic": "success|failed|skipped",
|
|
28
|
+
"verifyLive": "success|failed|skipped",
|
|
29
|
+
"cleanupOldReleases": "success|failed|skipped",
|
|
30
|
+
"recordHistory": "success|failed|skipped"
|
|
31
|
+
},
|
|
32
|
+
"healthCheckResults": [
|
|
33
|
+
{
|
|
34
|
+
"name": "home",
|
|
35
|
+
"url": "/",
|
|
36
|
+
"expected": [200],
|
|
37
|
+
"actual": 200,
|
|
38
|
+
"pass": true
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"rollbackResult": null,
|
|
42
|
+
"logPath": "<server log path>",
|
|
43
|
+
"operatorMode": "ai-assisted|user-managed",
|
|
44
|
+
"notes": "<human-readable summary of what happened>"
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Field Notes
|
|
49
|
+
|
|
50
|
+
- `eventId`: Use `<releaseId>` for deploy events, `<releaseId>-rollback` for rollbacks.
|
|
51
|
+
- `eventType`: Use `failed-deploy` when deploy fails before traffic switch, `deploy` when it succeeds. Use `adapter-gap` when no adapter exists for the detected project type or target — include `detectedProjectType`, `missingAdapter`, and `fallbackOutput` in the record.
|
|
52
|
+
- `phases`: Only include phases that were attempted. Skip phases that were never reached.
|
|
53
|
+
- `healthCheckResults`: Include all configured health checks. `pass` = actual status matches one of the expected status codes.
|
|
54
|
+
- `rollbackResult`: `null` for non-rollback events, `"success"` or `"failed"` for rollbacks.
|
|
55
|
+
- `notes`: Keep concise but include any anomalies or manual interventions.
|
|
56
|
+
|
|
57
|
+
## What NOT to record
|
|
58
|
+
|
|
59
|
+
- Raw secret values or API keys — never.
|
|
60
|
+
- Unsalted hashes of secret values — inferable with rainbow tables.
|
|
61
|
+
- Passphrases or decryption keys — even if hashed.
|
|
62
|
+
- Full environment variable values — presence metadata only (e.g., `{"SUPABASE_KEY": {"present": true}}`).
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Deployment Mode Details
|
|
2
|
+
|
|
3
|
+
Read this file when the user needs a detailed comparison of deployment modes during mode selection. SKILL.md contains the routing logic; this file has the full descriptions.
|
|
4
|
+
|
|
5
|
+
## Mode A — Direct Upload
|
|
6
|
+
|
|
7
|
+
1. Local build on the user's machine.
|
|
8
|
+
2. SCP built output + `node_modules` + `.env.production` to server.
|
|
9
|
+
3. PM2 start → health check → Nginx switch.
|
|
10
|
+
4. After success: offer to upgrade to CI/CD.
|
|
11
|
+
5. Bypasses: deploy key, git clone on server, server-side build.
|
|
12
|
+
|
|
13
|
+
Best for: first-time deployment, getting something live fast, low-spec servers.
|
|
14
|
+
|
|
15
|
+
## Mode B1 — CI/CD Push
|
|
16
|
+
|
|
17
|
+
1. Generate `.github/workflows/deploy.yml`: checkout → install → build → SCP tarball → SSH restart.
|
|
18
|
+
2. Add GitHub Secrets: `SSH_HOST`, `SSH_USER`, `SSH_KEY`, `SSH_PORT`.
|
|
19
|
+
3. First deploy triggered by push to configured branch.
|
|
20
|
+
4. Server only needs Node.js runtime + PM2 — no git, no build tools needed.
|
|
21
|
+
5. GitHub Actions runner handles the heavy lifting.
|
|
22
|
+
|
|
23
|
+
Best for: low-spec servers, heavy build processes, projects with large dependencies.
|
|
24
|
+
|
|
25
|
+
## Mode B2 — CI/CD Pull
|
|
26
|
+
|
|
27
|
+
1. Configure deploy key on server → add to GitHub.
|
|
28
|
+
2. Generate `.github/workflows/deploy.yml`: triggers SSH command on server.
|
|
29
|
+
3. Server-side deploy script: `git pull` → install → build → PM2 restart → health check.
|
|
30
|
+
4. Server needs full build toolchain (Node.js, npm, git).
|
|
31
|
+
5. Simpler workflow file, heavier server load.
|
|
32
|
+
|
|
33
|
+
Best for: simple setup, servers with sufficient CPU/RAM, projects where build is fast.
|
|
34
|
+
|
|
35
|
+
## Comparison
|
|
36
|
+
|
|
37
|
+
| 对比 | Push 模式 | Pull 模式 |
|
|
38
|
+
|------|----------|----------|
|
|
39
|
+
| 构建位置 | GitHub Actions runner | 服务器本地 |
|
|
40
|
+
| 服务器压力 | 低(只运行应用) | 高(编译+运行) |
|
|
41
|
+
| 配置复杂度 | 中(需 SCP 传产物) | 低(只需 SSH 触发脚本) |
|
|
42
|
+
| 适合场景 | 服务器配置低、编译重 | 部署简单优先、服务器性能充裕 |
|
|
43
|
+
| Deploy Key 需要 | 不需要 | 需要 |
|
|
44
|
+
| 产物传输 | SCP tarball | git pull(仅增量) |
|
|
45
|
+
|
|
46
|
+
## Common ground between all modes
|
|
47
|
+
|
|
48
|
+
- Same PM2 + Nginx blue/green strategy.
|
|
49
|
+
- Same health check and traffic switch procedure.
|
|
50
|
+
- Same ops commands (status/logs/restart/rollback).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Direct Upload Deployment
|
|
2
|
+
|
|
3
|
+
Read this file when `deployStrategy` is `"direct-upload"`. The AI handles the build locally and transfers built artifacts to the server. No Git operations on the server.
|
|
4
|
+
|
|
5
|
+
## Build phase (local)
|
|
6
|
+
|
|
7
|
+
1. Run `<buildCommand>` locally (e.g., `npm run build`) in the project root.
|
|
8
|
+
2. Identify the build output directory: `.next/` for Next.js, `dist/` for Vite, `build/` for CRA.
|
|
9
|
+
3. Prepare a deployment tarball containing: build output + `node_modules/` + `package.json` + `package-lock.json` + any runtime config files.
|
|
10
|
+
|
|
11
|
+
## Transfer phase (SCP)
|
|
12
|
+
|
|
13
|
+
```powershell
|
|
14
|
+
scp.exe -P <port> deploy-<releaseId>.tar.gz <runtimeUser>@<host>:/var/www/<project>/releases/
|
|
15
|
+
ssh.exe <runtimeUser>@<host> "cd /var/www/<project>/releases && mkdir <releaseId> && tar xzf deploy-<releaseId>.tar.gz -C <releaseId>"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Server-side setup
|
|
19
|
+
|
|
20
|
+
1. Copy `.env.production` from `shared/` into the release directory (or SCP it alongside the tarball if first deploy).
|
|
21
|
+
2. No `npm install` needed — `node_modules` was transferred directly.
|
|
22
|
+
3. Start PM2 on the inactive port. Health checks and traffic switch follow the standard flow (Groups 3-5 in SKILL.md).
|
|
23
|
+
|
|
24
|
+
## Why transfer node_modules
|
|
25
|
+
|
|
26
|
+
Direct upload is optimized for "fast first deploy." Re-running `npm ci` on a low-spec server can be slow. Transferring pre-built artifacts means the server only needs to run the app.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# DNS Setup Guidance
|
|
2
|
+
|
|
3
|
+
Read this file when the user has a domain for their project but DNS is not yet pointing to the server.
|
|
4
|
+
|
|
5
|
+
## Step 1 — Check DNS resolution
|
|
6
|
+
|
|
7
|
+
```powershell
|
|
8
|
+
Resolve-DnsName <domain> -Type A | Where-Object { $_.QueryType -eq 'A' } | Select-Object -ExpandProperty IPAddress
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
If it resolves to the server IP: DNS is already configured, proceed to SSL (`references/ssl-setup.md`).
|
|
12
|
+
If not: continue below.
|
|
13
|
+
|
|
14
|
+
## Step 2 — DNS setup guidance
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
域名 <example.com> 还未指向服务器 <服务器IP>。
|
|
18
|
+
|
|
19
|
+
请在 DNS 服务商(如阿里云、Cloudflare、Namecheap)添加以下记录:
|
|
20
|
+
|
|
21
|
+
Type: A
|
|
22
|
+
Name: @
|
|
23
|
+
Value: <服务器IP>
|
|
24
|
+
TTL: 600
|
|
25
|
+
|
|
26
|
+
如果要同时支持 www 子域名:
|
|
27
|
+
Type: A
|
|
28
|
+
Name: www
|
|
29
|
+
Value: <服务器IP>
|
|
30
|
+
|
|
31
|
+
配置完成后回复"好了",我继续检查并配 SSL 证书。
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Step 3 — Verify after user confirmation
|
|
35
|
+
|
|
36
|
+
- Re-run `Resolve-DnsName <domain> -Type A` to confirm resolution.
|
|
37
|
+
- If still not resolved: warn about DNS propagation delay (can take up to 48 hours, usually 5-30 minutes). Offer to wait or continue without SSL for now.
|
|
38
|
+
- Once confirmed: proceed to SSL (`references/ssl-setup.md`).
|
|
39
|
+
|
|
40
|
+
## Edge case — IP-only deployment
|
|
41
|
+
|
|
42
|
+
If user has no domain: skip DNS + SSL sections. Generate a note in deploy.md: "项目通过 IP 访问,未配置域名和 HTTPS。建议购买域名后运行 `/prizmkit-deploy setup-ssl`。"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Docker Deployment Path
|
|
2
|
+
|
|
3
|
+
Guided deployment when a `Dockerfile` or `docker-compose.yml` is detected, or the user requests Docker deployment.
|
|
4
|
+
|
|
5
|
+
## Detect and Configure
|
|
6
|
+
|
|
7
|
+
1. Read `Dockerfile` — extract base image, exposed ports, build steps.
|
|
8
|
+
2. Read `docker-compose.yml` if present — extract services, volumes, environment, ports.
|
|
9
|
+
3. Identify image name: from compose project name or repo directory name.
|
|
10
|
+
4. Identify port mappings: from `EXPOSE`, `ports:` in compose, or ask the user.
|
|
11
|
+
|
|
12
|
+
## Build and Deploy
|
|
13
|
+
|
|
14
|
+
1. Build: `docker build -t <project>:<releaseId> .` or `docker compose build`.
|
|
15
|
+
2. Check for running containers with the same name: `docker ps -a --filter name=<project>`.
|
|
16
|
+
3. If a previous container exists:
|
|
17
|
+
- For blue/green on a server with Nginx: start new container on different port, health check, switch upstream.
|
|
18
|
+
- For single-container setup: stop old, start new — warn about brief downtime.
|
|
19
|
+
4. Start: `docker run -d --name <project>-<releaseId> -p <port>:<port> <project>:<releaseId>` or `docker compose up -d`.
|
|
20
|
+
5. Health check the new container.
|
|
21
|
+
6. Write deploy-history event.
|
|
22
|
+
|
|
23
|
+
## Operations
|
|
24
|
+
|
|
25
|
+
| Command | Docker CLI |
|
|
26
|
+
|---------|-----------|
|
|
27
|
+
| status | `docker ps --filter name=<project>` |
|
|
28
|
+
| logs | `docker logs <container-name> --tail 100` |
|
|
29
|
+
| restart | `docker restart <container-name>` |
|
|
30
|
+
| rollback | `docker stop <new-container> && docker start <old-container>` |
|
|
31
|
+
| cleanup | `docker image prune -a --filter "label=project=<project>"` |
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Firewall Setup (UFW)
|
|
2
|
+
|
|
3
|
+
Read this file when the user wants AI-assisted firewall configuration during bootstrap.
|
|
4
|
+
|
|
5
|
+
## Flow
|
|
6
|
+
|
|
7
|
+
1. After core tools are installed, ask the user:
|
|
8
|
+
> "是否需要帮你配置防火墙(ufw)?只开放必要的端口,提高服务器安全性。"
|
|
9
|
+
|
|
10
|
+
2. If user declines: skip, record to deploy config.
|
|
11
|
+
|
|
12
|
+
3. If user agrees, ask which additional ports to open (beyond SSH/HTTP/HTTPS):
|
|
13
|
+
> "默认只开放 SSH(22)、HTTP(80)、HTTPS(443)。蓝绿部署预览端口(3101/3102)要不要也开放?如果需要其他端口(如数据库远程管理),可以一起列出来。"
|
|
14
|
+
|
|
15
|
+
4. Collect ports, then ask:
|
|
16
|
+
> "防火墙规则已整理好。是我直接上去改,还是你自己来?"
|
|
17
|
+
> - **A. 你帮我改** — AI 执行 ufw 命令
|
|
18
|
+
> - **B. 我自己改** — 输出规则清单,用户手工执行
|
|
19
|
+
|
|
20
|
+
## Planned rules (output before executing)
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
ufw default deny incoming
|
|
24
|
+
ufw default allow outgoing
|
|
25
|
+
ufw allow 22/tcp # SSH
|
|
26
|
+
ufw allow 80/tcp # HTTP
|
|
27
|
+
ufw allow 443/tcp # HTTPS
|
|
28
|
+
ufw allow 3101/tcp # blue preview (user-approved)
|
|
29
|
+
ufw allow 3102/tcp # green preview (user-approved)
|
|
30
|
+
ufw --force enable
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Rules for automatic execution
|
|
34
|
+
|
|
35
|
+
- Check `ufw status` first — if rules already exist, append only missing rules, don't overwrite.
|
|
36
|
+
- Never `ufw reset` unless explicitly asked, because it wipes custom rules the user may have configured manually.
|
|
37
|
+
- Record a `"security-baseline"` event in deploy history with the rule list, so future sessions can detect existing configuration.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Implementation Notes from Live Validation
|
|
2
|
+
|
|
3
|
+
These findings from the first PrizmKit deployment (PrizmIdeas) guide edge-case handling. Read when troubleshooting bootstrap or deploy issues.
|
|
4
|
+
|
|
5
|
+
1. **Detect port conflicts before installing Nginx.** Check what's on port 80/443 and ask before stopping anything, because overwriting an existing web server without confirmation can break unrelated services.
|
|
6
|
+
|
|
7
|
+
2. **Verify npm separately from node.** Minimal Node installs may not bundle npm. Run `which npm` after installing Node, because `node --version` succeeding doesn't guarantee npm is available.
|
|
8
|
+
|
|
9
|
+
3. **Fix locale on bare Ubuntu.** Run `locale-gen en_US.UTF-8` early to avoid perl warnings in apt. This is safe to run unconditionally even if locale is already configured.
|
|
10
|
+
|
|
11
|
+
4. **Deploy key workflow is inherently interactive.** Generate key → wait for user to add to GitHub → verify. Headless mode cannot complete this because it requires the user to paste the key into GitHub's UI.
|
|
12
|
+
|
|
13
|
+
5. **`pm2 startup` needs explicit PATH.** Always use `env PATH=$PATH:/usr/bin pm2 startup ...`, because the pm2 binary may not be on root's default PATH.
|
|
14
|
+
|
|
15
|
+
6. **Persist deploy metadata on server.** Write `activeColor`, `activePort`, `lastReleaseId`, `lastDeployTimestamp` to `shared/deploy-metadata.json`, because subsequent deploys and rollbacks depend on knowing the current active slot.
|
|
16
|
+
|
|
17
|
+
7. **Detect first deployment.** If no `current` symlink and no PM2 process for the app, skip rollback safety checks and use blue (3101) as initial color.
|
|
18
|
+
|
|
19
|
+
8. **Build-time env vars.** Copy `.env.production` before `npm run build`, not after. `NEXT_PUBLIC_*` vars are baked at build time and won't be picked up if the .env is added later.
|
|
20
|
+
|
|
21
|
+
9. **Node.js version flexibility.** Default to v22 LTS if v25 is unavailable. Most frameworks tolerate a minor version diff, and v22 has broader package compatibility.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Nginx Blue/Green Configuration Template
|
|
2
|
+
|
|
3
|
+
## Server Block Template
|
|
4
|
+
|
|
5
|
+
```nginx
|
|
6
|
+
# PrizmKit Managed: <project> — DO NOT EDIT MANUALLY
|
|
7
|
+
upstream <project>_backend {
|
|
8
|
+
server 127.0.0.1:<activePort>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
server {
|
|
12
|
+
listen 80 default_server;
|
|
13
|
+
server_name _;
|
|
14
|
+
|
|
15
|
+
# PrizmKit managed marker: <project>
|
|
16
|
+
location / {
|
|
17
|
+
proxy_pass http://<project>_backend;
|
|
18
|
+
proxy_http_version 1.1;
|
|
19
|
+
proxy_set_header Host $host;
|
|
20
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
21
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
22
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Traffic Switch Procedure
|
|
28
|
+
|
|
29
|
+
When switching from one color to another:
|
|
30
|
+
|
|
31
|
+
1. Update the `upstream` block: change `server 127.0.0.1:<oldPort>` to `server 127.0.0.1:<newPort>`
|
|
32
|
+
2. Run `nginx -t` to validate syntax
|
|
33
|
+
3. If syntax check passes: `systemctl reload nginx`
|
|
34
|
+
4. If syntax check fails: DO NOT reload. Abort the switch. Report the error.
|
|
35
|
+
|
|
36
|
+
## Managed Marker
|
|
37
|
+
|
|
38
|
+
All PrizmKit-generated Nginx config must contain:
|
|
39
|
+
```
|
|
40
|
+
# PrizmKit Managed: <project> — DO NOT EDIT MANUALLY
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Before modifying any server block that lacks this marker, ask for user confirmation.
|
|
44
|
+
|
|
45
|
+
## First-Time Setup
|
|
46
|
+
|
|
47
|
+
- Disable default nginx site: `rm -f /etc/nginx/sites-enabled/default`
|
|
48
|
+
- Create new config: `/etc/nginx/sites-available/<project>`
|
|
49
|
+
- Symlink: `ln -sf /etc/nginx/sites-available/<project> /etc/nginx/sites-enabled/<project>`
|
|
50
|
+
- Test: `nginx -t`
|
|
51
|
+
- Reload: `systemctl reload nginx`
|
|
52
|
+
|
|
53
|
+
## Rediscovery of Active Port
|
|
54
|
+
|
|
55
|
+
If `deploy-metadata.json` is missing, rediscover the active upstream port from Nginx config:
|
|
56
|
+
```
|
|
57
|
+
grep "server 127.0.0.1:" /etc/nginx/sites-available/<project>
|
|
58
|
+
```
|
|
59
|
+
Then match the port against configured blue/green ports to determine active color.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# SSL/HTTPS Configuration (Let's Encrypt + Certbot)
|
|
2
|
+
|
|
3
|
+
Read this file when DNS is confirmed pointing to the server and SSL needs to be configured.
|
|
4
|
+
|
|
5
|
+
## Step 1 — Detect cloud vendor
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
# Try metadata endpoints to detect cloud vendor (run on server via SSH)
|
|
9
|
+
curl -s --connect-timeout 2 http://100.100.100.200/latest/meta-data/ && echo "ALIBABA"
|
|
10
|
+
curl -s --connect-timeout 2 http://metadata.tencentyun.com/latest/meta-data/ && echo "TENCENT"
|
|
11
|
+
curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ && echo "AWS/GCP/AZURE"
|
|
12
|
+
```
|
|
13
|
+
Also check `/etc/hostname` for vendor patterns.
|
|
14
|
+
|
|
15
|
+
## Step 2 — Choose SSL strategy
|
|
16
|
+
|
|
17
|
+
- **Cloud vendor detected** → ask user:
|
|
18
|
+
> "检测到服务器运行在 <云厂商>。用哪种 SSL 方案?"
|
|
19
|
+
> - **A. Let's Encrypt 免费证书(推荐)** — 一行命令永久自动续期,最省心
|
|
20
|
+
> - **B. <云厂商> 自有证书** — 需手动下载配置,1年有效期需手动续期
|
|
21
|
+
>
|
|
22
|
+
> 选 A 我直接帮你搞定;选 B 你需要在云控制台下载证书后告诉我路径。
|
|
23
|
+
- **No cloud vendor / unknown** → use certbot directly, no choice needed.
|
|
24
|
+
|
|
25
|
+
## Step 3 — Certbot install & certificate request
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
# Install certbot (idempotent, on server)
|
|
29
|
+
which certbot || apt-get install -y certbot python3-certbot-nginx
|
|
30
|
+
|
|
31
|
+
# Request certificate
|
|
32
|
+
certbot --nginx -d <domain> -d www.<domain> --non-interactive --agree-tos --email <user-email>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Collect from user before running:**
|
|
36
|
+
- Email address (Let's Encrypt expiry notifications)
|
|
37
|
+
- Confirm domain list (e.g., `example.com, www.example.com`)
|
|
38
|
+
|
|
39
|
+
## Step 4 — Verify auto-renewal
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
systemctl status certbot.timer
|
|
43
|
+
certbot renew --dry-run
|
|
44
|
+
```
|
|
45
|
+
If timer is inactive, enable it: `systemctl enable --now certbot.timer`.
|
|
46
|
+
|
|
47
|
+
## Step 5 — Record
|
|
48
|
+
|
|
49
|
+
- Write SSL configuration summary to deploy.md: certificate paths, auto-renewal status, expiry date.
|
|
50
|
+
- Record a `"ssl-setup"` event in deploy history.
|
|
51
|
+
|
|
52
|
+
## Edge cases
|
|
53
|
+
|
|
54
|
+
- **DNS not yet propagated** → certbot challenge fails. Tell user to wait and retry: `/prizmkit-deploy setup-ssl`.
|
|
55
|
+
- **Existing certificate found** → check expiry date (`certbot certificates`). If expiring within 30 days, warn. Otherwise skip.
|
|
56
|
+
- **Port 80/443 occupied by non-Nginx process** → report and ask how to resolve before proceeding.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "prizmkit-implement"
|
|
3
|
+
description: "Execute plan.md tasks with TDD approach. Respects task ordering and dependencies. Use after /prizmkit-plan. Trigger on: 'implement', 'build', 'code it', 'start coding', 'execute', 'write the code'. (project)"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PrizmKit Implement
|
|
7
|
+
|
|
8
|
+
### When to Use
|
|
9
|
+
- After `/prizmkit-plan` when ready to write code
|
|
10
|
+
- User says "implement", "build", "code it", "start coding", "develop"
|
|
11
|
+
- For fast-path: user describes a simple change directly (fast-path skips specify, but still requires a simplified plan.md with Tasks section)
|
|
12
|
+
|
|
13
|
+
**PRECONDITION:**
|
|
14
|
+
|
|
15
|
+
| Required Artifact | Check | If Missing |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `plan.md` with Tasks section | File exists + unchecked tasks | Run `/prizmkit-plan` |
|
|
18
|
+
| `spec.md` | File exists in same directory as plan.md | Run `/prizmkit-plan` |
|
|
19
|
+
|
|
20
|
+
**Artifact directory**: Accept `artifact_dir` from caller. If not provided, scan `.prizmkit/` subdirectories for the most recently modified `plan.md` with unchecked tasks.
|
|
21
|
+
|
|
22
|
+
## Input
|
|
23
|
+
|
|
24
|
+
| Parameter | Required | Description |
|
|
25
|
+
|-----------|----------|-------------|
|
|
26
|
+
| `artifact_dir` | No | Directory containing spec.md + plan.md. If omitted, auto-detect per precondition above. |
|
|
27
|
+
|
|
28
|
+
## Context Loading
|
|
29
|
+
|
|
30
|
+
Before implementation, load context once:
|
|
31
|
+
|
|
32
|
+
1. **Task context**: Read `plan.md` (including Tasks section) and `spec.md` from the artifact directory. If other companion documents exist in the directory (e.g., `refactor-analysis.md`), read them for additional context.
|
|
33
|
+
2. **Architecture context**: Read `.prizmkit/prizm-docs/root.prizm` (L0 — project overview, module index, tech stack, conventions) and relevant L1/L2 docs for affected modules. Pay special attention to TRAPS (known pitfalls) and DECISIONS (architectural choices).
|
|
34
|
+
3. **Dev rules** (if configured): Check `.prizmkit/prizm-docs/root.prizm` for a `RULES:` line — if present, read all referenced `.prizmkit/rules/<layer>-rules.md` files. If a referenced file does not exist, skip it silently and continue. These define per-layer conventions (frameworks, naming, patterns, state management, etc.) that AI must follow when generating code for that layer. Apply these rules during implementation — if a rule conflicts with what plan.md describes, call it out and ask the user.
|
|
35
|
+
|
|
36
|
+
> `.prizmkit/prizm-docs/` uses a 3-level hierarchy: L0 (`root.prizm`) is the project-wide index. L1 (e.g., `auth.prizm`) covers a module — its key files, interfaces, dependencies, traps, and decisions. L2 is for sub-modules with their own complexity. Implement reads these docs to avoid repeating known mistakes; `/prizmkit-retrospective` is responsible for updating them after implementation.
|
|
37
|
+
|
|
38
|
+
## Execution
|
|
39
|
+
|
|
40
|
+
For each unchecked task in plan.md, in order:
|
|
41
|
+
|
|
42
|
+
1. Read L1/L2 doc for the target file's module — check TRAPS and DECISIONS before modifying files
|
|
43
|
+
2. Apply TDD where applicable: write a failing test first, then implement until it passes. For UI components or configuration changes where unit tests don't apply, skip the test-first step.
|
|
44
|
+
- **Internal ID hygiene**: Do not place PrizmKit feature/bug/refactor IDs (`F-001`, `B-001`, `R-001`), task IDs, session IDs, run IDs, branch names, absolute worktree paths, or `.prizmkit/specs` / `.prizmkit/dev-pipeline` artifact paths in `.prizmkit/prizm-docs/`, user-visible UI text, API responses, emails, notifications, or tests that assert visible product copy. Translate internal references into durable product/domain language before writing memory docs, tests, or UI copy.
|
|
45
|
+
- **Cover three paths for each function**: happy path (valid inputs producing expected behavior), edge cases (boundary values specific to the parameter type and domain — e.g., zero/min/max for numeric, empty collection, boundary index), and error conditions (inputs that should trigger error handling). Determine edge cases from the function's parameter types and domain logic, not from a fixed checklist. If a function has no edge or error paths, don't force them.
|
|
46
|
+
- **No redundant tests**: Check if a test for this behavior already exists before writing. Each test must verify a uniquely different code path — don't write multiple tests that exercise the same logic.
|
|
47
|
+
- **Test your own code only**: Don't test framework behavior, third-party library internals, or language built-ins. For library calls, test the integration point (correct parameters passed, return value correctly handled), not the library itself.
|
|
48
|
+
3. Mark task as `[x]` in `plan.md` immediately after completion — not batched at the end. Immediate marking means plan.md always reflects true progress, even if the session is interrupted.
|
|
49
|
+
4. **Parallel tasks**: If task has `[P]` marker, it can run in parallel with other `[P]` tasks in the same group. Sequential tasks stop on failure (later tasks may depend on this one). Parallel `[P]` tasks continue — report all failures at the end.
|
|
50
|
+
5. **Checkpoint tasks** (`CP:` prefix in plan.md): When a checkpoint task is reached, verify build passes and tests pass before continuing. Checkpoints catch integration errors early — skipping them means cascading failures in later phases.
|
|
51
|
+
6. After all tasks complete: run full test suite.
|
|
52
|
+
|
|
53
|
+
## Recovery
|
|
54
|
+
|
|
55
|
+
If a session is interrupted mid-implementation:
|
|
56
|
+
- Completed tasks are already marked `[x]` in plan.md (because we mark immediately)
|
|
57
|
+
- Resume by re-running `/prizmkit-implement` — it picks up from the first unchecked `[ ]` task
|
|
58
|
+
|
|
59
|
+
**HANDOFF:** `/prizmkit-code-review`
|
|
60
|
+
|
|
61
|
+
## Output
|
|
62
|
+
|
|
63
|
+
- Code files created/modified as specified in plan.md Tasks section
|
|
64
|
+
- `plan.md` Tasks section updated with completion markers `[x]`
|
|
65
|
+
- Implementation summary output to conversation
|