@f5-sales-demo/xcsh 21.40.0 → 21.41.1
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/package.json +8 -8
- package/src/capability/fs.ts +20 -10
- package/src/capability/index.ts +5 -2
- package/src/capability/types.ts +4 -0
- package/src/deprecations.ts +4 -4
- package/src/discovery/agents-md.ts +2 -1
- package/src/discovery/agents.ts +4 -4
- package/src/discovery/builtin.ts +6 -4
- package/src/discovery/claude-plugins.ts +2 -1
- package/src/discovery/claude.ts +5 -4
- package/src/discovery/codex.ts +3 -1
- package/src/discovery/gemini.ts +4 -4
- package/src/discovery/github.ts +1 -1
- package/src/discovery/helpers.ts +110 -17
- package/src/discovery/opencode.ts +3 -1
- package/src/extensibility/plugins/marketplace/cache.ts +78 -1
- package/src/extensibility/plugins/marketplace/manager.ts +10 -3
- package/src/extensibility/skills.ts +12 -3
- package/src/integrations/index.ts +8 -1
- package/src/integrations/registry.ts +2 -1
- package/src/integrations/setup.ts +35 -15
- package/src/internal-urls/api-catalog-index.generated.ts +1525 -1525
- package/src/internal-urls/api-catalog-preflight.ts +210 -0
- package/src/internal-urls/api-spec-index.generated.ts +1 -1
- package/src/internal-urls/api-spec-resolve.ts +156 -0
- package/src/internal-urls/branding-index.generated.ts +1 -1
- package/src/internal-urls/build-info.generated.ts +8 -8
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/modes/components/plugins/plugin-dashboard.ts +28 -3
- package/src/modes/components/plugins/state-manager.ts +16 -10
- package/src/modes/controllers/extension-ui-controller.ts +3 -1
- package/src/modes/controllers/selector-controller.ts +86 -1
- package/src/modes/print-mode.ts +8 -4
- package/src/prompts/rules/llms-search.md +2 -1
- package/src/prompts/system/system-prompt.md +12 -3
- package/src/sdk.ts +73 -43
- package/src/session/agent-session.ts +54 -1
- package/src/slash-commands/builtin-registry.ts +18 -2
- package/src/system-prompt.ts +469 -162
- package/src/task/executor.ts +5 -7
- package/src/task/index.ts +1 -0
- package/src/tools/index.ts +2 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5-sales-demo/xcsh",
|
|
4
|
-
"version": "21.
|
|
4
|
+
"version": "21.41.1",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/f5-sales-demo/xcsh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -64,13 +64,13 @@
|
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@agentclientprotocol/sdk": "1.4.0",
|
|
67
|
-
"@f5-sales-demo/pi-agent-core": "21.
|
|
68
|
-
"@f5-sales-demo/pi-ai": "21.
|
|
69
|
-
"@f5-sales-demo/pi-natives": "21.
|
|
70
|
-
"@f5-sales-demo/pi-resource-management": "21.
|
|
71
|
-
"@f5-sales-demo/pi-tui": "21.
|
|
72
|
-
"@f5-sales-demo/pi-utils": "21.
|
|
73
|
-
"@f5-sales-demo/xcsh-stats": "21.
|
|
67
|
+
"@f5-sales-demo/pi-agent-core": "21.41.1",
|
|
68
|
+
"@f5-sales-demo/pi-ai": "21.41.1",
|
|
69
|
+
"@f5-sales-demo/pi-natives": "21.41.1",
|
|
70
|
+
"@f5-sales-demo/pi-resource-management": "21.41.1",
|
|
71
|
+
"@f5-sales-demo/pi-tui": "21.41.1",
|
|
72
|
+
"@f5-sales-demo/pi-utils": "21.41.1",
|
|
73
|
+
"@f5-sales-demo/xcsh-stats": "21.41.1",
|
|
74
74
|
"@mozilla/readability": "^0.6",
|
|
75
75
|
"@sinclair/typebox": "0.34.52",
|
|
76
76
|
"@tobilu/qmd": "2.8.3",
|
package/src/capability/fs.ts
CHANGED
|
@@ -8,40 +8,47 @@ function resolvePath(filePath: string): string {
|
|
|
8
8
|
return path.resolve(filePath);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export async function readFile(filePath: string): Promise<string | null> {
|
|
11
|
+
export async function readFile(filePath: string, signal?: AbortSignal): Promise<string | null> {
|
|
12
12
|
const abs = resolvePath(filePath);
|
|
13
13
|
if (contentCache.has(abs)) {
|
|
14
14
|
return contentCache.get(abs) ?? null;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
try {
|
|
18
|
-
|
|
18
|
+
signal?.throwIfAborted();
|
|
19
|
+
const stat = await fs.promises.stat(abs);
|
|
20
|
+
if (!stat.isFile()) return null;
|
|
21
|
+
const content = await fs.promises.readFile(abs, { encoding: "utf8", signal });
|
|
19
22
|
contentCache.set(abs, content);
|
|
20
23
|
return content;
|
|
21
|
-
} catch {
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (signal?.aborted) throw error;
|
|
22
26
|
contentCache.set(abs, null);
|
|
23
27
|
return null;
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
export async function readDirEntries(dirPath: string): Promise<fs.Dirent[]> {
|
|
31
|
+
export async function readDirEntries(dirPath: string, signal?: AbortSignal): Promise<fs.Dirent[]> {
|
|
28
32
|
const abs = resolvePath(dirPath);
|
|
29
33
|
if (dirCache.has(abs)) {
|
|
30
34
|
return dirCache.get(abs) ?? [];
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
try {
|
|
38
|
+
signal?.throwIfAborted();
|
|
34
39
|
const entries = await fs.promises.readdir(abs, { withFileTypes: true });
|
|
40
|
+
signal?.throwIfAborted();
|
|
35
41
|
dirCache.set(abs, entries);
|
|
36
42
|
return entries;
|
|
37
|
-
} catch {
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (signal?.aborted) throw error;
|
|
38
45
|
dirCache.set(abs, []);
|
|
39
46
|
return [];
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
|
|
43
|
-
export async function readDir(dirPath: string): Promise<string[]> {
|
|
44
|
-
const entries = await readDirEntries(dirPath);
|
|
50
|
+
export async function readDir(dirPath: string, signal?: AbortSignal): Promise<string[]> {
|
|
51
|
+
const entries = await readDirEntries(dirPath, signal);
|
|
45
52
|
return entries.map(entry => entry.name);
|
|
46
53
|
}
|
|
47
54
|
|
|
@@ -49,12 +56,14 @@ export async function walkUp(
|
|
|
49
56
|
startDir: string,
|
|
50
57
|
name: string,
|
|
51
58
|
opts: { file?: boolean; dir?: boolean } = {},
|
|
59
|
+
signal?: AbortSignal,
|
|
52
60
|
): Promise<string | null> {
|
|
53
61
|
const { file = true, dir = true } = opts;
|
|
54
62
|
let current = resolvePath(startDir);
|
|
55
63
|
|
|
56
64
|
while (true) {
|
|
57
|
-
|
|
65
|
+
signal?.throwIfAborted();
|
|
66
|
+
const entries = await readDirEntries(current, signal);
|
|
58
67
|
const entry = entries.find(e => e.name === name);
|
|
59
68
|
if (entry) {
|
|
60
69
|
if (file && entry.isFile()) return path.join(current, name);
|
|
@@ -71,10 +80,11 @@ export async function walkUp(
|
|
|
71
80
|
* Returns the directory containing `.git` (the repo root), or null if not in a git repo.
|
|
72
81
|
* Results are based on the cached readDirEntries, so repeated calls are cheap.
|
|
73
82
|
*/
|
|
74
|
-
export async function findRepoRoot(startDir: string): Promise<string | null> {
|
|
83
|
+
export async function findRepoRoot(startDir: string, signal?: AbortSignal): Promise<string | null> {
|
|
75
84
|
let current = resolvePath(startDir);
|
|
76
85
|
while (true) {
|
|
77
|
-
|
|
86
|
+
signal?.throwIfAborted();
|
|
87
|
+
const entries = await readDirEntries(current, signal);
|
|
78
88
|
if (entries.some(e => e.name === ".git")) {
|
|
79
89
|
return current;
|
|
80
90
|
}
|
package/src/capability/index.ts
CHANGED
|
@@ -114,6 +114,7 @@ async function loadImpl<T>(
|
|
|
114
114
|
const results = await Promise.all(
|
|
115
115
|
providers.map(async provider => {
|
|
116
116
|
try {
|
|
117
|
+
ctx.signal?.throwIfAborted();
|
|
117
118
|
const result = await logger.time(
|
|
118
119
|
`capability:${capability.id}:${provider.id}`,
|
|
119
120
|
provider.load.bind(provider),
|
|
@@ -121,6 +122,7 @@ async function loadImpl<T>(
|
|
|
121
122
|
);
|
|
122
123
|
return { provider, result };
|
|
123
124
|
} catch (error) {
|
|
125
|
+
if (ctx.signal?.aborted) throw error;
|
|
124
126
|
logger.debug(`capability:${capability.id}:${provider.id}:error`);
|
|
125
127
|
return { provider, error };
|
|
126
128
|
}
|
|
@@ -235,8 +237,9 @@ export async function loadCapability<T>(capabilityId: string, options: LoadOptio
|
|
|
235
237
|
|
|
236
238
|
const cwd = options.cwd ?? getProjectDir();
|
|
237
239
|
const home = os.homedir();
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
+
options.signal?.throwIfAborted();
|
|
241
|
+
const repoRoot = await findRepoRoot(cwd, options.signal);
|
|
242
|
+
const ctx: LoadContext = { cwd, home, repoRoot, signal: options.signal };
|
|
240
243
|
const providers = filterProviders(capability, options);
|
|
241
244
|
|
|
242
245
|
return await loadImpl(capability, providers, ctx, options);
|
package/src/capability/types.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface LoadContext {
|
|
|
16
16
|
home: string;
|
|
17
17
|
/** Git repository root (directory containing .git), or null if not in a repo */
|
|
18
18
|
repoRoot: string | null;
|
|
19
|
+
/** Cancellation for bounded discovery. */
|
|
20
|
+
signal?: AbortSignal;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
/**
|
|
@@ -72,6 +74,8 @@ export interface LoadOptions {
|
|
|
72
74
|
includeDisabled?: boolean;
|
|
73
75
|
/** Explicit disabled extension IDs to apply instead of settings. */
|
|
74
76
|
disabledExtensions?: string[];
|
|
77
|
+
/** Cancellation for bounded discovery. */
|
|
78
|
+
signal?: AbortSignal;
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
/**
|
package/src/deprecations.ts
CHANGED
|
@@ -17,9 +17,9 @@ interface DeprecationEntry {
|
|
|
17
17
|
const DEPRECATIONS = BRANDING_DEPRECATIONS as unknown as Record<string, DeprecationEntry>;
|
|
18
18
|
|
|
19
19
|
/** Markers that identify a command as targeting the F5 XC API. */
|
|
20
|
-
const
|
|
21
|
-
"
|
|
22
|
-
"
|
|
20
|
+
const XCSH_API_MARKERS = [
|
|
21
|
+
"xcsh_api_url",
|
|
22
|
+
"xcsh_api_token",
|
|
23
23
|
"apitoken",
|
|
24
24
|
".volterra.io",
|
|
25
25
|
".volterra.us",
|
|
@@ -57,7 +57,7 @@ export function isDisallowedCliCommand(command: string): boolean {
|
|
|
57
57
|
if (!lower) return false;
|
|
58
58
|
const leadingToken = lower.split(/\s+/)[0] ?? "";
|
|
59
59
|
if (getDeprecatedClis().includes(leadingToken)) return true;
|
|
60
|
-
if (leadingToken === "curl" &&
|
|
60
|
+
if (leadingToken === "curl" && XCSH_API_MARKERS.some(marker => lower.includes(marker))) return true;
|
|
61
61
|
return false;
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -26,8 +26,9 @@ async function loadAgentsMd(ctx: LoadContext): Promise<LoadResult<ContextFile>>
|
|
|
26
26
|
let current = ctx.cwd;
|
|
27
27
|
|
|
28
28
|
while (true) {
|
|
29
|
+
ctx.signal?.throwIfAborted();
|
|
29
30
|
const candidate = path.join(current, "XCSH.md");
|
|
30
|
-
const content = await readFile(candidate);
|
|
31
|
+
const content = await readFile(candidate, ctx.signal);
|
|
31
32
|
|
|
32
33
|
if (content !== null) {
|
|
33
34
|
const parent = path.dirname(candidate);
|
package/src/discovery/agents.ts
CHANGED
|
@@ -52,10 +52,10 @@ function getProjectPathCandidates(ctx: LoadContext, ...segments: string[]): stri
|
|
|
52
52
|
// Skills
|
|
53
53
|
async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
54
54
|
const projectScans = getProjectPathCandidates(ctx, "skills").map(dir =>
|
|
55
|
-
scanSkillsFromDir(ctx, { dir, providerId: PROVIDER_ID, level: "project" }),
|
|
55
|
+
scanSkillsFromDir(ctx, { dir, providerId: PROVIDER_ID, level: "project", signal: ctx.signal }),
|
|
56
56
|
);
|
|
57
57
|
const userScans = getUserPathCandidates(ctx, "skills").map(dir =>
|
|
58
|
-
scanSkillsFromDir(ctx, { dir, providerId: PROVIDER_ID, level: "user" }),
|
|
58
|
+
scanSkillsFromDir(ctx, { dir, providerId: PROVIDER_ID, level: "user", signal: ctx.signal }),
|
|
59
59
|
);
|
|
60
60
|
|
|
61
61
|
const results = await Promise.all([...projectScans, ...userScans]);
|
|
@@ -170,7 +170,7 @@ registerProvider<SlashCommand>(slashCommandCapability.id, {
|
|
|
170
170
|
// Context Files (AGENTS.md)
|
|
171
171
|
async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFile>> {
|
|
172
172
|
const load = async (filePath: string, level: "user" | "project"): Promise<ContextFile | null> => {
|
|
173
|
-
const content = await readFile(filePath);
|
|
173
|
+
const content = await readFile(filePath, ctx.signal);
|
|
174
174
|
if (!content) return null;
|
|
175
175
|
// filePath is <ancestor>/.agent(s)/AGENTS.md — go up past the config dir to the ancestor
|
|
176
176
|
const ancestorDir = path.dirname(path.dirname(filePath));
|
|
@@ -197,7 +197,7 @@ registerProvider<ContextFile>(contextFileCapability.id, {
|
|
|
197
197
|
// System Prompt (SYSTEM.md)
|
|
198
198
|
async function loadSystemPrompt(ctx: LoadContext): Promise<LoadResult<SystemPrompt>> {
|
|
199
199
|
const load = async (filePath: string, level: "user" | "project"): Promise<SystemPrompt | null> => {
|
|
200
|
-
const content = await readFile(filePath);
|
|
200
|
+
const content = await readFile(filePath, ctx.signal);
|
|
201
201
|
if (!content) return null;
|
|
202
202
|
return { path: filePath, content, level, _source: createSourceMeta(PROVIDER_ID, filePath, level) };
|
|
203
203
|
};
|
package/src/discovery/builtin.ts
CHANGED
|
@@ -225,7 +225,7 @@ async function loadSystemPrompt(ctx: LoadContext): Promise<LoadResult<SystemProm
|
|
|
225
225
|
const items: SystemPrompt[] = [];
|
|
226
226
|
|
|
227
227
|
const userPath = path.join(ctx.home, PATHS.userAgent, "SYSTEM.md");
|
|
228
|
-
const userContent = await readFile(userPath);
|
|
228
|
+
const userContent = await readFile(userPath, ctx.signal);
|
|
229
229
|
if (userContent) {
|
|
230
230
|
items.push({
|
|
231
231
|
path: userPath,
|
|
@@ -238,7 +238,7 @@ async function loadSystemPrompt(ctx: LoadContext): Promise<LoadResult<SystemProm
|
|
|
238
238
|
const nearestProjectConfigDir = await findNearestProjectConfigDir(ctx.cwd, ctx.repoRoot);
|
|
239
239
|
if (nearestProjectConfigDir) {
|
|
240
240
|
const projectPath = path.join(nearestProjectConfigDir.dir, "SYSTEM.md");
|
|
241
|
-
const projectContent = await readFile(projectPath);
|
|
241
|
+
const projectContent = await readFile(projectPath, ctx.signal);
|
|
242
242
|
if (projectContent) {
|
|
243
243
|
items.push({
|
|
244
244
|
path: projectPath,
|
|
@@ -270,6 +270,7 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
|
270
270
|
providerId: PROVIDER_ID,
|
|
271
271
|
level: "project",
|
|
272
272
|
requireDescription: true,
|
|
273
|
+
signal: ctx.signal,
|
|
273
274
|
}),
|
|
274
275
|
);
|
|
275
276
|
|
|
@@ -279,6 +280,7 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
|
279
280
|
providerId: PROVIDER_ID,
|
|
280
281
|
level: "user",
|
|
281
282
|
requireDescription: true,
|
|
283
|
+
signal: ctx.signal,
|
|
282
284
|
});
|
|
283
285
|
|
|
284
286
|
const results = await Promise.all([...projectScans, userScan]);
|
|
@@ -814,7 +816,7 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
|
|
|
814
816
|
const warnings: string[] = [];
|
|
815
817
|
|
|
816
818
|
const userPath = path.join(ctx.home, PATHS.userAgent, "XCSH.md");
|
|
817
|
-
const userContent = await readFile(userPath);
|
|
819
|
+
const userContent = await readFile(userPath, ctx.signal);
|
|
818
820
|
if (userContent) {
|
|
819
821
|
items.push({
|
|
820
822
|
path: userPath,
|
|
@@ -827,7 +829,7 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
|
|
|
827
829
|
const nearestProjectConfigDir = await findNearestProjectConfigDir(ctx.cwd, ctx.repoRoot);
|
|
828
830
|
if (nearestProjectConfigDir) {
|
|
829
831
|
const projectPath = path.join(nearestProjectConfigDir.dir, "XCSH.md");
|
|
830
|
-
const projectContent = await readFile(projectPath);
|
|
832
|
+
const projectContent = await readFile(projectPath, ctx.signal);
|
|
831
833
|
if (projectContent) {
|
|
832
834
|
items.push({
|
|
833
835
|
path: projectPath,
|
|
@@ -37,7 +37,7 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
|
37
37
|
const items: Skill[] = [];
|
|
38
38
|
const warnings: string[] = [];
|
|
39
39
|
|
|
40
|
-
const { roots, warnings: rootWarnings } = await listXcshPluginRoots(ctx.home, ctx.cwd);
|
|
40
|
+
const { roots, warnings: rootWarnings } = await listXcshPluginRoots(ctx.home, ctx.cwd, ctx.signal);
|
|
41
41
|
warnings.push(...rootWarnings);
|
|
42
42
|
|
|
43
43
|
const results = await Promise.all(
|
|
@@ -47,6 +47,7 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
|
47
47
|
dir: skillsDir,
|
|
48
48
|
providerId: PROVIDER_ID,
|
|
49
49
|
level: scopeToLevel(root.scope),
|
|
50
|
+
signal: ctx.signal,
|
|
50
51
|
});
|
|
51
52
|
return { root, result };
|
|
52
53
|
}),
|
package/src/discovery/claude.ts
CHANGED
|
@@ -132,7 +132,7 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
|
|
|
132
132
|
const userBase = getUserClaude(ctx);
|
|
133
133
|
const userClaudeMd = path.join(userBase, "CLAUDE.md");
|
|
134
134
|
|
|
135
|
-
const userContent = await readFile(userClaudeMd);
|
|
135
|
+
const userContent = await readFile(userClaudeMd, ctx.signal);
|
|
136
136
|
if (userContent !== null) {
|
|
137
137
|
items.push({
|
|
138
138
|
path: userClaudeMd,
|
|
@@ -144,7 +144,7 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
|
|
|
144
144
|
|
|
145
145
|
const projectBase = getProjectClaude(ctx);
|
|
146
146
|
const projectClaudeMd = path.join(projectBase, "CLAUDE.md");
|
|
147
|
-
const projectContent = await readFile(projectClaudeMd);
|
|
147
|
+
const projectContent = await readFile(projectClaudeMd, ctx.signal);
|
|
148
148
|
if (projectContent !== null) {
|
|
149
149
|
const depth = calculateDepth(ctx.cwd, path.dirname(projectBase), path.sep);
|
|
150
150
|
items.push({
|
|
@@ -175,6 +175,7 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
|
175
175
|
dir: path.join(current, CONFIG_DIR, "skills"),
|
|
176
176
|
providerId: PROVIDER_ID,
|
|
177
177
|
level: "project",
|
|
178
|
+
signal: ctx.signal,
|
|
178
179
|
}),
|
|
179
180
|
);
|
|
180
181
|
if (current === (ctx.repoRoot ?? ctx.home)) break;
|
|
@@ -184,7 +185,7 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
|
184
185
|
}
|
|
185
186
|
|
|
186
187
|
const [userResult, ...projectResults] = await Promise.allSettled([
|
|
187
|
-
scanSkillsFromDir(ctx, { dir: userSkillsDir, providerId: PROVIDER_ID, level: "user" }),
|
|
188
|
+
scanSkillsFromDir(ctx, { dir: userSkillsDir, providerId: PROVIDER_ID, level: "user", signal: ctx.signal }),
|
|
188
189
|
...projectScans,
|
|
189
190
|
]);
|
|
190
191
|
|
|
@@ -407,7 +408,7 @@ async function loadSystemPrompts(ctx: LoadContext): Promise<LoadResult<SystemPro
|
|
|
407
408
|
const userBase = getUserClaude(ctx);
|
|
408
409
|
const userSystemMd = path.join(userBase, "SYSTEM.md");
|
|
409
410
|
|
|
410
|
-
const content = await readFile(userSystemMd);
|
|
411
|
+
const content = await readFile(userSystemMd, ctx.signal);
|
|
411
412
|
if (content !== null) {
|
|
412
413
|
items.push({
|
|
413
414
|
path: userSystemMd,
|
package/src/discovery/codex.ts
CHANGED
|
@@ -56,7 +56,7 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
|
|
|
56
56
|
|
|
57
57
|
// User level only: ~/.codex/AGENTS.md
|
|
58
58
|
const agentsMd = path.join(ctx.home, SOURCE_PATHS.codex.userBase, "AGENTS.md");
|
|
59
|
-
const agentsContent = await readFile(agentsMd);
|
|
59
|
+
const agentsContent = await readFile(agentsMd, ctx.signal);
|
|
60
60
|
if (agentsContent) {
|
|
61
61
|
items.push({
|
|
62
62
|
path: agentsMd,
|
|
@@ -221,11 +221,13 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
|
221
221
|
dir: userSkillsDir,
|
|
222
222
|
providerId: PROVIDER_ID,
|
|
223
223
|
level: "user",
|
|
224
|
+
signal: ctx.signal,
|
|
224
225
|
}),
|
|
225
226
|
scanSkillsFromDir(ctx, {
|
|
226
227
|
dir: projectSkillsDir,
|
|
227
228
|
providerId: PROVIDER_ID,
|
|
228
229
|
level: "project",
|
|
230
|
+
signal: ctx.signal,
|
|
229
231
|
}),
|
|
230
232
|
]);
|
|
231
233
|
|
package/src/discovery/gemini.ts
CHANGED
|
@@ -129,7 +129,7 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
|
|
|
129
129
|
// User-level: ~/.gemini/GEMINI.md
|
|
130
130
|
const userGeminiMd = getUserPath(ctx, "gemini", "GEMINI.md");
|
|
131
131
|
if (userGeminiMd) {
|
|
132
|
-
const content = await readFile(userGeminiMd);
|
|
132
|
+
const content = await readFile(userGeminiMd, ctx.signal);
|
|
133
133
|
if (content) {
|
|
134
134
|
items.push({
|
|
135
135
|
path: userGeminiMd,
|
|
@@ -143,7 +143,7 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
|
|
|
143
143
|
// Project-level: .gemini/GEMINI.md
|
|
144
144
|
const projectGeminiMd = getProjectPath(ctx, "gemini", "GEMINI.md");
|
|
145
145
|
if (projectGeminiMd) {
|
|
146
|
-
const content = await readFile(projectGeminiMd);
|
|
146
|
+
const content = await readFile(projectGeminiMd, ctx.signal);
|
|
147
147
|
if (content) {
|
|
148
148
|
const projectBase = getProjectPath(ctx, "gemini", "");
|
|
149
149
|
const depth = projectBase ? calculateDepth(ctx.cwd, projectBase, path.sep) : 0;
|
|
@@ -335,7 +335,7 @@ async function loadSystemPrompt(ctx: LoadContext): Promise<LoadResult<SystemProm
|
|
|
335
335
|
// User-level: ~/.gemini/system.md
|
|
336
336
|
const userSystemMd = getUserPath(ctx, "gemini", "system.md");
|
|
337
337
|
if (userSystemMd) {
|
|
338
|
-
const content = await readFile(userSystemMd);
|
|
338
|
+
const content = await readFile(userSystemMd, ctx.signal);
|
|
339
339
|
if (content) {
|
|
340
340
|
items.push({
|
|
341
341
|
path: userSystemMd,
|
|
@@ -349,7 +349,7 @@ async function loadSystemPrompt(ctx: LoadContext): Promise<LoadResult<SystemProm
|
|
|
349
349
|
// Project-level: .gemini/system.md
|
|
350
350
|
const projectSystemMd = getProjectPath(ctx, "gemini", "system.md");
|
|
351
351
|
if (projectSystemMd) {
|
|
352
|
-
const content = await readFile(projectSystemMd);
|
|
352
|
+
const content = await readFile(projectSystemMd, ctx.signal);
|
|
353
353
|
if (content) {
|
|
354
354
|
items.push({
|
|
355
355
|
path: projectSystemMd,
|
package/src/discovery/github.ts
CHANGED
|
@@ -35,7 +35,7 @@ async function loadContextFiles(ctx: LoadContext): Promise<LoadResult<ContextFil
|
|
|
35
35
|
|
|
36
36
|
const copilotInstructionsPath = getProjectPath(ctx, "github", "copilot-instructions.md");
|
|
37
37
|
if (copilotInstructionsPath) {
|
|
38
|
-
const content = await readFile(copilotInstructionsPath);
|
|
38
|
+
const content = await readFile(copilotInstructionsPath, ctx.signal);
|
|
39
39
|
if (content) {
|
|
40
40
|
const fileDir = path.dirname(copilotInstructionsPath);
|
|
41
41
|
const depth = calculateDepth(ctx.cwd, fileDir, path.sep);
|