prosicht 1.0.0 → 1.2.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/README.md +43 -0
- package/index.js +168 -41
- package/package.json +16 -3
- package/tasks/todo.md +0 -21
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# prosicht
|
|
2
|
+
|
|
3
|
+
Pro Sicht AI standartlarını ve sunum altyapısını projeye indiren CLI. Şablonlar [prosicht/ai-standards](https://github.com/prosicht/ai-standards) deposundan canlı olarak çekilir.
|
|
4
|
+
|
|
5
|
+
## Kullanım
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx prosicht init
|
|
9
|
+
```
|
|
10
|
+
Önce ne yapmak istediğinizi sorar:
|
|
11
|
+
- **Uygulama:** Proje şablonunu seçersiniz (web, landing, mobile, backend); kurallar `AGENTS.md` olarak iner.
|
|
12
|
+
- **Sunum:** Etkileşimli, animasyonlu sunum altyapısı (çekirdek dosyalar, `AGENTS.md` ve çalışan bir örnek deste) bulunduğunuz klasöre iner.
|
|
13
|
+
|
|
14
|
+
Şablonu doğrudan vermek için:
|
|
15
|
+
```bash
|
|
16
|
+
npx prosicht init -t web
|
|
17
|
+
npx prosicht init -t presentation
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Güncelleme (şablon, `AGENTS.md` başındaki etiketten otomatik tespit edilir):
|
|
21
|
+
```bash
|
|
22
|
+
npx prosicht update
|
|
23
|
+
```
|
|
24
|
+
Sunum klasörlerinde `update` yalnızca çekirdek dosyaları yeniler; `scenes.js`, `sims/`, `styles/theme.css` ve `sources.md` dokunulmadan kalır.
|
|
25
|
+
|
|
26
|
+
## Sunum hazırlama
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
mkdir yeni-sunum && cd yeni-sunum
|
|
30
|
+
npx prosicht init -t presentation
|
|
31
|
+
python3 -m http.server 8000 # http://localhost:8000
|
|
32
|
+
```
|
|
33
|
+
Ardından AI aracına konuyu söyleyin: *"KOBİ'ler için yapay zekâ konusunda 10 dakikalık sunum hazırla."*
|
|
34
|
+
|
|
35
|
+
## Geliştirme
|
|
36
|
+
|
|
37
|
+
Şablonları push etmeden yerel bir sunucudan denemek için:
|
|
38
|
+
```bash
|
|
39
|
+
cd ai-standards/templates && python3 -m http.server 8765
|
|
40
|
+
PROSICHT_TEMPLATES_URL=http://127.0.0.1:8765 node /path/to/prosicht-cli/index.js init -t presentation
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Node.js 18 veya üstü gerekir.
|
package/index.js
CHANGED
|
@@ -4,86 +4,213 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { program } = require('commander');
|
|
6
6
|
const prompts = require('prompts');
|
|
7
|
+
const { version } = require('./package.json');
|
|
7
8
|
|
|
8
|
-
//
|
|
9
|
-
const BASE_URL = 'https://raw.githubusercontent.com/ProSicht/ai-standards/main/templates';
|
|
9
|
+
// PROSICHT_TEMPLATES_URL: sablonlari push etmeden yerel bir sunucudan denemek icin
|
|
10
|
+
const BASE_URL = (process.env.PROSICHT_TEMPLATES_URL || 'https://raw.githubusercontent.com/ProSicht/ai-standards/main/templates').replace(/\/+$/, '');
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
+
const KINDS = {
|
|
13
|
+
app: { title: 'Uygulama', description: 'Proje turune gore AGENTS.md (web, landing, mobile, backend)' },
|
|
14
|
+
presentation: { title: 'Sunum', description: 'Etkilesimli, animasyonlu sunum altyapisi + AGENTS.md' }
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const APP_TEMPLATES = {
|
|
12
18
|
web: { name: 'Web Application (Next.js, Shadcn, Docker)', file: 'web.md' },
|
|
13
19
|
landing: { name: 'Landing Page (SEO & Speed Focused)', file: 'landing.md' },
|
|
14
20
|
mobile: { name: 'Mobile Application', file: 'mobile.md' },
|
|
15
21
|
backend: { name: 'Backend API Service', file: 'backend.md' }
|
|
16
22
|
};
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
// Sunum tek dosya degil, klasor: dosya listesi templates/presentation/manifest.json icinde
|
|
25
|
+
const PRESENTATION = { key: 'presentation', name: 'Sunum Altyapisi', dir: 'presentation' };
|
|
26
|
+
|
|
27
|
+
const TEMPLATE_KEYS = [...Object.keys(APP_TEMPLATES), PRESENTATION.key];
|
|
28
|
+
const TAG_PATTERN = /<!--\s*template:\s*(\w+)\s*-->\n?/;
|
|
29
|
+
|
|
30
|
+
// Projedeki mevcut AGENTS.md dosyasından şablon türünü okur
|
|
31
|
+
function detectExistingTemplate() {
|
|
32
|
+
const targetPath = path.join(process.cwd(), 'AGENTS.md');
|
|
33
|
+
if (!fs.existsSync(targetPath)) return null;
|
|
34
|
+
|
|
35
|
+
const content = fs.readFileSync(targetPath, 'utf8');
|
|
36
|
+
const match = content.match(TAG_PATTERN);
|
|
37
|
+
return match ? match[1] : null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// En üste gizli metadata etiketini ekler; önceki etiket varsa temizler
|
|
41
|
+
function withTemplateTag(content, templateKey) {
|
|
42
|
+
return `<!-- template: ${templateKey} -->\n` + content.replace(TAG_PATTERN, '');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function download(url) {
|
|
46
|
+
const response = await fetch(url);
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
throw new Error(`HTTP ${response.status}: Dosya bulunamadi (${url})`);
|
|
23
49
|
}
|
|
50
|
+
return Buffer.from(await response.arrayBuffer());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function askKind() {
|
|
54
|
+
const response = await prompts({
|
|
55
|
+
type: 'select',
|
|
56
|
+
name: 'kind',
|
|
57
|
+
message: 'Ne yapmak istiyorsunuz?',
|
|
58
|
+
choices: Object.entries(KINDS).map(([value, kind]) => ({
|
|
59
|
+
title: kind.title,
|
|
60
|
+
description: kind.description,
|
|
61
|
+
value
|
|
62
|
+
}))
|
|
63
|
+
});
|
|
64
|
+
return response.kind;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function askAppTemplate(message) {
|
|
68
|
+
const response = await prompts({
|
|
69
|
+
type: 'select',
|
|
70
|
+
name: 'template',
|
|
71
|
+
message,
|
|
72
|
+
choices: Object.entries(APP_TEMPLATES).map(([key, value]) => ({
|
|
73
|
+
title: value.name,
|
|
74
|
+
value: key
|
|
75
|
+
}))
|
|
76
|
+
});
|
|
77
|
+
return response.template;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Önce tür (Uygulama / Sunum), uygulamaysa ardından şablon sorulur
|
|
81
|
+
async function askTemplate(message) {
|
|
82
|
+
const kind = await askKind();
|
|
83
|
+
if (!kind) return null;
|
|
84
|
+
if (kind === 'presentation') return PRESENTATION.key;
|
|
85
|
+
return askAppTemplate(message);
|
|
86
|
+
}
|
|
24
87
|
|
|
88
|
+
async function fetchAndSaveTemplate(templateKey) {
|
|
89
|
+
const selected = APP_TEMPLATES[templateKey];
|
|
25
90
|
const fileUrl = `${BASE_URL}/${selected.file}`;
|
|
26
91
|
console.log(`\n[Pro Sicht] "${selected.name}" sablonu indiriliyor...`);
|
|
27
92
|
|
|
28
93
|
try {
|
|
29
|
-
const
|
|
30
|
-
if (!response.ok) {
|
|
31
|
-
throw new Error(`HTTP ${response.status}: Dosya bulunamadi (${fileUrl})`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const content = await response.text();
|
|
94
|
+
const content = (await download(fileUrl)).toString('utf8');
|
|
35
95
|
const targetPath = path.join(process.cwd(), 'AGENTS.md');
|
|
96
|
+
fs.writeFileSync(targetPath, withTemplateTag(content, templateKey), 'utf8');
|
|
36
97
|
|
|
37
|
-
|
|
38
|
-
console.log(`Basarili: AGENTS.md dosyasi olusturuldu! (Sablon: ${templateKey})`);
|
|
98
|
+
console.log(`Basarili: AGENTS.md kaydedildi! (Sablon: ${templateKey})`);
|
|
39
99
|
console.log(`Konum: ${targetPath}\n`);
|
|
40
|
-
|
|
41
100
|
} catch (error) {
|
|
42
101
|
console.error('Indirme hatasi:', error.message);
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Manifest uzaktan gelir: proje klasörünün dışına yazan yolları reddet
|
|
107
|
+
function resolveInsideCwd(relPath) {
|
|
108
|
+
const root = process.cwd();
|
|
109
|
+
const target = path.resolve(root, relPath);
|
|
110
|
+
if (typeof relPath !== 'string' || path.isAbsolute(relPath) || !target.startsWith(root + path.sep)) {
|
|
111
|
+
throw new Error(`Gecersiz dosya yolu: ${relPath}`);
|
|
43
112
|
}
|
|
113
|
+
return target;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// init: çekirdek + başlangıç dosyaları (mevcut başlangıç dosyaları korunur)
|
|
117
|
+
// update: yalnızca çekirdek dosyalar; sunum içeriğine dokunulmaz
|
|
118
|
+
async function installPresentation(mode) {
|
|
119
|
+
const base = `${BASE_URL}/${PRESENTATION.dir}`;
|
|
120
|
+
console.log(`\n[Pro Sicht] Sunum altyapisi ${mode === 'update' ? 'guncelleniyor' : 'indiriliyor'}...`);
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const manifest = JSON.parse((await download(`${base}/manifest.json`)).toString('utf8'));
|
|
124
|
+
const core = Array.isArray(manifest.core) ? manifest.core : [];
|
|
125
|
+
const starter = mode === 'init' && Array.isArray(manifest.starter) ? manifest.starter : [];
|
|
126
|
+
|
|
127
|
+
const jobs = [
|
|
128
|
+
...core.map((file) => ({ file, starter: false })),
|
|
129
|
+
...starter.map((file) => ({ file, starter: true }))
|
|
130
|
+
].map((job) => ({ ...job, target: resolveInsideCwd(job.file) }));
|
|
131
|
+
const kept = jobs.filter((job) => job.starter && fs.existsSync(job.target));
|
|
132
|
+
const toWrite = jobs.filter((job) => !kept.includes(job));
|
|
133
|
+
|
|
134
|
+
// Önce hepsini indir, sonra yaz: ağ hatasında yarım kurulum kalmasın
|
|
135
|
+
const files = await Promise.all(toWrite.map(async (job) => {
|
|
136
|
+
const url = `${base}/${job.file.split('/').map(encodeURIComponent).join('/')}`;
|
|
137
|
+
let data = await download(url);
|
|
138
|
+
if (job.file === 'AGENTS.md') {
|
|
139
|
+
data = Buffer.from(withTemplateTag(data.toString('utf8'), PRESENTATION.key), 'utf8');
|
|
140
|
+
}
|
|
141
|
+
return { ...job, data };
|
|
142
|
+
}));
|
|
143
|
+
|
|
144
|
+
for (const file of files) {
|
|
145
|
+
fs.mkdirSync(path.dirname(file.target), { recursive: true });
|
|
146
|
+
fs.writeFileSync(file.target, file.data);
|
|
147
|
+
console.log(` + ${file.file}`);
|
|
148
|
+
}
|
|
149
|
+
for (const job of kept) console.log(` = ${job.file} (mevcut, korundu)`);
|
|
150
|
+
|
|
151
|
+
console.log(`Basarili: ${files.length} dosya yazildi (Sunum altyapisi v${manifest.version || '?'}).`);
|
|
152
|
+
if (mode === 'init') {
|
|
153
|
+
console.log('\nSonraki adimlar:');
|
|
154
|
+
console.log(' 1. python3 -m http.server 8000 -> http://localhost:8000 (ornek sunum)');
|
|
155
|
+
console.log(' 2. AI aracina konuyu soyleyin: "<konu> hakkinda 10 dakikalik sunum hazirla"\n');
|
|
156
|
+
} else {
|
|
157
|
+
console.log('Sunum icerigi (scenes.js, sims/, styles/theme.css, sources.md) degistirilmedi.\n');
|
|
158
|
+
}
|
|
159
|
+
} catch (error) {
|
|
160
|
+
console.error('Indirme hatasi:', error.message);
|
|
161
|
+
process.exitCode = 1;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function install(templateKey, mode) {
|
|
166
|
+
if (!TEMPLATE_KEYS.includes(templateKey)) {
|
|
167
|
+
console.error(`Hata: Gecersiz sablon "${templateKey}". Gecerli: ${TEMPLATE_KEYS.join(', ')}`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
if (templateKey === PRESENTATION.key) return installPresentation(mode);
|
|
171
|
+
return fetchAndSaveTemplate(templateKey);
|
|
44
172
|
}
|
|
45
173
|
|
|
46
174
|
program
|
|
47
175
|
.name('prosicht')
|
|
48
176
|
.description('Pro Sicht AI Standards CLI')
|
|
49
|
-
.version(
|
|
177
|
+
.version(version);
|
|
50
178
|
|
|
51
179
|
program
|
|
52
180
|
.command('init')
|
|
53
|
-
.description('Projeye AI
|
|
54
|
-
.option('-t, --template <type>',
|
|
181
|
+
.description('Projeye AI standartlarini (AGENTS.md) veya sunum altyapisini indirir')
|
|
182
|
+
.option('-t, --template <type>', `Sablon turu (${TEMPLATE_KEYS.join(', ')})`)
|
|
55
183
|
.action(async (options) => {
|
|
56
184
|
let templateKey = options.template;
|
|
57
185
|
|
|
58
186
|
if (!templateKey) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
name: 'template',
|
|
62
|
-
message: 'Lutfen bir Pro Sicht AI sablonu secin:',
|
|
63
|
-
choices: Object.entries(TEMPLATES).map(([key, value]) => ({
|
|
64
|
-
title: value.name,
|
|
65
|
-
value: key
|
|
66
|
-
}))
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
templateKey = response.template;
|
|
70
|
-
|
|
71
|
-
// Kullanıcı menüden çıkış yaparsa (Ctrl+C)
|
|
72
|
-
if (!templateKey) {
|
|
73
|
-
console.log('Islem iptal edildi.');
|
|
74
|
-
process.exit(0);
|
|
75
|
-
}
|
|
187
|
+
templateKey = await askTemplate('Lutfen bir Pro Sicht AI sablonu secin:');
|
|
188
|
+
if (!templateKey) process.exit(0);
|
|
76
189
|
}
|
|
77
190
|
|
|
78
|
-
await
|
|
191
|
+
await install(templateKey, 'init');
|
|
79
192
|
});
|
|
80
193
|
|
|
81
194
|
program
|
|
82
195
|
.command('update')
|
|
83
|
-
.description('
|
|
84
|
-
.option('-t, --template <type>', 'Sablon
|
|
196
|
+
.description('Projedeki AGENTS.md (ve sunum altyapisinin cekirdek dosyalarini) tespit edip gunceller')
|
|
197
|
+
.option('-t, --template <type>', 'Sablon turunu zorla belirle')
|
|
85
198
|
.action(async (options) => {
|
|
86
|
-
|
|
199
|
+
let templateKey = options.template;
|
|
200
|
+
|
|
201
|
+
// -t verilmediyse mevcut dosyadan otomatik tespit et
|
|
202
|
+
if (!templateKey) {
|
|
203
|
+
templateKey = detectExistingTemplate();
|
|
204
|
+
if (templateKey) {
|
|
205
|
+
console.log(`🔍 Tespit edilen mevcut sablon: "${templateKey}"`);
|
|
206
|
+
} else {
|
|
207
|
+
console.log('⚠️ Projede mevcut bir AGENTS.md veya sablon etiketi bulunamadi.');
|
|
208
|
+
templateKey = await askTemplate('Guncellemek istediginiz sablonu secin:');
|
|
209
|
+
if (!templateKey) process.exit(0);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
await install(templateKey, 'update');
|
|
87
214
|
});
|
|
88
215
|
|
|
89
216
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prosicht",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Pro Sicht AI Standards CLI",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Pro Sicht AI Standards CLI: AGENTS.md sablonlari ve sunum altyapisi",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"prosicht": "./index.js"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"index.js"
|
|
11
|
+
],
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=18"
|
|
14
|
+
},
|
|
9
15
|
"scripts": {
|
|
10
16
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
17
|
},
|
|
12
|
-
"keywords": [
|
|
18
|
+
"keywords": [
|
|
19
|
+
"ai",
|
|
20
|
+
"agents",
|
|
21
|
+
"cli",
|
|
22
|
+
"prosicht",
|
|
23
|
+
"presentation"
|
|
24
|
+
],
|
|
13
25
|
"author": "Pro Sicht",
|
|
14
26
|
"license": "MIT",
|
|
27
|
+
"homepage": "https://github.com/prosicht/ai-standards#readme",
|
|
15
28
|
"dependencies": {
|
|
16
29
|
"commander": "^11.1.0",
|
|
17
30
|
"prompts": "^2.4.2"
|
package/tasks/todo.md
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# Pro Sicht CLI Kurulumu
|
|
2
|
-
|
|
3
|
-
## Plan
|
|
4
|
-
|
|
5
|
-
- [x] Adım 1: `npm init -y` ile proje başlat
|
|
6
|
-
- [x] Adım 2: `commander` ve `prompts` kur
|
|
7
|
-
- [x] Adım 3: `package.json` (name, bin, metadata)
|
|
8
|
-
- [x] Adım 4: `index.js` CLI kodunu yaz
|
|
9
|
-
- [x] Adım 5: `npm link` ile lokal test
|
|
10
|
-
- [ ] Adım 6: NPM yayınlama (login + publish) — bu oturumda atlandı
|
|
11
|
-
|
|
12
|
-
## Review
|
|
13
|
-
|
|
14
|
-
CLI lokal olarak çalışıyor. `npm link` sonrası:
|
|
15
|
-
|
|
16
|
-
- `prosicht --help` komutları listeliyor (`init`, `update`)
|
|
17
|
-
- `prosicht init -t web` GitHub'dan şablonu çekip geçici dizine `AGENTS.md` yazdı (4446 byte, başlık: Pro Sicht Web Application AI Instructions)
|
|
18
|
-
|
|
19
|
-
Paket adı `prosicht`; `bin.prosicht` `./index.js`. npm yayını yapılmadı.
|
|
20
|
-
|
|
21
|
-
Not: GitHub `templates/` altında şu an yalnızca `web.md` var. `landing.md`, `mobile.md`, `backend.md` 404 dönüyor; CLI bunu hata mesajıyla bildiriyor. Diğer şablonlar repo'ya eklenince komutlar ek değişiklik olmadan çalışır.
|