onlymcp 0.9.0 → 0.10.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/dist/apiClient.d.ts +99 -7
- package/dist/apiClient.js +58 -2
- package/dist/apiClient.js.map +1 -1
- package/dist/auth/deviceLogin.js +5 -1
- package/dist/auth/deviceLogin.js.map +1 -1
- package/dist/bin/cli.js +204 -24
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/mcp.js +16 -2
- package/dist/bin/mcp.js.map +1 -1
- package/dist/export/unpack.d.ts +33 -0
- package/dist/export/unpack.js +54 -0
- package/dist/export/unpack.js.map +1 -0
- package/dist/identity.d.ts +25 -0
- package/dist/identity.js +106 -0
- package/dist/identity.js.map +1 -0
- package/dist/import/collect.d.ts +14 -1
- package/dist/import/collect.js +25 -3
- package/dist/import/collect.js.map +1 -1
- package/dist/import/frontmatter.d.ts +31 -5
- package/dist/import/frontmatter.js +64 -22
- package/dist/import/frontmatter.js.map +1 -1
- package/dist/import/plan.d.ts +22 -1
- package/dist/import/plan.js +66 -19
- package/dist/import/plan.js.map +1 -1
- package/dist/import/prune.d.ts +46 -0
- package/dist/import/prune.js +61 -0
- package/dist/import/prune.js.map +1 -0
- package/dist/import/upload.js +10 -1
- package/dist/import/upload.js.map +1 -1
- package/dist/install.d.ts +7 -0
- package/dist/install.js +6 -2
- package/dist/install.js.map +1 -1
- package/dist/instructions.d.ts +3 -1
- package/dist/instructions.js +19 -2
- package/dist/instructions.js.map +1 -1
- package/dist/memorySync.d.ts +28 -0
- package/dist/memorySync.js +56 -0
- package/dist/memorySync.js.map +1 -0
- package/dist/paths.d.ts +12 -0
- package/dist/paths.js +34 -8
- package/dist/paths.js.map +1 -1
- package/dist/stubs.d.ts +1 -0
- package/dist/stubs.js +83 -11
- package/dist/stubs.js.map +1 -1
- package/dist/tools/memoryGraph.d.ts +69 -0
- package/dist/tools/memoryGraph.js +123 -0
- package/dist/tools/memoryGraph.js.map +1 -0
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/import/frontmatter.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/import/frontmatter.ts"],"names":[],"mappings":"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"}
|
package/dist/import/plan.d.ts
CHANGED
|
@@ -5,10 +5,24 @@ export type PlannedFile = {
|
|
|
5
5
|
bytes: number;
|
|
6
6
|
binary: boolean;
|
|
7
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
|
+
};
|
|
8
14
|
/** `source` ist der absolute Pfad der SKILL.md. Gelesen wird erst beim Hochladen. */
|
|
9
15
|
export type SkillPlan = {
|
|
10
16
|
name: string;
|
|
11
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;
|
|
12
26
|
bytes: number;
|
|
13
27
|
files: PlannedFile[];
|
|
14
28
|
};
|
|
@@ -33,10 +47,15 @@ export type ImportPlan = {
|
|
|
33
47
|
/** Funde von scanForSecrets. Ausgeschlossen, aber nicht verschwiegen. */
|
|
34
48
|
flagged: Candidate[];
|
|
35
49
|
skipped: Skipped[];
|
|
50
|
+
/** Skills ohne `description` im Kopf. Sie gehen hoch, aber gemeldet. */
|
|
51
|
+
noDescription: string[];
|
|
36
52
|
};
|
|
37
|
-
export declare function planSkills(items: Candidate[]
|
|
53
|
+
export declare function planSkills(items: Candidate[], opts?: {
|
|
54
|
+
root?: string;
|
|
55
|
+
}): {
|
|
38
56
|
plans: SkillPlan[];
|
|
39
57
|
skipped: Skipped[];
|
|
58
|
+
noDescription: string[];
|
|
40
59
|
};
|
|
41
60
|
export declare function planAgents(items: Candidate[]): {
|
|
42
61
|
plans: AgentPlan[];
|
|
@@ -50,4 +69,6 @@ export declare function buildImportPlan(sources: {
|
|
|
50
69
|
skills?: Candidate[];
|
|
51
70
|
agents?: Candidate[];
|
|
52
71
|
memory?: Candidate[];
|
|
72
|
+
}, opts?: {
|
|
73
|
+
skillsRoot?: string;
|
|
53
74
|
}): ImportPlan;
|
package/dist/import/plan.js
CHANGED
|
@@ -1,9 +1,32 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
1
2
|
import { isSafeMemoryPath } from '../memoryPath.js';
|
|
2
3
|
import { isSafeSkillFilePath } from '../skillFilePath.js';
|
|
3
4
|
// Die Namensregel ist die des Servers (packages/api/src/http/names.ts), hier
|
|
4
5
|
// noch einmal geprueft, damit der Bericht "uebersprungen, ungueltiger Name"
|
|
5
6
|
// sagen kann, statt dass jemand 40 Uploads zuschaut und dann eine 400 sieht.
|
|
6
7
|
const SAFE_NAME = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
8
|
+
// Skills duerfen seit Aufgabe 11 ein Namensraum-Segment tragen, Agents nicht.
|
|
9
|
+
const SAFE_SKILL_NAME = /^[a-z0-9]+(-[a-z0-9]+)*(:[a-z0-9]+(-[a-z0-9]+)*)?$/;
|
|
10
|
+
// Der Schluessel einer Sammlung, wie ihn `Collection` in skills/route.ts
|
|
11
|
+
// annimmt. Ein Wurzelordner, dessen Name hier durchfaellt (`.claude` etwa),
|
|
12
|
+
// liefert einfach keine Sammlung statt den ganzen Import scheitern zu lassen.
|
|
13
|
+
const SAFE_COLLECTION_KEY = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
14
|
+
function locate(relative) {
|
|
15
|
+
const parts = relative.split('/');
|
|
16
|
+
const i = parts.indexOf('skills');
|
|
17
|
+
if (i >= 4 && parts[i - 4] === 'cache' && i + 1 < parts.length - 1) {
|
|
18
|
+
return {
|
|
19
|
+
prefix: parts.slice(0, i + 2).join('/'),
|
|
20
|
+
name: `${parts[i - 2]}:${parts[i + 1]}`,
|
|
21
|
+
plugin: parts[i - 2],
|
|
22
|
+
path: parts.slice(i + 2).join('/'),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
// Eine Datei direkt in der Wurzel gehoert zu keinem Skill.
|
|
26
|
+
if (parts.length < 2)
|
|
27
|
+
return null;
|
|
28
|
+
return { prefix: parts[0], name: parts[0], plugin: null, path: parts.slice(1).join('/') };
|
|
29
|
+
}
|
|
7
30
|
/**
|
|
8
31
|
* Eine markierte Datei faellt aus dem Plan, nicht aus dem Bericht. Der
|
|
9
32
|
* Benutzer sieht sie unter "zurueckgehalten" mit Regel und Zeile und kann sie
|
|
@@ -16,42 +39,49 @@ function usable(c) {
|
|
|
16
39
|
function reasonOf(c) {
|
|
17
40
|
return c.skip ?? (c.hits.length > 0 ? 'flagged' : 'unusable');
|
|
18
41
|
}
|
|
19
|
-
export function planSkills(items) {
|
|
42
|
+
export function planSkills(items, opts = {}) {
|
|
20
43
|
const plans = [];
|
|
21
44
|
const skipped = [];
|
|
45
|
+
const noDescription = [];
|
|
22
46
|
const folders = new Map();
|
|
47
|
+
// Der Ordnername der Wurzel ist die Sammlung fuer alles, was nicht aus
|
|
48
|
+
// einem Plugin kommt (Spec 8.1). Ohne Wurzel - etwa im Test, der nur
|
|
49
|
+
// Kandidaten uebergibt - gibt es keine, und das ist kein Fehler.
|
|
50
|
+
const rootKey = opts.root ? basename(opts.root.replace(/[/\\]+$/, '')) : '';
|
|
51
|
+
const rootCollection = SAFE_COLLECTION_KEY.test(rootKey)
|
|
52
|
+
? { key: rootKey, kind: 'directory', label: rootKey }
|
|
53
|
+
: null;
|
|
23
54
|
for (const c of items) {
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
// Eine Datei direkt in der Wurzel gehoert zu keinem Skill.
|
|
55
|
+
const at = locate(c.relative);
|
|
56
|
+
if (!at) {
|
|
27
57
|
skipped.push({ relative: c.relative, reason: 'not-in-a-skill-folder' });
|
|
28
58
|
continue;
|
|
29
59
|
}
|
|
30
|
-
const
|
|
31
|
-
const bucket = folders.get(name);
|
|
60
|
+
const bucket = folders.get(at.prefix);
|
|
32
61
|
if (bucket)
|
|
33
|
-
bucket.push(c);
|
|
62
|
+
bucket.entries.push(c);
|
|
34
63
|
else
|
|
35
|
-
folders.set(
|
|
64
|
+
folders.set(at.prefix, { at, entries: [c] });
|
|
36
65
|
}
|
|
37
|
-
for (const [
|
|
38
|
-
|
|
39
|
-
|
|
66
|
+
for (const [prefix, { at, entries }] of folders) {
|
|
67
|
+
const name = at.name;
|
|
68
|
+
if (!SAFE_SKILL_NAME.test(name)) {
|
|
69
|
+
skipped.push({ relative: prefix, reason: 'invalid-name' });
|
|
40
70
|
continue;
|
|
41
71
|
}
|
|
42
|
-
const skillMd = entries.find((c) => c.relative === `${
|
|
72
|
+
const skillMd = entries.find((c) => c.relative === `${prefix}/SKILL.md`);
|
|
43
73
|
if (!skillMd) {
|
|
44
74
|
// Ein Ordner ohne SKILL.md ist kein Skill. Seine Streudateien unter
|
|
45
75
|
// einem erfundenen Namen hochzuladen legte etwas ins Konto, das auch
|
|
46
76
|
// auf der Platte nie ein Skill war.
|
|
47
|
-
skipped.push({ relative:
|
|
77
|
+
skipped.push({ relative: prefix, reason: 'no-skill-md' });
|
|
48
78
|
continue;
|
|
49
79
|
}
|
|
50
80
|
if (!usable(skillMd)) {
|
|
51
81
|
// Ohne seinen eigenen Text ist der Skill nichts. Nur die Begleitdateien
|
|
52
82
|
// hochzuladen ergaebe einen Skill, der auf einen Inhalt verweist, den es
|
|
53
83
|
// im Konto nicht gibt.
|
|
54
|
-
skipped.push({ relative: `${
|
|
84
|
+
skipped.push({ relative: `${prefix}/SKILL.md`, reason: reasonOf(skillMd) });
|
|
55
85
|
continue;
|
|
56
86
|
}
|
|
57
87
|
const files = [];
|
|
@@ -62,7 +92,7 @@ export function planSkills(items) {
|
|
|
62
92
|
skipped.push({ relative: c.relative, reason: reasonOf(c) });
|
|
63
93
|
continue;
|
|
64
94
|
}
|
|
65
|
-
const path = c.relative.slice(
|
|
95
|
+
const path = c.relative.slice(prefix.length + 1);
|
|
66
96
|
if (!isSafeSkillFilePath(path)) {
|
|
67
97
|
// Dieselbe Ueberlegung wie beim Skill-Namen: was der Server ablehnt,
|
|
68
98
|
// gehoert in den Bericht und nicht in den Upload.
|
|
@@ -77,10 +107,26 @@ export function planSkills(items) {
|
|
|
77
107
|
});
|
|
78
108
|
}
|
|
79
109
|
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
80
|
-
|
|
110
|
+
const description = skillMd.description ?? '';
|
|
111
|
+
if (!description)
|
|
112
|
+
noDescription.push(name);
|
|
113
|
+
plans.push({
|
|
114
|
+
name,
|
|
115
|
+
source: skillMd.absolute,
|
|
116
|
+
sourcePath: skillMd.relative,
|
|
117
|
+
description,
|
|
118
|
+
collection: at.plugin
|
|
119
|
+
? SAFE_COLLECTION_KEY.test(at.plugin)
|
|
120
|
+
? { key: at.plugin, kind: 'plugin', label: at.plugin }
|
|
121
|
+
: null
|
|
122
|
+
: rootCollection,
|
|
123
|
+
bytes: skillMd.bytes,
|
|
124
|
+
files,
|
|
125
|
+
});
|
|
81
126
|
}
|
|
82
127
|
plans.sort((a, b) => a.name.localeCompare(b.name));
|
|
83
|
-
|
|
128
|
+
noDescription.sort();
|
|
129
|
+
return { plans, skipped, noDescription };
|
|
84
130
|
}
|
|
85
131
|
export function planAgents(items) {
|
|
86
132
|
const plans = [];
|
|
@@ -127,8 +173,8 @@ export function planMemory(items) {
|
|
|
127
173
|
plans.sort((a, b) => a.path.localeCompare(b.path));
|
|
128
174
|
return { plans, skipped };
|
|
129
175
|
}
|
|
130
|
-
export function buildImportPlan(sources) {
|
|
131
|
-
const s = planSkills(sources.skills ?? []);
|
|
176
|
+
export function buildImportPlan(sources, opts = {}) {
|
|
177
|
+
const s = planSkills(sources.skills ?? [], { root: opts.skillsRoot });
|
|
132
178
|
const a = planAgents(sources.agents ?? []);
|
|
133
179
|
const m = planMemory(sources.memory ?? []);
|
|
134
180
|
const all = [...(sources.skills ?? []), ...(sources.agents ?? []), ...(sources.memory ?? [])];
|
|
@@ -138,6 +184,7 @@ export function buildImportPlan(sources) {
|
|
|
138
184
|
memory: m.plans,
|
|
139
185
|
flagged: all.filter((c) => c.skip === null && c.hits.length > 0),
|
|
140
186
|
skipped: [...s.skipped, ...a.skipped, ...m.skipped],
|
|
187
|
+
noDescription: s.noDescription,
|
|
141
188
|
};
|
|
142
189
|
}
|
|
143
190
|
//# sourceMappingURL=plan.js.map
|
package/dist/import/plan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/import/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG1D,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,MAAM,SAAS,GAAG,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/import/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG1D,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,MAAM,SAAS,GAAG,0BAA0B,CAAC;AAC7C,8EAA8E;AAC9E,MAAM,eAAe,GAAG,oDAAoD,CAAC;AAC7E,yEAAyE;AACzE,4EAA4E;AAC5E,8EAA8E;AAC9E,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AAoDtD,SAAS,MAAM,CAAC,QAAgB;IAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnE,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YACvC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,EAAE;YACzC,MAAM,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE;YACrB,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;SACnC,CAAC;IACJ,CAAC;IACD,2DAA2D;IAC3D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC9F,CAAC;AAED;;;;;GAKG;AACH,SAAS,MAAM,CAAC,CAAY;IAC1B,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,QAAQ,CAAC,CAAY;IAC5B,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,KAAkB,EAClB,OAA0B,EAAE;IAE5B,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAiD,CAAC;IAEzE,uEAAuE;IACvE,qEAAqE;IACrE,iEAAiE;IACjE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,MAAM,cAAc,GAA6B,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC;QAChF,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE;QACrD,CAAC,CAAC,IAAI,CAAC;IAET,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC,CAAC;YACxE,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,MAAM;YAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;YAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;YAC3D,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,GAAG,MAAM,WAAW,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,oEAAoE;YACpE,qEAAqE;YACrE,oCAAoC;YACpC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;YAC1D,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACrB,wEAAwE;YACxE,yEAAyE;YACzE,uBAAuB;YACvB,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,MAAM,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC5E,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAkB,EAAE,CAAC;QAChC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,OAAO;gBAAE,SAAS;YAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC5D,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACjD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,qEAAqE;gBACrE,kDAAkD;gBAClD,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;gBAC/D,SAAS;YACX,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI;gBACJ,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,MAAM,EAAE,CAAC,CAAC,MAAM;aACjB,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;QAC9C,IAAI,CAAC,WAAW;YAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC;YACT,IAAI;YACJ,MAAM,EAAE,OAAO,CAAC,QAAQ;YACxB,UAAU,EAAE,OAAO,CAAC,QAAQ;YAC5B,WAAW;YACX,UAAU,EAAE,EAAE,CAAC,MAAM;gBACnB,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;oBACnC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE;oBACtD,CAAC,CAAC,IAAI;gBACR,CAAC,CAAC,cAAc;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,aAAa,CAAC,IAAI,EAAE,CAAC;IACrB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAkB;IAC3C,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAc,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;YACnE,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;YAC/D,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;YAC/D,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5D,SAAS;QACX,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAkB;IAC3C,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAc,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,0EAA0E;QAC1E,gEAAgE;QAChE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;YAC/D,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5D,SAAS;QACX,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,OAIC,EACD,OAAgC,EAAE;IAElC,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACtE,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9F,OAAO;QACL,MAAM,EAAE,CAAC,CAAC,KAAK;QACf,MAAM,EAAE,CAAC,CAAC,KAAK;QACf,MAAM,EAAE,CAAC,CAAC,KAAK;QACf,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChE,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC;QACnD,aAAa,EAAE,CAAC,CAAC,aAAa;KAC/B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ApiClient } from '../apiClient.js';
|
|
2
|
+
import type { ImportPlan } from './plan.js';
|
|
3
|
+
/**
|
|
4
|
+
* What `--prune` would delete: entries the account holds and the source
|
|
5
|
+
* directory does not.
|
|
6
|
+
*
|
|
7
|
+
* Package 03 task 12, spec 8.4. Three rules decide what may appear here, and
|
|
8
|
+
* all three are about not deleting something the source never claimed to
|
|
9
|
+
* describe:
|
|
10
|
+
*
|
|
11
|
+
* 1. **Only a category that was read.** `onlymcp import --skills x --prune`
|
|
12
|
+
* must not touch memory: nothing was read about memory, so "not in the
|
|
13
|
+
* source" says nothing about it. Without this rule the flag would empty
|
|
14
|
+
* the memory of anyone who pruned a skill folder.
|
|
15
|
+
* 2. **Only personal rows the caller owns.** A team skill is somebody else's
|
|
16
|
+
* work sitting in a shared scope; the fact that it is missing from one
|
|
17
|
+
* member's disk is not a reason to delete it for everyone.
|
|
18
|
+
* 3. **Nothing archived.** An archived row is by definition not on disk any
|
|
19
|
+
* more. Deleting it on the next import would turn the archive into a trap.
|
|
20
|
+
*/
|
|
21
|
+
export type PruneTargets = {
|
|
22
|
+
skills: string[];
|
|
23
|
+
agents: string[];
|
|
24
|
+
memory: string[];
|
|
25
|
+
};
|
|
26
|
+
export type Covered = {
|
|
27
|
+
skills: boolean;
|
|
28
|
+
agents: boolean;
|
|
29
|
+
memory: boolean;
|
|
30
|
+
};
|
|
31
|
+
export declare function isEmpty(t: PruneTargets): boolean;
|
|
32
|
+
export declare function countTargets(t: PruneTargets): number;
|
|
33
|
+
export declare function planPrune(api: ApiClient, plan: ImportPlan, covered: Covered): Promise<PruneTargets>;
|
|
34
|
+
export type PruneResult = {
|
|
35
|
+
deleted: number;
|
|
36
|
+
failures: {
|
|
37
|
+
what: string;
|
|
38
|
+
code: string;
|
|
39
|
+
}[];
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* One by one, and a failure never stops the rest: the caller has already
|
|
43
|
+
* confirmed this exact list, so a single 404 in the middle should not leave
|
|
44
|
+
* the other entries behind in a state nobody asked for.
|
|
45
|
+
*/
|
|
46
|
+
export declare function runPrune(api: ApiClient, targets: PruneTargets): Promise<PruneResult>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ApiError } from '../apiClient.js';
|
|
2
|
+
export function isEmpty(t) {
|
|
3
|
+
return t.skills.length === 0 && t.agents.length === 0 && t.memory.length === 0;
|
|
4
|
+
}
|
|
5
|
+
export function countTargets(t) {
|
|
6
|
+
return t.skills.length + t.agents.length + t.memory.length;
|
|
7
|
+
}
|
|
8
|
+
function deletable(row) {
|
|
9
|
+
return row.scope === 'personal' && row.isOwn && row.archivedAt === null;
|
|
10
|
+
}
|
|
11
|
+
export async function planPrune(api, plan, covered) {
|
|
12
|
+
const targets = { skills: [], agents: [], memory: [] };
|
|
13
|
+
if (covered.skills) {
|
|
14
|
+
const keep = new Set(plan.skills.map((s) => s.name));
|
|
15
|
+
const { skills } = await api.listSkills();
|
|
16
|
+
targets.skills = skills.filter((s) => deletable(s) && !keep.has(s.name)).map((s) => s.name);
|
|
17
|
+
}
|
|
18
|
+
if (covered.agents) {
|
|
19
|
+
const keep = new Set(plan.agents.map((a) => a.name));
|
|
20
|
+
const { agents } = await api.listAgents();
|
|
21
|
+
targets.agents = agents.filter((a) => deletable(a) && !keep.has(a.name)).map((a) => a.name);
|
|
22
|
+
}
|
|
23
|
+
if (covered.memory) {
|
|
24
|
+
const keep = new Set(plan.memory.map((m) => m.path));
|
|
25
|
+
const { files } = await api.listMemory();
|
|
26
|
+
targets.memory = files.filter((f) => deletable(f) && !keep.has(f.path)).map((f) => f.path);
|
|
27
|
+
}
|
|
28
|
+
targets.skills.sort();
|
|
29
|
+
targets.agents.sort();
|
|
30
|
+
targets.memory.sort();
|
|
31
|
+
return targets;
|
|
32
|
+
}
|
|
33
|
+
function codeOf(e) {
|
|
34
|
+
if (e instanceof ApiError)
|
|
35
|
+
return e.code;
|
|
36
|
+
return e instanceof Error ? e.message : String(e);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* One by one, and a failure never stops the rest: the caller has already
|
|
40
|
+
* confirmed this exact list, so a single 404 in the middle should not leave
|
|
41
|
+
* the other entries behind in a state nobody asked for.
|
|
42
|
+
*/
|
|
43
|
+
export async function runPrune(api, targets) {
|
|
44
|
+
const result = { deleted: 0, failures: [] };
|
|
45
|
+
const each = async (items, what, go) => {
|
|
46
|
+
for (const item of items) {
|
|
47
|
+
try {
|
|
48
|
+
await go(item);
|
|
49
|
+
result.deleted += 1;
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
result.failures.push({ what: what(item), code: codeOf(e) });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
await each(targets.skills, (n) => `skill ${n}`, (n) => api.deleteSkill(n));
|
|
57
|
+
await each(targets.agents, (n) => `agent ${n}`, (n) => api.deleteAgent(n));
|
|
58
|
+
await each(targets.memory, (p) => p, (p) => api.deleteMemory(p));
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=prune.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune.js","sourceRoot":"","sources":["../../src/import/prune.ts"],"names":[],"mappings":"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"}
|
package/dist/import/upload.js
CHANGED
|
@@ -25,7 +25,16 @@ export async function runUpload(api, plan, onProgress) {
|
|
|
25
25
|
const step = (label) => onProgress((done += 1), total, label);
|
|
26
26
|
for (const s of plan.skills) {
|
|
27
27
|
try {
|
|
28
|
-
|
|
28
|
+
// Die Herkunft geht mit dem Inhalt in EINEM Aufruf hoch. Ein zweiter
|
|
29
|
+
// Aufruf danach koennte scheitern und liesse einen Skill zurueck, der
|
|
30
|
+
// laut Konto aus dem Nichts kam, obwohl er eben importiert wurde.
|
|
31
|
+
await api.putSkill(s.name, await readFile(s.source, 'utf8'), {
|
|
32
|
+
// Leere Beschreibung heisst "keine gefunden" und darf die vorhandene
|
|
33
|
+
// nicht ueberschreiben (Spec 5, Regel 1).
|
|
34
|
+
...(s.description ? { description: s.description } : {}),
|
|
35
|
+
sourcePath: s.sourcePath,
|
|
36
|
+
...(s.collection ? { collection: s.collection } : {}),
|
|
37
|
+
});
|
|
29
38
|
result.skills += 1;
|
|
30
39
|
}
|
|
31
40
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/import/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAkB,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAYrE,SAAS,MAAM,CAAC,CAAU;IACxB,IAAI,CAAC,YAAY,QAAQ;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC;IACzC,OAAO,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAgB;IACxC,OAAO,CACL,IAAI,CAAC,MAAM,CAAC,MAAM;QAClB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,MAAM;QAClB,IAAI,CAAC,MAAM,CAAC,MAAM,CACnB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAc,EACd,IAAgB,EAChB,UAAoB;IAEpB,MAAM,MAAM,GAAiB,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC9F,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAEtE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/import/upload.ts"],"names":[],"mappings":"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"}
|
package/dist/install.d.ts
CHANGED
|
@@ -5,6 +5,13 @@ export interface InstallTarget {
|
|
|
5
5
|
configPath: string;
|
|
6
6
|
/** null = dieser Client hat keinen Skill-Scanner und braucht keine Stubs. */
|
|
7
7
|
stubDir: string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Die Wurzel, unter der dieser Client `skills/` (und, wo es das gibt,
|
|
10
|
+
* `agents/`) liest. Genau das kommt in ONLYMCP_STUB_DIRS, nicht `stubDir`
|
|
11
|
+
* selbst: writeStubs haengt `skills/` an, und mit dem Skill-Ordner als
|
|
12
|
+
* Wurzel landeten die Stubs in `skills/skills`.
|
|
13
|
+
*/
|
|
14
|
+
stubRoot: string | null;
|
|
8
15
|
snippet: string;
|
|
9
16
|
}
|
|
10
17
|
/** Das npm-Paket, das sowohl `onlymcp` als auch `onlymcp-mcp` mitbringt. */
|
package/dist/install.js
CHANGED
|
@@ -46,7 +46,8 @@ function tomlSnippet(env) {
|
|
|
46
46
|
// Typ verankert und nicht bloss eine Absicht.
|
|
47
47
|
export function targets(home) {
|
|
48
48
|
// Geprueft an Codex 0.147.0: ~/.codex/skills wird direkt gescannt.
|
|
49
|
-
const
|
|
49
|
+
const codexRoot = join(home, '.codex');
|
|
50
|
+
const codexStubs = join(codexRoot, 'skills');
|
|
50
51
|
return [
|
|
51
52
|
{
|
|
52
53
|
id: 'claude',
|
|
@@ -55,6 +56,7 @@ export function targets(home) {
|
|
|
55
56
|
// Die Stubs setzt bei Claude Code die Plugin-Installation ueber
|
|
56
57
|
// CLAUDE_PLUGIN_ROOT, nicht dieser Befehl.
|
|
57
58
|
stubDir: null,
|
|
59
|
+
stubRoot: null,
|
|
58
60
|
snippet: jsonSnippet(),
|
|
59
61
|
},
|
|
60
62
|
{
|
|
@@ -62,12 +64,13 @@ export function targets(home) {
|
|
|
62
64
|
label: 'Codex',
|
|
63
65
|
configPath: join(home, '.codex', 'config.toml'),
|
|
64
66
|
stubDir: codexStubs,
|
|
67
|
+
stubRoot: codexRoot,
|
|
65
68
|
// Ohne ONLYMCP_STUB_DIRS im Eintrag selbst faellt stubDirs() auf
|
|
66
69
|
// ~/.claude/onlymcp/plugin zurueck: die Stubs landen dann an einer
|
|
67
70
|
// Stelle, die Codex nie liest, und ~/.codex/skills bleibt leer. Die
|
|
68
71
|
// Variable gehoert deshalb in die Konfiguration und nicht bloss als
|
|
69
72
|
// Hinweis in die Ausgabe.
|
|
70
|
-
snippet: tomlSnippet({ ONLYMCP_STUB_DIRS:
|
|
73
|
+
snippet: tomlSnippet({ ONLYMCP_STUB_DIRS: codexRoot }),
|
|
71
74
|
},
|
|
72
75
|
{
|
|
73
76
|
id: 'gemini',
|
|
@@ -75,6 +78,7 @@ export function targets(home) {
|
|
|
75
78
|
configPath: join(home, '.gemini', 'settings.json'),
|
|
76
79
|
// Kein eigener Skill-Begriff: laeuft ueber instructions und list_skills.
|
|
77
80
|
stubDir: null,
|
|
81
|
+
stubRoot: null,
|
|
78
82
|
snippet: jsonSnippet(),
|
|
79
83
|
},
|
|
80
84
|
];
|
package/dist/install.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
package/dist/instructions.d.ts
CHANGED
package/dist/instructions.js
CHANGED
|
@@ -16,6 +16,20 @@ const PREAMBLE = [
|
|
|
16
16
|
'skill_write, agent_write and the matching *_delete tools; connection_create',
|
|
17
17
|
'adds another MCP server to this account.',
|
|
18
18
|
].join(' ');
|
|
19
|
+
/**
|
|
20
|
+
* Der BrainVault-Ablauf in drei Saetzen (Spec 7), wortgleich mit dem der
|
|
21
|
+
* gehosteten Oberflaeche (packages/api/src/mcp/instructions.ts). Zwei
|
|
22
|
+
* Fassungen desselben Satzes waeren zwei Gewohnheiten.
|
|
23
|
+
*
|
|
24
|
+
* Je Konto abschaltbar: wer OnlyMCP als reinen Skill-Speicher benutzt, will
|
|
25
|
+
* keinen Ablauf und will die Zeichen fuer Namen zurueck.
|
|
26
|
+
*/
|
|
27
|
+
const BRAINVAULT = [
|
|
28
|
+
'Memory is a vault, not a scratch file: read MEMORY.md first, it is the index.',
|
|
29
|
+
'After finishing a task, write one solutions/sol-*.md for what was not obvious',
|
|
30
|
+
'and one entry in history/YYYY-MM-DD.md. Link related files with [[name]];',
|
|
31
|
+
"memory_links(path) says which of a file's links point nowhere yet.",
|
|
32
|
+
].join(' ');
|
|
19
33
|
function section(label, tool, names, used) {
|
|
20
34
|
if (names.length === 0)
|
|
21
35
|
return '';
|
|
@@ -34,8 +48,11 @@ function section(label, tool, names, used) {
|
|
|
34
48
|
const tail = rest > 0 ? ` (+${rest} more, call ${tool})` : '';
|
|
35
49
|
return `\n\n${label}: ${kept.join(', ')}${tail}`;
|
|
36
50
|
}
|
|
37
|
-
export function buildInstructions(skills, agents) {
|
|
38
|
-
|
|
51
|
+
export function buildInstructions(skills, agents, opts = {}) {
|
|
52
|
+
// Vor den Namenslisten und nach der Anleitung: abgeschnitten wird der
|
|
53
|
+
// Schluss, also steht vorn, was ueberleben muss - und ein halb angekommener
|
|
54
|
+
// Ablauf ist schlimmer als gar keiner.
|
|
55
|
+
let out = opts.brainvault === false ? PREAMBLE : `${PREAMBLE} ${BRAINVAULT}`;
|
|
39
56
|
// Platz fuer die Agents-Zeile zuruecklegen, BEVOR die Skills ihn aufbrauchen.
|
|
40
57
|
// Ohne diese Reserve frisst eine lange Skill-Liste das ganze Budget, die
|
|
41
58
|
// Agents-Zeile wird trotzdem angehaengt, und das Feld ueberschreitet 1800.
|
package/dist/instructions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instructions.js","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,sEAAsE;AACtE,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,yEAAyE;AACzE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC,MAAM,QAAQ,GAAG;IACf,6EAA6E;IAC7E,qEAAqE;IACrE,0DAA0D;IAC1D,8EAA8E;IAC9E,gEAAgE;IAChE,wEAAwE;IACxE,6EAA6E;IAC7E,0CAA0C;CAC3C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,SAAS,OAAO,CAAC,KAAa,EAAE,IAAY,EAAE,KAAe,EAAE,IAAY;IACzE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,eAAe,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;QAClE,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,mBAAmB;YAAE,MAAM;QACpD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,KAAK,UAAU,IAAI,EAAE,CAAC;IAC3D,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,eAAe,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,OAAO,OAAO,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,iBAAiB,
|
|
1
|
+
{"version":3,"file":"instructions.js","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,sEAAsE;AACtE,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,yEAAyE;AACzE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC,MAAM,QAAQ,GAAG;IACf,6EAA6E;IAC7E,qEAAqE;IACrE,0DAA0D;IAC1D,8EAA8E;IAC9E,gEAAgE;IAChE,wEAAwE;IACxE,6EAA6E;IAC7E,0CAA0C;CAC3C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG;IACjB,+EAA+E;IAC/E,+EAA+E;IAC/E,2EAA2E;IAC3E,oEAAoE;CACrE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,SAAS,OAAO,CAAC,KAAa,EAAE,IAAY,EAAE,KAAe,EAAE,IAAY;IACzE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,eAAe,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;QAClE,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,mBAAmB;YAAE,MAAM;QACpD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,KAAK,UAAU,IAAI,EAAE,CAAC;IAC3D,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,eAAe,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,OAAO,OAAO,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAAgB,EAChB,MAAgB,EAChB,OAAiC,EAAE;IAEnC,sEAAsE;IACtE,4EAA4E;IAC5E,uCAAuC;IACvC,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,UAAU,EAAE,CAAC;IAC7E,8EAA8E;IAC9E,yEAAyE;IACzE,2EAA2E;IAC3E,6EAA6E;IAC7E,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,GAAG,IAAI,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;IACtE,GAAG,IAAI,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5D,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ApiClient } from './apiClient.js';
|
|
2
|
+
export type MemorySyncResult = {
|
|
3
|
+
written: number;
|
|
4
|
+
/** Paths the server sent that this command refused to turn into a file. */
|
|
5
|
+
refused: string[];
|
|
6
|
+
/** A team file whose path a personal file already took. */
|
|
7
|
+
collisions: string[];
|
|
8
|
+
failures: {
|
|
9
|
+
what: string;
|
|
10
|
+
code: string;
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Write every memory file this account can read into one directory, folder
|
|
15
|
+
* structure included (package 03 task 12, spec 8.5).
|
|
16
|
+
*
|
|
17
|
+
* Two independent checks stand between a path from the server and a write on
|
|
18
|
+
* the disk, and they are not redundant: `isSafeMemoryPath` is the rule the
|
|
19
|
+
* server enforces on the way in, and the prefix check below is the one that
|
|
20
|
+
* holds even if that rule is ever loosened, if a path arrives from a wrongly
|
|
21
|
+
* configured ONLYMCP_API_URL, or if `resolve` and the regexp disagree about
|
|
22
|
+
* some encoding. Nothing outside `dir` is ever written.
|
|
23
|
+
*
|
|
24
|
+
* Archived rows are included on purpose. The archive is exactly the state in
|
|
25
|
+
* which somebody wants their notes back on their own disk, and spec 8a calls
|
|
26
|
+
* leaving them out a shortcoming, not a feature.
|
|
27
|
+
*/
|
|
28
|
+
export declare function syncMemoryToDisk(api: ApiClient, dir: string): Promise<MemorySyncResult>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, resolve, sep } from 'node:path';
|
|
3
|
+
import { isSafeMemoryPath } from './memoryPath.js';
|
|
4
|
+
/**
|
|
5
|
+
* Write every memory file this account can read into one directory, folder
|
|
6
|
+
* structure included (package 03 task 12, spec 8.5).
|
|
7
|
+
*
|
|
8
|
+
* Two independent checks stand between a path from the server and a write on
|
|
9
|
+
* the disk, and they are not redundant: `isSafeMemoryPath` is the rule the
|
|
10
|
+
* server enforces on the way in, and the prefix check below is the one that
|
|
11
|
+
* holds even if that rule is ever loosened, if a path arrives from a wrongly
|
|
12
|
+
* configured ONLYMCP_API_URL, or if `resolve` and the regexp disagree about
|
|
13
|
+
* some encoding. Nothing outside `dir` is ever written.
|
|
14
|
+
*
|
|
15
|
+
* Archived rows are included on purpose. The archive is exactly the state in
|
|
16
|
+
* which somebody wants their notes back on their own disk, and spec 8a calls
|
|
17
|
+
* leaving them out a shortcoming, not a feature.
|
|
18
|
+
*/
|
|
19
|
+
export async function syncMemoryToDisk(api, dir) {
|
|
20
|
+
const base = resolve(dir);
|
|
21
|
+
await mkdir(base, { recursive: true });
|
|
22
|
+
const result = { written: 0, refused: [], collisions: [], failures: [] };
|
|
23
|
+
const { files } = await api.listMemory();
|
|
24
|
+
// Personal first, so a path claimed by both scopes belongs to the file this
|
|
25
|
+
// account owns. The team file is then reported rather than quietly dropped;
|
|
26
|
+
// a directory per scope is the export's job (task 12a), not this one's.
|
|
27
|
+
const ordered = [...files].sort((a, b) => a.scope === b.scope ? a.path.localeCompare(b.path) : a.scope === 'personal' ? -1 : 1);
|
|
28
|
+
const taken = new Set();
|
|
29
|
+
for (const f of ordered) {
|
|
30
|
+
if (!isSafeMemoryPath(f.path)) {
|
|
31
|
+
result.refused.push(f.path);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const dest = resolve(base, ...f.path.split('/'));
|
|
35
|
+
if (!dest.startsWith(base + sep)) {
|
|
36
|
+
result.refused.push(f.path);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (taken.has(dest)) {
|
|
40
|
+
result.collisions.push(f.path);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const file = await api.readMemory(f.path);
|
|
45
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
46
|
+
await writeFile(dest, file.content, 'utf8');
|
|
47
|
+
taken.add(dest);
|
|
48
|
+
result.written += 1;
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
result.failures.push({ what: f.path, code: e instanceof Error ? e.message : String(e) });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=memorySync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memorySync.js","sourceRoot":"","sources":["../src/memorySync.ts"],"names":[],"mappings":"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"}
|