claude-brain 0.17.13 → 0.22.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.
- package/VERSION +1 -1
- package/package.json +3 -1
- package/scripts/postinstall.mjs +80 -104
- package/src/cli/auto-setup.ts +1 -9
- package/src/cli/bin.ts +23 -2
- package/src/cli/commands/export.ts +130 -0
- package/src/cli/commands/reindex.ts +107 -0
- package/src/cli/commands/serve.ts +54 -0
- package/src/cli/commands/status.ts +158 -0
- package/src/code-intelligence/indexer.ts +315 -0
- package/src/code-intelligence/linker.ts +178 -0
- package/src/code-intelligence/parser.ts +484 -0
- package/src/code-intelligence/query.ts +291 -0
- package/src/code-intelligence/schema.ts +83 -0
- package/src/code-intelligence/types.ts +95 -0
- package/src/config/defaults.ts +3 -3
- package/src/config/loader.ts +6 -0
- package/src/config/schema.ts +28 -2
- package/src/health/index.ts +5 -2
- package/src/hooks/brain-hook.ts +4 -1
- package/src/hooks/context-hook.ts +69 -10
- package/src/hooks/installer.ts +4 -7
- package/src/intelligence/cross-project/index.ts +1 -7
- package/src/intelligence/prediction/index.ts +1 -7
- package/src/intelligence/reasoning/index.ts +1 -7
- package/src/memory/compression.ts +105 -0
- package/src/memory/fts5-search.ts +456 -0
- package/src/memory/index.ts +342 -38
- package/src/memory/migrations/add-fts5.ts +98 -0
- package/src/memory/pruning.ts +60 -0
- package/src/routing/intent-classifier.ts +58 -1
- package/src/routing/response-filter.ts +128 -0
- package/src/routing/router.ts +457 -54
- package/src/server/http-api.ts +319 -1
- package/src/server/providers/resources.ts +1 -42
- package/src/server/services.ts +113 -12
- package/src/server/web-viewer.ts +1115 -0
- package/src/setup/index.ts +12 -22
- package/src/tools/schemas.ts +1 -1
- package/src/intelligence/cross-project/affinity.ts +0 -159
- package/src/intelligence/cross-project/transfer.ts +0 -201
- package/src/intelligence/prediction/context-anticipator.ts +0 -198
- package/src/intelligence/prediction/decision-predictor.ts +0 -184
- package/src/intelligence/reasoning/counterfactual.ts +0 -248
- package/src/intelligence/reasoning/synthesizer.ts +0 -167
- package/src/setup/wizard.ts +0 -459
package/src/setup/wizard.ts
DELETED
|
@@ -1,459 +0,0 @@
|
|
|
1
|
-
import prompts from 'prompts'
|
|
2
|
-
import fs from 'fs/promises'
|
|
3
|
-
import { existsSync } from 'fs'
|
|
4
|
-
import { execSync } from 'child_process'
|
|
5
|
-
import path from 'path'
|
|
6
|
-
import os from 'os'
|
|
7
|
-
import { fileURLToPath } from 'url'
|
|
8
|
-
import type { Logger } from 'pino'
|
|
9
|
-
import { getHomePaths } from '@/config/home'
|
|
10
|
-
import {
|
|
11
|
-
theme, heading, successText, errorText, warningText, dimText,
|
|
12
|
-
box, stepIndicator, summaryPanel,
|
|
13
|
-
withSpinner, transition,
|
|
14
|
-
} from '@/cli/ui/index.js'
|
|
15
|
-
|
|
16
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
17
|
-
const __dirname = path.dirname(__filename)
|
|
18
|
-
// Package root is two levels up from src/setup/
|
|
19
|
-
const PACKAGE_ROOT = path.resolve(__dirname, '..', '..')
|
|
20
|
-
|
|
21
|
-
export interface SetupAnswers {
|
|
22
|
-
vaultPath: string
|
|
23
|
-
logLevel: string
|
|
24
|
-
enableFileWatch: boolean
|
|
25
|
-
enableChromaDB: boolean
|
|
26
|
-
createSampleProject: boolean
|
|
27
|
-
installClaudeMd: boolean
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export class SetupWizard {
|
|
31
|
-
constructor(_logger: Logger) {
|
|
32
|
-
// Logger available for future use
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async run(): Promise<SetupAnswers> {
|
|
36
|
-
// Step 1: Detect Vaults
|
|
37
|
-
console.log(stepIndicator(1, 6, 'Detecting Obsidian Vaults'))
|
|
38
|
-
await transition()
|
|
39
|
-
|
|
40
|
-
const suggestedPaths = await withSpinner('Scanning for Obsidian vaults', () =>
|
|
41
|
-
this.detectVaultLocations()
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
if (suggestedPaths.length > 0) {
|
|
45
|
-
console.log(successText(`Found ${suggestedPaths.length} vault${suggestedPaths.length > 1 ? 's' : ''}`))
|
|
46
|
-
} else {
|
|
47
|
-
console.log(warningText('No vaults auto-detected — enter path manually'))
|
|
48
|
-
}
|
|
49
|
-
console.log()
|
|
50
|
-
|
|
51
|
-
// Step 2: Vault Configuration
|
|
52
|
-
console.log(stepIndicator(2, 6, 'Vault Configuration'))
|
|
53
|
-
await transition()
|
|
54
|
-
|
|
55
|
-
const vaultAnswers = await prompts([
|
|
56
|
-
{
|
|
57
|
-
type: 'select',
|
|
58
|
-
name: 'vaultPathChoice',
|
|
59
|
-
message: 'Where is your Obsidian vault?',
|
|
60
|
-
choices: [
|
|
61
|
-
...suggestedPaths.map(p => ({ title: p, value: p })),
|
|
62
|
-
{ title: 'Enter custom path', value: 'custom' }
|
|
63
|
-
],
|
|
64
|
-
initial: 0
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
type: (prev) => prev === 'custom' ? 'text' : null,
|
|
68
|
-
name: 'vaultPath',
|
|
69
|
-
message: 'Enter vault path:',
|
|
70
|
-
validate: async (value: string) => {
|
|
71
|
-
try {
|
|
72
|
-
const stat = await fs.stat(value)
|
|
73
|
-
return stat.isDirectory() || 'Path must be a directory'
|
|
74
|
-
} catch {
|
|
75
|
-
return 'Path does not exist'
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
])
|
|
80
|
-
|
|
81
|
-
if (!vaultAnswers.vaultPathChoice) {
|
|
82
|
-
console.log('\n' + errorText('Setup cancelled.'))
|
|
83
|
-
process.exit(0)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const finalVaultPath = vaultAnswers.vaultPath || vaultAnswers.vaultPathChoice
|
|
87
|
-
|
|
88
|
-
// Step 3: Logging
|
|
89
|
-
console.log(stepIndicator(3, 6, 'Logging Configuration'))
|
|
90
|
-
await transition()
|
|
91
|
-
|
|
92
|
-
const loggingAnswers = await prompts({
|
|
93
|
-
type: 'select',
|
|
94
|
-
name: 'logLevel',
|
|
95
|
-
message: 'Select log level:',
|
|
96
|
-
choices: [
|
|
97
|
-
{ title: 'Error (production)', value: 'error' },
|
|
98
|
-
{ title: 'Warn (recommended)', value: 'warn' },
|
|
99
|
-
{ title: 'Info', value: 'info' },
|
|
100
|
-
{ title: 'Debug (verbose)', value: 'debug' }
|
|
101
|
-
],
|
|
102
|
-
initial: 1
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
// Step 4: Features
|
|
106
|
-
console.log(stepIndicator(4, 6, 'Feature Selection'))
|
|
107
|
-
await transition()
|
|
108
|
-
|
|
109
|
-
const featureAnswers = await prompts([
|
|
110
|
-
{
|
|
111
|
-
type: 'confirm',
|
|
112
|
-
name: 'enableFileWatch',
|
|
113
|
-
message: 'Enable automatic file watching?',
|
|
114
|
-
initial: true
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
type: 'confirm',
|
|
118
|
-
name: 'createSampleProject',
|
|
119
|
-
message: 'Create a sample project to test with?',
|
|
120
|
-
initial: true
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
type: 'confirm',
|
|
124
|
-
name: 'installClaudeMd',
|
|
125
|
-
message: 'Install CLAUDE.md protocol file to ~/.claude/CLAUDE.md?',
|
|
126
|
-
initial: true
|
|
127
|
-
}
|
|
128
|
-
])
|
|
129
|
-
|
|
130
|
-
// Step 5: ChromaDB
|
|
131
|
-
console.log(stepIndicator(5, 6, 'ChromaDB (Vector Database)'))
|
|
132
|
-
await transition()
|
|
133
|
-
|
|
134
|
-
console.log(dimText('ChromaDB enables semantic search, knowledge graph,'))
|
|
135
|
-
console.log(dimText('and advanced intelligence features. Requires Python 3.'))
|
|
136
|
-
console.log()
|
|
137
|
-
|
|
138
|
-
const chromaInstalled = this.isChromaInstalled()
|
|
139
|
-
if (chromaInstalled) {
|
|
140
|
-
console.log(successText('ChromaDB CLI detected'))
|
|
141
|
-
} else {
|
|
142
|
-
console.log(warningText('ChromaDB CLI not found — you can install it later'))
|
|
143
|
-
}
|
|
144
|
-
console.log()
|
|
145
|
-
|
|
146
|
-
const chromaAnswers = await prompts({
|
|
147
|
-
type: 'confirm',
|
|
148
|
-
name: 'enableChromaDB',
|
|
149
|
-
message: chromaInstalled
|
|
150
|
-
? 'Enable ChromaDB for advanced features?'
|
|
151
|
-
: 'Enable ChromaDB? (install later: pip install chromadb)',
|
|
152
|
-
initial: chromaInstalled
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
// Step 6: Review
|
|
156
|
-
console.log(stepIndicator(6, 6, 'Review Configuration'))
|
|
157
|
-
await transition()
|
|
158
|
-
|
|
159
|
-
const answers: SetupAnswers = {
|
|
160
|
-
vaultPath: finalVaultPath,
|
|
161
|
-
logLevel: loggingAnswers.logLevel ?? 'warn',
|
|
162
|
-
enableFileWatch: featureAnswers.enableFileWatch ?? true,
|
|
163
|
-
enableChromaDB: chromaAnswers.enableChromaDB ?? false,
|
|
164
|
-
createSampleProject: featureAnswers.createSampleProject ?? true,
|
|
165
|
-
installClaudeMd: featureAnswers.installClaudeMd ?? true,
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
console.log(summaryPanel('Configuration Summary', [
|
|
169
|
-
{ label: 'Vault Path', value: answers.vaultPath, status: 'success' },
|
|
170
|
-
{ label: 'Log Level', value: answers.logLevel, status: 'info' },
|
|
171
|
-
{ label: 'File Watching', value: answers.enableFileWatch ? 'Enabled' : 'Disabled', status: answers.enableFileWatch ? 'success' : 'warning' },
|
|
172
|
-
{ label: 'ChromaDB', value: answers.enableChromaDB ? 'Enabled' : 'Disabled', status: answers.enableChromaDB ? 'success' : 'warning' },
|
|
173
|
-
{ label: 'Sample Project', value: answers.createSampleProject ? 'Yes' : 'No', status: 'info' },
|
|
174
|
-
{ label: 'Install CLAUDE.md', value: answers.installClaudeMd ? 'Yes' : 'No', status: 'info' },
|
|
175
|
-
]))
|
|
176
|
-
console.log()
|
|
177
|
-
|
|
178
|
-
const { confirm } = await prompts({
|
|
179
|
-
type: 'confirm',
|
|
180
|
-
name: 'confirm',
|
|
181
|
-
message: 'Apply this configuration?',
|
|
182
|
-
initial: true
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
if (!confirm) {
|
|
186
|
-
console.log('\n' + errorText('Setup cancelled.'))
|
|
187
|
-
process.exit(0)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return answers
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
private async detectVaultLocations(): Promise<string[]> {
|
|
194
|
-
const locations: string[] = []
|
|
195
|
-
const home = os.homedir()
|
|
196
|
-
const homePaths = getHomePaths()
|
|
197
|
-
|
|
198
|
-
const commonPaths = [
|
|
199
|
-
homePaths.vault,
|
|
200
|
-
path.join(home, 'Documents', 'Obsidian'),
|
|
201
|
-
path.join(home, 'Obsidian'),
|
|
202
|
-
path.join(home, 'vault'),
|
|
203
|
-
path.join(home, 'Documents', 'vault'),
|
|
204
|
-
path.join(home, 'iCloud', 'Obsidian'),
|
|
205
|
-
path.join(home, 'Library', 'Mobile Documents', 'iCloud~md~obsidian', 'Documents')
|
|
206
|
-
]
|
|
207
|
-
|
|
208
|
-
for (const loc of commonPaths) {
|
|
209
|
-
try {
|
|
210
|
-
const stat = await fs.stat(loc)
|
|
211
|
-
if (stat.isDirectory()) {
|
|
212
|
-
locations.push(loc)
|
|
213
|
-
}
|
|
214
|
-
} catch {
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return locations
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
private isChromaInstalled(): boolean {
|
|
222
|
-
try {
|
|
223
|
-
execSync('chroma --version', { stdio: 'pipe', timeout: 5000 })
|
|
224
|
-
return true
|
|
225
|
-
} catch {
|
|
226
|
-
return false
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async applyConfiguration(answers: SetupAnswers): Promise<void> {
|
|
231
|
-
console.log('\n' + heading('Applying configuration...') + '\n')
|
|
232
|
-
|
|
233
|
-
const homePaths = getHomePaths()
|
|
234
|
-
|
|
235
|
-
const chromaEnvLines = answers.enableChromaDB
|
|
236
|
-
? [
|
|
237
|
-
'',
|
|
238
|
-
'# ChromaDB Configuration',
|
|
239
|
-
'CHROMA_MODE=client-server',
|
|
240
|
-
'CHROMA_HOST=localhost',
|
|
241
|
-
'CHROMA_PORT=8000',
|
|
242
|
-
'CHROMA_EMBEDDING_PROVIDER=transformers',
|
|
243
|
-
].join('\n')
|
|
244
|
-
: ''
|
|
245
|
-
|
|
246
|
-
const envContent = `# Claude Brain Configuration
|
|
247
|
-
VAULT_PATH=${answers.vaultPath}
|
|
248
|
-
LOG_LEVEL=${answers.logLevel}
|
|
249
|
-
ENABLE_FILE_WATCH=${answers.enableFileWatch}
|
|
250
|
-
DB_PATH=./data/memory.db
|
|
251
|
-
LOG_FILE_PATH=./logs/claude-brain.log
|
|
252
|
-
SERVER_NAME=claude-brain
|
|
253
|
-
${chromaEnvLines}
|
|
254
|
-
`
|
|
255
|
-
|
|
256
|
-
await withSpinner('Writing .env configuration', async () => {
|
|
257
|
-
await fs.writeFile(homePaths.env, envContent, 'utf-8')
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
await withSpinner('Creating data and log directories', async () => {
|
|
261
|
-
await fs.mkdir(homePaths.data, { recursive: true })
|
|
262
|
-
await fs.mkdir(homePaths.chroma, { recursive: true })
|
|
263
|
-
await fs.mkdir(homePaths.logs, { recursive: true })
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
if (answers.createSampleProject) {
|
|
267
|
-
await withSpinner('Creating sample project in vault', async () => {
|
|
268
|
-
await this.createSampleProject(answers.vaultPath)
|
|
269
|
-
})
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (answers.installClaudeMd) {
|
|
273
|
-
const shouldInstall = await this.confirmClaudeMdInstall()
|
|
274
|
-
if (shouldInstall) {
|
|
275
|
-
await withSpinner('Installing CLAUDE.md', async () => {
|
|
276
|
-
await this.copyClaudeMd()
|
|
277
|
-
})
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
const nextSteps: string[] = [
|
|
282
|
-
heading('Setup complete!'),
|
|
283
|
-
'',
|
|
284
|
-
dimText('Next steps:'),
|
|
285
|
-
` ${theme.primary('1.')} ${theme.bold('claude-brain install')}`,
|
|
286
|
-
` ${dimText('Register as MCP server')}`,
|
|
287
|
-
]
|
|
288
|
-
|
|
289
|
-
if (answers.enableChromaDB) {
|
|
290
|
-
nextSteps.push(
|
|
291
|
-
` ${theme.primary('2.')} ${theme.bold('claude-brain chroma install')}`,
|
|
292
|
-
` ${dimText('Install ChromaDB (if not already installed)')}`,
|
|
293
|
-
` ${theme.primary('3.')} ${theme.bold('claude-brain chroma start')}`,
|
|
294
|
-
` ${dimText('Start the ChromaDB server')}`,
|
|
295
|
-
` ${theme.primary('4.')} ${theme.bold('claude-brain health')}`,
|
|
296
|
-
` ${dimText('Verify everything works')}`,
|
|
297
|
-
)
|
|
298
|
-
} else {
|
|
299
|
-
nextSteps.push(
|
|
300
|
-
` ${theme.primary('2.')} ${theme.bold('claude-brain health')}`,
|
|
301
|
-
` ${dimText('Verify everything works')}`,
|
|
302
|
-
'',
|
|
303
|
-
dimText('Optional: Enable ChromaDB later for advanced features:'),
|
|
304
|
-
` ${dimText('claude-brain chroma install && claude-brain chroma start')}`,
|
|
305
|
-
)
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
console.log()
|
|
309
|
-
console.log(box(nextSteps.join('\n'), 'Done'))
|
|
310
|
-
console.log()
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
private async confirmClaudeMdInstall(): Promise<boolean> {
|
|
314
|
-
const sourcePath = path.join(PACKAGE_ROOT, 'assets', 'CLAUDE.md')
|
|
315
|
-
const destPath = path.join(os.homedir(), '.claude', 'CLAUDE.md')
|
|
316
|
-
|
|
317
|
-
if (!existsSync(sourcePath)) {
|
|
318
|
-
console.log(warningText('CLAUDE.md asset not found, skipping'))
|
|
319
|
-
return false
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (existsSync(destPath)) {
|
|
323
|
-
const { overwrite } = await prompts({
|
|
324
|
-
type: 'confirm',
|
|
325
|
-
name: 'overwrite',
|
|
326
|
-
message: '~/.claude/CLAUDE.md already exists. Overwrite?',
|
|
327
|
-
initial: false,
|
|
328
|
-
})
|
|
329
|
-
if (!overwrite) {
|
|
330
|
-
console.log(dimText(' Skipped CLAUDE.md installation'))
|
|
331
|
-
return false
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
return true
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
private async copyClaudeMd(): Promise<void> {
|
|
339
|
-
const sourcePath = path.join(PACKAGE_ROOT, 'assets', 'CLAUDE.md')
|
|
340
|
-
const claudeDir = path.join(os.homedir(), '.claude')
|
|
341
|
-
const destPath = path.join(claudeDir, 'CLAUDE.md')
|
|
342
|
-
await fs.mkdir(claudeDir, { recursive: true })
|
|
343
|
-
await fs.copyFile(sourcePath, destPath)
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
private async createSampleProject(vaultPath: string): Promise<void> {
|
|
347
|
-
const projectPath = path.join(vaultPath, 'Projects', 'sample-project')
|
|
348
|
-
|
|
349
|
-
await fs.mkdir(projectPath, { recursive: true })
|
|
350
|
-
|
|
351
|
-
await fs.writeFile(
|
|
352
|
-
path.join(projectPath, 'context.md'),
|
|
353
|
-
`---
|
|
354
|
-
type: project-context
|
|
355
|
-
project: sample-project
|
|
356
|
-
status: active
|
|
357
|
-
created: ${new Date().toISOString().split('T')[0]}
|
|
358
|
-
updated: ${new Date().toISOString().split('T')[0]}
|
|
359
|
-
tech_stack:
|
|
360
|
-
- TypeScript
|
|
361
|
-
- Node.js
|
|
362
|
-
tags:
|
|
363
|
-
- sample
|
|
364
|
-
---
|
|
365
|
-
|
|
366
|
-
# Sample Project
|
|
367
|
-
|
|
368
|
-
## Overview
|
|
369
|
-
This is a sample project created by Claude Brain setup wizard.
|
|
370
|
-
|
|
371
|
-
## Tech Stack
|
|
372
|
-
- TypeScript
|
|
373
|
-
- Node.js
|
|
374
|
-
- Bun
|
|
375
|
-
|
|
376
|
-
## Goals
|
|
377
|
-
- Test Claude Brain integration
|
|
378
|
-
- Learn the workflow
|
|
379
|
-
`,
|
|
380
|
-
'utf-8'
|
|
381
|
-
)
|
|
382
|
-
|
|
383
|
-
await fs.writeFile(
|
|
384
|
-
path.join(projectPath, 'progress.md'),
|
|
385
|
-
`---
|
|
386
|
-
type: progress-tracker
|
|
387
|
-
project: sample-project
|
|
388
|
-
status: in-progress
|
|
389
|
-
current_phase: setup
|
|
390
|
-
completion_percentage: 0
|
|
391
|
-
---
|
|
392
|
-
|
|
393
|
-
# Progress
|
|
394
|
-
|
|
395
|
-
## Next Steps
|
|
396
|
-
- [ ] Configure Claude Brain
|
|
397
|
-
- [ ] Test MCP integration
|
|
398
|
-
- [ ] Try all tools
|
|
399
|
-
`,
|
|
400
|
-
'utf-8'
|
|
401
|
-
)
|
|
402
|
-
|
|
403
|
-
await fs.writeFile(
|
|
404
|
-
path.join(projectPath, 'decisions.md'),
|
|
405
|
-
`---
|
|
406
|
-
type: decision-log
|
|
407
|
-
project: sample-project
|
|
408
|
-
decision_count: 0
|
|
409
|
-
---
|
|
410
|
-
|
|
411
|
-
# Decision Log
|
|
412
|
-
|
|
413
|
-
This file will track important decisions for the project.
|
|
414
|
-
`,
|
|
415
|
-
'utf-8'
|
|
416
|
-
)
|
|
417
|
-
|
|
418
|
-
await fs.writeFile(
|
|
419
|
-
path.join(projectPath, 'standards.md'),
|
|
420
|
-
`---
|
|
421
|
-
type: coding-standards
|
|
422
|
-
project: sample-project
|
|
423
|
-
---
|
|
424
|
-
|
|
425
|
-
# Coding Standards
|
|
426
|
-
|
|
427
|
-
## TypeScript
|
|
428
|
-
- Use strict mode
|
|
429
|
-
- Prefer const over let
|
|
430
|
-
`,
|
|
431
|
-
'utf-8'
|
|
432
|
-
)
|
|
433
|
-
|
|
434
|
-
const globalPath = path.join(vaultPath, 'Global')
|
|
435
|
-
await fs.mkdir(globalPath, { recursive: true })
|
|
436
|
-
|
|
437
|
-
const globalStandardsPath = path.join(globalPath, 'standards.md')
|
|
438
|
-
try {
|
|
439
|
-
await fs.access(globalStandardsPath)
|
|
440
|
-
} catch {
|
|
441
|
-
await fs.writeFile(
|
|
442
|
-
globalStandardsPath,
|
|
443
|
-
`---
|
|
444
|
-
type: global-standards
|
|
445
|
-
last_updated: ${new Date().toISOString().split('T')[0]}
|
|
446
|
-
---
|
|
447
|
-
|
|
448
|
-
# Global Coding Standards
|
|
449
|
-
|
|
450
|
-
## TypeScript
|
|
451
|
-
- Use strict mode
|
|
452
|
-
- Prefer const over let
|
|
453
|
-
- Add JSDoc comments for public APIs
|
|
454
|
-
`,
|
|
455
|
-
'utf-8'
|
|
456
|
-
)
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|