@nexrall/code-core 1.4.46 → 1.4.48
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/agent/agentTypes.d.ts.map +1 -1
- package/dist/agent/agentTypes.js +12 -15
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +14 -1
- package/dist/agent/memory.d.ts +38 -10
- package/dist/agent/memory.d.ts.map +1 -1
- package/dist/agent/memory.js +223 -67
- package/dist/agent/skills.d.ts +34 -4
- package/dist/agent/skills.d.ts.map +1 -1
- package/dist/agent/skills.js +111 -38
- package/dist/agent/trust.d.ts +7 -0
- package/dist/agent/trust.d.ts.map +1 -0
- package/dist/agent/trust.js +163 -0
- package/dist/api/client.d.ts +30 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +52 -0
- package/dist/checkpoint/manager.d.ts.map +1 -1
- package/dist/checkpoint/manager.js +6 -0
- package/dist/commands/loader.d.ts.map +1 -1
- package/dist/commands/loader.js +2 -13
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/permissions/modePolicy.d.ts.map +1 -1
- package/dist/permissions/modePolicy.js +1 -0
- package/dist/permissions/rules.js +1 -1
- package/dist/plugins/index.d.ts +31 -4
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +72 -5
- package/dist/plugins/installer.d.ts +47 -0
- package/dist/plugins/installer.d.ts.map +1 -1
- package/dist/plugins/installer.js +173 -0
- package/dist/tools/executor.d.ts.map +1 -1
- package/dist/tools/executor.js +196 -5
- package/dist/util/frontmatter.d.ts +79 -0
- package/dist/util/frontmatter.d.ts.map +1 -0
- package/dist/util/frontmatter.js +172 -0
- package/package.json +5 -2
package/dist/agent/skills.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export interface SkillWarning {
|
|
2
|
+
/** Absolute path of the SKILL.md / command file the problem was found in. */
|
|
3
|
+
file: string;
|
|
4
|
+
/** Skill name, when one could be determined. */
|
|
5
|
+
name: string;
|
|
6
|
+
message: string;
|
|
7
|
+
}
|
|
1
8
|
export interface Skill {
|
|
2
9
|
name: string;
|
|
3
10
|
description: string;
|
|
@@ -11,10 +18,33 @@ export interface Skill {
|
|
|
11
18
|
disableModelInvocation: boolean;
|
|
12
19
|
/** false → only the model may invoke it (auto-load only, not meant to be typed as a command). */
|
|
13
20
|
userInvocable: boolean;
|
|
21
|
+
/** agentskills.io spec field — license name or reference to a bundled license file. Informational only. */
|
|
22
|
+
license?: string;
|
|
23
|
+
/** agentskills.io spec field — environment requirements (e.g. "Requires git, docker"). Informational only. */
|
|
24
|
+
compatibility?: string;
|
|
25
|
+
/** agentskills.io spec field — arbitrary author-supplied key/value metadata (from a nested `metadata:` block). */
|
|
26
|
+
metadata?: Record<string, string>;
|
|
27
|
+
/** agentskills.io spec field (experimental) — space-separated tool names the skill declares it needs. Not yet enforced as an allowlist; informational. */
|
|
28
|
+
allowedTools?: string[];
|
|
14
29
|
}
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
30
|
+
/**
|
|
31
|
+
* Discover all skills, with diagnostics.
|
|
32
|
+
*
|
|
33
|
+
* Precedence, most to least authoritative: project `.nexrall/skills` >
|
|
34
|
+
* project `.nexrall/commands` > project `.agents/skills` (cross-client) >
|
|
35
|
+
* global `.nexrall/commands` > global `.nexrall/skills` > global
|
|
36
|
+
* `.agents/skills` (cross-client) > plugin > builtin.
|
|
37
|
+
*
|
|
38
|
+
* The `.agents/skills` scans are always the weakest source within their tier
|
|
39
|
+
* — see the module comment above for why. Directory-style
|
|
40
|
+
* `.nexrall/skills/<name>/SKILL.md` beats a flat `.nexrall/commands/<name>.md`
|
|
41
|
+
* of the same name within the same precedence tier.
|
|
42
|
+
*/
|
|
43
|
+
export declare function loadSkillsWithWarnings(workDir: string): {
|
|
44
|
+
skills: Skill[];
|
|
45
|
+
warnings: SkillWarning[];
|
|
46
|
+
};
|
|
47
|
+
/** Discover all skills (project overrides global overrides plugin overrides builtin). See loadSkillsWithWarnings for the full precedence rule and diagnostics. */
|
|
18
48
|
export declare function loadSkills(workDir: string): Skill[];
|
|
19
49
|
export declare function findSkill(skills: Skill[], name: string): Skill | undefined;
|
|
20
50
|
/** Skills the MODEL may auto-invoke via the use_skill tool (excludes disable-model-invocation:true ones). */
|
|
@@ -28,7 +58,7 @@ export declare function summariseSkills(skills: Skill[]): string;
|
|
|
28
58
|
* substitution as slash commands — see commands/loader.ts#expandBody), then
|
|
29
59
|
* prepend a short header pointing at the skill's own directory (if any) so
|
|
30
60
|
* the model knows where to find supporting files it may need to read_file
|
|
31
|
-
* on demand, mirroring
|
|
61
|
+
* on demand, mirroring the spec's "reference files from your SKILL.md"
|
|
32
62
|
* guidance without loading them into context up front.
|
|
33
63
|
*/
|
|
34
64
|
export declare function expandSkill(skill: Skill, argString: string, workDir: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/agent/skills.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/agent/skills.ts"],"names":[],"mappings":"AAyEA,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpD,0IAA0I;IAC1I,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kHAAkH;IAClH,sBAAsB,EAAE,OAAO,CAAC;IAChC,iGAAiG;IACjG,aAAa,EAAE,OAAO,CAAC;IACvB,2GAA2G;IAC3G,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8GAA8G;IAC9G,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kHAAkH;IAClH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,0JAA0J;IAC1J,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AA8LD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,CAsBrG;AAED,kKAAkK;AAClK,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,CAEnD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAG1E;AAED,6GAA6G;AAC7G,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAE5D;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAE5D;AAED,oHAAoH;AACpH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAIvD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAcpF"}
|
package/dist/agent/skills.js
CHANGED
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadSkillsWithWarnings = loadSkillsWithWarnings;
|
|
36
37
|
exports.loadSkills = loadSkills;
|
|
37
38
|
exports.findSkill = findSkill;
|
|
38
39
|
exports.autoInvokableSkills = autoInvokableSkills;
|
|
@@ -44,18 +45,19 @@ const path = __importStar(require("path"));
|
|
|
44
45
|
const os = __importStar(require("os"));
|
|
45
46
|
const index_1 = require("../plugins/index");
|
|
46
47
|
const loader_1 = require("../commands/loader");
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
const frontmatter_1 = require("../util/frontmatter");
|
|
49
|
+
/** Frontmatter keys this parser understands, for typo/unrecognised-key detection (see SkillWarning). */
|
|
50
|
+
const KNOWN_META_KEYS = new Set([
|
|
51
|
+
'name', 'description', 'model', 'mode',
|
|
52
|
+
'disable-model-invocation', 'user-invocable',
|
|
53
|
+
'license', 'compatibility', 'metadata', 'allowed-tools',
|
|
54
|
+
]);
|
|
55
|
+
// agentskills.io's `name` constraint: 1-64 chars, lowercase alphanumeric and
|
|
56
|
+
// hyphens, no leading/trailing/consecutive hyphens. Validated LENIENTLY here
|
|
57
|
+
// (warn, still load) per the spec's own client-implementation guidance —
|
|
58
|
+
// rejecting a skill outright over a cosmetic name issue would be a worse
|
|
59
|
+
// failure mode than a slightly-off name that still works.
|
|
60
|
+
const SPEC_NAME_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
59
61
|
function parseBool(v, fallback) {
|
|
60
62
|
if (v === undefined)
|
|
61
63
|
return fallback;
|
|
@@ -66,7 +68,14 @@ function parseBool(v, fallback) {
|
|
|
66
68
|
return false;
|
|
67
69
|
return fallback;
|
|
68
70
|
}
|
|
69
|
-
|
|
71
|
+
/** Space- (or comma-) separated tool list, same leniency as agentTypes.ts's parseToolList. */
|
|
72
|
+
function parseSpaceList(v) {
|
|
73
|
+
if (!v)
|
|
74
|
+
return undefined;
|
|
75
|
+
const items = v.split(/[,\s]+/).map((t) => t.trim()).filter(Boolean);
|
|
76
|
+
return items.length ? items : undefined;
|
|
77
|
+
}
|
|
78
|
+
function toSkill(meta, body, name, source, dir, nested) {
|
|
70
79
|
const model = ['turbo', 'pro', 'ultra'].find((x) => x === (meta.model ?? '').toLowerCase());
|
|
71
80
|
return {
|
|
72
81
|
name,
|
|
@@ -78,13 +87,51 @@ function toSkill(meta, body, name, source, dir) {
|
|
|
78
87
|
dir,
|
|
79
88
|
disableModelInvocation: parseBool(meta['disable-model-invocation'], false),
|
|
80
89
|
userInvocable: parseBool(meta['user-invocable'], true),
|
|
90
|
+
license: meta.license || undefined,
|
|
91
|
+
compatibility: meta.compatibility || undefined,
|
|
92
|
+
metadata: nested?.metadata,
|
|
93
|
+
allowedTools: parseSpaceList(meta['allowed-tools']),
|
|
81
94
|
};
|
|
82
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Lenient validation warnings for a skill's frontmatter — never blocks loading, only reported.
|
|
98
|
+
*
|
|
99
|
+
* `rawName` is the name BEFORE lowercasing (whatever the frontmatter or the
|
|
100
|
+
* directory/file actually said) — validated against the spec's naming rule,
|
|
101
|
+
* which is itself case-sensitive ("lowercase ... only" is a real constraint,
|
|
102
|
+
* not cosmetic). `effectiveName` is the lowercased name used as the map key
|
|
103
|
+
* and `Skill.name` — using it here instead would make an uppercase name
|
|
104
|
+
* always "pass" validation simply because it had already been normalised
|
|
105
|
+
* away by the time this function saw it.
|
|
106
|
+
*/
|
|
107
|
+
function validateSkillMeta(meta, rawName, effectiveName, dirName, file, warnings) {
|
|
108
|
+
if (!warnings)
|
|
109
|
+
return;
|
|
110
|
+
if (!SPEC_NAME_RE.test(rawName)) {
|
|
111
|
+
warnings.push({
|
|
112
|
+
file, name: effectiveName,
|
|
113
|
+
message: `name "${rawName}" does not match the agentskills.io convention (lowercase letters, numbers, and single hyphens only) — loaded anyway, but other clients reading this skill may warn or reject it.`,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else if (rawName.length > 64) {
|
|
117
|
+
warnings.push({ file, name: effectiveName, message: `name is ${rawName.length} characters — the spec caps this at 64. Loaded anyway.` });
|
|
118
|
+
}
|
|
119
|
+
if (dirName !== undefined && meta.name && meta.name.trim().toLowerCase() !== dirName.toLowerCase()) {
|
|
120
|
+
warnings.push({
|
|
121
|
+
file, name: effectiveName,
|
|
122
|
+
message: `frontmatter name "${meta.name}" does not match its directory name "${dirName}" — the spec requires them to match for cross-client compatibility. Loaded anyway, using the frontmatter name.`,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
const strayKeys = Object.keys(meta).filter((k) => !KNOWN_META_KEYS.has(k));
|
|
126
|
+
if (strayKeys.length) {
|
|
127
|
+
warnings.push({ file, name: effectiveName, message: `has unrecognised frontmatter key(s): ${strayKeys.join(', ')} — these are ignored.` });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
83
130
|
// Legacy flat-file skills: .nexrall/commands/<name>.md (and plugin commands/).
|
|
84
131
|
// Kept as its own loader (rather than merged into loadSkillDir below) since the
|
|
85
132
|
// naming/precedence rule ("skill directory wins over a same-name flat command")
|
|
86
133
|
// requires knowing about both shapes before the caller merges them.
|
|
87
|
-
function loadFlatCommandDir(dir, source, into) {
|
|
134
|
+
function loadFlatCommandDir(dir, source, into, warnings) {
|
|
88
135
|
let files;
|
|
89
136
|
try {
|
|
90
137
|
files = fs.readdirSync(dir).filter((f) => f.endsWith('.md'));
|
|
@@ -93,23 +140,27 @@ function loadFlatCommandDir(dir, source, into) {
|
|
|
93
140
|
return;
|
|
94
141
|
}
|
|
95
142
|
for (const file of files) {
|
|
143
|
+
const full = path.join(dir, file);
|
|
96
144
|
try {
|
|
97
|
-
const raw = fs.readFileSync(
|
|
98
|
-
const { meta, body } = parseFrontmatter(raw);
|
|
99
|
-
const
|
|
145
|
+
const raw = fs.readFileSync(full, 'utf-8');
|
|
146
|
+
const { meta, body } = (0, frontmatter_1.parseFrontmatter)(raw);
|
|
147
|
+
const rawName = (meta.name || path.basename(file, '.md')).trim();
|
|
148
|
+
const name = rawName.toLowerCase();
|
|
100
149
|
if (!name)
|
|
101
150
|
continue;
|
|
102
151
|
if (source !== 'project' && into.has(name))
|
|
103
152
|
continue; // earlier tiers win
|
|
153
|
+
validateSkillMeta(meta, rawName, name, undefined, full, warnings);
|
|
104
154
|
into.set(name, toSkill(meta, body, name, source));
|
|
105
155
|
}
|
|
106
|
-
catch {
|
|
107
|
-
|
|
156
|
+
catch (err) {
|
|
157
|
+
warnings?.push({ file: full, name: path.basename(file, '.md'), message: `could not be read or parsed (${err.message}) — skipped.` });
|
|
108
158
|
}
|
|
109
159
|
}
|
|
110
160
|
}
|
|
111
161
|
// Directory-style skills: .nexrall/skills/<name>/SKILL.md (+ optional supporting files).
|
|
112
|
-
|
|
162
|
+
// Also used for the cross-client `.agents/skills/<name>/SKILL.md` convention — same shape.
|
|
163
|
+
function loadSkillDir(root, source, into, warnings) {
|
|
113
164
|
let entries;
|
|
114
165
|
try {
|
|
115
166
|
entries = fs.readdirSync(root, { withFileTypes: true });
|
|
@@ -131,8 +182,9 @@ function loadSkillDir(root, source, into) {
|
|
|
131
182
|
}
|
|
132
183
|
try {
|
|
133
184
|
const raw = fs.readFileSync(skillFile, 'utf-8');
|
|
134
|
-
const { meta, body } = parseFrontmatter(raw);
|
|
135
|
-
const
|
|
185
|
+
const { meta, body, nested } = (0, frontmatter_1.parseFrontmatter)(raw);
|
|
186
|
+
const rawName = (meta.name || entry.name).trim();
|
|
187
|
+
const name = rawName.toLowerCase();
|
|
136
188
|
if (!name)
|
|
137
189
|
continue;
|
|
138
190
|
// A directory-style skill always wins over an earlier flat command of
|
|
@@ -140,10 +192,11 @@ function loadSkillDir(root, source, into) {
|
|
|
140
192
|
// project tier always wins outright regardless of load order.
|
|
141
193
|
if (source !== 'project' && into.has(name))
|
|
142
194
|
continue;
|
|
143
|
-
|
|
195
|
+
validateSkillMeta(meta, rawName, name, entry.name, skillFile, warnings);
|
|
196
|
+
into.set(name, toSkill(meta, body, name, source, skillDir, nested));
|
|
144
197
|
}
|
|
145
|
-
catch {
|
|
146
|
-
|
|
198
|
+
catch (err) {
|
|
199
|
+
warnings?.push({ file: skillFile, name: entry.name, message: `could not be read or parsed (${err.message}) — skipped.` });
|
|
147
200
|
}
|
|
148
201
|
}
|
|
149
202
|
}
|
|
@@ -187,25 +240,45 @@ const BUILTIN_SKILLS = [
|
|
|
187
240
|
].join('\n'),
|
|
188
241
|
},
|
|
189
242
|
];
|
|
190
|
-
/**
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
|
|
243
|
+
/**
|
|
244
|
+
* Discover all skills, with diagnostics.
|
|
245
|
+
*
|
|
246
|
+
* Precedence, most to least authoritative: project `.nexrall/skills` >
|
|
247
|
+
* project `.nexrall/commands` > project `.agents/skills` (cross-client) >
|
|
248
|
+
* global `.nexrall/commands` > global `.nexrall/skills` > global
|
|
249
|
+
* `.agents/skills` (cross-client) > plugin > builtin.
|
|
250
|
+
*
|
|
251
|
+
* The `.agents/skills` scans are always the weakest source within their tier
|
|
252
|
+
* — see the module comment above for why. Directory-style
|
|
253
|
+
* `.nexrall/skills/<name>/SKILL.md` beats a flat `.nexrall/commands/<name>.md`
|
|
254
|
+
* of the same name within the same precedence tier.
|
|
255
|
+
*/
|
|
256
|
+
function loadSkillsWithWarnings(workDir) {
|
|
194
257
|
const out = new Map();
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
258
|
+
const warnings = [];
|
|
259
|
+
// Project tier is last-write-wins (see loadSkillDir/loadFlatCommandDir's
|
|
260
|
+
// `source !== 'project'` guard), so the WEAKEST project source loads first.
|
|
261
|
+
loadSkillDir(path.join(workDir, '.agents', 'skills'), 'project', out, warnings);
|
|
262
|
+
loadFlatCommandDir(path.join(workDir, '.nexrall', 'commands'), 'project', out, warnings);
|
|
263
|
+
loadSkillDir(path.join(workDir, '.nexrall', 'skills'), 'project', out, warnings);
|
|
264
|
+
// Global tier is first-write-wins (the guard skips a repeat name), so the
|
|
265
|
+
// STRONGEST global source loads first, and .agents/skills loads last.
|
|
266
|
+
loadFlatCommandDir(path.join(os.homedir(), '.nexrall', 'commands'), 'global', out, warnings);
|
|
267
|
+
loadSkillDir(path.join(os.homedir(), '.nexrall', 'skills'), 'global', out, warnings);
|
|
268
|
+
loadSkillDir(path.join(os.homedir(), '.agents', 'skills'), 'global', out, warnings);
|
|
200
269
|
for (const dir of (0, index_1.pluginAssetDirs)(workDir, 'commands'))
|
|
201
|
-
loadFlatCommandDir(dir, 'plugin', out);
|
|
270
|
+
loadFlatCommandDir(dir, 'plugin', out, warnings);
|
|
202
271
|
for (const dir of (0, index_1.pluginAssetDirs)(workDir, 'skills'))
|
|
203
|
-
loadSkillDir(dir, 'plugin', out);
|
|
272
|
+
loadSkillDir(dir, 'plugin', out, warnings);
|
|
204
273
|
for (const skill of BUILTIN_SKILLS) {
|
|
205
274
|
if (!out.has(skill.name))
|
|
206
275
|
out.set(skill.name, skill);
|
|
207
276
|
}
|
|
208
|
-
return [...out.values()];
|
|
277
|
+
return { skills: [...out.values()], warnings };
|
|
278
|
+
}
|
|
279
|
+
/** Discover all skills (project overrides global overrides plugin overrides builtin). See loadSkillsWithWarnings for the full precedence rule and diagnostics. */
|
|
280
|
+
function loadSkills(workDir) {
|
|
281
|
+
return loadSkillsWithWarnings(workDir).skills;
|
|
209
282
|
}
|
|
210
283
|
function findSkill(skills, name) {
|
|
211
284
|
const want = name.replace(/^\//, '').trim().toLowerCase();
|
|
@@ -231,7 +304,7 @@ function summariseSkills(skills) {
|
|
|
231
304
|
* substitution as slash commands — see commands/loader.ts#expandBody), then
|
|
232
305
|
* prepend a short header pointing at the skill's own directory (if any) so
|
|
233
306
|
* the model knows where to find supporting files it may need to read_file
|
|
234
|
-
* on demand, mirroring
|
|
307
|
+
* on demand, mirroring the spec's "reference files from your SKILL.md"
|
|
235
308
|
* guidance without loading them into context up front.
|
|
236
309
|
*/
|
|
237
310
|
function expandSkill(skill, argString, workDir) {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which trust-sensitive files actually exist in `dir`, so a confirmation
|
|
3
|
+
* prompt can tell the user what THIS folder will do rather than describing
|
|
4
|
+
* risks in the abstract. Ordered most- to least-dangerous.
|
|
5
|
+
*/
|
|
6
|
+
export declare function detectTrustSignals(dir: string): string[];
|
|
7
|
+
//# sourceMappingURL=trust.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.d.ts","sourceRoot":"","sources":["../../src/agent/trust.ts"],"names":[],"mappings":"AAqDA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAkExD"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.detectTrustSignals = detectTrustSignals;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
// ─── Workspace Trust Signals (shared) ─────────────────────────────────────
|
|
40
|
+
//
|
|
41
|
+
// Opening a folder for an agent to work in is not a passive act. Before the
|
|
42
|
+
// user types anything, a session can already read and act on files found in
|
|
43
|
+
// that folder:
|
|
44
|
+
//
|
|
45
|
+
// • `.nexrall/mcp.json` declares MCP servers, and connecting to a stdio
|
|
46
|
+
// server runs `spawn(server.command, server.args)` — arbitrary command
|
|
47
|
+
// execution, straight from a file in the repo (see mcp/manager.ts /
|
|
48
|
+
// mcp/client.ts).
|
|
49
|
+
// • `.nexrall/plugins/` may contribute their OWN `mcp.json`/`hooks.json`
|
|
50
|
+
// (see plugins/index.ts's pluginMcpServers/pluginHooks) — same risk
|
|
51
|
+
// class as a bare mcp.json, just one hop further away.
|
|
52
|
+
// • `nexrall.md` is injected into the system prompt as trusted project
|
|
53
|
+
// instructions, so its contents steer the agent for the whole session.
|
|
54
|
+
// • `.nexrall/{skills,commands}` define playbooks the agent will follow,
|
|
55
|
+
// and `.nexrall/permissions.json` can pre-approve tool calls that would
|
|
56
|
+
// otherwise prompt.
|
|
57
|
+
// • `.agents/skills/` is the same kind of playbook, discovered from the
|
|
58
|
+
// agentskills.io cross-client convention (see agent/skills.ts) rather
|
|
59
|
+
// than a Nexrall-specific path — worth its own line since it may have
|
|
60
|
+
// been authored for a different client entirely.
|
|
61
|
+
//
|
|
62
|
+
// So `git clone` of a hostile repo followed by pointing an agent at it is
|
|
63
|
+
// enough to execute attacker-chosen commands before a human reviews anything.
|
|
64
|
+
//
|
|
65
|
+
// This module is the shared, pure "what would this folder do" detector. The
|
|
66
|
+
// CLI has its own longstanding copy (packages/cli/src/trust.ts) — kept
|
|
67
|
+
// independent there rather than migrated onto this one, so a change here
|
|
68
|
+
// can never silently alter the CLI's own trust-prompt wording/behaviour or
|
|
69
|
+
// its own dedicated test suite. Any NEW client (e.g. the desktop app) should
|
|
70
|
+
// use this shared copy instead of hand-rolling a third one.
|
|
71
|
+
//
|
|
72
|
+
// Deliberately stateless: nothing here reads or writes any trust STORE.
|
|
73
|
+
// Whether/how a client remembers "already confirmed this session" is the
|
|
74
|
+
// caller's job (see e.g. desktop's main/trustGate.ts) — this function only
|
|
75
|
+
// ever reports what is true of the folder RIGHT NOW.
|
|
76
|
+
/** Does the project settings file bind plugin aliases to remote repos? */
|
|
77
|
+
function declaresPluginSources(dir) {
|
|
78
|
+
try {
|
|
79
|
+
const raw = fs.readFileSync(path.join(dir, '.nexrall', 'settings.json'), 'utf-8');
|
|
80
|
+
const obj = JSON.parse(raw);
|
|
81
|
+
const s = obj.pluginSources;
|
|
82
|
+
return Boolean(s && typeof s === 'object' && !Array.isArray(s) && Object.keys(s).length > 0);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Which trust-sensitive files actually exist in `dir`, so a confirmation
|
|
90
|
+
* prompt can tell the user what THIS folder will do rather than describing
|
|
91
|
+
* risks in the abstract. Ordered most- to least-dangerous.
|
|
92
|
+
*/
|
|
93
|
+
function detectTrustSignals(dir) {
|
|
94
|
+
const signals = [];
|
|
95
|
+
const exists = (...p) => {
|
|
96
|
+
try {
|
|
97
|
+
return fs.existsSync(path.join(dir, ...p));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
// Code-executing first — these can run local commands before the user
|
|
104
|
+
// types anything, so they are what the decision really hinges on.
|
|
105
|
+
if (exists('.nexrall', 'mcp.json')) {
|
|
106
|
+
signals.push('.nexrall/mcp.json — can start MCP servers (runs local commands)');
|
|
107
|
+
}
|
|
108
|
+
if (exists('.nexrall', 'plugins')) {
|
|
109
|
+
// Plugins are scanned from the workspace and may contribute their own MCP
|
|
110
|
+
// servers/hooks (see plugins/index.ts → pluginMcpServers/pluginHooks), so
|
|
111
|
+
// this is in the same risk class as mcp.json rather than a cosmetic add-on.
|
|
112
|
+
signals.push('.nexrall/plugins/ — project plugins (may add MCP servers or hooks)');
|
|
113
|
+
}
|
|
114
|
+
// Then things that widen what the agent may do without asking.
|
|
115
|
+
if (exists('.nexrall', 'permissions.json')) {
|
|
116
|
+
signals.push('.nexrall/permissions.json — pre-approved tool permissions');
|
|
117
|
+
}
|
|
118
|
+
if (exists('.nexrall', 'settings.json')) {
|
|
119
|
+
// Called out separately when the file declares plugin sources: those bind
|
|
120
|
+
// a short alias to a remote repo, so installing that alias would fetch
|
|
121
|
+
// whatever the REPOSITORY chose. Installing still needs a human and its
|
|
122
|
+
// own confirmation — nothing is fetched from a declaration alone — but the
|
|
123
|
+
// user should know the repo is trying to name what they install. A
|
|
124
|
+
// settings.json can also carry a project's own `hooks` config, which runs
|
|
125
|
+
// shell commands automatically around tool calls — worth flagging here too.
|
|
126
|
+
let hasHooks = false;
|
|
127
|
+
try {
|
|
128
|
+
const raw = fs.readFileSync(path.join(dir, '.nexrall', 'settings.json'), 'utf-8');
|
|
129
|
+
const obj = JSON.parse(raw);
|
|
130
|
+
hasHooks = Boolean(obj.hooks && typeof obj.hooks === 'object' && Object.keys(obj.hooks).length > 0);
|
|
131
|
+
}
|
|
132
|
+
catch { /* absent or malformed — treated as no hooks declared */ }
|
|
133
|
+
const bits = ['.nexrall/settings.json — project settings and permission rules'];
|
|
134
|
+
if (declaresPluginSources(dir))
|
|
135
|
+
bits.push('declares plugin sources (aliases for remote plugin repos)');
|
|
136
|
+
if (hasHooks)
|
|
137
|
+
bits.push('runs hooks (shell commands) automatically around tool calls');
|
|
138
|
+
signals.push(bits.join(', '));
|
|
139
|
+
}
|
|
140
|
+
// Then things that steer the agent's behaviour.
|
|
141
|
+
if (exists('nexrall.md')) {
|
|
142
|
+
signals.push('nexrall.md — project instructions added to the agent\u2019s prompt');
|
|
143
|
+
}
|
|
144
|
+
if (exists('.nexrall', 'skills')) {
|
|
145
|
+
signals.push('.nexrall/skills/ — custom agent playbooks');
|
|
146
|
+
}
|
|
147
|
+
if (exists('.nexrall', 'commands')) {
|
|
148
|
+
signals.push('.nexrall/commands/ — custom slash commands');
|
|
149
|
+
}
|
|
150
|
+
if (exists('.nexrall', 'agents')) {
|
|
151
|
+
signals.push('.nexrall/agents/ — custom sub-agent definitions');
|
|
152
|
+
}
|
|
153
|
+
if (exists('.agents', 'skills')) {
|
|
154
|
+
// Same risk class as .nexrall/skills/ (a playbook is instructions the
|
|
155
|
+
// agent follows, not code it executes) — called out separately because
|
|
156
|
+
// this path is the agentskills.io cross-client convention, so a skill
|
|
157
|
+
// here may have been authored for/by a DIFFERENT tool than the one
|
|
158
|
+
// asking to trust this folder right now.
|
|
159
|
+
signals.push('.agents/skills/ — cross-client agent playbooks (agentskills.io convention)');
|
|
160
|
+
}
|
|
161
|
+
return signals;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=trust.js.map
|
package/dist/api/client.d.ts
CHANGED
|
@@ -131,6 +131,36 @@ export interface DescribeAttachmentResult {
|
|
|
131
131
|
}
|
|
132
132
|
export declare function describeAttachment(kind: 'image' | 'pdf', data: string, mediaType?: string, name?: string): Promise<DescribeAttachmentResult>;
|
|
133
133
|
export declare function getBalance(): Promise<number>;
|
|
134
|
+
export interface UsageDailyDay {
|
|
135
|
+
date: string;
|
|
136
|
+
total: number;
|
|
137
|
+
byType: Record<string, number>;
|
|
138
|
+
}
|
|
139
|
+
export interface UsageDailyResult {
|
|
140
|
+
days: UsageDailyDay[];
|
|
141
|
+
totalSpent: number;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Day-by-day spend breakdown, same endpoint the web app's Settings > Usage
|
|
145
|
+
* chart reads (backend/routes/user.js's /usage-daily). Used by Nexrall Work's
|
|
146
|
+
* own Settings > Usage panel so both surfaces show the identical numbers.
|
|
147
|
+
*/
|
|
148
|
+
export declare function getUsageDaily(days?: number): Promise<UsageDailyResult>;
|
|
134
149
|
export declare function exchangeVscodeCode(code: string): Promise<AuthConfig>;
|
|
135
150
|
export declare function login(email: string, password: string): Promise<AuthConfig>;
|
|
151
|
+
export interface UserProfile {
|
|
152
|
+
id: string | number;
|
|
153
|
+
email: string;
|
|
154
|
+
name?: string;
|
|
155
|
+
phone?: string;
|
|
156
|
+
avatar_url?: string;
|
|
157
|
+
username?: string;
|
|
158
|
+
bio?: string;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Same GET /api/user/profile the web app's Settings > Profile section reads.
|
|
162
|
+
* Used by Nexrall Work's own Settings > Profile panel so both surfaces show
|
|
163
|
+
* identical account data.
|
|
164
|
+
*/
|
|
165
|
+
export declare function getUserProfile(): Promise<UserProfile>;
|
|
136
166
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/api/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAA8B,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAiErH,eAAO,MAAM,QAAQ,QAAmB,CAAC;AAIzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5D,OAAO,EAAE,CAAC,EAAE,EACZ,UAAU,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GACtD,CAAC,EAAE,CAeL;AAiGD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnC,oFAAoF;IACpF,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACjG,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6IAA6I;IAC7I,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;;;;;;;;;;OAeG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AA8ID,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,GAC7B,OAAO,CAAC,OAAO,CAAC,CAkmClB;AAID;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9D;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAYxD;AAeD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,OAAO,GAAG,KAAK,EACrB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,wBAAwB,CAAC,CAmCnC;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CA0BlD;AAID,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA+B1E;AAID,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA0BhF"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
package/dist/api/client.js
CHANGED
|
@@ -10,8 +10,10 @@ exports.cancelTurn = cancelTurn;
|
|
|
10
10
|
exports.revokeRefreshToken = revokeRefreshToken;
|
|
11
11
|
exports.describeAttachment = describeAttachment;
|
|
12
12
|
exports.getBalance = getBalance;
|
|
13
|
+
exports.getUsageDaily = getUsageDaily;
|
|
13
14
|
exports.exchangeVscodeCode = exchangeVscodeCode;
|
|
14
15
|
exports.login = login;
|
|
16
|
+
exports.getUserProfile = getUserProfile;
|
|
15
17
|
const eventsource_parser_1 = require("eventsource-parser");
|
|
16
18
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
17
19
|
const crypto_1 = require("crypto");
|
|
@@ -1544,6 +1546,33 @@ async function getBalance() {
|
|
|
1544
1546
|
const data = (await response.json());
|
|
1545
1547
|
return typeof data.balance === 'number' ? data.balance : 0;
|
|
1546
1548
|
}
|
|
1549
|
+
/**
|
|
1550
|
+
* Day-by-day spend breakdown, same endpoint the web app's Settings > Usage
|
|
1551
|
+
* chart reads (backend/routes/user.js's /usage-daily). Used by Nexrall Work's
|
|
1552
|
+
* own Settings > Usage panel so both surfaces show the identical numbers.
|
|
1553
|
+
*/
|
|
1554
|
+
async function getUsageDaily(days = 30) {
|
|
1555
|
+
const fetchOnce = () => (0, node_fetch_1.default)(`${exports.API_BASE}/api/user/usage-daily?days=${days}`, { method: 'GET', headers: authHeaders() });
|
|
1556
|
+
let response = await fetchOnce();
|
|
1557
|
+
if (response.status === 401 || response.status === 403) {
|
|
1558
|
+
const body = await response.text().catch(() => '');
|
|
1559
|
+
if (isExpiredTokenResponse(response.status, body) && await refreshAccessToken()) {
|
|
1560
|
+
response = await fetchOnce();
|
|
1561
|
+
}
|
|
1562
|
+
else {
|
|
1563
|
+
throw new Error(`API error ${response.status}: ${body}`);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
if (!response.ok) {
|
|
1567
|
+
const errText = await response.text();
|
|
1568
|
+
throw new Error(`API error ${response.status}: ${errText}`);
|
|
1569
|
+
}
|
|
1570
|
+
const data = (await response.json());
|
|
1571
|
+
return {
|
|
1572
|
+
days: Array.isArray(data.days) ? data.days : [],
|
|
1573
|
+
totalSpent: typeof data.totalSpent === 'number' ? data.totalSpent : 0,
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1547
1576
|
// ─── VSCode OAuth ─────────────────────────────────────────────────────────────
|
|
1548
1577
|
async function exchangeVscodeCode(code) {
|
|
1549
1578
|
const response = await (0, node_fetch_1.default)(`${exports.API_BASE}/api/auth/vscode-exchange`, {
|
|
@@ -1596,4 +1625,27 @@ async function login(email, password) {
|
|
|
1596
1625
|
email: data.email ?? email,
|
|
1597
1626
|
};
|
|
1598
1627
|
}
|
|
1628
|
+
/**
|
|
1629
|
+
* Same GET /api/user/profile the web app's Settings > Profile section reads.
|
|
1630
|
+
* Used by Nexrall Work's own Settings > Profile panel so both surfaces show
|
|
1631
|
+
* identical account data.
|
|
1632
|
+
*/
|
|
1633
|
+
async function getUserProfile() {
|
|
1634
|
+
const fetchOnce = () => (0, node_fetch_1.default)(`${exports.API_BASE}/api/user/profile`, { method: 'GET', headers: authHeaders() });
|
|
1635
|
+
let response = await fetchOnce();
|
|
1636
|
+
if (response.status === 401 || response.status === 403) {
|
|
1637
|
+
const body = await response.text().catch(() => '');
|
|
1638
|
+
if (isExpiredTokenResponse(response.status, body) && await refreshAccessToken()) {
|
|
1639
|
+
response = await fetchOnce();
|
|
1640
|
+
}
|
|
1641
|
+
else {
|
|
1642
|
+
throw new Error(`API error ${response.status}: ${body}`);
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
if (!response.ok) {
|
|
1646
|
+
const errText = await response.text();
|
|
1647
|
+
throw new Error(`API error ${response.status}: ${errText}`);
|
|
1648
|
+
}
|
|
1649
|
+
return (await response.json());
|
|
1650
|
+
}
|
|
1599
1651
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/checkpoint/manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/checkpoint/manager.ts"],"names":[],"mappings":"AA+CA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAQD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAMlE;AA4BD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,8FAA8F;IAC9F,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;IAClB,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kFAAkF;IAClF,YAAY,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC;IAClB,6FAA6F;IAC7F,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AA6BD,qBAAa,iBAAiB;IAWhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAVpC,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAElC;;;;OAIG;gBAC0B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAa5D,OAAO,CAAC,OAAO;IAIf;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAcpD;;;;;OAKG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA8BxE;;;;;;;OAOG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQxC,OAAO,CAAC,iBAAiB;IAiBzB,0FAA0F;IAC1F,UAAU,IAAI,IAAI;IAWlB,IAAI,IAAI,iBAAiB,EAAE;IAY3B,cAAc,IAAI,OAAO;IAIzB;;;;;OAKG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IA0BnD,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,YAAY;CAkCrB"}
|
|
@@ -68,6 +68,9 @@ const MAX_SNAPSHOT_BYTES = 2 * 1024 * 1024; // 2 MB/file — larger files are no
|
|
|
68
68
|
const MAX_PERSISTED_TURNS = 50; // pruned oldest-first on commit
|
|
69
69
|
const MUTATING_TOOLS = new Set([
|
|
70
70
|
'write_file',
|
|
71
|
+
'write_docx',
|
|
72
|
+
'write_xlsx',
|
|
73
|
+
'write_pptx',
|
|
71
74
|
'edit_file',
|
|
72
75
|
'multi_edit',
|
|
73
76
|
'delete_file',
|
|
@@ -99,6 +102,9 @@ function str(v) {
|
|
|
99
102
|
function affectedPaths(name, input) {
|
|
100
103
|
switch (name) {
|
|
101
104
|
case 'write_file':
|
|
105
|
+
case 'write_docx':
|
|
106
|
+
case 'write_xlsx':
|
|
107
|
+
case 'write_pptx':
|
|
102
108
|
case 'edit_file':
|
|
103
109
|
case 'multi_edit':
|
|
104
110
|
case 'delete_file':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/commands/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/commands/loader.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;CACrD;AAsED,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CASjE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAG7F;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAuCnF;AAED,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3F"}
|