@elyracode/coding-agent 0.9.19 → 0.9.21
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 +11 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/doctor-cli.d.ts.map +1 -1
- package/dist/cli/doctor-cli.js +8 -1
- package/dist/cli/doctor-cli.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/core/model-fallback.d.ts +17 -5
- package/dist/core/model-fallback.d.ts.map +1 -1
- package/dist/core/model-fallback.js +29 -5
- package/dist/core/model-fallback.js.map +1 -1
- package/dist/core/routing-ledger.d.ts +83 -0
- package/dist/core/routing-ledger.d.ts.map +1 -0
- package/dist/core/routing-ledger.js +238 -0
- package/dist/core/routing-ledger.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +36 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +3 -0
- package/dist/core/settings-manager.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/stack-detector.d.ts +14 -0
- package/dist/core/stack-detector.d.ts.map +1 -1
- package/dist/core/stack-detector.js +90 -1
- package/dist/core/stack-detector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +51 -10
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slash-commands.js","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"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","sourcesContent":["import { APP_NAME } from \"../config.js\";\nimport type { SourceInfo } from \"./source-info.js\";\n\nexport type SlashCommandSource = \"extension\" | \"prompt\" | \"skill\";\n\nexport interface SlashCommandInfo {\n\tname: string;\n\tdescription?: string;\n\tsource: SlashCommandSource;\n\tsourceInfo: SourceInfo;\n}\n\nexport interface BuiltinSlashCommand {\n\tname: string;\n\tdescription: string;\n}\n\nexport const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [\n\t{ name: \"help\", description: \"Show help with example prompts and useful commands\" },\n\t{ name: \"skills\", description: \"List loaded skills, or install from registry: /skills install <name>\" },\n\t{ name: \"init\", description: \"Set up Elyra for this project (.elyra/ directory, extensions, blueprints)\" },\n\t{ name: \"settings\", description: \"Open settings menu\" },\n\t{ name: \"model\", description: \"Select model (opens selector UI)\" },\n\t{ name: \"scoped-models\", description: \"Enable/disable models for Ctrl+P cycling\" },\n\t{ name: \"export\", description: \"Export session (HTML default, or specify path: .html/.jsonl)\" },\n\t{ name: \"import\", description: \"Import and resume a session from a JSONL file\" },\n\t{ name: \"share\", description: \"Share session as a secret GitHub gist\" },\n\t{ name: \"copy\", description: \"Copy last agent message to clipboard\" },\n\t{ name: \"name\", description: \"Set session display name\" },\n\t{ name: \"session\", description: \"Show session info and stats\" },\n\t{ name: \"changelog\", description: \"Show changelog entries\" },\n\t{ name: \"hotkeys\", description: \"Show all keyboard shortcuts\" },\n\t{ name: \"fork\", description: \"Create a new fork from a previous user message\" },\n\t{ name: \"clone\", description: \"Duplicate the current session at the current position\" },\n\t{ name: \"tree\", description: \"Navigate session tree (switch branches)\" },\n\t{ name: \"rewind\", description: \"Rewind session and file state to a previous point\" },\n\t{ name: \"login\", description: \"Configure provider authentication\" },\n\t{ name: \"logout\", description: \"Remove provider authentication\" },\n\t{ name: \"new\", description: \"Start a new session\" },\n\t{ name: \"compact\", description: \"Manually compact the session context\" },\n\t{ name: \"resume\", description: \"Resume a different session\" },\n\t{ name: \"cost\", description: \"Show session cost and token usage\" },\n\t{\n\t\tname: \"diff\",\n\t\tdescription: \"Show changes (git diff). Flags: --session, --cached, --editor (open in $EDITOR), or a path\",\n\t},\n\t{\n\t\tname: \"review\",\n\t\tdescription:\n\t\t\t\"Get an independent code review of your changes. Flags: --cross (review with a different vendor's model for a true second opinion), --session, or a path\",\n\t},\n\t{\n\t\tname: \"bisect\",\n\t\tdescription:\n\t\t\t\"Find which agent turn introduced a problem. /bisect <command> runs it automatically (like git bisect run)\",\n\t},\n\t{ name: \"pin\", description: \"Pin a file to context (survives compaction): /pin <path>\" },\n\t{ name: \"memory\", description: \"View or manage project memory\" },\n\t{ name: \"unpin\", description: \"Unpin a file from context: /unpin <path>\" },\n\t{ name: \"pins\", description: \"List pinned context files\" },\n\t{ name: \"blueprint\", description: \"Apply a session blueprint: /blueprint [name]\" },\n\t{ name: \"snippet\", description: \"Send a saved instruction snippet: /snippet [name]\" },\n\t{ name: \"theme\", description: \"Switch color theme (opens selector, or /theme <name>)\" },\n\t{ name: \"footer\", description: \"Toggle minimal footer (hide token stats and context usage)\" },\n\t{ name: \"reload\", description: \"Reload keybindings, extensions, skills, prompts, and themes\" },\n\t{ name: \"packages\", description: \"Browse and install available extensions\" },\n\t{ name: \"ext\", description: \"Browse and install available extensions (alias for /packages)\" },\n\t{\n\t\tname: \"goal\",\n\t\tdescription: \"Set a goal: agent keeps working until the command exits with code 0 (--budget <usd> caps spend)\",\n\t},\n\t{ name: \"learn\", description: \"Extract a reusable skill from the current session\" },\n\t{ name: \"replay\", description: \"Replay the last turn on a new branch with a different model\" },\n\t{ name: \"route\", description: \"Show what smart routing would do for the next turn\" },\n\t{ name: \"update\", description: \"Update Elyra and installed extensions to the latest version and restart\" },\n\t{ name: \"quit\", description: `Quit ${APP_NAME}` },\n];\n"]}
|
|
1
|
+
{"version":3,"file":"slash-commands.js","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"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","sourcesContent":["import { APP_NAME } from \"../config.js\";\nimport type { SourceInfo } from \"./source-info.js\";\n\nexport type SlashCommandSource = \"extension\" | \"prompt\" | \"skill\";\n\nexport interface SlashCommandInfo {\n\tname: string;\n\tdescription?: string;\n\tsource: SlashCommandSource;\n\tsourceInfo: SourceInfo;\n}\n\nexport interface BuiltinSlashCommand {\n\tname: string;\n\tdescription: string;\n}\n\nexport const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [\n\t{ name: \"help\", description: \"Show help with example prompts and useful commands\" },\n\t{ name: \"skills\", description: \"List loaded skills, or install from registry: /skills install <name>\" },\n\t{ name: \"init\", description: \"Set up Elyra for this project (.elyra/ directory, extensions, blueprints)\" },\n\t{ name: \"settings\", description: \"Open settings menu\" },\n\t{ name: \"model\", description: \"Select model (opens selector UI)\" },\n\t{ name: \"scoped-models\", description: \"Enable/disable models for Ctrl+P cycling\" },\n\t{ name: \"export\", description: \"Export session (HTML default, or specify path: .html/.jsonl)\" },\n\t{ name: \"import\", description: \"Import and resume a session from a JSONL file\" },\n\t{ name: \"share\", description: \"Share session as a secret GitHub gist\" },\n\t{ name: \"copy\", description: \"Copy last agent message to clipboard\" },\n\t{ name: \"name\", description: \"Set session display name\" },\n\t{ name: \"session\", description: \"Show session info and stats\" },\n\t{ name: \"changelog\", description: \"Show changelog entries\" },\n\t{ name: \"hotkeys\", description: \"Show all keyboard shortcuts\" },\n\t{ name: \"fork\", description: \"Create a new fork from a previous user message\" },\n\t{ name: \"clone\", description: \"Duplicate the current session at the current position\" },\n\t{ name: \"tree\", description: \"Navigate session tree (switch branches)\" },\n\t{ name: \"rewind\", description: \"Rewind session and file state to a previous point\" },\n\t{ name: \"login\", description: \"Configure provider authentication\" },\n\t{ name: \"logout\", description: \"Remove provider authentication\" },\n\t{ name: \"new\", description: \"Start a new session\" },\n\t{ name: \"compact\", description: \"Manually compact the session context\" },\n\t{ name: \"resume\", description: \"Resume a different session\" },\n\t{ name: \"cost\", description: \"Show session cost and token usage\" },\n\t{\n\t\tname: \"diff\",\n\t\tdescription: \"Show changes (git diff). Flags: --session, --cached, --editor (open in $EDITOR), or a path\",\n\t},\n\t{\n\t\tname: \"review\",\n\t\tdescription:\n\t\t\t\"Get an independent code review of your changes. Flags: --cross (review with a different vendor's model for a true second opinion), --session, or a path\",\n\t},\n\t{\n\t\tname: \"bisect\",\n\t\tdescription:\n\t\t\t\"Find which agent turn introduced a problem. /bisect <command> runs it automatically (like git bisect run)\",\n\t},\n\t{ name: \"pin\", description: \"Pin a file to context (survives compaction): /pin <path>\" },\n\t{ name: \"memory\", description: \"View or manage project memory\" },\n\t{ name: \"unpin\", description: \"Unpin a file from context: /unpin <path>\" },\n\t{ name: \"pins\", description: \"List pinned context files\" },\n\t{ name: \"blueprint\", description: \"Apply a session blueprint: /blueprint [name]\" },\n\t{ name: \"snippet\", description: \"Send a saved instruction snippet: /snippet [name]\" },\n\t{ name: \"theme\", description: \"Switch color theme (opens selector, or /theme <name>)\" },\n\t{ name: \"footer\", description: \"Toggle minimal footer (hide token stats and context usage)\" },\n\t{ name: \"reload\", description: \"Reload keybindings, extensions, skills, prompts, and themes\" },\n\t{ name: \"packages\", description: \"Browse and install available extensions\" },\n\t{ name: \"ext\", description: \"Browse and install available extensions (alias for /packages)\" },\n\t{\n\t\tname: \"goal\",\n\t\tdescription: \"Set a goal: agent keeps working until the command exits with code 0 (--budget <usd> caps spend)\",\n\t},\n\t{ name: \"learn\", description: \"Extract a reusable skill from the current session\" },\n\t{ name: \"replay\", description: \"Replay the last turn on a new branch with a different model\" },\n\t{ name: \"route\", description: \"Show what smart routing would do for the next turn\" },\n\t{ name: \"routing-stats\", description: \"Show local per-model outcome measurements from the routing ledger\" },\n\t{ name: \"update\", description: \"Update Elyra and installed extensions to the latest version and restart\" },\n\t{ name: \"quit\", description: `Quit ${APP_NAME}` },\n];\n"]}
|
|
@@ -18,4 +18,18 @@ export interface StackDetectionResult {
|
|
|
18
18
|
export declare function detectStack(cwd: string): StackDetectionResult;
|
|
19
19
|
/** Get the suggested package name for a detected stack */
|
|
20
20
|
export declare function getSuggestedPackage(stack: KnownStack): string;
|
|
21
|
+
/** Result of Grove site detection */
|
|
22
|
+
export interface GroveSiteDetection {
|
|
23
|
+
/** Site name (registered name, or the directory name for parked sites) */
|
|
24
|
+
siteName: string;
|
|
25
|
+
/** The URL Grove serves this site at */
|
|
26
|
+
url: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Detect whether `cwd` is served by Grove (the local dev environment
|
|
30
|
+
* manager): either registered as a site in Grove's config.toml, or a direct
|
|
31
|
+
* child of a parked path. Uses a line-based scan of the config rather than a
|
|
32
|
+
* TOML parser dependency (same tradeoff as the Cargo.toml check above).
|
|
33
|
+
*/
|
|
34
|
+
export declare function detectGroveSite(cwd: string, groveHomeOverride?: string): GroveSiteDetection | undefined;
|
|
21
35
|
//# sourceMappingURL=stack-detector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-detector.d.ts","sourceRoot":"","sources":["../../src/core/stack-detector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stack-detector.d.ts","sourceRoot":"","sources":["../../src/core/stack-detector.ts"],"names":[],"mappings":"AAIA,mDAAmD;AACnD,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,iBAAiB,CAAC;AAE/E,gCAAgC;AAChC,MAAM,WAAW,oBAAoB;IACpC,8BAA8B;IAC9B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,yEAAyE;IACzE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CA+I7D;AASD,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAa7D;AAMD,qCAAqC;AACrC,MAAM,WAAW,kBAAkB;IAClC,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;CACZ;AAcD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAuEvG"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { basename, join } from "node:path";
|
|
3
4
|
/** Detect the technology stack in a project directory */
|
|
4
5
|
export function detectStack(cwd) {
|
|
5
6
|
const frameworks = [];
|
|
@@ -165,4 +166,92 @@ export function getSuggestedPackage(stack) {
|
|
|
165
166
|
return "@elyracode/stack-elyra-framework";
|
|
166
167
|
}
|
|
167
168
|
}
|
|
169
|
+
function findGroveHome(override) {
|
|
170
|
+
if (override)
|
|
171
|
+
return existsSync(override) ? override : undefined;
|
|
172
|
+
const envHome = process.env.GROVE_HOME;
|
|
173
|
+
if (envHome && existsSync(envHome))
|
|
174
|
+
return envHome;
|
|
175
|
+
const candidates = [join(homedir(), "Library", "Application Support", "Grove"), join(homedir(), ".config", "grove")];
|
|
176
|
+
return candidates.find((p) => existsSync(p));
|
|
177
|
+
}
|
|
178
|
+
function expandTilde(p) {
|
|
179
|
+
return p.startsWith("~/") ? join(homedir(), p.slice(2)) : p;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Detect whether `cwd` is served by Grove (the local dev environment
|
|
183
|
+
* manager): either registered as a site in Grove's config.toml, or a direct
|
|
184
|
+
* child of a parked path. Uses a line-based scan of the config rather than a
|
|
185
|
+
* TOML parser dependency (same tradeoff as the Cargo.toml check above).
|
|
186
|
+
*/
|
|
187
|
+
export function detectGroveSite(cwd, groveHomeOverride) {
|
|
188
|
+
const groveHome = findGroveHome(groveHomeOverride);
|
|
189
|
+
if (!groveHome)
|
|
190
|
+
return undefined;
|
|
191
|
+
const configPath = join(groveHome, "config.toml");
|
|
192
|
+
if (!existsSync(configPath))
|
|
193
|
+
return undefined;
|
|
194
|
+
let text;
|
|
195
|
+
try {
|
|
196
|
+
text = readFileSync(configPath, "utf-8");
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
let tld = "test";
|
|
202
|
+
const parked = [];
|
|
203
|
+
const sites = [];
|
|
204
|
+
let section = "root";
|
|
205
|
+
let currentSite;
|
|
206
|
+
for (const rawLine of text.split("\n")) {
|
|
207
|
+
const line = rawLine.trim();
|
|
208
|
+
if (!line || line.startsWith("#"))
|
|
209
|
+
continue;
|
|
210
|
+
const header = /^\[\[?([^\]]+?)\]?\]$/.exec(line);
|
|
211
|
+
if (header) {
|
|
212
|
+
const name = header[1].trim();
|
|
213
|
+
if (name === "sites") {
|
|
214
|
+
section = "sites";
|
|
215
|
+
currentSite = {};
|
|
216
|
+
sites.push(currentSite);
|
|
217
|
+
}
|
|
218
|
+
else if (name === "parked") {
|
|
219
|
+
section = "parked";
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
section = "other";
|
|
223
|
+
}
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
const kv = /^([A-Za-z0-9_-]+)\s*=\s*(.+)$/.exec(line);
|
|
227
|
+
if (!kv)
|
|
228
|
+
continue;
|
|
229
|
+
const key = kv[1];
|
|
230
|
+
const value = kv[2].trim().replace(/^["']/, "").replace(/["']$/, "");
|
|
231
|
+
if (key === "tld" && value) {
|
|
232
|
+
tld = value;
|
|
233
|
+
}
|
|
234
|
+
else if (section === "parked" && key === "path") {
|
|
235
|
+
parked.push(expandTilde(value));
|
|
236
|
+
}
|
|
237
|
+
else if (section === "sites" && currentSite) {
|
|
238
|
+
if (key === "name")
|
|
239
|
+
currentSite.name = value;
|
|
240
|
+
else if (key === "path")
|
|
241
|
+
currentSite.path = expandTilde(value);
|
|
242
|
+
else if (key === "secure")
|
|
243
|
+
currentSite.secure = value === "true";
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const registered = sites.find((s) => s.path === cwd && s.name);
|
|
247
|
+
if (registered?.name) {
|
|
248
|
+
const scheme = registered.secure ? "https" : "http";
|
|
249
|
+
return { siteName: registered.name, url: `${scheme}://${registered.name}.${tld}` };
|
|
250
|
+
}
|
|
251
|
+
if (parked.some((p) => cwd.startsWith(`${p}/`) && cwd !== p)) {
|
|
252
|
+
const siteName = basename(cwd);
|
|
253
|
+
return { siteName, url: `http://${siteName}.${tld}` };
|
|
254
|
+
}
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
168
257
|
//# sourceMappingURL=stack-detector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-detector.js","sourceRoot":"","sources":["../../src/core/stack-detector.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** Individual framework detected in the project */\nexport interface DetectedFramework {\n\tname: string;\n\tversion?: string;\n}\n\n/** Known stack profiles that can be suggested for installation */\nexport type KnownStack = \"TALL\" | \"RILT\" | \"VILT\" | \"SILT\" | \"ELYRA_FRAMEWORK\";\n\n/** Result of stack detection */\nexport interface StackDetectionResult {\n\t/** All detected frameworks */\n\tframeworks: DetectedFramework[];\n\t/** Recognized stack profile (if frameworks match a known combination) */\n\tstack?: KnownStack;\n\t/** Human-readable summary for system prompt injection */\n\tsummary: string;\n}\n\n/** Detect the technology stack in a project directory */\nexport function detectStack(cwd: string): StackDetectionResult {\n\tconst frameworks: DetectedFramework[] = [];\n\n\t// Parse composer.json for PHP/Laravel dependencies\n\tconst composerPath = join(cwd, \"composer.json\");\n\tif (existsSync(composerPath)) {\n\t\ttry {\n\t\t\tconst composer = JSON.parse(readFileSync(composerPath, \"utf-8\"));\n\t\t\tconst deps = { ...composer.require, ...composer[\"require-dev\"] };\n\n\t\t\tif (deps[\"laravel/framework\"]) {\n\t\t\t\tframeworks.push({ name: \"Laravel\", version: extractVersion(deps[\"laravel/framework\"]) });\n\t\t\t}\n\t\t\tif (deps[\"livewire/livewire\"]) {\n\t\t\t\tframeworks.push({ name: \"Livewire\", version: extractVersion(deps[\"livewire/livewire\"]) });\n\t\t\t}\n\t\t\tif (deps[\"livewire/flux\"]) {\n\t\t\t\tframeworks.push({ name: \"Flux UI\", version: extractVersion(deps[\"livewire/flux\"]) });\n\t\t\t}\n\t\t\tif (deps[\"inertiajs/inertia-laravel\"]) {\n\t\t\t\tframeworks.push({ name: \"Inertia\", version: extractVersion(deps[\"inertiajs/inertia-laravel\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/reverb\"]) {\n\t\t\t\tframeworks.push({ name: \"Reverb\", version: extractVersion(deps[\"laravel/reverb\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/sanctum\"]) {\n\t\t\t\tframeworks.push({ name: \"Sanctum\", version: extractVersion(deps[\"laravel/sanctum\"]) });\n\t\t\t}\n\t\t\tif (deps[\"filament/filament\"]) {\n\t\t\t\tframeworks.push({ name: \"Filament\", version: extractVersion(deps[\"filament/filament\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/ai\"]) {\n\t\t\t\tframeworks.push({ name: \"Laravel AI SDK\", version: extractVersion(deps[\"laravel/ai\"]) });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore malformed composer.json\n\t\t}\n\t}\n\n\t// Parse package.json for JS/frontend dependencies\n\tconst packagePath = join(cwd, \"package.json\");\n\tif (existsSync(packagePath)) {\n\t\ttry {\n\t\t\tconst pkg = JSON.parse(readFileSync(packagePath, \"utf-8\"));\n\t\t\tconst deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n\t\t\tif (deps.vue) {\n\t\t\t\tframeworks.push({ name: \"Vue\", version: extractVersion(deps.vue) });\n\t\t\t}\n\t\t\tif (deps.alpinejs) {\n\t\t\t\tframeworks.push({ name: \"Alpine.js\", version: extractVersion(deps.alpinejs) });\n\t\t\t}\n\t\t\tif (deps.tailwindcss) {\n\t\t\t\tframeworks.push({ name: \"Tailwind CSS\", version: extractVersion(deps.tailwindcss) });\n\t\t\t}\n\t\t\tif (\n\t\t\t\tdeps[\"@inertiajs/vue3\"] ||\n\t\t\t\tdeps[\"@inertiajs/vue2\"] ||\n\t\t\t\tdeps[\"@inertiajs/react\"] ||\n\t\t\t\tdeps[\"@inertiajs/svelte\"]\n\t\t\t) {\n\t\t\t\t// Inertia frontend adapter -- version from whichever is present\n\t\t\t\tconst inertiaFe =\n\t\t\t\t\tdeps[\"@inertiajs/vue3\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/vue2\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/react\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/svelte\"];\n\t\t\t\tif (!frameworks.some((f) => f.name === \"Inertia\")) {\n\t\t\t\t\tframeworks.push({ name: \"Inertia\", version: extractVersion(inertiaFe) });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (deps.react || deps[\"react-dom\"]) {\n\t\t\t\tframeworks.push({ name: \"React\", version: extractVersion(deps.react || deps[\"react-dom\"]) });\n\t\t\t}\n\t\t\tif (deps.svelte) {\n\t\t\t\tframeworks.push({ name: \"Svelte\", version: extractVersion(deps.svelte) });\n\t\t\t}\n\t\t\tif (deps.typescript) {\n\t\t\t\tframeworks.push({ name: \"TypeScript\", version: extractVersion(deps.typescript) });\n\t\t\t}\n\t\t\tif (deps.vite) {\n\t\t\t\tframeworks.push({ name: \"Vite\", version: extractVersion(deps.vite) });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore malformed package.json\n\t\t}\n\t}\n\n\t// Detect Elyra Framework (Rust + Svelte 5 desktop apps). `rata new` scaffolds\n\t// an `elyra.toml` config file, which is the most reliable signal; fall back\n\t// to a plain-text check for the `elyra` crate dependency in Cargo.toml (TOML\n\t// isn't parsed here to avoid adding a parser dependency for one field).\n\tconst cargoPath = join(cwd, \"Cargo.toml\");\n\tif (existsSync(join(cwd, \"elyra.toml\")) || existsSync(cargoPath)) {\n\t\ttry {\n\t\t\tconst cargoText = existsSync(cargoPath) ? readFileSync(cargoPath, \"utf-8\") : \"\";\n\t\t\tconst hasElyraCrate = /^\\s*elyra\\s*=/m.test(cargoText) || /\\[dependencies\\.elyra\\]/.test(cargoText);\n\t\t\tif (existsSync(join(cwd, \"elyra.toml\")) || hasElyraCrate) {\n\t\t\t\tconst versionMatch = cargoText.match(/^\\s*elyra\\s*=\\s*\\{[^}]*version\\s*=\\s*\"([^\"]+)\"/m);\n\t\t\t\tframeworks.push({ name: \"Elyra Framework\", version: versionMatch?.[1] });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore unreadable Cargo.toml\n\t\t}\n\t}\n\n\tif (frameworks.length === 0) {\n\t\treturn { frameworks, summary: \"\" };\n\t}\n\n\t// Detect known stack profiles\n\tconst has = (name: string) => frameworks.some((f) => f.name === name);\n\tlet stack: KnownStack | undefined;\n\n\tif (has(\"Elyra Framework\")) {\n\t\tstack = \"ELYRA_FRAMEWORK\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Alpine.js\") && has(\"Livewire\")) {\n\t\tstack = \"TALL\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"React\")) {\n\t\tstack = \"RILT\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"Vue\")) {\n\t\tstack = \"VILT\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"Svelte\")) {\n\t\tstack = \"SILT\";\n\t}\n\n\t// Build human-readable summary\n\tconst frameworkList = frameworks.map((f) => (f.version ? `${f.name} ${f.version}` : f.name)).join(\", \");\n\tlet summary = `Detected frameworks: ${frameworkList}`;\n\tif (stack === \"TALL\") {\n\t\tconst hasFlux = has(\"Flux UI\");\n\t\tsummary = `TALL stack project (Tailwind, Alpine.js, Laravel, Livewire${hasFlux ? \", Flux UI\" : \"\"}).\\n${frameworkList}`;\n\t} else if (stack === \"RILT\") {\n\t\tsummary = `RILT stack project (React, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"VILT\") {\n\t\tsummary = `VILT stack project (Vue, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"SILT\") {\n\t\tsummary = `SILT stack project (Svelte, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"ELYRA_FRAMEWORK\") {\n\t\tsummary = `Elyra Framework project (Rust + Svelte 5 desktop app, Laravel-inspired ergonomics).\\n${frameworkList}`;\n\t}\n\n\treturn { frameworks, stack, summary };\n}\n\n/** Strip semver constraint prefixes (^, ~, >=, etc.) to get a clean version */\nfunction extractVersion(constraint: string | undefined): string | undefined {\n\tif (!constraint) return undefined;\n\tconst match = constraint.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/);\n\treturn match?.[1];\n}\n\n/** Get the suggested package name for a detected stack */\nexport function getSuggestedPackage(stack: KnownStack): string {\n\tswitch (stack) {\n\t\tcase \"TALL\":\n\t\t\treturn \"@elyracode/stack-tall\";\n\t\tcase \"RILT\":\n\t\t\treturn \"@elyracode/stack-rilt\";\n\t\tcase \"VILT\":\n\t\t\treturn \"@elyracode/stack-vilt\";\n\t\tcase \"SILT\":\n\t\t\treturn \"@elyracode/stack-silt\";\n\t\tcase \"ELYRA_FRAMEWORK\":\n\t\t\treturn \"@elyracode/stack-elyra-framework\";\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"stack-detector.js","sourceRoot":"","sources":["../../src/core/stack-detector.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, join } from \"node:path\";\n\n/** Individual framework detected in the project */\nexport interface DetectedFramework {\n\tname: string;\n\tversion?: string;\n}\n\n/** Known stack profiles that can be suggested for installation */\nexport type KnownStack = \"TALL\" | \"RILT\" | \"VILT\" | \"SILT\" | \"ELYRA_FRAMEWORK\";\n\n/** Result of stack detection */\nexport interface StackDetectionResult {\n\t/** All detected frameworks */\n\tframeworks: DetectedFramework[];\n\t/** Recognized stack profile (if frameworks match a known combination) */\n\tstack?: KnownStack;\n\t/** Human-readable summary for system prompt injection */\n\tsummary: string;\n}\n\n/** Detect the technology stack in a project directory */\nexport function detectStack(cwd: string): StackDetectionResult {\n\tconst frameworks: DetectedFramework[] = [];\n\n\t// Parse composer.json for PHP/Laravel dependencies\n\tconst composerPath = join(cwd, \"composer.json\");\n\tif (existsSync(composerPath)) {\n\t\ttry {\n\t\t\tconst composer = JSON.parse(readFileSync(composerPath, \"utf-8\"));\n\t\t\tconst deps = { ...composer.require, ...composer[\"require-dev\"] };\n\n\t\t\tif (deps[\"laravel/framework\"]) {\n\t\t\t\tframeworks.push({ name: \"Laravel\", version: extractVersion(deps[\"laravel/framework\"]) });\n\t\t\t}\n\t\t\tif (deps[\"livewire/livewire\"]) {\n\t\t\t\tframeworks.push({ name: \"Livewire\", version: extractVersion(deps[\"livewire/livewire\"]) });\n\t\t\t}\n\t\t\tif (deps[\"livewire/flux\"]) {\n\t\t\t\tframeworks.push({ name: \"Flux UI\", version: extractVersion(deps[\"livewire/flux\"]) });\n\t\t\t}\n\t\t\tif (deps[\"inertiajs/inertia-laravel\"]) {\n\t\t\t\tframeworks.push({ name: \"Inertia\", version: extractVersion(deps[\"inertiajs/inertia-laravel\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/reverb\"]) {\n\t\t\t\tframeworks.push({ name: \"Reverb\", version: extractVersion(deps[\"laravel/reverb\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/sanctum\"]) {\n\t\t\t\tframeworks.push({ name: \"Sanctum\", version: extractVersion(deps[\"laravel/sanctum\"]) });\n\t\t\t}\n\t\t\tif (deps[\"filament/filament\"]) {\n\t\t\t\tframeworks.push({ name: \"Filament\", version: extractVersion(deps[\"filament/filament\"]) });\n\t\t\t}\n\t\t\tif (deps[\"laravel/ai\"]) {\n\t\t\t\tframeworks.push({ name: \"Laravel AI SDK\", version: extractVersion(deps[\"laravel/ai\"]) });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore malformed composer.json\n\t\t}\n\t}\n\n\t// Parse package.json for JS/frontend dependencies\n\tconst packagePath = join(cwd, \"package.json\");\n\tif (existsSync(packagePath)) {\n\t\ttry {\n\t\t\tconst pkg = JSON.parse(readFileSync(packagePath, \"utf-8\"));\n\t\t\tconst deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n\t\t\tif (deps.vue) {\n\t\t\t\tframeworks.push({ name: \"Vue\", version: extractVersion(deps.vue) });\n\t\t\t}\n\t\t\tif (deps.alpinejs) {\n\t\t\t\tframeworks.push({ name: \"Alpine.js\", version: extractVersion(deps.alpinejs) });\n\t\t\t}\n\t\t\tif (deps.tailwindcss) {\n\t\t\t\tframeworks.push({ name: \"Tailwind CSS\", version: extractVersion(deps.tailwindcss) });\n\t\t\t}\n\t\t\tif (\n\t\t\t\tdeps[\"@inertiajs/vue3\"] ||\n\t\t\t\tdeps[\"@inertiajs/vue2\"] ||\n\t\t\t\tdeps[\"@inertiajs/react\"] ||\n\t\t\t\tdeps[\"@inertiajs/svelte\"]\n\t\t\t) {\n\t\t\t\t// Inertia frontend adapter -- version from whichever is present\n\t\t\t\tconst inertiaFe =\n\t\t\t\t\tdeps[\"@inertiajs/vue3\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/vue2\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/react\"] ||\n\t\t\t\t\tdeps[\"@inertiajs/svelte\"];\n\t\t\t\tif (!frameworks.some((f) => f.name === \"Inertia\")) {\n\t\t\t\t\tframeworks.push({ name: \"Inertia\", version: extractVersion(inertiaFe) });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (deps.react || deps[\"react-dom\"]) {\n\t\t\t\tframeworks.push({ name: \"React\", version: extractVersion(deps.react || deps[\"react-dom\"]) });\n\t\t\t}\n\t\t\tif (deps.svelte) {\n\t\t\t\tframeworks.push({ name: \"Svelte\", version: extractVersion(deps.svelte) });\n\t\t\t}\n\t\t\tif (deps.typescript) {\n\t\t\t\tframeworks.push({ name: \"TypeScript\", version: extractVersion(deps.typescript) });\n\t\t\t}\n\t\t\tif (deps.vite) {\n\t\t\t\tframeworks.push({ name: \"Vite\", version: extractVersion(deps.vite) });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore malformed package.json\n\t\t}\n\t}\n\n\t// Detect Elyra Framework (Rust + Svelte 5 desktop apps). `rata new` scaffolds\n\t// an `elyra.toml` config file, which is the most reliable signal; fall back\n\t// to a plain-text check for the `elyra` crate dependency in Cargo.toml (TOML\n\t// isn't parsed here to avoid adding a parser dependency for one field).\n\tconst cargoPath = join(cwd, \"Cargo.toml\");\n\tif (existsSync(join(cwd, \"elyra.toml\")) || existsSync(cargoPath)) {\n\t\ttry {\n\t\t\tconst cargoText = existsSync(cargoPath) ? readFileSync(cargoPath, \"utf-8\") : \"\";\n\t\t\tconst hasElyraCrate = /^\\s*elyra\\s*=/m.test(cargoText) || /\\[dependencies\\.elyra\\]/.test(cargoText);\n\t\t\tif (existsSync(join(cwd, \"elyra.toml\")) || hasElyraCrate) {\n\t\t\t\tconst versionMatch = cargoText.match(/^\\s*elyra\\s*=\\s*\\{[^}]*version\\s*=\\s*\"([^\"]+)\"/m);\n\t\t\t\tframeworks.push({ name: \"Elyra Framework\", version: versionMatch?.[1] });\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore unreadable Cargo.toml\n\t\t}\n\t}\n\n\tif (frameworks.length === 0) {\n\t\treturn { frameworks, summary: \"\" };\n\t}\n\n\t// Detect known stack profiles\n\tconst has = (name: string) => frameworks.some((f) => f.name === name);\n\tlet stack: KnownStack | undefined;\n\n\tif (has(\"Elyra Framework\")) {\n\t\tstack = \"ELYRA_FRAMEWORK\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Alpine.js\") && has(\"Livewire\")) {\n\t\tstack = \"TALL\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"React\")) {\n\t\tstack = \"RILT\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"Vue\")) {\n\t\tstack = \"VILT\";\n\t} else if (has(\"Laravel\") && has(\"Tailwind CSS\") && has(\"Inertia\") && has(\"Svelte\")) {\n\t\tstack = \"SILT\";\n\t}\n\n\t// Build human-readable summary\n\tconst frameworkList = frameworks.map((f) => (f.version ? `${f.name} ${f.version}` : f.name)).join(\", \");\n\tlet summary = `Detected frameworks: ${frameworkList}`;\n\tif (stack === \"TALL\") {\n\t\tconst hasFlux = has(\"Flux UI\");\n\t\tsummary = `TALL stack project (Tailwind, Alpine.js, Laravel, Livewire${hasFlux ? \", Flux UI\" : \"\"}).\\n${frameworkList}`;\n\t} else if (stack === \"RILT\") {\n\t\tsummary = `RILT stack project (React, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"VILT\") {\n\t\tsummary = `VILT stack project (Vue, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"SILT\") {\n\t\tsummary = `SILT stack project (Svelte, Inertia, Laravel, Tailwind).\\n${frameworkList}`;\n\t} else if (stack === \"ELYRA_FRAMEWORK\") {\n\t\tsummary = `Elyra Framework project (Rust + Svelte 5 desktop app, Laravel-inspired ergonomics).\\n${frameworkList}`;\n\t}\n\n\treturn { frameworks, stack, summary };\n}\n\n/** Strip semver constraint prefixes (^, ~, >=, etc.) to get a clean version */\nfunction extractVersion(constraint: string | undefined): string | undefined {\n\tif (!constraint) return undefined;\n\tconst match = constraint.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/);\n\treturn match?.[1];\n}\n\n/** Get the suggested package name for a detected stack */\nexport function getSuggestedPackage(stack: KnownStack): string {\n\tswitch (stack) {\n\t\tcase \"TALL\":\n\t\t\treturn \"@elyracode/stack-tall\";\n\t\tcase \"RILT\":\n\t\t\treturn \"@elyracode/stack-rilt\";\n\t\tcase \"VILT\":\n\t\t\treturn \"@elyracode/stack-vilt\";\n\t\tcase \"SILT\":\n\t\t\treturn \"@elyracode/stack-silt\";\n\t\tcase \"ELYRA_FRAMEWORK\":\n\t\t\treturn \"@elyracode/stack-elyra-framework\";\n\t}\n}\n\n// =============================================================================\n// Grove environment detection\n// =============================================================================\n\n/** Result of Grove site detection */\nexport interface GroveSiteDetection {\n\t/** Site name (registered name, or the directory name for parked sites) */\n\tsiteName: string;\n\t/** The URL Grove serves this site at */\n\turl: string;\n}\n\nfunction findGroveHome(override?: string): string | undefined {\n\tif (override) return existsSync(override) ? override : undefined;\n\tconst envHome = process.env.GROVE_HOME;\n\tif (envHome && existsSync(envHome)) return envHome;\n\tconst candidates = [join(homedir(), \"Library\", \"Application Support\", \"Grove\"), join(homedir(), \".config\", \"grove\")];\n\treturn candidates.find((p) => existsSync(p));\n}\n\nfunction expandTilde(p: string): string {\n\treturn p.startsWith(\"~/\") ? join(homedir(), p.slice(2)) : p;\n}\n\n/**\n * Detect whether `cwd` is served by Grove (the local dev environment\n * manager): either registered as a site in Grove's config.toml, or a direct\n * child of a parked path. Uses a line-based scan of the config rather than a\n * TOML parser dependency (same tradeoff as the Cargo.toml check above).\n */\nexport function detectGroveSite(cwd: string, groveHomeOverride?: string): GroveSiteDetection | undefined {\n\tconst groveHome = findGroveHome(groveHomeOverride);\n\tif (!groveHome) return undefined;\n\tconst configPath = join(groveHome, \"config.toml\");\n\tif (!existsSync(configPath)) return undefined;\n\n\tlet text: string;\n\ttry {\n\t\ttext = readFileSync(configPath, \"utf-8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n\n\tlet tld = \"test\";\n\tconst parked: string[] = [];\n\tinterface SiteEntry {\n\t\tname?: string;\n\t\tpath?: string;\n\t\tsecure?: boolean;\n\t}\n\tconst sites: SiteEntry[] = [];\n\tlet section: \"sites\" | \"parked\" | \"other\" | \"root\" = \"root\";\n\tlet currentSite: SiteEntry | undefined;\n\n\tfor (const rawLine of text.split(\"\\n\")) {\n\t\tconst line = rawLine.trim();\n\t\tif (!line || line.startsWith(\"#\")) continue;\n\n\t\tconst header = /^\\[\\[?([^\\]]+?)\\]?\\]$/.exec(line);\n\t\tif (header) {\n\t\t\tconst name = header[1].trim();\n\t\t\tif (name === \"sites\") {\n\t\t\t\tsection = \"sites\";\n\t\t\t\tcurrentSite = {};\n\t\t\t\tsites.push(currentSite);\n\t\t\t} else if (name === \"parked\") {\n\t\t\t\tsection = \"parked\";\n\t\t\t} else {\n\t\t\t\tsection = \"other\";\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst kv = /^([A-Za-z0-9_-]+)\\s*=\\s*(.+)$/.exec(line);\n\t\tif (!kv) continue;\n\t\tconst key = kv[1];\n\t\tconst value = kv[2].trim().replace(/^[\"']/, \"\").replace(/[\"']$/, \"\");\n\n\t\tif (key === \"tld\" && value) {\n\t\t\ttld = value;\n\t\t} else if (section === \"parked\" && key === \"path\") {\n\t\t\tparked.push(expandTilde(value));\n\t\t} else if (section === \"sites\" && currentSite) {\n\t\t\tif (key === \"name\") currentSite.name = value;\n\t\t\telse if (key === \"path\") currentSite.path = expandTilde(value);\n\t\t\telse if (key === \"secure\") currentSite.secure = value === \"true\";\n\t\t}\n\t}\n\n\tconst registered = sites.find((s) => s.path === cwd && s.name);\n\tif (registered?.name) {\n\t\tconst scheme = registered.secure ? \"https\" : \"http\";\n\t\treturn { siteName: registered.name, url: `${scheme}://${registered.name}.${tld}` };\n\t}\n\n\tif (parked.some((p) => cwd.startsWith(`${p}/`) && cwd !== p)) {\n\t\tconst siteName = basename(cwd);\n\t\treturn { siteName, url: `http://${siteName}.${tld}` };\n\t}\n\n\treturn undefined;\n}\n"]}
|
|
@@ -292,6 +292,7 @@ export declare class InteractiveMode {
|
|
|
292
292
|
showWarning(warningMessage: string): void;
|
|
293
293
|
showPackageUpdateNotification(packages: string[]): void;
|
|
294
294
|
private checkStackProfile;
|
|
295
|
+
private hasPackageInstalled;
|
|
295
296
|
/**
|
|
296
297
|
* Get all queued messages (read-only).
|
|
297
298
|
* Combines session queue and compaction queue.
|
|
@@ -321,6 +322,7 @@ export declare class InteractiveMode {
|
|
|
321
322
|
private handleInAppUpdate;
|
|
322
323
|
private handleGoalCommand;
|
|
323
324
|
private handleRouteCommand;
|
|
325
|
+
private handleRoutingStatsCommand;
|
|
324
326
|
private getLastUserMessageText;
|
|
325
327
|
private handleReplayCommand;
|
|
326
328
|
private handleLearnCommand;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-mode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAKN,KAAK,YAAY,EAKjB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"interactive-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-mode.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ import * as path from "node:path";
|
|
|
9
9
|
import { completeSimple, getProviders, } from "@elyracode/ai";
|
|
10
10
|
import { CombinedAutocompleteProvider, Container, fuzzyFilter, Loader, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TUI, visibleWidth, } from "@elyracode/tui";
|
|
11
11
|
import { spawn, spawnSync } from "child_process";
|
|
12
|
-
import { APP_NAME, APP_TITLE, getAgentDir, getAuthPath, getBlueprintsDir, getDebugLogPath, getDocsPath, getProjectBlueprintsDir, getProjectSnippetsDir, getSelfUpdateCommand, getShareViewerUrl, getSnippetsDir, PACKAGE_NAME, VERSION, } from "../../config.js";
|
|
12
|
+
import { APP_NAME, APP_TITLE, getAgentDir, getAuthPath, getBlueprintsDir, getDebugLogPath, getDocsPath, getProjectBlueprintsDir, getProjectSnippetsDir, getRoutingLedgerPath, getSelfUpdateCommand, getShareViewerUrl, getSnippetsDir, PACKAGE_NAME, VERSION, } from "../../config.js";
|
|
13
13
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
14
14
|
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
15
15
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
@@ -20,11 +20,12 @@ import { selectDiverseModels } from "../../core/model-panel.js";
|
|
|
20
20
|
import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScope } from "../../core/model-resolver.js";
|
|
21
21
|
import { DefaultPackageManager } from "../../core/package-manager.js";
|
|
22
22
|
import { BUILT_IN_PROVIDER_DISPLAY_NAMES } from "../../core/provider-display-names.js";
|
|
23
|
+
import { formatStatsReport, loadStats } from "../../core/routing-ledger.js";
|
|
23
24
|
import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
|
|
24
25
|
import { SessionManager } from "../../core/session-manager.js";
|
|
25
26
|
import { extractSkillFromSession } from "../../core/skill-extraction.js";
|
|
26
27
|
import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
27
|
-
import { detectStack, getSuggestedPackage } from "../../core/stack-detector.js";
|
|
28
|
+
import { detectGroveSite, detectStack, getSuggestedPackage } from "../../core/stack-detector.js";
|
|
28
29
|
import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/changelog.js";
|
|
29
30
|
import { copyToClipboard } from "../../utils/clipboard.js";
|
|
30
31
|
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
|
|
@@ -2253,6 +2254,11 @@ export class InteractiveMode {
|
|
|
2253
2254
|
await this.handleRouteCommand();
|
|
2254
2255
|
return;
|
|
2255
2256
|
}
|
|
2257
|
+
if (text === "/routing-stats") {
|
|
2258
|
+
this.editor.setText("");
|
|
2259
|
+
this.handleRoutingStatsCommand();
|
|
2260
|
+
return;
|
|
2261
|
+
}
|
|
2256
2262
|
// Handle bash command (! for normal, !! for excluded from context)
|
|
2257
2263
|
if (text.startsWith("!")) {
|
|
2258
2264
|
const isExcluded = text.startsWith("!!");
|
|
@@ -3099,19 +3105,34 @@ export class InteractiveMode {
|
|
|
3099
3105
|
checkStackProfile() {
|
|
3100
3106
|
try {
|
|
3101
3107
|
const result = detectStack(this.sessionManager.getCwd());
|
|
3102
|
-
if (
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3108
|
+
if (result.stack) {
|
|
3109
|
+
const pkg = getSuggestedPackage(result.stack);
|
|
3110
|
+
const install = theme.fg("accent", `${APP_NAME} install ${pkg}`);
|
|
3111
|
+
const stackLabel = theme.bold(theme.fg("accent", result.stack));
|
|
3112
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3113
|
+
this.chatContainer.addChild(new Text(`${stackLabel} ${theme.fg("muted", "stack detected.")} ${theme.fg("dim", "Install the stack profile:")} ${install}`, 1, 0));
|
|
3114
|
+
this.ui.requestRender();
|
|
3115
|
+
}
|
|
3116
|
+
// Grove is an environment, not a stack -- suggest its integration
|
|
3117
|
+
// independently, but only when it isn't installed already.
|
|
3118
|
+
const groveSite = detectGroveSite(this.sessionManager.getCwd());
|
|
3119
|
+
if (groveSite && !this.hasPackageInstalled("@elyracode/grove")) {
|
|
3120
|
+
const install = theme.fg("accent", `${APP_NAME} install npm:@elyracode/grove`);
|
|
3121
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3122
|
+
this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("accent", "Grove"))} ${theme.fg("muted", `site detected (${groveSite.url}).`)} ${theme.fg("dim", "Install the Grove integration:")} ${install}`, 1, 0));
|
|
3123
|
+
this.ui.requestRender();
|
|
3124
|
+
}
|
|
3110
3125
|
}
|
|
3111
3126
|
catch {
|
|
3112
3127
|
// Never block startup on detection failure
|
|
3113
3128
|
}
|
|
3114
3129
|
}
|
|
3130
|
+
hasPackageInstalled(name) {
|
|
3131
|
+
return this.settingsManager.getPackages().some((pkg) => {
|
|
3132
|
+
const source = typeof pkg === "string" ? pkg : pkg.source;
|
|
3133
|
+
return source.includes(name);
|
|
3134
|
+
});
|
|
3135
|
+
}
|
|
3115
3136
|
/**
|
|
3116
3137
|
* Get all queued messages (read-only).
|
|
3117
3138
|
* Combines session queue and compaction queue.
|
|
@@ -3515,6 +3536,12 @@ export class InteractiveMode {
|
|
|
3515
3536
|
if (fs.existsSync(path.join(cwd, "docker-compose.yml")) || fs.existsSync(path.join(cwd, "compose.yml"))) {
|
|
3516
3537
|
parts.push(` ${theme.fg("dim", "Install:")} elyra install npm:@elyracode/docker`);
|
|
3517
3538
|
}
|
|
3539
|
+
const groveSite = detectGroveSite(cwd);
|
|
3540
|
+
if (groveSite) {
|
|
3541
|
+
parts.push("");
|
|
3542
|
+
parts.push(` ${theme.fg("accent", "Detected:")} Grove site (${groveSite.url})`);
|
|
3543
|
+
parts.push(` ${theme.fg("dim", "Install:")} elyra install npm:@elyracode/grove`);
|
|
3544
|
+
}
|
|
3518
3545
|
// Always suggest useful general extensions
|
|
3519
3546
|
parts.push("");
|
|
3520
3547
|
parts.push(theme.fg("dim", "Edit .elyra/AGENTS.md to add project rules and conventions."));
|
|
@@ -3766,6 +3793,19 @@ export class InteractiveMode {
|
|
|
3766
3793
|
this.chatContainer.addChild(new Text(lines.join("\n"), 1, 0));
|
|
3767
3794
|
this.ui.requestRender();
|
|
3768
3795
|
}
|
|
3796
|
+
handleRoutingStatsCommand() {
|
|
3797
|
+
let report;
|
|
3798
|
+
try {
|
|
3799
|
+
report = formatStatsReport(loadStats(getRoutingLedgerPath(), "main"));
|
|
3800
|
+
}
|
|
3801
|
+
catch (err) {
|
|
3802
|
+
report = `Could not read the routing ledger: ${err instanceof Error ? err.message : String(err)}`;
|
|
3803
|
+
}
|
|
3804
|
+
const lines = [theme.bold("Routing Stats"), "", report];
|
|
3805
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3806
|
+
this.chatContainer.addChild(new Text(lines.join("\n"), 1, 0));
|
|
3807
|
+
this.ui.requestRender();
|
|
3808
|
+
}
|
|
3769
3809
|
getLastUserMessageText() {
|
|
3770
3810
|
const messages = this.session.state.messages;
|
|
3771
3811
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
@@ -5533,6 +5573,7 @@ export class InteractiveMode {
|
|
|
5533
5573
|
mk("perf-tools", "Performance: N+1 queries, slow queries, indexes"),
|
|
5534
5574
|
mk("i18n-tools", "Localization: hardcoded strings, missing translations"),
|
|
5535
5575
|
mk("herd", "Laravel Herd: services, logs, PHP version, .env sync"),
|
|
5576
|
+
mk("grove", "Grove: dev environment status, sites, services, logs, .env sync"),
|
|
5536
5577
|
mk("anna", "Presentations: Anna.js slides, terminal demos, diagrams"),
|
|
5537
5578
|
mk("swarm", "Swarm: automated build, review, and refactor pipelines"),
|
|
5538
5579
|
mk("docker", "Docker: container exec, logs, compose, env sync"),
|