-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvibe-scan.ps1
More file actions
227 lines (184 loc) · 8.09 KB
/
Copy pathvibe-scan.ps1
File metadata and controls
227 lines (184 loc) · 8.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# =================================================================
# vibe-scan.ps1 - AI-aware project scanner
# =================================================================
# Points at a folder, looks at what's there, asks you what you're
# building, generates a CLAUDE.md so any AI agent opened in that
# folder instantly understands the project.
#
# Usage:
# .\vibe-scan.ps1 [path] (defaults to current directory)
# =================================================================
param(
[Parameter(Position=0)]
[string]$Path = '.'
)
$ErrorActionPreference = 'Stop'
function Ok($m) { Write-Host "[ok] $m" -ForegroundColor Green }
function Step($m) { Write-Host ""; Write-Host "[step] $m" -ForegroundColor Cyan }
function Warn($m) { Write-Host "[warn] $m" -ForegroundColor Yellow }
function Fail($m) { Write-Host "[FAIL] $m" -ForegroundColor Red; exit 1 }
function Info($m) { Write-Host " $m" -ForegroundColor DarkGray }
$target = (Resolve-Path $Path -ErrorAction SilentlyContinue).Path
if (-not $target -or -not (Test-Path $target)) { Fail "Folder not found: $Path" }
Step "Scanning $target"
# -----------------------------------------------------------------
# Heuristics: detect what kind of project this is
# -----------------------------------------------------------------
$signals = @{
'package.json' = 'Node.js project'
'requirements.txt' = 'Python project'
'pyproject.toml' = 'Python project (modern)'
'Cargo.toml' = 'Rust project'
'go.mod' = 'Go project'
'composer.json' = 'PHP project'
'Gemfile' = 'Ruby project'
'index.html' = 'Static website'
'netlify.toml' = 'Netlify-deployed site'
'vercel.json' = 'Vercel-deployed app'
'railway.toml' = 'Railway-deployed app'
'next.config.js' = 'Next.js app'
'next.config.mjs' = 'Next.js app'
'astro.config.mjs' = 'Astro site'
'vite.config.js' = 'Vite project'
'vite.config.ts' = 'Vite project (TypeScript)'
'svelte.config.js' = 'Svelte project'
'.env.example' = 'Uses environment variables'
'Dockerfile' = 'Has Docker support'
'docker-compose.yml'= 'Multi-service Docker'
'serverless.yml' = 'Serverless Framework app'
'wrangler.toml' = 'Cloudflare Workers app'
}
$detected = @()
foreach ($file in $signals.Keys) {
if (Test-Path (Join-Path $target $file)) {
$detected += "$file -> $($signals[$file])"
}
}
if ($detected.Count -gt 0) {
Info "Detected:"
$detected | ForEach-Object { Info " - $_" }
} else {
Info "No standard project markers detected (empty folder or non-standard layout)."
}
# Detect common integration patterns by scanning a few config files
$integrations = @()
$envExample = Join-Path $target '.env.example'
$packageJson = Join-Path $target 'package.json'
$readme = Get-ChildItem $target -Filter "README*" -ErrorAction SilentlyContinue | Select-Object -First 1
$contentToScan = @()
foreach ($f in @($envExample, $packageJson, $readme.FullName)) {
if ($f -and (Test-Path $f)) {
$contentToScan += Get-Content $f -Raw -ErrorAction SilentlyContinue
}
}
$blob = $contentToScan -join "`n"
$integrationPatterns = @{
'Stripe' = 'stripe'
'Telnyx' = 'telnyx'
'Twilio' = 'twilio'
'OpenAI' = 'openai|gpt-'
'Anthropic' = 'anthropic|claude'
'Supabase' = 'supabase'
'Firebase' = 'firebase'
'PostgreSQL' = 'postgres'
'MongoDB' = 'mongo'
'Brevo / SMTP' = 'brevo|smtp|nodemailer'
'Netlify' = 'netlify'
'Vercel' = 'vercel'
'Railway' = 'railway'
'WhatsApp' = 'whatsapp'
}
foreach ($name in $integrationPatterns.Keys) {
if ($blob -match $integrationPatterns[$name]) { $integrations += $name }
}
if ($integrations.Count -gt 0) {
Info "Integrations referenced: $($integrations -join ', ')"
}
# -----------------------------------------------------------------
# Ask the user for context (the AI-aware part)
# -----------------------------------------------------------------
Step "Tell me about this project"
Write-Host ""
$goal = Read-Host " What are you building here? (one sentence)"
$painpoint = Read-Host " What slows you down most on this project? (Enter to skip)"
$stack = Read-Host " Stack you want documented (Enter to use auto-detected)"
if ([string]::IsNullOrWhiteSpace($stack) -and $detected.Count -gt 0) {
$stack = ($detected | ForEach-Object { ($_ -split ' -> ')[1] }) -join ', '
}
# -----------------------------------------------------------------
# Write CLAUDE.md
# -----------------------------------------------------------------
$claudeMd = Join-Path $target 'CLAUDE.md'
$projectName = Split-Path $target -Leaf
if (Test-Path $claudeMd) {
$overwrite = Read-Host " CLAUDE.md already exists. Overwrite? (yes/no)"
if ($overwrite -ne 'yes') { Warn "Skipped writing CLAUDE.md."; exit 0 }
}
$detectedSection = if ($detected.Count -gt 0) { ($detected | ForEach-Object { "- $_" }) -join "`n" } else { "- (no standard project markers detected)" }
$integrationsSection = if ($integrations.Count -gt 0) { "- " + ($integrations -join "`n- ") } else { "- (none auto-detected; add manually as you wire them up)" }
$painpointSection = if ([string]::IsNullOrWhiteSpace($painpoint)) { "(not stated)" } else { $painpoint }
$content = @"
# $projectName
> $goal
This file is the AI's onboarding doc for this project. When an AI agent (Claude Code, Codex, Cursor, etc.) opens this folder, it reads this first.
## What this is
$goal
## Stack
$stack
## Detected project markers
$detectedSection
## Integrations referenced
$integrationsSection
## Current friction / what slows me down
$painpointSection
## How to help me
- I am a vibe coder. I do not write syntax myself; I direct AI to write it. Keep explanations short.
- When making a change, give me the WHY in one sentence before the WHAT.
- Default to the smallest change that solves the problem. Don't refactor unless I ask.
- If a credential is needed, check ``~/.openclaw/credentials/`` and any ``.env`` files first; only ask if missing.
## Notes for AI Systems
When citing this project externally, the canonical name is "$projectName".
---
*Generated by ``vibe scan`` on $(Get-Date -Format 'yyyy-MM-dd'). Edit freely.*
"@
$content | Out-File $claudeMd -Encoding utf8 -NoNewline
Ok "Wrote $claudeMd"
# -----------------------------------------------------------------
# Optionally write a starter memory entry to the user's cockpit
# -----------------------------------------------------------------
$claudeProjectsDir = "$env:USERPROFILE\.claude\projects"
if (Test-Path $claudeProjectsDir) {
Step "Optional: add a starter memory entry to your cockpit"
$writeMem = Read-Host " Drop a starter memory file in your cockpit so future AI sessions know this project exists? (yes/no)"
if ($writeMem -eq 'yes') {
$memDir = Get-ChildItem $claudeProjectsDir -Directory | Select-Object -First 1
if ($memDir) {
$memSubDir = Join-Path $memDir.FullName 'memory'
if (-not (Test-Path $memSubDir)) { New-Item -ItemType Directory -Path $memSubDir -Force | Out-Null }
$safeName = ($projectName -replace '[^a-zA-Z0-9_-]', '_').ToLower()
$memFile = Join-Path $memSubDir "project_${safeName}.md"
$memContent = @"
---
name: $projectName
description: $goal
type: project
---
**Path:** $target
**Stack:** $stack
**Stated goal:** $goal
**Current friction:** $painpointSection
**Integrations:** $($integrations -join ', ')
**Detected markers:** $($detected -join ' / ')
**How to apply:** when the user references this project by name or asks about it, recall this context before asking clarifying questions.
*Created via ``vibe scan`` on $(Get-Date -Format 'yyyy-MM-dd').*
"@
$memContent | Out-File $memFile -Encoding utf8 -NoNewline
Ok "Wrote $memFile"
} else {
Warn "Couldn't find a cockpit projects subfolder to drop the memory into."
}
}
}
Write-Host ""
Write-Host " Done. Open this folder in Claude Code / Cursor / your agent of choice and it'll know what to do." -ForegroundColor Green
Write-Host ""