onlymcp 0.17.0 → 0.20.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/LICENSE +33 -17
- package/README.md +2 -1
- package/dist/bin/cli.js +68 -583
- package/dist/bin/mcp.js +45 -73
- package/package.json +7 -10
- package/dist/apiBaseUrl.d.ts +0 -12
- package/dist/apiBaseUrl.js +0 -28
- package/dist/apiBaseUrl.js.map +0 -1
- package/dist/apiClient.d.ts +0 -296
- package/dist/apiClient.js +0 -224
- package/dist/apiClient.js.map +0 -1
- package/dist/auth/deviceLogin.d.ts +0 -5
- package/dist/auth/deviceLogin.js +0 -40
- package/dist/auth/deviceLogin.js.map +0 -1
- package/dist/auth/keyring.d.ts +0 -16
- package/dist/auth/keyring.js +0 -33
- package/dist/auth/keyring.js.map +0 -1
- package/dist/bin/cli.d.ts +0 -2
- package/dist/bin/cli.js.map +0 -1
- package/dist/bin/mcp.d.ts +0 -2
- package/dist/bin/mcp.js.map +0 -1
- package/dist/cache.d.ts +0 -7
- package/dist/cache.js +0 -32
- package/dist/cache.js.map +0 -1
- package/dist/deviceId.d.ts +0 -2
- package/dist/deviceId.js +0 -97
- package/dist/deviceId.js.map +0 -1
- package/dist/export/unpack.d.ts +0 -33
- package/dist/export/unpack.js +0 -54
- package/dist/export/unpack.js.map +0 -1
- package/dist/identity.d.ts +0 -29
- package/dist/identity.js +0 -116
- package/dist/identity.js.map +0 -1
- package/dist/import/collect.d.ts +0 -25
- package/dist/import/collect.js +0 -101
- package/dist/import/collect.js.map +0 -1
- package/dist/import/frontmatter.d.ts +0 -44
- package/dist/import/frontmatter.js +0 -93
- package/dist/import/frontmatter.js.map +0 -1
- package/dist/import/plan.d.ts +0 -74
- package/dist/import/plan.js +0 -190
- package/dist/import/plan.js.map +0 -1
- package/dist/import/prune.d.ts +0 -46
- package/dist/import/prune.js +0 -61
- package/dist/import/prune.js.map +0 -1
- package/dist/import/secrets.d.ts +0 -7
- package/dist/import/secrets.js +0 -77
- package/dist/import/secrets.js.map +0 -1
- package/dist/import/upload.d.ts +0 -21
- package/dist/import/upload.js +0 -99
- package/dist/import/upload.js.map +0 -1
- package/dist/install.d.ts +0 -81
- package/dist/install.js +0 -168
- package/dist/install.js.map +0 -1
- package/dist/instructions.d.ts +0 -4
- package/dist/instructions.js +0 -67
- package/dist/instructions.js.map +0 -1
- package/dist/memoryPath.d.ts +0 -1
- package/dist/memoryPath.js +0 -13
- package/dist/memoryPath.js.map +0 -1
- package/dist/memorySync.d.ts +0 -28
- package/dist/memorySync.js +0 -56
- package/dist/memorySync.js.map +0 -1
- package/dist/paths.d.ts +0 -18
- package/dist/paths.js +0 -62
- package/dist/paths.js.map +0 -1
- package/dist/registry/caveats.d.ts +0 -17
- package/dist/registry/caveats.js +0 -74
- package/dist/registry/caveats.js.map +0 -1
- package/dist/registry/clients.d.ts +0 -17
- package/dist/registry/clients.js +0 -402
- package/dist/registry/clients.js.map +0 -1
- package/dist/registry/index.d.ts +0 -6
- package/dist/registry/index.js +0 -7
- package/dist/registry/index.js.map +0 -1
- package/dist/registry/serverInfo.d.ts +0 -25
- package/dist/registry/serverInfo.js +0 -33
- package/dist/registry/serverInfo.js.map +0 -1
- package/dist/registry/servers.d.ts +0 -58
- package/dist/registry/servers.js +0 -259
- package/dist/registry/servers.js.map +0 -1
- package/dist/registry/toolHints.d.ts +0 -29
- package/dist/registry/toolHints.js +0 -41
- package/dist/registry/toolHints.js.map +0 -1
- package/dist/registry/types.d.ts +0 -71
- package/dist/registry/types.js +0 -6
- package/dist/registry/types.js.map +0 -1
- package/dist/skillFilePath.d.ts +0 -1
- package/dist/skillFilePath.js +0 -29
- package/dist/skillFilePath.js.map +0 -1
- package/dist/stubIgnore.d.ts +0 -22
- package/dist/stubIgnore.js +0 -29
- package/dist/stubIgnore.js.map +0 -1
- package/dist/stubs.d.ts +0 -12
- package/dist/stubs.js +0 -188
- package/dist/stubs.js.map +0 -1
- package/dist/tools/connections.d.ts +0 -154
- package/dist/tools/connections.js +0 -164
- package/dist/tools/connections.js.map +0 -1
- package/dist/tools/getAgentDefinition.d.ts +0 -26
- package/dist/tools/getAgentDefinition.js +0 -29
- package/dist/tools/getAgentDefinition.js.map +0 -1
- package/dist/tools/getSkill.d.ts +0 -26
- package/dist/tools/getSkill.js +0 -26
- package/dist/tools/getSkill.js.map +0 -1
- package/dist/tools/getSkillFile.d.ts +0 -27
- package/dist/tools/getSkillFile.js +0 -39
- package/dist/tools/getSkillFile.js.map +0 -1
- package/dist/tools/index.d.ts +0 -263
- package/dist/tools/index.js +0 -69
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/lists.d.ts +0 -38
- package/dist/tools/lists.js +0 -39
- package/dist/tools/lists.js.map +0 -1
- package/dist/tools/memoryGraph.d.ts +0 -69
- package/dist/tools/memoryGraph.js +0 -128
- package/dist/tools/memoryGraph.js.map +0 -1
- package/dist/tools/memoryRead.d.ts +0 -25
- package/dist/tools/memoryRead.js +0 -33
- package/dist/tools/memoryRead.js.map +0 -1
- package/dist/tools/memoryWrite.d.ts +0 -27
- package/dist/tools/memoryWrite.js +0 -34
- package/dist/tools/memoryWrite.js.map +0 -1
- package/dist/tools/write.d.ts +0 -166
- package/dist/tools/write.js +0 -193
- package/dist/tools/write.js.map +0 -1
package/dist/export/unpack.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { dirname, resolve, sep } from 'node:path';
|
|
3
|
-
import { unzipSync } from 'fflate';
|
|
4
|
-
/**
|
|
5
|
-
* An export archive laid out as plain files (package 03 task 12a, spec 8a).
|
|
6
|
-
*
|
|
7
|
-
* The result is exactly the directory `onlymcp import` reads back:
|
|
8
|
-
* `memory/`, `skills/<name>/`, `agents/`, plus `connections.json` and
|
|
9
|
-
* `manifest.json`, which the import ignores and a person can read.
|
|
10
|
-
*
|
|
11
|
-
* Two guards stand between a name inside the archive and a path on the disk,
|
|
12
|
-
* and neither is the other's duplicate. The first refuses what a zip entry
|
|
13
|
-
* must never contain - an absolute path, a `..` segment, a backslash that
|
|
14
|
-
* Windows would read as a separator. The second resolves the result and
|
|
15
|
-
* refuses anything that did not land under `dir` anyway. A zip is a file
|
|
16
|
-
* format anybody can hand us, so "our own server wrote it" is not a reason to
|
|
17
|
-
* trust a path in it.
|
|
18
|
-
*/
|
|
19
|
-
export async function unpackArchive(bytes, dir) {
|
|
20
|
-
const base = resolve(dir);
|
|
21
|
-
await mkdir(base, { recursive: true });
|
|
22
|
-
const result = { written: 0, refused: [], failed: [] };
|
|
23
|
-
const files = unzipSync(bytes);
|
|
24
|
-
for (const [name, data] of Object.entries(files)) {
|
|
25
|
-
// A directory entry carries no content and needs no file of its own; the
|
|
26
|
-
// files under it create it.
|
|
27
|
-
if (name.endsWith('/'))
|
|
28
|
-
continue;
|
|
29
|
-
const segments = name.split('/');
|
|
30
|
-
const unsafe = name.startsWith('/') ||
|
|
31
|
-
/^[a-zA-Z]:/.test(name) ||
|
|
32
|
-
name.includes('\\') ||
|
|
33
|
-
segments.some((s) => s === '' || s === '.' || s === '..');
|
|
34
|
-
if (unsafe) {
|
|
35
|
-
result.refused.push(name);
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
const dest = resolve(base, ...segments);
|
|
39
|
-
if (!dest.startsWith(base + sep)) {
|
|
40
|
-
result.refused.push(name);
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
try {
|
|
44
|
-
await mkdir(dirname(dest), { recursive: true });
|
|
45
|
-
await writeFile(dest, data);
|
|
46
|
-
result.written += 1;
|
|
47
|
-
}
|
|
48
|
-
catch (e) {
|
|
49
|
-
result.failed.push({ path: name, reason: e instanceof Error ? e.message : String(e) });
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return result;
|
|
53
|
-
}
|
|
54
|
-
//# sourceMappingURL=unpack.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"unpack.js","sourceRoot":"","sources":["../../src/export/unpack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAiBnC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAiB,EAAE,GAAW;IAChE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvC,MAAM,MAAM,GAAiB,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACrE,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAE/B,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,yEAAyE;QACzE,4BAA4B;QAC5B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QAEjC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,MAAM,GACV,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACnB,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAC5D,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC5B,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;QACtB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/identity.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wer hier anruft.
|
|
3
|
-
*
|
|
4
|
-
* Drei Koepfe, alle auf jeder Anfrage:
|
|
5
|
-
*
|
|
6
|
-
* - `user-agent`: ohne ihn schickt Node die Zeichenkette `node`, Better Auth
|
|
7
|
-
* legt sie unveraendert ab, und in der Geraeteliste steht dann ein Geraet
|
|
8
|
-
* namens **node**. Drei davon beantworten keine einzige Frage, fuer die es
|
|
9
|
-
* diese Liste gibt.
|
|
10
|
-
* - `x-onlymcp-device`: die Maschine. Rechnername, und wenn er billig zu
|
|
11
|
-
* haben ist, das Modell - "ThinkPad T15 Gen 1" erkennt man wieder, "fpa-2"
|
|
12
|
-
* nicht unbedingt.
|
|
13
|
-
*
|
|
14
|
-
* - `x-onlymcp-device-id`: a random id that stays with this machine, so a
|
|
15
|
-
* second login is the same device (see deviceId.ts). Absent when the id
|
|
16
|
-
* file can be neither read nor written.
|
|
17
|
-
*
|
|
18
|
-
* Beides ist ein Etikett, kein Zugang. Nichts davon darf einen Befehl
|
|
19
|
-
* scheitern lassen, und nichts davon darf ihn spuerbar verzoegern: das Lesen
|
|
20
|
-
* des Modells bekommt 200 ms und wird sonst weggeworfen.
|
|
21
|
-
*
|
|
22
|
-
* Privat bleibt privat: die beiden Werte sieht nur der Kontoinhaber in seiner
|
|
23
|
-
* eigenen Geraeteliste. `onlymcp login` sagt beim Anmelden einmal, was es
|
|
24
|
-
* schickt - wer das nicht will, soll es wissen, bevor es passiert.
|
|
25
|
-
*/
|
|
26
|
-
export declare const USER_AGENT: string;
|
|
27
|
-
/** Rechnername plus Modell, so weit vorhanden. Nie laenger als 60 Zeichen. */
|
|
28
|
-
export declare function deviceLabel(): Promise<string>;
|
|
29
|
-
export declare function identityHeaders(): Promise<Record<string, string>>;
|
package/dist/identity.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { execFile } from 'node:child_process';
|
|
2
|
-
import { hostname } from 'node:os';
|
|
3
|
-
import { readFile } from 'node:fs/promises';
|
|
4
|
-
import { createRequire } from 'node:module';
|
|
5
|
-
import { promisify } from 'node:util';
|
|
6
|
-
import { deviceId } from './deviceId.js';
|
|
7
|
-
const execFileAsync = promisify(execFile);
|
|
8
|
-
const { version } = createRequire(import.meta.url)('../package.json');
|
|
9
|
-
/**
|
|
10
|
-
* Wer hier anruft.
|
|
11
|
-
*
|
|
12
|
-
* Drei Koepfe, alle auf jeder Anfrage:
|
|
13
|
-
*
|
|
14
|
-
* - `user-agent`: ohne ihn schickt Node die Zeichenkette `node`, Better Auth
|
|
15
|
-
* legt sie unveraendert ab, und in der Geraeteliste steht dann ein Geraet
|
|
16
|
-
* namens **node**. Drei davon beantworten keine einzige Frage, fuer die es
|
|
17
|
-
* diese Liste gibt.
|
|
18
|
-
* - `x-onlymcp-device`: die Maschine. Rechnername, und wenn er billig zu
|
|
19
|
-
* haben ist, das Modell - "ThinkPad T15 Gen 1" erkennt man wieder, "fpa-2"
|
|
20
|
-
* nicht unbedingt.
|
|
21
|
-
*
|
|
22
|
-
* - `x-onlymcp-device-id`: a random id that stays with this machine, so a
|
|
23
|
-
* second login is the same device (see deviceId.ts). Absent when the id
|
|
24
|
-
* file can be neither read nor written.
|
|
25
|
-
*
|
|
26
|
-
* Beides ist ein Etikett, kein Zugang. Nichts davon darf einen Befehl
|
|
27
|
-
* scheitern lassen, und nichts davon darf ihn spuerbar verzoegern: das Lesen
|
|
28
|
-
* des Modells bekommt 200 ms und wird sonst weggeworfen.
|
|
29
|
-
*
|
|
30
|
-
* Privat bleibt privat: die beiden Werte sieht nur der Kontoinhaber in seiner
|
|
31
|
-
* eigenen Geraeteliste. `onlymcp login` sagt beim Anmelden einmal, was es
|
|
32
|
-
* schickt - wer das nicht will, soll es wissen, bevor es passiert.
|
|
33
|
-
*/
|
|
34
|
-
export const USER_AGENT = `onlymcp-cli/${version} (${process.platform} ${process.arch}; node ${process.versions.node})`;
|
|
35
|
-
const MODEL_TIMEOUT_MS = 200;
|
|
36
|
-
async function withTimeout(work, ms) {
|
|
37
|
-
let timer;
|
|
38
|
-
try {
|
|
39
|
-
return await Promise.race([
|
|
40
|
-
work,
|
|
41
|
-
new Promise((resolve) => {
|
|
42
|
-
timer = setTimeout(() => resolve(null), ms);
|
|
43
|
-
// Ein offener Timer darf den Prozess nicht am Beenden hindern.
|
|
44
|
-
timer.unref?.();
|
|
45
|
-
}),
|
|
46
|
-
]);
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
finally {
|
|
52
|
-
if (timer)
|
|
53
|
-
clearTimeout(timer);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Das Maschinenmodell, wenn es ohne Aufwand zu lesen ist.
|
|
58
|
-
*
|
|
59
|
-
* Linux: /sys/class/dmi/id/product_version - eine Datei, kein Prozess.
|
|
60
|
-
* macOS: sysctl -n hw.model.
|
|
61
|
-
* Windows: nichts. Der Weg dorthin ginge ueber WMI, und das ist ein Prozess
|
|
62
|
-
* mit mehreren hundert Millisekunden Startzeit fuer eine Beschriftung.
|
|
63
|
-
*/
|
|
64
|
-
async function machineModel() {
|
|
65
|
-
try {
|
|
66
|
-
if (process.platform === 'linux') {
|
|
67
|
-
const read = readFile('/sys/class/dmi/id/product_version', 'utf8');
|
|
68
|
-
const raw = await withTimeout(read, MODEL_TIMEOUT_MS);
|
|
69
|
-
const value = raw?.trim();
|
|
70
|
-
// Hersteller lassen das Feld gern mit Platzhaltern stehen.
|
|
71
|
-
if (!value || /^(to be filled|default string|system version|none|n\/a)/i.test(value))
|
|
72
|
-
return null;
|
|
73
|
-
return value;
|
|
74
|
-
}
|
|
75
|
-
if (process.platform === 'darwin') {
|
|
76
|
-
const run = execFileAsync('sysctl', ['-n', 'hw.model']);
|
|
77
|
-
const out = await withTimeout(run, MODEL_TIMEOUT_MS);
|
|
78
|
-
return out?.stdout.trim() || null;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
// Kein Modell ist ein vollstaendig annehmbares Ergebnis.
|
|
83
|
-
}
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
/** Rechnername plus Modell, so weit vorhanden. Nie laenger als 60 Zeichen. */
|
|
87
|
-
export async function deviceLabel() {
|
|
88
|
-
let host = 'unknown';
|
|
89
|
-
try {
|
|
90
|
-
host = hostname() || 'unknown';
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
// Ein Rechner ohne Namen ist selten, aber kein Grund abzubrechen.
|
|
94
|
-
}
|
|
95
|
-
const model = await machineModel();
|
|
96
|
-
const label = model && model !== host ? `${host} (${model})` : host;
|
|
97
|
-
return label.slice(0, 60);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Die Koepfe fuer jede Anfrage.
|
|
101
|
-
*
|
|
102
|
-
* Das Etikett wird einmal ermittelt und dann behalten: es aendert sich
|
|
103
|
-
* waehrend eines Prozesslebens nicht, und `onlymcp import` macht hunderte
|
|
104
|
-
* Anfragen hintereinander.
|
|
105
|
-
*/
|
|
106
|
-
let cachedLabel = null;
|
|
107
|
-
export async function identityHeaders() {
|
|
108
|
-
cachedLabel ??= await deviceLabel();
|
|
109
|
-
const id = await deviceId();
|
|
110
|
-
return {
|
|
111
|
-
'user-agent': USER_AGENT,
|
|
112
|
-
'x-onlymcp-device': cachedLabel,
|
|
113
|
-
...(id ? { 'x-onlymcp-device-id': id } : {}),
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
//# sourceMappingURL=identity.js.map
|
package/dist/identity.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"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"}
|
package/dist/import/collect.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { type SecretHit } from './secrets.js';
|
|
2
|
-
export type Candidate = {
|
|
3
|
-
absolute: string;
|
|
4
|
-
relative: string;
|
|
5
|
-
bytes: number;
|
|
6
|
-
binary: boolean;
|
|
7
|
-
hits: SecretHit[];
|
|
8
|
-
/**
|
|
9
|
-
* `'stub'` ist der einzige Grund, der aus dem INHALT kommt und nicht aus
|
|
10
|
-
* dem Namen oder der Groesse: die Datei traegt `x-onlymcp-stub: true` und
|
|
11
|
-
* wurde damit von `onlymcp sync` selbst geschrieben. Seit Aufgabe 12 liegen
|
|
12
|
-
* diese Platzhalter in denselben Ordnern, die der Import liest, also muss
|
|
13
|
-
* genau hier der Kreis unterbrochen werden.
|
|
14
|
-
*/
|
|
15
|
-
skip: null | 'denied-name' | 'too-large' | 'stub';
|
|
16
|
-
/**
|
|
17
|
-
* Die `description` aus dem YAML-Kopf, sofern die Datei einen hat. Nur fuer
|
|
18
|
-
* Markdown gelesen; fuer alles andere `null`. Der Planer nimmt sie aus der
|
|
19
|
-
* SKILL.md, der Rest der Kandidaten traegt sie ungenutzt mit.
|
|
20
|
-
*/
|
|
21
|
-
description: string | null;
|
|
22
|
-
};
|
|
23
|
-
export declare function collect(root: string, opts?: {
|
|
24
|
-
maxBytes?: number;
|
|
25
|
-
}): Promise<Candidate[]>;
|
package/dist/import/collect.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { readdir, readFile, realpath, stat } from 'node:fs/promises';
|
|
2
|
-
import { join, relative, resolve, sep } from 'node:path';
|
|
3
|
-
import { descriptionOf, isStub } from './frontmatter.js';
|
|
4
|
-
import { isDeniedName, scanForSecrets } from './secrets.js';
|
|
5
|
-
/**
|
|
6
|
-
* Verzeichnisse, die nie hochzuladen sind und haeufig gross. Sie fallen
|
|
7
|
-
* stillschweigend weg statt gemeldet zu werden: ein Bericht mit 4000 Zeilen
|
|
8
|
-
* aus node_modules begraebt genau die Funde, auf die es ankommt.
|
|
9
|
-
*/
|
|
10
|
-
const DENIED_DIRS = new Set([
|
|
11
|
-
'.git', 'node_modules', '__pycache__', '.venv', 'venv',
|
|
12
|
-
'.pytest_cache', '.mypy_cache', 'dist', 'build', '.next', '.cache',
|
|
13
|
-
]);
|
|
14
|
-
const DEFAULT_MAX_BYTES = 2 * 1024 * 1024;
|
|
15
|
-
/** Ein NUL-Byte in den ersten 8 KB - dieselbe Heuristik wie bei `git` und `grep`. */
|
|
16
|
-
function looksBinary(buf) {
|
|
17
|
-
return buf.subarray(0, 8192).includes(0);
|
|
18
|
-
}
|
|
19
|
-
export async function collect(root, opts = {}) {
|
|
20
|
-
const maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
21
|
-
// Die echte Wurzel, einmal aufgeloest. Jeder Kandidat wird gegen sie
|
|
22
|
-
// geprueft und nicht gegen die Zeichenkette, die der Aufrufer uebergab:
|
|
23
|
-
// eine verlinkte Wurzel funktioniert damit weiterhin, ein Link aus ihr
|
|
24
|
-
// heraus nicht.
|
|
25
|
-
const base = await realpath(resolve(root));
|
|
26
|
-
const out = [];
|
|
27
|
-
async function walk(dir) {
|
|
28
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
29
|
-
for (const entry of entries) {
|
|
30
|
-
const abs = join(dir, entry.name);
|
|
31
|
-
if (entry.isDirectory()) {
|
|
32
|
-
if (DENIED_DIRS.has(entry.name))
|
|
33
|
-
continue;
|
|
34
|
-
await walk(abs);
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
// Ein Symlink wird aufgeloest und danach geprueft. `isDirectory()` ist
|
|
38
|
-
// fuer einen Symlink falsch, also landen Links hier - und das ist die
|
|
39
|
-
// einzige Stelle, an der der Baum ueberhaupt verlassen werden koennte.
|
|
40
|
-
let real;
|
|
41
|
-
try {
|
|
42
|
-
real = await realpath(abs);
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
continue; // ins Leere zeigender Link
|
|
46
|
-
}
|
|
47
|
-
if (real !== base && !real.startsWith(base + sep))
|
|
48
|
-
continue;
|
|
49
|
-
const rel = relative(base, real).split(sep).join('/');
|
|
50
|
-
if (isDeniedName(entry.name)) {
|
|
51
|
-
// Gemeldet, aber nie geoeffnet. Genau dafuer gibt es eine Namensregel.
|
|
52
|
-
out.push({
|
|
53
|
-
absolute: real,
|
|
54
|
-
relative: rel,
|
|
55
|
-
bytes: 0,
|
|
56
|
-
binary: false,
|
|
57
|
-
hits: [],
|
|
58
|
-
skip: 'denied-name',
|
|
59
|
-
description: null,
|
|
60
|
-
});
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
const info = await stat(real);
|
|
64
|
-
if (!info.isFile())
|
|
65
|
-
continue;
|
|
66
|
-
if (info.size > maxBytes) {
|
|
67
|
-
out.push({
|
|
68
|
-
absolute: real,
|
|
69
|
-
relative: rel,
|
|
70
|
-
bytes: info.size,
|
|
71
|
-
binary: false,
|
|
72
|
-
hits: [],
|
|
73
|
-
skip: 'too-large',
|
|
74
|
-
description: null,
|
|
75
|
-
});
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
const buf = await readFile(real);
|
|
79
|
-
const binary = looksBinary(buf);
|
|
80
|
-
// Der Kopf wird nur fuer Markdown gelesen. Er kostet sonst eine
|
|
81
|
-
// Zeichenkette pro Datei fuer eine Frage, die sich bei einer .ttf nie
|
|
82
|
-
// mit ja beantwortet.
|
|
83
|
-
const text = !binary && rel.toLowerCase().endsWith('.md') ? buf.toString('utf8') : null;
|
|
84
|
-
out.push({
|
|
85
|
-
absolute: real,
|
|
86
|
-
relative: rel,
|
|
87
|
-
bytes: info.size,
|
|
88
|
-
binary,
|
|
89
|
-
// Eine Binaerdatei nach Textmustern zu durchsuchen ergibt Rauschen,
|
|
90
|
-
// keine Funde.
|
|
91
|
-
hits: binary ? [] : scanForSecrets(buf.toString('utf8')),
|
|
92
|
-
skip: text !== null && isStub(text) ? 'stub' : null,
|
|
93
|
-
description: text === null ? null : (descriptionOf(text) || null),
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
await walk(base);
|
|
98
|
-
out.sort((a, b) => a.relative.localeCompare(b.relative));
|
|
99
|
-
return out;
|
|
100
|
-
}
|
|
101
|
-
//# sourceMappingURL=collect.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"collect.js","sourceRoot":"","sources":["../../src/import/collect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAkB,MAAM,cAAc,CAAC;AAE5E;;;;GAIG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM;IACtD,eAAe,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ;CACnE,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAwB1C,qFAAqF;AACrF,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAY,EACZ,OAA8B,EAAE;IAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IACpD,qEAAqE;IACrE,wEAAwE;IACxE,uEAAuE;IACvE,gBAAgB;IAChB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAgB,EAAE,CAAC;IAE5B,KAAK,UAAU,IAAI,CAAC,GAAW;QAC7B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAC1C,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;gBAChB,SAAS;YACX,CAAC;YACD,uEAAuE;YACvE,sEAAsE;YACtE,uEAAuE;YACvE,IAAI,IAAY,CAAC;YACjB,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS,CAAC,2BAA2B;YACvC,CAAC;YACD,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC;gBAAE,SAAS;YAE5D,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtD,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,uEAAuE;gBACvE,GAAG,CAAC,IAAI,CAAC;oBACP,QAAQ,EAAE,IAAI;oBACd,QAAQ,EAAE,GAAG;oBACb,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,KAAK;oBACb,IAAI,EAAE,EAAE;oBACR,IAAI,EAAE,aAAa;oBACnB,WAAW,EAAE,IAAI;iBAClB,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBAAE,SAAS;YAC7B,IAAI,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC;gBACzB,GAAG,CAAC,IAAI,CAAC;oBACP,QAAQ,EAAE,IAAI;oBACd,QAAQ,EAAE,GAAG;oBACb,KAAK,EAAE,IAAI,CAAC,IAAI;oBAChB,MAAM,EAAE,KAAK;oBACb,IAAI,EAAE,EAAE;oBACR,IAAI,EAAE,WAAW;oBACjB,WAAW,EAAE,IAAI;iBAClB,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAChC,gEAAgE;YAChE,sEAAsE;YACtE,sBAAsB;YACtB,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACxF,GAAG,CAAC,IAAI,CAAC;gBACP,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,GAAG;gBACb,KAAK,EAAE,IAAI,CAAC,IAAI;gBAChB,MAAM;gBACN,oEAAoE;gBACpE,eAAe;gBACf,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACxD,IAAI,EAAE,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;gBACnD,WAAW,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;aAClE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export type AgentHeader = {
|
|
2
|
-
description: string;
|
|
3
|
-
model?: string;
|
|
4
|
-
tools: string[];
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Der rohe YAML-Kopf, ohne die beiden `---`-Zeilen. `null`, wenn die Datei
|
|
8
|
-
* keinen hat.
|
|
9
|
-
*/
|
|
10
|
-
export declare function headerOf(text: string): string | null;
|
|
11
|
-
/**
|
|
12
|
-
* Ein einzelnes Feld aus einem Kopf.
|
|
13
|
-
*
|
|
14
|
-
* Bewusst kein YAML-Parser: gebraucht werden eine Handvoll Felder aus einem
|
|
15
|
-
* Kopf, den ein Werkzeug erzeugt hat, und eine Abhaengigkeit dafuer in die
|
|
16
|
-
* CLI zu ziehen ist mehr Angriffsflaeche als Nutzen.
|
|
17
|
-
*/
|
|
18
|
-
export declare function headerField(head: string, key: string): string | undefined;
|
|
19
|
-
/**
|
|
20
|
-
* Liest den YAML-Kopf einer Agent-Datei - denselben Kopf, den
|
|
21
|
-
* `agency-agents-normalize.py` schreibt.
|
|
22
|
-
*
|
|
23
|
-
* Alles, was nicht dieser Form entspricht, gibt `null` und die Datei wird
|
|
24
|
-
* uebersprungen - nicht mit einer erfundenen Beschreibung hochgeladen.
|
|
25
|
-
*/
|
|
26
|
-
export declare function parseAgentHeader(text: string): AgentHeader | null;
|
|
27
|
-
/**
|
|
28
|
-
* Die Beschreibung aus einem SKILL.md-Kopf, oder `''`.
|
|
29
|
-
*
|
|
30
|
-
* Anders als beim Agent ist ihr Fehlen kein Grund, die Datei wegzulassen: ein
|
|
31
|
-
* Skill ohne Beschreibung ist ein vollstaendiger Skill, nur einer, den die
|
|
32
|
-
* Liste schlechter zeigen kann. Er wird gemeldet, nicht uebersprungen.
|
|
33
|
-
*/
|
|
34
|
-
export declare function descriptionOf(text: string): string;
|
|
35
|
-
/**
|
|
36
|
-
* Das Merkmal, das `writeStubs` in jede erzeugte SKILL.md schreibt.
|
|
37
|
-
*
|
|
38
|
-
* Ohne dieses Merkmal laedt der naechste `import` die Stubs als Skills hoch
|
|
39
|
-
* und ersetzt damit jeden echten Skill durch seinen eigenen Platzhalter -
|
|
40
|
-
* Stubs liegen seit Aufgabe 12 in genau den Ordnern, die der Import liest.
|
|
41
|
-
*/
|
|
42
|
-
export declare function isStub(text: string): boolean;
|
|
43
|
-
/** Der Teil unter dem Kopf. Ohne Kopf ist die ganze Datei der Inhalt. */
|
|
44
|
-
export declare function bodyBelowHeader(text: string): string;
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Der rohe YAML-Kopf, ohne die beiden `---`-Zeilen. `null`, wenn die Datei
|
|
3
|
-
* keinen hat.
|
|
4
|
-
*/
|
|
5
|
-
export function headerOf(text) {
|
|
6
|
-
if (!text.startsWith('---\n'))
|
|
7
|
-
return null;
|
|
8
|
-
const end = text.indexOf('\n---', 3);
|
|
9
|
-
if (end < 0)
|
|
10
|
-
return null;
|
|
11
|
-
return text.slice(4, end);
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Ein einzelnes Feld aus einem Kopf.
|
|
15
|
-
*
|
|
16
|
-
* Bewusst kein YAML-Parser: gebraucht werden eine Handvoll Felder aus einem
|
|
17
|
-
* Kopf, den ein Werkzeug erzeugt hat, und eine Abhaengigkeit dafuer in die
|
|
18
|
-
* CLI zu ziehen ist mehr Angriffsflaeche als Nutzen.
|
|
19
|
-
*/
|
|
20
|
-
export function headerField(head, key) {
|
|
21
|
-
// Der Schluessel wird in den Ausdruck eingesetzt, also darf nur stehen, was
|
|
22
|
-
// dort nichts bedeutet. Alle Aufrufer geben Literale, die Pruefung faengt
|
|
23
|
-
// den Tag ab, an dem einer davon aus einer Eingabe kommt.
|
|
24
|
-
if (!/^[a-zA-Z0-9_-]+$/.test(key))
|
|
25
|
-
return undefined;
|
|
26
|
-
const m = new RegExp(`^${key}:[ \\t]*(.*)$`, 'm').exec(head);
|
|
27
|
-
if (!m)
|
|
28
|
-
return undefined;
|
|
29
|
-
const raw = m[1].trim();
|
|
30
|
-
// Anfuehrungszeichen sind im Bestand optional und tragen keine Bedeutung.
|
|
31
|
-
const unquoted = raw.replace(/^(['"])(.*)\1$/, '$2').trim();
|
|
32
|
-
return unquoted.length > 0 ? unquoted : undefined;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Liest den YAML-Kopf einer Agent-Datei - denselben Kopf, den
|
|
36
|
-
* `agency-agents-normalize.py` schreibt.
|
|
37
|
-
*
|
|
38
|
-
* Alles, was nicht dieser Form entspricht, gibt `null` und die Datei wird
|
|
39
|
-
* uebersprungen - nicht mit einer erfundenen Beschreibung hochgeladen.
|
|
40
|
-
*/
|
|
41
|
-
export function parseAgentHeader(text) {
|
|
42
|
-
const head = headerOf(text);
|
|
43
|
-
if (head === null)
|
|
44
|
-
return null;
|
|
45
|
-
const description = headerField(head, 'description');
|
|
46
|
-
if (!description)
|
|
47
|
-
return null;
|
|
48
|
-
const toolsRaw = headerField(head, 'tools');
|
|
49
|
-
const tools = toolsRaw
|
|
50
|
-
? toolsRaw
|
|
51
|
-
.replace(/^\[(.*)\]$/, '$1')
|
|
52
|
-
.split(',')
|
|
53
|
-
.map((t) => t.trim())
|
|
54
|
-
.filter((t) => t.length > 0)
|
|
55
|
-
: [];
|
|
56
|
-
const model = headerField(head, 'model');
|
|
57
|
-
return model ? { description, model, tools } : { description, tools };
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Die Beschreibung aus einem SKILL.md-Kopf, oder `''`.
|
|
61
|
-
*
|
|
62
|
-
* Anders als beim Agent ist ihr Fehlen kein Grund, die Datei wegzulassen: ein
|
|
63
|
-
* Skill ohne Beschreibung ist ein vollstaendiger Skill, nur einer, den die
|
|
64
|
-
* Liste schlechter zeigen kann. Er wird gemeldet, nicht uebersprungen.
|
|
65
|
-
*/
|
|
66
|
-
export function descriptionOf(text) {
|
|
67
|
-
const head = headerOf(text);
|
|
68
|
-
return (head === null ? undefined : headerField(head, 'description')) ?? '';
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Das Merkmal, das `writeStubs` in jede erzeugte SKILL.md schreibt.
|
|
72
|
-
*
|
|
73
|
-
* Ohne dieses Merkmal laedt der naechste `import` die Stubs als Skills hoch
|
|
74
|
-
* und ersetzt damit jeden echten Skill durch seinen eigenen Platzhalter -
|
|
75
|
-
* Stubs liegen seit Aufgabe 12 in genau den Ordnern, die der Import liest.
|
|
76
|
-
*/
|
|
77
|
-
export function isStub(text) {
|
|
78
|
-
const head = headerOf(text);
|
|
79
|
-
if (head === null)
|
|
80
|
-
return false;
|
|
81
|
-
return headerField(head, 'x-onlymcp-stub') === 'true';
|
|
82
|
-
}
|
|
83
|
-
/** Der Teil unter dem Kopf. Ohne Kopf ist die ganze Datei der Inhalt. */
|
|
84
|
-
export function bodyBelowHeader(text) {
|
|
85
|
-
if (!text.startsWith('---\n'))
|
|
86
|
-
return text;
|
|
87
|
-
const end = text.indexOf('\n---', 3);
|
|
88
|
-
if (end < 0)
|
|
89
|
-
return text;
|
|
90
|
-
const after = text.indexOf('\n', end + 4);
|
|
91
|
-
return after < 0 ? '' : text.slice(after + 1);
|
|
92
|
-
}
|
|
93
|
-
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/import/frontmatter.ts"],"names":[],"mappings":"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"}
|
package/dist/import/plan.d.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import type { Candidate } from './collect.js';
|
|
2
|
-
export type PlannedFile = {
|
|
3
|
-
path: string;
|
|
4
|
-
absolute: string;
|
|
5
|
-
bytes: number;
|
|
6
|
-
binary: boolean;
|
|
7
|
-
};
|
|
8
|
-
/** Herkunft eines Skills, so wie `PUT /api/skills/:name` sie entgegennimmt. */
|
|
9
|
-
export type PlannedCollection = {
|
|
10
|
-
key: string;
|
|
11
|
-
kind: 'plugin' | 'directory';
|
|
12
|
-
label: string;
|
|
13
|
-
};
|
|
14
|
-
/** `source` ist der absolute Pfad der SKILL.md. Gelesen wird erst beim Hochladen. */
|
|
15
|
-
export type SkillPlan = {
|
|
16
|
-
name: string;
|
|
17
|
-
source: string;
|
|
18
|
-
/**
|
|
19
|
-
* Der Pfad der SKILL.md RELATIV zur Import-Wurzel. Der absolute Pfad ginge
|
|
20
|
-
* als Herkunft mit hoch und traegt den Benutzernamen des Geraets mit sich;
|
|
21
|
-
* der relative sagt dasselbe ueber die Ablage und nichts ueber die Person.
|
|
22
|
-
*/
|
|
23
|
-
sourcePath: string;
|
|
24
|
-
description: string;
|
|
25
|
-
collection: PlannedCollection | null;
|
|
26
|
-
bytes: number;
|
|
27
|
-
files: PlannedFile[];
|
|
28
|
-
};
|
|
29
|
-
export type AgentPlan = {
|
|
30
|
-
name: string;
|
|
31
|
-
source: string;
|
|
32
|
-
bytes: number;
|
|
33
|
-
};
|
|
34
|
-
export type MemoryPlan = {
|
|
35
|
-
path: string;
|
|
36
|
-
source: string;
|
|
37
|
-
bytes: number;
|
|
38
|
-
};
|
|
39
|
-
export type Skipped = {
|
|
40
|
-
relative: string;
|
|
41
|
-
reason: string;
|
|
42
|
-
};
|
|
43
|
-
export type ImportPlan = {
|
|
44
|
-
skills: SkillPlan[];
|
|
45
|
-
agents: AgentPlan[];
|
|
46
|
-
memory: MemoryPlan[];
|
|
47
|
-
/** Funde von scanForSecrets. Ausgeschlossen, aber nicht verschwiegen. */
|
|
48
|
-
flagged: Candidate[];
|
|
49
|
-
skipped: Skipped[];
|
|
50
|
-
/** Skills ohne `description` im Kopf. Sie gehen hoch, aber gemeldet. */
|
|
51
|
-
noDescription: string[];
|
|
52
|
-
};
|
|
53
|
-
export declare function planSkills(items: Candidate[], opts?: {
|
|
54
|
-
root?: string;
|
|
55
|
-
}): {
|
|
56
|
-
plans: SkillPlan[];
|
|
57
|
-
skipped: Skipped[];
|
|
58
|
-
noDescription: string[];
|
|
59
|
-
};
|
|
60
|
-
export declare function planAgents(items: Candidate[]): {
|
|
61
|
-
plans: AgentPlan[];
|
|
62
|
-
skipped: Skipped[];
|
|
63
|
-
};
|
|
64
|
-
export declare function planMemory(items: Candidate[]): {
|
|
65
|
-
plans: MemoryPlan[];
|
|
66
|
-
skipped: Skipped[];
|
|
67
|
-
};
|
|
68
|
-
export declare function buildImportPlan(sources: {
|
|
69
|
-
skills?: Candidate[];
|
|
70
|
-
agents?: Candidate[];
|
|
71
|
-
memory?: Candidate[];
|
|
72
|
-
}, opts?: {
|
|
73
|
-
skillsRoot?: string;
|
|
74
|
-
}): ImportPlan;
|