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 +32 -12
- package/bin/akademia.js +230 -31
- package/package.json +1 -1
- package/src/format.js +7 -6
package/README.md
CHANGED
|
@@ -1,34 +1,54 @@
|
|
|
1
1
|
# Akademia CLI
|
|
2
2
|
|
|
3
|
-
|
|
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
|
|
9
|
+
akademia
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Po instalacji wpisz:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
akademia
|
|
16
|
-
akademia search "landing page"
|
|
17
|
-
akademia show wywiad-przed-startem-projektu
|
|
15
|
+
akademia
|
|
18
16
|
```
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
Program zostanie otwarty w terminalu. Wpisz frazę, której szukasz:
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
```bash
|
|
21
|
+
landing page
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Po wynikach wpisz numer, żeby otworzyć materiał:
|
|
23
25
|
|
|
24
26
|
```bash
|
|
25
|
-
|
|
27
|
+
1
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
W każdej chwili możesz wpisać:
|
|
29
31
|
|
|
30
32
|
```bash
|
|
31
|
-
|
|
33
|
+
pomoc
|
|
34
|
+
status
|
|
35
|
+
wyjdz
|
|
32
36
|
```
|
|
33
37
|
|
|
34
|
-
|
|
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.
|
|
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 (
|
|
21
|
+
if (flags.help || isHelpCommand(command)) {
|
|
20
22
|
printHelp();
|
|
21
23
|
return;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
if (command
|
|
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 (
|
|
39
|
+
if (action === "search") {
|
|
31
40
|
const query = args.join(" ").trim();
|
|
32
|
-
if (!query) throw new Error("Podaj frazę, np. akademia
|
|
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 (
|
|
51
|
+
if (action === "show") {
|
|
43
52
|
const id = args[0];
|
|
44
|
-
if (!id) throw new Error("Podaj ID zasobu, np. akademia
|
|
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 (
|
|
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 (
|
|
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(`
|
|
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
|
-
|
|
143
|
-
akademia
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
akademia
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
akademia
|
|
150
|
-
|
|
151
|
-
|
|
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
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(`
|
|
11
|
-
console.log(`
|
|
12
|
-
console.log(`
|
|
13
|
-
console.log(`
|
|
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) {
|