@oh-my-pi/pi-coding-agent 4.2.1 → 4.2.3
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 +30 -0
- package/docs/sdk.md +5 -5
- package/examples/sdk/10-settings.ts +2 -2
- package/package.json +5 -5
- package/src/capability/fs.ts +90 -0
- package/src/capability/index.ts +41 -227
- package/src/capability/types.ts +1 -11
- package/src/cli/args.ts +4 -0
- package/src/core/agent-session.ts +4 -4
- package/src/core/agent-storage.ts +50 -0
- package/src/core/auth-storage.ts +112 -4
- package/src/core/bash-executor.ts +1 -1
- package/src/core/custom-tools/loader.ts +2 -2
- package/src/core/extensions/loader.ts +2 -2
- package/src/core/extensions/types.ts +1 -1
- package/src/core/hooks/loader.ts +2 -2
- package/src/core/mcp/config.ts +2 -2
- package/src/core/model-registry.ts +46 -0
- package/src/core/sdk.ts +37 -29
- package/src/core/settings-manager.ts +152 -135
- package/src/core/skills.ts +72 -51
- package/src/core/slash-commands.ts +3 -3
- package/src/core/system-prompt.ts +10 -10
- package/src/core/tools/edit.ts +7 -4
- package/src/core/tools/find.ts +2 -2
- package/src/core/tools/index.test.ts +16 -0
- package/src/core/tools/index.ts +21 -8
- package/src/core/tools/lsp/index.ts +4 -1
- package/src/core/tools/ssh.ts +6 -6
- package/src/core/tools/task/commands.ts +3 -5
- package/src/core/tools/task/executor.ts +88 -3
- package/src/core/tools/task/index.ts +4 -0
- package/src/core/tools/task/model-resolver.ts +10 -7
- package/src/core/tools/task/worker-protocol.ts +48 -2
- package/src/core/tools/task/worker.ts +152 -7
- package/src/core/tools/write.ts +7 -4
- package/src/discovery/agents-md.ts +13 -19
- package/src/discovery/builtin.ts +367 -247
- package/src/discovery/claude.ts +181 -290
- package/src/discovery/cline.ts +30 -10
- package/src/discovery/codex.ts +185 -244
- package/src/discovery/cursor.ts +106 -121
- package/src/discovery/gemini.ts +72 -97
- package/src/discovery/github.ts +7 -10
- package/src/discovery/helpers.ts +94 -88
- package/src/discovery/index.ts +1 -2
- package/src/discovery/mcp-json.ts +15 -18
- package/src/discovery/ssh.ts +9 -17
- package/src/discovery/vscode.ts +10 -5
- package/src/discovery/windsurf.ts +52 -86
- package/src/main.ts +5 -1
- package/src/modes/interactive/components/extensions/extension-dashboard.ts +24 -11
- package/src/modes/interactive/components/extensions/state-manager.ts +19 -15
- package/src/modes/interactive/controllers/selector-controller.ts +6 -2
- package/src/modes/interactive/interactive-mode.ts +19 -15
- package/src/prompts/agents/plan.md +107 -30
- package/src/utils/shell.ts +2 -2
- package/src/prompts/agents/planner.md +0 -112
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { type Settings, settingsCapability } from "../../../capability/settings";
|
|
15
|
-
import {
|
|
15
|
+
import { loadCapability } from "../../../discovery";
|
|
16
16
|
import { resolveOmpCommand } from "./omp-command";
|
|
17
17
|
|
|
18
18
|
/** Cache for available models (provider/modelId format) */
|
|
@@ -79,8 +79,8 @@ export function clearModelCache(): void {
|
|
|
79
79
|
/**
|
|
80
80
|
* Load model roles from settings files using capability API.
|
|
81
81
|
*/
|
|
82
|
-
function loadModelRoles(): Record<string, string
|
|
83
|
-
const result =
|
|
82
|
+
async function loadModelRoles(): Promise<Record<string, string>> {
|
|
83
|
+
const result = await loadCapability<Settings>(settingsCapability.id, { cwd: process.cwd() });
|
|
84
84
|
|
|
85
85
|
// Merge all settings, prioritizing first (highest priority)
|
|
86
86
|
let modelRoles: Record<string, string> = {};
|
|
@@ -99,8 +99,8 @@ function loadModelRoles(): Record<string, string> {
|
|
|
99
99
|
* Looks up the role in settings.modelRoles and returns the configured model.
|
|
100
100
|
* Returns undefined if the role isn't configured.
|
|
101
101
|
*/
|
|
102
|
-
function resolveOmpAlias(role: string, availableModels: string[]): string | undefined {
|
|
103
|
-
const roles = loadModelRoles();
|
|
102
|
+
async function resolveOmpAlias(role: string, availableModels: string[]): Promise<string | undefined> {
|
|
103
|
+
const roles = await loadModelRoles();
|
|
104
104
|
|
|
105
105
|
// Look up role in settings (case-insensitive)
|
|
106
106
|
const configured = roles[role] || roles[role.toLowerCase()];
|
|
@@ -127,7 +127,10 @@ function getModelId(fullModel: string): string {
|
|
|
127
127
|
* @param pattern - Model pattern to resolve
|
|
128
128
|
* @param availableModels - Optional pre-fetched list of available models (in provider/modelId format)
|
|
129
129
|
*/
|
|
130
|
-
export function resolveModelPattern(
|
|
130
|
+
export async function resolveModelPattern(
|
|
131
|
+
pattern: string | undefined,
|
|
132
|
+
availableModels?: string[],
|
|
133
|
+
): Promise<string | undefined> {
|
|
131
134
|
if (!pattern || pattern === "default") {
|
|
132
135
|
return undefined;
|
|
133
136
|
}
|
|
@@ -149,7 +152,7 @@ export function resolveModelPattern(pattern: string | undefined, availableModels
|
|
|
149
152
|
const lower = p.toLowerCase();
|
|
150
153
|
if (lower.startsWith("omp/") || lower.startsWith("pi/")) {
|
|
151
154
|
const role = lower.startsWith("omp/") ? p.slice(4) : p.slice(3);
|
|
152
|
-
const resolved = resolveOmpAlias(role, models);
|
|
155
|
+
const resolved = await resolveOmpAlias(role, models);
|
|
153
156
|
if (resolved) return resolved;
|
|
154
157
|
continue; // Role not configured, try next pattern
|
|
155
158
|
}
|
|
@@ -1,4 +1,42 @@
|
|
|
1
1
|
import type { AgentEvent } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
import type { SerializedAuthStorage } from "../../auth-storage";
|
|
3
|
+
import type { SerializedModelRegistry } from "../../model-registry";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* MCP tool metadata passed from parent to worker for proxy tool creation.
|
|
7
|
+
*/
|
|
8
|
+
export interface MCPToolMetadata {
|
|
9
|
+
name: string;
|
|
10
|
+
label: string;
|
|
11
|
+
description: string;
|
|
12
|
+
parameters: unknown;
|
|
13
|
+
serverName: string;
|
|
14
|
+
mcpToolName: string;
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Worker -> Parent: request to execute an MCP tool via parent's connection.
|
|
20
|
+
*/
|
|
21
|
+
export interface MCPToolCallRequest {
|
|
22
|
+
type: "mcp_tool_call";
|
|
23
|
+
callId: string;
|
|
24
|
+
toolName: string;
|
|
25
|
+
params: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Parent -> Worker: result of an MCP tool call.
|
|
30
|
+
*/
|
|
31
|
+
export interface MCPToolCallResponse {
|
|
32
|
+
type: "mcp_tool_result";
|
|
33
|
+
callId: string;
|
|
34
|
+
result?: {
|
|
35
|
+
content: Array<{ type: string; text?: string; [key: string]: unknown }>;
|
|
36
|
+
isError?: boolean;
|
|
37
|
+
};
|
|
38
|
+
error?: string;
|
|
39
|
+
}
|
|
2
40
|
|
|
3
41
|
export interface SubagentWorkerStartPayload {
|
|
4
42
|
cwd: string;
|
|
@@ -7,12 +45,20 @@ export interface SubagentWorkerStartPayload {
|
|
|
7
45
|
model?: string;
|
|
8
46
|
toolNames?: string[];
|
|
9
47
|
outputSchema?: unknown;
|
|
48
|
+
enableLsp?: boolean;
|
|
10
49
|
sessionFile?: string | null;
|
|
11
50
|
spawnsEnv?: string;
|
|
51
|
+
serializedAuth?: SerializedAuthStorage;
|
|
52
|
+
serializedModels?: SerializedModelRegistry;
|
|
53
|
+
mcpTools?: MCPToolMetadata[];
|
|
12
54
|
}
|
|
13
55
|
|
|
14
|
-
export type SubagentWorkerRequest =
|
|
56
|
+
export type SubagentWorkerRequest =
|
|
57
|
+
| { type: "start"; payload: SubagentWorkerStartPayload }
|
|
58
|
+
| { type: "abort" }
|
|
59
|
+
| MCPToolCallResponse;
|
|
15
60
|
|
|
16
61
|
export type SubagentWorkerResponse =
|
|
17
62
|
| { type: "event"; event: AgentEvent }
|
|
18
|
-
| { type: "done"; exitCode: number; durationMs: number; error?: string; aborted?: boolean }
|
|
63
|
+
| { type: "done"; exitCode: number; durationMs: number; error?: string; aborted?: boolean }
|
|
64
|
+
| MCPToolCallRequest;
|
|
@@ -15,12 +15,22 @@
|
|
|
15
15
|
|
|
16
16
|
import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
17
17
|
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
18
|
+
import type { TSchema } from "@sinclair/typebox";
|
|
18
19
|
import type { AgentSessionEvent } from "../../agent-session";
|
|
20
|
+
import { AuthStorage } from "../../auth-storage";
|
|
21
|
+
import type { CustomTool } from "../../custom-tools/types";
|
|
22
|
+
import { ModelRegistry } from "../../model-registry";
|
|
19
23
|
import { parseModelPattern, parseModelString } from "../../model-resolver";
|
|
20
24
|
import { createAgentSession, discoverAuthStorage, discoverModels } from "../../sdk";
|
|
21
25
|
import { SessionManager } from "../../session-manager";
|
|
22
26
|
import { untilAborted } from "../../utils";
|
|
23
|
-
import type {
|
|
27
|
+
import type {
|
|
28
|
+
MCPToolCallResponse,
|
|
29
|
+
MCPToolMetadata,
|
|
30
|
+
SubagentWorkerRequest,
|
|
31
|
+
SubagentWorkerResponse,
|
|
32
|
+
SubagentWorkerStartPayload,
|
|
33
|
+
} from "./worker-protocol";
|
|
24
34
|
|
|
25
35
|
type PostMessageFn = (message: SubagentWorkerResponse) => void;
|
|
26
36
|
|
|
@@ -32,6 +42,120 @@ const postMessageSafe: PostMessageFn = (message) => {
|
|
|
32
42
|
}
|
|
33
43
|
};
|
|
34
44
|
|
|
45
|
+
interface PendingMCPCall {
|
|
46
|
+
resolve: (result: MCPToolCallResponse["result"]) => void;
|
|
47
|
+
reject: (error: Error) => void;
|
|
48
|
+
timeoutId: ReturnType<typeof setTimeout>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const pendingMCPCalls = new Map<string, PendingMCPCall>();
|
|
52
|
+
const MCP_CALL_TIMEOUT_MS = 60_000;
|
|
53
|
+
let mcpCallIdCounter = 0;
|
|
54
|
+
|
|
55
|
+
function generateMCPCallId(): string {
|
|
56
|
+
return `mcp_${Date.now()}_${++mcpCallIdCounter}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function callMCPToolViaParent(
|
|
60
|
+
toolName: string,
|
|
61
|
+
params: Record<string, unknown>,
|
|
62
|
+
signal?: AbortSignal,
|
|
63
|
+
timeoutMs = MCP_CALL_TIMEOUT_MS,
|
|
64
|
+
): Promise<{ content: Array<{ type: string; text?: string; [key: string]: unknown }>; isError?: boolean }> {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const callId = generateMCPCallId();
|
|
67
|
+
if (signal?.aborted) {
|
|
68
|
+
reject(new Error("Aborted"));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const timeoutId = setTimeout(() => {
|
|
73
|
+
pendingMCPCalls.delete(callId);
|
|
74
|
+
reject(new Error(`MCP call timed out after ${timeoutMs}ms`));
|
|
75
|
+
}, timeoutMs);
|
|
76
|
+
|
|
77
|
+
const cleanup = () => {
|
|
78
|
+
clearTimeout(timeoutId);
|
|
79
|
+
pendingMCPCalls.delete(callId);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
signal?.addEventListener(
|
|
83
|
+
"abort",
|
|
84
|
+
() => {
|
|
85
|
+
cleanup();
|
|
86
|
+
reject(new Error("Aborted"));
|
|
87
|
+
},
|
|
88
|
+
{ once: true },
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
pendingMCPCalls.set(callId, {
|
|
92
|
+
resolve: (result) => {
|
|
93
|
+
cleanup();
|
|
94
|
+
resolve(result ?? { content: [] });
|
|
95
|
+
},
|
|
96
|
+
reject: (error) => {
|
|
97
|
+
cleanup();
|
|
98
|
+
reject(error);
|
|
99
|
+
},
|
|
100
|
+
timeoutId,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
postMessageSafe({
|
|
104
|
+
type: "mcp_tool_call",
|
|
105
|
+
callId,
|
|
106
|
+
toolName,
|
|
107
|
+
params,
|
|
108
|
+
} as SubagentWorkerResponse);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function handleMCPToolResult(response: MCPToolCallResponse): void {
|
|
113
|
+
const pending = pendingMCPCalls.get(response.callId);
|
|
114
|
+
if (!pending) return;
|
|
115
|
+
if (response.error) {
|
|
116
|
+
pending.reject(new Error(response.error));
|
|
117
|
+
} else {
|
|
118
|
+
pending.resolve(response.result);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function createMCPProxyTool(metadata: MCPToolMetadata): CustomTool<TSchema> {
|
|
123
|
+
return {
|
|
124
|
+
name: metadata.name,
|
|
125
|
+
label: metadata.label,
|
|
126
|
+
description: metadata.description,
|
|
127
|
+
parameters: metadata.parameters as TSchema,
|
|
128
|
+
execute: async (_toolCallId, params, _onUpdate, _ctx, signal) => {
|
|
129
|
+
try {
|
|
130
|
+
const result = await callMCPToolViaParent(
|
|
131
|
+
metadata.name,
|
|
132
|
+
params as Record<string, unknown>,
|
|
133
|
+
signal,
|
|
134
|
+
metadata.timeoutMs,
|
|
135
|
+
);
|
|
136
|
+
return {
|
|
137
|
+
content: result.content.map((c) =>
|
|
138
|
+
c.type === "text"
|
|
139
|
+
? { type: "text" as const, text: c.text ?? "" }
|
|
140
|
+
: { type: "text" as const, text: JSON.stringify(c) },
|
|
141
|
+
),
|
|
142
|
+
details: { serverName: metadata.serverName, mcpToolName: metadata.mcpToolName, isError: result.isError },
|
|
143
|
+
};
|
|
144
|
+
} catch (error) {
|
|
145
|
+
return {
|
|
146
|
+
content: [
|
|
147
|
+
{
|
|
148
|
+
type: "text" as const,
|
|
149
|
+
text: `MCP error: ${error instanceof Error ? error.message : String(error)}`,
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
details: { serverName: metadata.serverName, mcpToolName: metadata.mcpToolName, isError: true },
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
35
159
|
interface WorkerMessageEvent<T> {
|
|
36
160
|
data: T;
|
|
37
161
|
}
|
|
@@ -145,11 +269,22 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
|
|
|
145
269
|
// Set working directory (CLI does this implicitly)
|
|
146
270
|
process.chdir(payload.cwd);
|
|
147
271
|
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
272
|
+
// Use serialized auth/models if provided, otherwise discover from disk
|
|
273
|
+
let authStorage: AuthStorage;
|
|
274
|
+
let modelRegistry: ModelRegistry;
|
|
275
|
+
|
|
276
|
+
if (payload.serializedAuth && payload.serializedModels) {
|
|
277
|
+
authStorage = AuthStorage.fromSerialized(payload.serializedAuth);
|
|
278
|
+
modelRegistry = ModelRegistry.fromSerialized(payload.serializedModels, authStorage);
|
|
279
|
+
} else {
|
|
280
|
+
authStorage = await discoverAuthStorage();
|
|
281
|
+
checkAbort();
|
|
282
|
+
modelRegistry = await discoverModels(authStorage);
|
|
283
|
+
checkAbort();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Create MCP proxy tools if provided
|
|
287
|
+
const mcpProxyTools = payload.mcpTools?.map(createMCPProxyTool) ?? [];
|
|
153
288
|
|
|
154
289
|
// Resolve model override (equivalent to CLI's parseModelPattern with --model)
|
|
155
290
|
const { model, thinkingLevel } = resolveModelOverride(payload.model, modelRegistry);
|
|
@@ -180,6 +315,11 @@ async function runTask(runState: RunState, payload: SubagentWorkerStartPayload):
|
|
|
180
315
|
hasUI: false,
|
|
181
316
|
// Pass spawn restrictions to nested tasks
|
|
182
317
|
spawns: payload.spawnsEnv,
|
|
318
|
+
enableLsp: payload.enableLsp ?? true,
|
|
319
|
+
// Disable local MCP discovery if using proxy tools
|
|
320
|
+
enableMCP: !payload.mcpTools,
|
|
321
|
+
// Add MCP proxy tools
|
|
322
|
+
customTools: mcpProxyTools.length > 0 ? mcpProxyTools : undefined,
|
|
183
323
|
});
|
|
184
324
|
|
|
185
325
|
runState.session = session;
|
|
@@ -394,7 +534,7 @@ self.addEventListener("messageerror", () => {
|
|
|
394
534
|
reportFatal("Failed to deserialize parent message");
|
|
395
535
|
});
|
|
396
536
|
|
|
397
|
-
// Message handler - receives start/abort commands from parent
|
|
537
|
+
// Message handler - receives start/abort/mcp_tool_result commands from parent
|
|
398
538
|
globalThis.addEventListener("message", (event: WorkerMessageEvent<SubagentWorkerRequest>) => {
|
|
399
539
|
const message = event.data;
|
|
400
540
|
if (!message) return;
|
|
@@ -404,6 +544,11 @@ globalThis.addEventListener("message", (event: WorkerMessageEvent<SubagentWorker
|
|
|
404
544
|
return;
|
|
405
545
|
}
|
|
406
546
|
|
|
547
|
+
if (message.type === "mcp_tool_result") {
|
|
548
|
+
handleMCPToolResult(message);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
|
|
407
552
|
if (message.type === "start") {
|
|
408
553
|
// Only allow one task per worker
|
|
409
554
|
if (activeRun) return;
|
package/src/core/tools/write.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { RenderResultOptions } from "../custom-tools/types";
|
|
|
8
8
|
import { renderPromptTemplate } from "../prompt-templates";
|
|
9
9
|
import type { ToolSession } from "../sdk";
|
|
10
10
|
import { untilAborted } from "../utils";
|
|
11
|
-
import { createLspWritethrough, type FileDiagnosticsResult } from "./lsp/index";
|
|
11
|
+
import { createLspWritethrough, type FileDiagnosticsResult, writethroughNoop } from "./lsp/index";
|
|
12
12
|
import { resolveToCwd } from "./path-utils";
|
|
13
13
|
import { formatDiagnostics, replaceTabs, shortenPath } from "./render-utils";
|
|
14
14
|
|
|
@@ -23,9 +23,12 @@ export interface WriteToolDetails {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export function createWriteTool(session: ToolSession): AgentTool<typeof writeSchema, WriteToolDetails> {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
26
|
+
const enableLsp = session.enableLsp ?? true;
|
|
27
|
+
const enableFormat = enableLsp ? (session.settings?.getLspFormatOnWrite() ?? true) : false;
|
|
28
|
+
const enableDiagnostics = enableLsp ? (session.settings?.getLspDiagnosticsOnWrite() ?? true) : false;
|
|
29
|
+
const writethrough = enableLsp
|
|
30
|
+
? createLspWritethrough(session.cwd, { enableFormat, enableDiagnostics })
|
|
31
|
+
: writethroughNoop;
|
|
29
32
|
return {
|
|
30
33
|
name: "write",
|
|
31
34
|
label: "Write",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { dirname, join, sep } from "node:path";
|
|
10
10
|
import { type ContextFile, contextFileCapability } from "../capability/context-file";
|
|
11
|
+
import { readFile } from "../capability/fs";
|
|
11
12
|
import { registerProvider } from "../capability/index";
|
|
12
13
|
import type { LoadContext, LoadResult } from "../capability/types";
|
|
13
14
|
import { calculateDepth, createSourceMeta } from "./helpers";
|
|
@@ -19,7 +20,7 @@ const MAX_DEPTH = 20; // Prevent walking up excessively far from cwd
|
|
|
19
20
|
/**
|
|
20
21
|
* Load standalone AGENTS.md files.
|
|
21
22
|
*/
|
|
22
|
-
function loadAgentsMd(ctx: LoadContext): LoadResult<ContextFile
|
|
23
|
+
async function loadAgentsMd(ctx: LoadContext): Promise<LoadResult<ContextFile>> {
|
|
23
24
|
const items: ContextFile[] = [];
|
|
24
25
|
const warnings: string[] = [];
|
|
25
26
|
|
|
@@ -29,30 +30,23 @@ function loadAgentsMd(ctx: LoadContext): LoadResult<ContextFile> {
|
|
|
29
30
|
|
|
30
31
|
while (depth < MAX_DEPTH) {
|
|
31
32
|
const candidate = join(current, "AGENTS.md");
|
|
33
|
+
const content = await readFile(candidate);
|
|
32
34
|
|
|
33
|
-
if (
|
|
34
|
-
// Skip if it's inside a config directory (handled by other providers)
|
|
35
|
+
if (content !== null) {
|
|
35
36
|
const parent = dirname(candidate);
|
|
36
37
|
const baseName = parent.split(sep).pop() ?? "";
|
|
37
38
|
|
|
38
|
-
// Skip if inside .codex, .gemini, or other config dirs
|
|
39
39
|
if (!baseName.startsWith(".")) {
|
|
40
|
-
const
|
|
40
|
+
const fileDir = dirname(candidate);
|
|
41
|
+
const calculatedDepth = calculateDepth(ctx.cwd, fileDir, sep);
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
path: candidate,
|
|
50
|
-
content,
|
|
51
|
-
level: "project",
|
|
52
|
-
depth: calculatedDepth,
|
|
53
|
-
_source: createSourceMeta(PROVIDER_ID, candidate, "project"),
|
|
54
|
-
});
|
|
55
|
-
}
|
|
43
|
+
items.push({
|
|
44
|
+
path: candidate,
|
|
45
|
+
content,
|
|
46
|
+
level: "project",
|
|
47
|
+
depth: calculatedDepth,
|
|
48
|
+
_source: createSourceMeta(PROVIDER_ID, candidate, "project"),
|
|
49
|
+
});
|
|
56
50
|
}
|
|
57
51
|
}
|
|
58
52
|
|