@fleetagent/pi-coding-agent 0.0.9 → 0.0.11
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/CHANGELOG.md +44 -0
- package/README.md +9 -0
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +18 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session.d.ts +13 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +42 -8
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts +5 -3
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +4 -2
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +86 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +27 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +56 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/pi-agent.d.ts +2 -0
- package/dist/core/pi-agent.d.ts.map +1 -1
- package/dist/core/pi-agent.js +3 -0
- package/dist/core/pi-agent.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +5 -0
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +115 -0
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/resource-loader.d.ts +15 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +332 -40
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/rules.d.ts +6 -0
- package/dist/core/rules.d.ts.map +1 -1
- package/dist/core/rules.js +216 -0
- package/dist/core/rules.js.map +1 -1
- package/dist/core/skills.d.ts +6 -0
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +216 -0
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/source-info.d.ts +2 -0
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js +6 -0
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/tools/bash.d.ts +6 -29
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +27 -101
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +3 -2
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +6 -8
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +3 -16
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +12 -18
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +3 -17
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +13 -25
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +3 -14
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +95 -43
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +17 -15
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +53 -52
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +3 -20
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +11 -22
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/operations.d.ts +145 -0
- package/dist/core/tools/operations.d.ts.map +1 -0
- package/dist/core/tools/operations.js +418 -0
- package/dist/core/tools/operations.js.map +1 -0
- package/dist/core/tools/read.d.ts +3 -16
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +9 -15
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +9 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +14 -0
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/write.d.ts +3 -14
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +9 -12
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +40 -5
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +2 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +73 -9
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +9 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +14 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +9 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +22 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/extensions.md +83 -5
- package/docs/usage.md +2 -0
- package/examples/extensions/README.md +0 -1
- package/examples/extensions/bash-spawn-hook.ts +2 -2
- package/examples/extensions/built-in-tool-renderer.ts +12 -5
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/minimal-mode.ts +9 -7
- package/examples/extensions/sandbox/index.ts +55 -56
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
- package/examples/extensions/ssh.ts +0 -220
|
@@ -7,12 +7,12 @@ import { canonicalizePath, isLocalPath, resolvePath } from "../utils/paths.js";
|
|
|
7
7
|
import { createEventBus } from "./event-bus.js";
|
|
8
8
|
import { createExtensionRuntime, loadExtensionFromFactory, loadExtensions } from "./extensions/loader.js";
|
|
9
9
|
import { DefaultPackageManager } from "./package-manager.js";
|
|
10
|
-
import { loadPromptTemplates } from "./prompt-templates.js";
|
|
11
|
-
import { loadRules } from "./rules.js";
|
|
10
|
+
import { loadPromptTemplates, loadPromptTemplatesWithOperations } from "./prompt-templates.js";
|
|
11
|
+
import { loadRules, loadRulesWithOperations } from "./rules.js";
|
|
12
12
|
import { SettingsManager } from "./settings-manager.js";
|
|
13
|
-
import { loadSkills } from "./skills.js";
|
|
13
|
+
import { loadSkills, loadSkillsWithOperations } from "./skills.js";
|
|
14
14
|
import { createSourceInfo } from "./source-info.js";
|
|
15
|
-
function resolvePromptInput(input, description) {
|
|
15
|
+
async function resolvePromptInput(input, description, operations) {
|
|
16
16
|
if (!input) {
|
|
17
17
|
return undefined;
|
|
18
18
|
}
|
|
@@ -25,6 +25,13 @@ function resolvePromptInput(input, description) {
|
|
|
25
25
|
return input;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
if (operations) {
|
|
29
|
+
try {
|
|
30
|
+
await operations.access(input, "read");
|
|
31
|
+
return (await operations.readFile(input)).toString("utf-8");
|
|
32
|
+
}
|
|
33
|
+
catch { }
|
|
34
|
+
}
|
|
28
35
|
return input;
|
|
29
36
|
}
|
|
30
37
|
function loadContextFileFromDir(dir) {
|
|
@@ -74,6 +81,45 @@ export function loadProjectContextFiles(options) {
|
|
|
74
81
|
contextFiles.push(...ancestorContextFiles);
|
|
75
82
|
return contextFiles;
|
|
76
83
|
}
|
|
84
|
+
async function loadContextFileFromDirWithOperations(operations, dir) {
|
|
85
|
+
const candidates = ["AGENTS.md", "AGENTS.MD", "CLAUDE.md", "CLAUDE.MD"];
|
|
86
|
+
for (const filename of candidates) {
|
|
87
|
+
const filePath = join(dir, filename);
|
|
88
|
+
try {
|
|
89
|
+
await operations.access(filePath, "read");
|
|
90
|
+
return { path: filePath, content: (await operations.readFile(filePath)).toString("utf-8") };
|
|
91
|
+
}
|
|
92
|
+
catch { }
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
async function loadProjectContextFilesWithOperations(options) {
|
|
97
|
+
const contextFiles = [];
|
|
98
|
+
const seenPaths = new Set();
|
|
99
|
+
const globalContext = loadContextFileFromDir(resolvePath(options.agentDir));
|
|
100
|
+
if (globalContext) {
|
|
101
|
+
contextFiles.push(globalContext);
|
|
102
|
+
seenPaths.add(globalContext.path);
|
|
103
|
+
}
|
|
104
|
+
const ancestorContextFiles = [];
|
|
105
|
+
let currentDir = resolvePath(options.cwd);
|
|
106
|
+
const root = resolve("/");
|
|
107
|
+
while (true) {
|
|
108
|
+
const contextFile = await loadContextFileFromDirWithOperations(options.operations, currentDir);
|
|
109
|
+
if (contextFile && !seenPaths.has(contextFile.path)) {
|
|
110
|
+
ancestorContextFiles.unshift(contextFile);
|
|
111
|
+
seenPaths.add(contextFile.path);
|
|
112
|
+
}
|
|
113
|
+
if (currentDir === root)
|
|
114
|
+
break;
|
|
115
|
+
const parentDir = resolve(currentDir, "..");
|
|
116
|
+
if (parentDir === currentDir)
|
|
117
|
+
break;
|
|
118
|
+
currentDir = parentDir;
|
|
119
|
+
}
|
|
120
|
+
contextFiles.push(...ancestorContextFiles);
|
|
121
|
+
return contextFiles;
|
|
122
|
+
}
|
|
77
123
|
export class DefaultResourceLoader {
|
|
78
124
|
cwd;
|
|
79
125
|
agentDir;
|
|
@@ -94,6 +140,7 @@ export class DefaultResourceLoader {
|
|
|
94
140
|
noContextFiles;
|
|
95
141
|
systemPromptSource;
|
|
96
142
|
appendSystemPromptSource;
|
|
143
|
+
toolOperations;
|
|
97
144
|
extensionsOverride;
|
|
98
145
|
skillsOverride;
|
|
99
146
|
rulesOverride;
|
|
@@ -146,6 +193,7 @@ export class DefaultResourceLoader {
|
|
|
146
193
|
this.noContextFiles = options.noContextFiles ?? false;
|
|
147
194
|
this.systemPromptSource = options.systemPrompt;
|
|
148
195
|
this.appendSystemPromptSource = options.appendSystemPrompt;
|
|
196
|
+
this.toolOperations = options.toolOperations;
|
|
149
197
|
this.extensionsOverride = options.extensionsOverride;
|
|
150
198
|
this.skillsOverride = options.skillsOverride;
|
|
151
199
|
this.rulesOverride = options.rulesOverride;
|
|
@@ -198,6 +246,48 @@ export class DefaultResourceLoader {
|
|
|
198
246
|
getAppendSystemPrompt() {
|
|
199
247
|
return this.appendSystemPrompt;
|
|
200
248
|
}
|
|
249
|
+
getInstructionOperations() {
|
|
250
|
+
const backend = this.toolOperations?.getBackendInfo?.();
|
|
251
|
+
return backend?.type === "ssh" && backend.configured ? this.toolOperations : undefined;
|
|
252
|
+
}
|
|
253
|
+
getRemoteProjectInstructionResourcePaths(cwd) {
|
|
254
|
+
const projectBaseDir = join(cwd, CONFIG_DIR_NAME);
|
|
255
|
+
const projectMetadata = {
|
|
256
|
+
source: "ssh",
|
|
257
|
+
scope: "project",
|
|
258
|
+
origin: "top-level",
|
|
259
|
+
baseDir: projectBaseDir,
|
|
260
|
+
};
|
|
261
|
+
const skills = [
|
|
262
|
+
{ path: join(projectBaseDir, "skills"), metadata: projectMetadata },
|
|
263
|
+
];
|
|
264
|
+
const rules = [
|
|
265
|
+
{ path: join(projectBaseDir, "rules"), metadata: projectMetadata },
|
|
266
|
+
];
|
|
267
|
+
const prompts = [
|
|
268
|
+
{ path: join(projectBaseDir, "prompts"), metadata: projectMetadata },
|
|
269
|
+
];
|
|
270
|
+
let currentDir = resolve(cwd);
|
|
271
|
+
const root = resolve("/");
|
|
272
|
+
while (true) {
|
|
273
|
+
const agentsBaseDir = join(currentDir, ".agents");
|
|
274
|
+
const agentsMetadata = {
|
|
275
|
+
source: "ssh",
|
|
276
|
+
scope: "project",
|
|
277
|
+
origin: "top-level",
|
|
278
|
+
baseDir: agentsBaseDir,
|
|
279
|
+
};
|
|
280
|
+
skills.push({ path: join(agentsBaseDir, "skills"), metadata: agentsMetadata });
|
|
281
|
+
rules.push({ path: join(agentsBaseDir, "rules"), metadata: agentsMetadata });
|
|
282
|
+
if (currentDir === root)
|
|
283
|
+
break;
|
|
284
|
+
const parentDir = resolve(currentDir, "..");
|
|
285
|
+
if (parentDir === currentDir)
|
|
286
|
+
break;
|
|
287
|
+
currentDir = parentDir;
|
|
288
|
+
}
|
|
289
|
+
return { skills, rules, prompts };
|
|
290
|
+
}
|
|
201
291
|
extendResources(paths) {
|
|
202
292
|
const skillPaths = this.normalizeExtensionPaths(paths.skillPaths ?? []);
|
|
203
293
|
const rulePaths = this.normalizeExtensionPaths(paths.rulePaths ?? []);
|
|
@@ -253,10 +343,16 @@ export class DefaultResourceLoader {
|
|
|
253
343
|
return resources.filter((r) => r.enabled);
|
|
254
344
|
};
|
|
255
345
|
const getEnabledPaths = (resources) => getEnabledResources(resources).map((r) => r.path);
|
|
346
|
+
const instructionOperations = this.getInstructionOperations();
|
|
347
|
+
const loadProjectInstructionsRemotely = instructionOperations !== undefined;
|
|
348
|
+
const isLocalProjectInstructionResource = (resource) => loadProjectInstructionsRemotely &&
|
|
349
|
+
resource.metadata.scope === "project" &&
|
|
350
|
+
resource.metadata.origin === "top-level";
|
|
256
351
|
const enabledExtensions = getEnabledPaths(resolvedPaths.extensions);
|
|
257
|
-
const enabledSkillResources = getEnabledResources(resolvedPaths.skills);
|
|
258
|
-
const enabledRuleResources = getEnabledResources(resolvedPaths.rules);
|
|
259
|
-
const
|
|
352
|
+
const enabledSkillResources = getEnabledResources(resolvedPaths.skills).filter((resource) => !isLocalProjectInstructionResource(resource));
|
|
353
|
+
const enabledRuleResources = getEnabledResources(resolvedPaths.rules).filter((resource) => !isLocalProjectInstructionResource(resource));
|
|
354
|
+
const enabledPromptResources = getEnabledResources(resolvedPaths.prompts).filter((resource) => !isLocalProjectInstructionResource(resource));
|
|
355
|
+
const enabledPrompts = enabledPromptResources.map((resource) => resource.path);
|
|
260
356
|
const enabledThemes = getEnabledPaths(resolvedPaths.themes);
|
|
261
357
|
const mapSkillPath = (resource) => {
|
|
262
358
|
if (resource.metadata.source !== "auto" && resource.metadata.origin !== "package") {
|
|
@@ -280,7 +376,20 @@ export class DefaultResourceLoader {
|
|
|
280
376
|
}
|
|
281
377
|
return resource.path;
|
|
282
378
|
};
|
|
283
|
-
const
|
|
379
|
+
const remoteInstructionResourcePaths = instructionOperations
|
|
380
|
+
? this.getRemoteProjectInstructionResourcePaths(instructionOperations.cwd)
|
|
381
|
+
: { skills: [], rules: [], prompts: [] };
|
|
382
|
+
for (const entry of [
|
|
383
|
+
...remoteInstructionResourcePaths.skills,
|
|
384
|
+
...remoteInstructionResourcePaths.rules,
|
|
385
|
+
...remoteInstructionResourcePaths.prompts,
|
|
386
|
+
]) {
|
|
387
|
+
metadataByPath.set(entry.path, entry.metadata);
|
|
388
|
+
}
|
|
389
|
+
const enabledSkills = [
|
|
390
|
+
...enabledSkillResources.map(mapSkillPath),
|
|
391
|
+
...remoteInstructionResourcePaths.skills.map((entry) => entry.path),
|
|
392
|
+
];
|
|
284
393
|
const mapRulePath = (resource) => {
|
|
285
394
|
if (resource.metadata.source !== "auto" && resource.metadata.origin !== "package") {
|
|
286
395
|
return resource.path;
|
|
@@ -303,7 +412,10 @@ export class DefaultResourceLoader {
|
|
|
303
412
|
}
|
|
304
413
|
return resource.path;
|
|
305
414
|
};
|
|
306
|
-
const enabledRules =
|
|
415
|
+
const enabledRules = [
|
|
416
|
+
...enabledRuleResources.map(mapRulePath),
|
|
417
|
+
...remoteInstructionResourcePaths.rules.map((entry) => entry.path),
|
|
418
|
+
];
|
|
307
419
|
// Add CLI paths metadata
|
|
308
420
|
for (const r of cliExtensionPaths.extensions) {
|
|
309
421
|
if (!metadataByPath.has(r.path)) {
|
|
@@ -352,7 +464,7 @@ export class DefaultResourceLoader {
|
|
|
352
464
|
? this.mergePaths(cliEnabledSkills, this.additionalSkillPaths)
|
|
353
465
|
: this.mergePaths([...cliEnabledSkills, ...enabledSkills], this.additionalSkillPaths);
|
|
354
466
|
this.lastSkillPaths = skillPaths;
|
|
355
|
-
this.
|
|
467
|
+
await this.updateSkillsFromPathsForReload(skillPaths, metadataByPath);
|
|
356
468
|
for (const p of this.additionalSkillPaths) {
|
|
357
469
|
if (isLocalPath(p)) {
|
|
358
470
|
const resolved = this.resolveResourcePath(p);
|
|
@@ -365,7 +477,7 @@ export class DefaultResourceLoader {
|
|
|
365
477
|
? this.mergePaths(cliEnabledRules, this.additionalRulePaths)
|
|
366
478
|
: this.mergePaths([...cliEnabledRules, ...enabledRules], this.additionalRulePaths);
|
|
367
479
|
this.lastRulePaths = rulePaths;
|
|
368
|
-
this.
|
|
480
|
+
await this.updateRulesFromPathsForReload(rulePaths, metadataByPath);
|
|
369
481
|
for (const p of this.additionalRulePaths) {
|
|
370
482
|
if (isLocalPath(p)) {
|
|
371
483
|
const resolved = this.resolveResourcePath(p);
|
|
@@ -374,11 +486,12 @@ export class DefaultResourceLoader {
|
|
|
374
486
|
}
|
|
375
487
|
}
|
|
376
488
|
}
|
|
489
|
+
const remotePromptPaths = remoteInstructionResourcePaths.prompts.map((entry) => entry.path);
|
|
377
490
|
const promptPaths = this.noPromptTemplates
|
|
378
491
|
? this.mergePaths(cliEnabledPrompts, this.additionalPromptTemplatePaths)
|
|
379
|
-
: this.mergePaths([...cliEnabledPrompts, ...enabledPrompts], this.additionalPromptTemplatePaths);
|
|
492
|
+
: this.mergePaths([...cliEnabledPrompts, ...enabledPrompts, ...remotePromptPaths], this.additionalPromptTemplatePaths);
|
|
380
493
|
this.lastPromptPaths = promptPaths;
|
|
381
|
-
this.
|
|
494
|
+
await this.updatePromptsFromPathsForReload(promptPaths, metadataByPath);
|
|
382
495
|
for (const p of this.additionalPromptTemplatePaths) {
|
|
383
496
|
if (isLocalPath(p)) {
|
|
384
497
|
const resolved = this.resolveResourcePath(p);
|
|
@@ -403,17 +516,23 @@ export class DefaultResourceLoader {
|
|
|
403
516
|
}
|
|
404
517
|
}
|
|
405
518
|
const agentsFiles = {
|
|
406
|
-
agentsFiles: this.noContextFiles
|
|
519
|
+
agentsFiles: this.noContextFiles
|
|
520
|
+
? []
|
|
521
|
+
: instructionOperations
|
|
522
|
+
? await loadProjectContextFilesWithOperations({
|
|
523
|
+
cwd: instructionOperations.cwd,
|
|
524
|
+
agentDir: this.agentDir,
|
|
525
|
+
operations: instructionOperations,
|
|
526
|
+
})
|
|
527
|
+
: loadProjectContextFiles({ cwd: this.cwd, agentDir: this.agentDir }),
|
|
407
528
|
};
|
|
408
529
|
const resolvedAgentsFiles = this.agentsFilesOverride ? this.agentsFilesOverride(agentsFiles) : agentsFiles;
|
|
409
530
|
this.agentsFiles = resolvedAgentsFiles.agentsFiles;
|
|
410
|
-
const baseSystemPrompt = resolvePromptInput(this.systemPromptSource ?? this.discoverSystemPromptFile(), "system prompt");
|
|
531
|
+
const baseSystemPrompt = await resolvePromptInput(this.systemPromptSource ?? this.discoverSystemPromptFile(), "system prompt", this.getInstructionOperations());
|
|
411
532
|
this.systemPrompt = this.systemPromptOverride ? this.systemPromptOverride(baseSystemPrompt) : baseSystemPrompt;
|
|
412
533
|
const appendSources = this.appendSystemPromptSource ??
|
|
413
534
|
(this.discoverAppendSystemPromptFile() ? [this.discoverAppendSystemPromptFile()] : []);
|
|
414
|
-
const baseAppend = appendSources
|
|
415
|
-
.map((s) => resolvePromptInput(s, "append system prompt"))
|
|
416
|
-
.filter((s) => s !== undefined);
|
|
535
|
+
const baseAppend = (await Promise.all(appendSources.map((s) => resolvePromptInput(s, "append system prompt", this.getInstructionOperations())))).filter((s) => s !== undefined);
|
|
417
536
|
this.appendSystemPrompt = this.appendSystemPromptOverride
|
|
418
537
|
? this.appendSystemPromptOverride(baseAppend)
|
|
419
538
|
: baseAppend;
|
|
@@ -429,6 +548,31 @@ export class DefaultResourceLoader {
|
|
|
429
548
|
};
|
|
430
549
|
});
|
|
431
550
|
}
|
|
551
|
+
getExtensionRegisteredSkills() {
|
|
552
|
+
return this.extensionsResult.extensions.flatMap((extension) => Array.from(extension.skills.values()));
|
|
553
|
+
}
|
|
554
|
+
getExtensionRegisteredRules() {
|
|
555
|
+
return this.extensionsResult.extensions.flatMap((extension) => Array.from(extension.rules.values()));
|
|
556
|
+
}
|
|
557
|
+
getExtensionRegisteredPrompts() {
|
|
558
|
+
return this.extensionsResult.extensions.flatMap((extension) => Array.from(extension.prompts.values()));
|
|
559
|
+
}
|
|
560
|
+
applyLoadedSkills(skillsResult, metadataByPath) {
|
|
561
|
+
const extensionSkills = this.getExtensionRegisteredSkills();
|
|
562
|
+
const seenSkillNames = new Set(extensionSkills.map((skill) => skill.name));
|
|
563
|
+
const baseSkillsResult = {
|
|
564
|
+
skills: [...extensionSkills, ...skillsResult.skills.filter((skill) => !seenSkillNames.has(skill.name))],
|
|
565
|
+
diagnostics: skillsResult.diagnostics,
|
|
566
|
+
};
|
|
567
|
+
const resolvedSkills = this.skillsOverride ? this.skillsOverride(baseSkillsResult) : baseSkillsResult;
|
|
568
|
+
this.skills = resolvedSkills.skills.map((skill) => ({
|
|
569
|
+
...skill,
|
|
570
|
+
sourceInfo: this.findSourceInfoForPath(skill.filePath, this.extensionSkillSourceInfos, metadataByPath) ??
|
|
571
|
+
skill.sourceInfo ??
|
|
572
|
+
this.getDefaultSourceInfoForPath(skill.filePath),
|
|
573
|
+
}));
|
|
574
|
+
this.skillDiagnostics = resolvedSkills.diagnostics;
|
|
575
|
+
}
|
|
432
576
|
updateSkillsFromPaths(skillPaths, metadataByPath) {
|
|
433
577
|
let skillsResult;
|
|
434
578
|
if (this.noSkills && skillPaths.length === 0) {
|
|
@@ -442,14 +586,76 @@ export class DefaultResourceLoader {
|
|
|
442
586
|
includeDefaults: false,
|
|
443
587
|
});
|
|
444
588
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
589
|
+
this.applyLoadedSkills(skillsResult, metadataByPath);
|
|
590
|
+
}
|
|
591
|
+
shouldLoadPathWithInstructionOperations(path, metadataByPath) {
|
|
592
|
+
const operations = this.getInstructionOperations();
|
|
593
|
+
if (!operations)
|
|
594
|
+
return false;
|
|
595
|
+
const sourceInfo = this.findSourceInfoForPath(path, undefined, metadataByPath);
|
|
596
|
+
if (sourceInfo?.source === "ssh")
|
|
597
|
+
return true;
|
|
598
|
+
const cwd = operations.cwd.endsWith(sep) ? operations.cwd : `${operations.cwd}${sep}`;
|
|
599
|
+
return path === operations.cwd || path.startsWith(cwd);
|
|
600
|
+
}
|
|
601
|
+
async updateSkillsFromPathsForReload(skillPaths, metadataByPath) {
|
|
602
|
+
let skillsResult;
|
|
603
|
+
const operations = this.getInstructionOperations();
|
|
604
|
+
if (this.noSkills && skillPaths.length === 0) {
|
|
605
|
+
skillsResult = { skills: [], diagnostics: [] };
|
|
606
|
+
}
|
|
607
|
+
else if (operations) {
|
|
608
|
+
const remotePaths = skillPaths.filter((path) => this.shouldLoadPathWithInstructionOperations(path, metadataByPath));
|
|
609
|
+
const localPaths = skillPaths.filter((path) => !this.shouldLoadPathWithInstructionOperations(path, metadataByPath));
|
|
610
|
+
const remoteResult = await loadSkillsWithOperations({
|
|
611
|
+
cwd: operations.cwd,
|
|
612
|
+
agentDir: this.agentDir,
|
|
613
|
+
skillPaths: remotePaths,
|
|
614
|
+
includeDefaults: false,
|
|
615
|
+
operations,
|
|
616
|
+
});
|
|
617
|
+
const localResult = loadSkills({
|
|
618
|
+
cwd: this.cwd,
|
|
619
|
+
agentDir: this.agentDir,
|
|
620
|
+
skillPaths: localPaths,
|
|
621
|
+
includeDefaults: false,
|
|
622
|
+
});
|
|
623
|
+
const skillsByName = new Map();
|
|
624
|
+
for (const skill of [...remoteResult.skills, ...localResult.skills]) {
|
|
625
|
+
if (!skillsByName.has(skill.name)) {
|
|
626
|
+
skillsByName.set(skill.name, skill);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
skillsResult = {
|
|
630
|
+
skills: Array.from(skillsByName.values()),
|
|
631
|
+
diagnostics: [...remoteResult.diagnostics, ...localResult.diagnostics],
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
skillsResult = loadSkills({
|
|
636
|
+
cwd: this.cwd,
|
|
637
|
+
agentDir: this.agentDir,
|
|
638
|
+
skillPaths,
|
|
639
|
+
includeDefaults: false,
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
this.applyLoadedSkills(skillsResult, metadataByPath);
|
|
643
|
+
}
|
|
644
|
+
applyLoadedRules(rulesResult, metadataByPath) {
|
|
645
|
+
const extensionRules = this.getExtensionRegisteredRules();
|
|
646
|
+
const seenRuleNames = new Set(extensionRules.map((rule) => rule.name));
|
|
647
|
+
const baseRulesResult = {
|
|
648
|
+
rules: [...extensionRules, ...rulesResult.rules.filter((rule) => !seenRuleNames.has(rule.name))],
|
|
649
|
+
diagnostics: rulesResult.diagnostics,
|
|
650
|
+
};
|
|
651
|
+
const resolvedRules = this.rulesOverride ? this.rulesOverride(baseRulesResult) : baseRulesResult;
|
|
652
|
+
this.rules = resolvedRules.rules.map((rule) => ({
|
|
653
|
+
...rule,
|
|
654
|
+
sourceInfo: this.findSourceInfoForPath(rule.filePath, this.extensionRuleSourceInfos, metadataByPath) ??
|
|
655
|
+
rule.sourceInfo ??
|
|
656
|
+
this.getDefaultSourceInfoForPath(rule.filePath),
|
|
451
657
|
}));
|
|
452
|
-
this.
|
|
658
|
+
this.ruleDiagnostics = resolvedRules.diagnostics;
|
|
453
659
|
}
|
|
454
660
|
updateRulesFromPaths(rulePaths, metadataByPath) {
|
|
455
661
|
let rulesResult;
|
|
@@ -464,14 +670,63 @@ export class DefaultResourceLoader {
|
|
|
464
670
|
includeDefaults: false,
|
|
465
671
|
});
|
|
466
672
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
673
|
+
this.applyLoadedRules(rulesResult, metadataByPath);
|
|
674
|
+
}
|
|
675
|
+
async updateRulesFromPathsForReload(rulePaths, metadataByPath) {
|
|
676
|
+
let rulesResult;
|
|
677
|
+
const operations = this.getInstructionOperations();
|
|
678
|
+
if (this.noRules && rulePaths.length === 0) {
|
|
679
|
+
rulesResult = { rules: [], diagnostics: [] };
|
|
680
|
+
}
|
|
681
|
+
else if (operations) {
|
|
682
|
+
const remotePaths = rulePaths.filter((path) => this.shouldLoadPathWithInstructionOperations(path, metadataByPath));
|
|
683
|
+
const localPaths = rulePaths.filter((path) => !this.shouldLoadPathWithInstructionOperations(path, metadataByPath));
|
|
684
|
+
const remoteResult = await loadRulesWithOperations({
|
|
685
|
+
cwd: operations.cwd,
|
|
686
|
+
agentDir: this.agentDir,
|
|
687
|
+
rulePaths: remotePaths,
|
|
688
|
+
includeDefaults: false,
|
|
689
|
+
operations,
|
|
690
|
+
});
|
|
691
|
+
const localResult = loadRules({
|
|
692
|
+
cwd: this.cwd,
|
|
693
|
+
agentDir: this.agentDir,
|
|
694
|
+
rulePaths: localPaths,
|
|
695
|
+
includeDefaults: false,
|
|
696
|
+
});
|
|
697
|
+
const rulesByName = new Map();
|
|
698
|
+
for (const rule of [...remoteResult.rules, ...localResult.rules]) {
|
|
699
|
+
if (!rulesByName.has(rule.name)) {
|
|
700
|
+
rulesByName.set(rule.name, rule);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
rulesResult = {
|
|
704
|
+
rules: Array.from(rulesByName.values()),
|
|
705
|
+
diagnostics: [...remoteResult.diagnostics, ...localResult.diagnostics],
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
else {
|
|
709
|
+
rulesResult = loadRules({
|
|
710
|
+
cwd: this.cwd,
|
|
711
|
+
agentDir: this.agentDir,
|
|
712
|
+
rulePaths,
|
|
713
|
+
includeDefaults: false,
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
this.applyLoadedRules(rulesResult, metadataByPath);
|
|
717
|
+
}
|
|
718
|
+
applyLoadedPrompts(promptsResult, metadataByPath) {
|
|
719
|
+
const extensionPrompts = this.getExtensionRegisteredPrompts();
|
|
720
|
+
const basePromptsResult = this.dedupePrompts([...extensionPrompts, ...promptsResult.prompts]);
|
|
721
|
+
basePromptsResult.diagnostics.unshift(...promptsResult.diagnostics);
|
|
722
|
+
const resolvedPrompts = this.promptsOverride ? this.promptsOverride(basePromptsResult) : basePromptsResult;
|
|
723
|
+
this.prompts = resolvedPrompts.prompts.map((prompt) => ({
|
|
724
|
+
...prompt,
|
|
725
|
+
sourceInfo: this.findSourceInfoForPath(prompt.filePath, this.extensionPromptSourceInfos, metadataByPath) ??
|
|
726
|
+
prompt.sourceInfo ??
|
|
727
|
+
this.getDefaultSourceInfoForPath(prompt.filePath),
|
|
473
728
|
}));
|
|
474
|
-
this.
|
|
729
|
+
this.promptDiagnostics = resolvedPrompts.diagnostics;
|
|
475
730
|
}
|
|
476
731
|
updatePromptsFromPaths(promptPaths, metadataByPath) {
|
|
477
732
|
let promptsResult;
|
|
@@ -487,14 +742,42 @@ export class DefaultResourceLoader {
|
|
|
487
742
|
});
|
|
488
743
|
promptsResult = this.dedupePrompts(allPrompts);
|
|
489
744
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
745
|
+
this.applyLoadedPrompts(promptsResult, metadataByPath);
|
|
746
|
+
}
|
|
747
|
+
async updatePromptsFromPathsForReload(promptPaths, metadataByPath) {
|
|
748
|
+
let promptsResult;
|
|
749
|
+
const operations = this.getInstructionOperations();
|
|
750
|
+
if (this.noPromptTemplates && promptPaths.length === 0) {
|
|
751
|
+
promptsResult = { prompts: [], diagnostics: [] };
|
|
752
|
+
}
|
|
753
|
+
else if (operations) {
|
|
754
|
+
const remotePaths = promptPaths.filter((path) => this.shouldLoadPathWithInstructionOperations(path, metadataByPath));
|
|
755
|
+
const localPaths = promptPaths.filter((path) => !this.shouldLoadPathWithInstructionOperations(path, metadataByPath));
|
|
756
|
+
const remotePrompts = await loadPromptTemplatesWithOperations({
|
|
757
|
+
cwd: operations.cwd,
|
|
758
|
+
agentDir: this.agentDir,
|
|
759
|
+
promptPaths: remotePaths,
|
|
760
|
+
includeDefaults: false,
|
|
761
|
+
operations,
|
|
762
|
+
});
|
|
763
|
+
const localPrompts = loadPromptTemplates({
|
|
764
|
+
cwd: this.cwd,
|
|
765
|
+
agentDir: this.agentDir,
|
|
766
|
+
promptPaths: localPaths,
|
|
767
|
+
includeDefaults: false,
|
|
768
|
+
});
|
|
769
|
+
promptsResult = this.dedupePrompts([...remotePrompts, ...localPrompts]);
|
|
770
|
+
}
|
|
771
|
+
else {
|
|
772
|
+
const allPrompts = loadPromptTemplates({
|
|
773
|
+
cwd: this.cwd,
|
|
774
|
+
agentDir: this.agentDir,
|
|
775
|
+
promptPaths,
|
|
776
|
+
includeDefaults: false,
|
|
777
|
+
});
|
|
778
|
+
promptsResult = this.dedupePrompts(allPrompts);
|
|
779
|
+
}
|
|
780
|
+
this.applyLoadedPrompts(promptsResult, metadataByPath);
|
|
498
781
|
}
|
|
499
782
|
updateThemesFromPaths(themePaths, metadataByPath) {
|
|
500
783
|
let themesResult;
|
|
@@ -529,6 +812,15 @@ export class DefaultResourceLoader {
|
|
|
529
812
|
for (const tool of extension.tools.values()) {
|
|
530
813
|
tool.sourceInfo = extension.sourceInfo;
|
|
531
814
|
}
|
|
815
|
+
for (const skill of extension.skills.values()) {
|
|
816
|
+
skill.sourceInfo = extension.sourceInfo;
|
|
817
|
+
}
|
|
818
|
+
for (const rule of extension.rules.values()) {
|
|
819
|
+
rule.sourceInfo = extension.sourceInfo;
|
|
820
|
+
}
|
|
821
|
+
for (const prompt of extension.prompts.values()) {
|
|
822
|
+
prompt.sourceInfo = extension.sourceInfo;
|
|
823
|
+
}
|
|
532
824
|
}
|
|
533
825
|
}
|
|
534
826
|
findSourceInfoForPath(resourcePath, extraSourceInfos, metadataByPath) {
|