akademia 0.1.0 → 0.1.2

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 CHANGED
@@ -1,34 +1,54 @@
1
1
  # Akademia CLI
2
2
 
3
- CLI do publicznego API Akademia.pl.
3
+ Prosty dostęp do publicznych promptów i checklist Akademia.pl z terminala.
4
4
 
5
5
  ## Instalacja
6
6
 
7
7
  ```bash
8
8
  npm install -g akademia
9
- akademia --help
9
+ akademia
10
10
  ```
11
11
 
12
- ## Komendy
12
+ Po instalacji wpisz:
13
13
 
14
14
  ```bash
15
- akademia doctor
16
- akademia search "landing page"
17
- akademia show wywiad-przed-startem-projektu
15
+ akademia
18
16
  ```
19
17
 
20
- ## Konfiguracja
18
+ Program zostanie otwarty w terminalu. Wpisz frazę, której szukasz:
21
19
 
22
- Domyślne API:
20
+ ```bash
21
+ landing page
22
+ ```
23
+
24
+ Po wynikach wpisz numer, żeby otworzyć materiał:
23
25
 
24
26
  ```bash
25
- https://akademia.pl
27
+ 1
26
28
  ```
27
29
 
28
- Możesz podmienić endpoint:
30
+ W każdej chwili możesz wpisać:
29
31
 
30
32
  ```bash
31
- AKADEMIA_API_BASE=http://127.0.0.1:8898 akademia doctor
33
+ pomoc
34
+ status
35
+ wyjdz
32
36
  ```
33
37
 
34
- CLI V1 pobiera tylko publiczne pliki JSON. Nie wysyła kodu projektu, plików, maili ani danych klientów do Akademii.
38
+ ## Prywatność
39
+
40
+ CLI V1 pobiera tylko publiczne pliki JSON. Samo otwarcie programu i wyszukiwanie nie wysyła kodu projektu, plików, maili ani danych klientów do Akademii.
41
+
42
+ ## API
43
+
44
+ Domyślnie CLI łączy się z:
45
+
46
+ ```bash
47
+ https://akademia.pl
48
+ ```
49
+
50
+ Technicznie możesz podmienić endpoint:
51
+
52
+ ```bash
53
+ AKADEMIA_API_BASE=http://127.0.0.1:8898 akademia status
54
+ ```
package/bin/akademia.js CHANGED
@@ -1,11 +1,13 @@
1
1
  #!/usr/bin/env node
2
+ import readline from "node:readline/promises";
3
+ import { stdin as input, stdout as output } from "node:process";
2
4
  import { AkademiaClient } from "../src/client.js";
3
5
  import { writeReport } from "../src/report.js";
4
6
  import { scanProject } from "../src/scan.js";
5
7
  import { searchResources } from "../src/search.js";
6
8
  import { printDoctor, printResource, printScanResults, printSearchResults } from "../src/format.js";
7
9
 
8
- const VERSION = "0.1.0";
10
+ const VERSION = "0.1.2";
9
11
 
10
12
  async function main(argv) {
11
13
  const { command, args, flags } = parseArgs(argv);
@@ -16,20 +18,27 @@ async function main(argv) {
16
18
  return;
17
19
  }
18
20
 
19
- if (!command || flags.help) {
21
+ if (flags.help || isHelpCommand(command)) {
20
22
  printHelp();
21
23
  return;
22
24
  }
23
25
 
24
- if (command === "doctor") {
26
+ if (!command) {
27
+ await startInteractive(client);
28
+ return;
29
+ }
30
+
31
+ const action = normalizeCommand(command);
32
+
33
+ if (action === "doctor") {
25
34
  const catalog = await client.catalog();
26
35
  printDoctor(catalog, client.baseUrl);
27
36
  return;
28
37
  }
29
38
 
30
- if (command === "search") {
39
+ if (action === "search") {
31
40
  const query = args.join(" ").trim();
32
- if (!query) throw new Error("Podaj frazę, np. akademia search \"landing page\".");
41
+ if (!query) throw new Error("Podaj frazę, np. akademia szukaj \"landing page\".");
33
42
  const index = await client.searchIndex();
34
43
  const results = searchResources(index, query, {
35
44
  limit: flags.limit || 10,
@@ -39,15 +48,15 @@ async function main(argv) {
39
48
  return;
40
49
  }
41
50
 
42
- if (command === "show") {
51
+ if (action === "show") {
43
52
  const id = args[0];
44
- if (!id) throw new Error("Podaj ID zasobu, np. akademia show wywiad-przed-startem-projektu.");
53
+ if (!id) throw new Error("Podaj ID zasobu, np. akademia pokaz wywiad-przed-startem-projektu.");
45
54
  const resource = await client.resource(id);
46
55
  printResource(resource, { full: flags.full });
47
56
  return;
48
57
  }
49
58
 
50
- if (command === "scan") {
59
+ if (action === "scan") {
51
60
  const target = args[0] || ".";
52
61
  const index = await client.searchIndex();
53
62
  const result = await scanProject(target, index, {
@@ -62,7 +71,7 @@ async function main(argv) {
62
71
  return;
63
72
  }
64
73
 
65
- if (command === "report") {
74
+ if (action === "report") {
66
75
  const target = args[0] || ".";
67
76
  const index = await client.searchIndex();
68
77
  const result = await scanProject(target, index, {
@@ -75,7 +84,7 @@ async function main(argv) {
75
84
  return;
76
85
  }
77
86
 
78
- throw new Error(`Nieznana komenda: ${command}`);
87
+ throw new Error(`Nie znam tej komendy. Wpisz: akademia pomoc`);
79
88
  }
80
89
 
81
90
  function parseArgs(argv) {
@@ -136,28 +145,218 @@ function parseArgs(argv) {
136
145
  return { command, args, flags };
137
146
  }
138
147
 
148
+ function normalizeCommand(command) {
149
+ const commands = new Map([
150
+ ["doctor", "doctor"],
151
+ ["status", "doctor"],
152
+ ["search", "search"],
153
+ ["szukaj", "search"],
154
+ ["show", "show"],
155
+ ["pokaz", "show"],
156
+ ["pokaż", "show"],
157
+ ["scan", "scan"],
158
+ ["report", "report"]
159
+ ]);
160
+
161
+ return commands.get(command) || command;
162
+ }
163
+
164
+ function isHelpCommand(command) {
165
+ return command === "help" || command === "pomoc";
166
+ }
167
+
168
+ async function printStart(client) {
169
+ try {
170
+ const catalog = await client.catalog();
171
+ const resources = catalog?.resources || [];
172
+ const total = resources.length;
173
+ const prompts = resources.filter((item) => item.type === "prompt").length;
174
+ const checklists = resources.filter((item) => item.type === "checklist").length;
175
+
176
+ console.log(`Akademia.pl CLI ${VERSION}
177
+
178
+ Łączy terminal z publicznymi promptami i checklistami Akademii.
179
+
180
+ Status: działa
181
+ Zasoby: ${total} publicznych materiałów, ${prompts} promptów, ${checklists} checklist
182
+
183
+ Następny krok:
184
+ akademia pomoc
185
+ `);
186
+ return;
187
+ } catch (error) {
188
+ console.log(`Akademia.pl CLI ${VERSION}
189
+
190
+ CLI jest zainstalowane, ale nie udało się połączyć z Akademia.pl.
191
+
192
+ Następny krok:
193
+ akademia pomoc
194
+
195
+ Szczegół techniczny: ${error.message}
196
+ `);
197
+ }
198
+ }
199
+
200
+ async function startInteractive(client) {
201
+ let catalog;
202
+ try {
203
+ catalog = await client.catalog();
204
+ } catch (error) {
205
+ printOfflineStart(error);
206
+ return;
207
+ }
208
+
209
+ printInteractiveStart(catalog);
210
+
211
+ const rl = readline.createInterface({ input, output });
212
+ let lastResults = [];
213
+
214
+ try {
215
+ rl.setPrompt("> ");
216
+ promptAgain(rl);
217
+
218
+ for await (const line of rl) {
219
+ const answer = line.trim();
220
+ const normalized = answer.toLowerCase();
221
+
222
+ if (!answer) {
223
+ promptAgain(rl);
224
+ continue;
225
+ }
226
+
227
+ if (["wyjdz", "wyjdź", "exit", "quit", "q"].includes(normalized)) {
228
+ console.log("Do zobaczenia.");
229
+ return;
230
+ }
231
+
232
+ if (isHelpCommand(normalized)) {
233
+ printInteractiveHelp();
234
+ promptAgain(rl);
235
+ continue;
236
+ }
237
+
238
+ if (normalizeCommand(normalized) === "doctor") {
239
+ const freshCatalog = await client.catalog();
240
+ printDoctor(freshCatalog, client.baseUrl);
241
+ console.log("");
242
+ promptAgain(rl);
243
+ continue;
244
+ }
245
+
246
+ const resourceId = parseShowInput(answer);
247
+ if (resourceId) {
248
+ const resource = await client.resource(resourceId);
249
+ printResource(resource, { full: false });
250
+ console.log("");
251
+ promptAgain(rl);
252
+ continue;
253
+ }
254
+
255
+ if (/^\d+$/.test(answer) && lastResults[Number(answer) - 1]) {
256
+ const resource = await client.resource(lastResults[Number(answer) - 1].id);
257
+ printResource(resource, { full: false });
258
+ console.log("");
259
+ promptAgain(rl);
260
+ continue;
261
+ }
262
+
263
+ const index = await client.searchIndex();
264
+ lastResults = searchResources(index, stripSearchPrefix(answer), { limit: 5 });
265
+ printInteractiveSearchResults(lastResults);
266
+ promptAgain(rl);
267
+ }
268
+ } finally {
269
+ rl.close();
270
+ }
271
+ }
272
+
273
+ function promptAgain(rl) {
274
+ if (input.isTTY) rl.prompt();
275
+ }
276
+
277
+ function printInteractiveStart(catalog) {
278
+ const resources = catalog?.resources || [];
279
+ const prompts = resources.filter((item) => item.type === "prompt").length;
280
+ const checklists = resources.filter((item) => item.type === "checklist").length;
281
+
282
+ console.log(`Akademia.pl CLI ${VERSION}
283
+
284
+ Działa. Masz dostęp do ${resources.length} publicznych materiałów.
285
+ Prompty: ${prompts}. Checklisty: ${checklists}.
286
+
287
+ Wpisz, czego szukasz, np. landing page.
288
+ Możesz też wpisać: pomoc, status, wyjdz.
289
+ `);
290
+ }
291
+
292
+ function printOfflineStart(error) {
293
+ console.log(`Akademia.pl CLI ${VERSION}
294
+
295
+ CLI jest zainstalowane, ale nie udało się połączyć z Akademia.pl.
296
+
297
+ Wpisz:
298
+ akademia pomoc
299
+
300
+ Szczegół techniczny: ${error.message}
301
+ `);
302
+ }
303
+
304
+ function printInteractiveHelp() {
305
+ console.log(`
306
+ Wpisz frazę, której szukasz:
307
+ landing page
308
+ umowa
309
+ oferta
310
+
311
+ Po wynikach wpisz numer, żeby otworzyć materiał:
312
+ 1
313
+
314
+ Inne komendy:
315
+ status
316
+ wyjdz
317
+ `);
318
+ }
319
+
320
+ function parseShowInput(value) {
321
+ const match = value.match(/^(pokaz|pokaż|show)\s+(.+)$/i);
322
+ return match ? match[2].trim() : "";
323
+ }
324
+
325
+ function stripSearchPrefix(value) {
326
+ return value.replace(/^(szukaj|search)\s+/i, "").trim();
327
+ }
328
+
329
+ function printInteractiveSearchResults(results) {
330
+ if (!results.length) {
331
+ console.log("Nie znalazłem pasujących materiałów. Spróbuj inną frazę.");
332
+ console.log("");
333
+ return;
334
+ }
335
+
336
+ console.log("Znalazłem:");
337
+ for (const [index, item] of results.entries()) {
338
+ console.log(`${index + 1}. ${item.title}`);
339
+ console.log(` ${item.type === "prompt" ? "prompt" : "checklista"}, ${item.application || item.applicationSlug || "Akademia"}`);
340
+ }
341
+ console.log("");
342
+ console.log("Wpisz numer, żeby otworzyć materiał, albo wpisz kolejną frazę.");
343
+ console.log("");
344
+ }
345
+
139
346
  function printHelp() {
140
- console.log(`Akademia CLI ${VERSION}
141
-
142
- Użycie:
143
- akademia doctor
144
- akademia search "landing page"
145
- akademia search "umowa" --type prompt --limit 5
146
- akademia show wywiad-przed-startem-projektu
147
- akademia show wywiad-przed-startem-projektu --full
148
- akademia scan .
149
- akademia scan . --limit 5 --max-files 120
150
- akademia report .
151
- akademia report . --out raport-akademii.md
152
-
153
- Flagi:
154
- --base-url URL Nadpisuje API, domyślnie https://akademia.pl
155
- --type TYPE Filtruje search po typie: prompt albo checklist
156
- --limit N Limit wyników search
157
- --max-files N Limit plików czytanych przez scan
158
- --out PATH Ścieżka raportu Markdown dla report
159
- --full Pokazuje pełną treść w show
160
- --json Zwraca wynik scan jako JSON
347
+ console.log(`Akademia.pl CLI ${VERSION}
348
+
349
+ Najprościej:
350
+ akademia
351
+
352
+ Szukaj promptu albo checklisty:
353
+ akademia szukaj "landing page"
354
+
355
+ Pokaż konkretny materiał:
356
+ akademia pokaz wywiad-przed-startem-projektu
357
+
358
+ Sprawdź połączenie:
359
+ akademia status
161
360
  `);
162
361
  }
163
362
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akademia",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "CLI Akademia.pl do lokalnego dostępu do promptów i checklist.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/format.js CHANGED
@@ -4,14 +4,15 @@ export function printDoctor(catalog, baseUrl) {
4
4
  const prompts = resources.filter((item) => item.type === "prompt").length;
5
5
  const checklists = resources.filter((item) => item.type === "checklist").length;
6
6
  const security = meta.security || {};
7
+ const connection = resources.length ? "działa" : "brak publicznych zasobów";
7
8
 
8
- console.log("Akademia CLI");
9
+ console.log("Akademia.pl CLI");
10
+ console.log(`Status: ${connection}`);
9
11
  console.log(`API: ${baseUrl}`);
10
- console.log(`Wersja API: ${meta.version || "brak"}`);
11
- console.log(`Zasoby: ${resources.length}, prompty: ${prompts}, checklisty: ${checklists}`);
12
- console.log(`Tryb: ${security.mode || "brak"}`);
13
- console.log(`Przyjmuje dane projektu: ${security.acceptsProjectFiles ? "tak" : "nie"}`);
14
- console.log(`LLM po stronie serwera: ${security.serverSideLlm ? "tak" : "nie"}`);
12
+ console.log(`Zasoby: ${resources.length} publicznych materiałów`);
13
+ console.log(`Prompty: ${prompts}`);
14
+ console.log(`Checklisty: ${checklists}`);
15
+ console.log(`Pliki z Twojego komputera: ${security.acceptsProjectFiles ? "wysyłane" : "nie są wysyłane"}`);
15
16
  }
16
17
 
17
18
  export function printSearchResults(results) {