@oh-my-pi/pi-coding-agent 2.3.1337 → 3.0.1337
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 +62 -34
- package/README.md +100 -100
- package/docs/compaction.md +8 -8
- package/docs/config-usage.md +113 -0
- package/docs/custom-tools.md +8 -8
- package/docs/extension-loading.md +58 -58
- package/docs/hooks.md +11 -11
- package/docs/rpc.md +4 -4
- package/docs/sdk.md +14 -14
- package/docs/session-tree-plan.md +1 -1
- package/docs/session.md +2 -2
- package/docs/skills.md +16 -16
- package/docs/theme.md +9 -9
- package/docs/tui.md +1 -1
- package/examples/README.md +1 -1
- package/examples/custom-tools/README.md +4 -4
- package/examples/custom-tools/subagent/README.md +13 -13
- package/examples/custom-tools/subagent/agents.ts +2 -2
- package/examples/custom-tools/subagent/index.ts +5 -5
- package/examples/hooks/README.md +3 -3
- package/examples/hooks/auto-commit-on-exit.ts +1 -1
- package/examples/hooks/custom-compaction.ts +1 -1
- package/examples/sdk/01-minimal.ts +1 -1
- package/examples/sdk/04-skills.ts +1 -1
- package/examples/sdk/05-tools.ts +1 -1
- package/examples/sdk/08-slash-commands.ts +1 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
- package/examples/sdk/README.md +2 -2
- package/package.json +13 -11
- package/src/capability/context-file.ts +40 -0
- package/src/capability/extension.ts +48 -0
- package/src/capability/hook.ts +40 -0
- package/src/capability/index.ts +616 -0
- package/src/capability/instruction.ts +37 -0
- package/src/capability/mcp.ts +52 -0
- package/src/capability/prompt.ts +35 -0
- package/src/capability/rule.ts +52 -0
- package/src/capability/settings.ts +35 -0
- package/src/capability/skill.ts +49 -0
- package/src/capability/slash-command.ts +40 -0
- package/src/capability/system-prompt.ts +35 -0
- package/src/capability/tool.ts +38 -0
- package/src/capability/types.ts +166 -0
- package/src/cli/args.ts +2 -2
- package/src/cli/plugin-cli.ts +24 -19
- package/src/cli/update-cli.ts +10 -10
- package/src/config.ts +290 -6
- package/src/core/auth-storage.ts +32 -9
- package/src/core/bash-executor.ts +1 -1
- package/src/core/custom-commands/loader.ts +44 -50
- package/src/core/custom-tools/index.ts +1 -0
- package/src/core/custom-tools/loader.ts +67 -69
- package/src/core/custom-tools/types.ts +10 -1
- package/src/core/hooks/loader.ts +13 -42
- package/src/core/index.ts +0 -1
- package/src/core/logger.ts +7 -7
- package/src/core/mcp/client.ts +1 -1
- package/src/core/mcp/config.ts +94 -146
- package/src/core/mcp/index.ts +0 -4
- package/src/core/mcp/loader.ts +26 -22
- package/src/core/mcp/manager.ts +18 -23
- package/src/core/mcp/tool-bridge.ts +9 -1
- package/src/core/mcp/types.ts +2 -0
- package/src/core/model-registry.ts +25 -8
- package/src/core/plugins/installer.ts +1 -1
- package/src/core/plugins/loader.ts +17 -11
- package/src/core/plugins/manager.ts +2 -2
- package/src/core/plugins/paths.ts +12 -7
- package/src/core/plugins/types.ts +3 -3
- package/src/core/sdk.ts +48 -27
- package/src/core/session-manager.ts +4 -4
- package/src/core/settings-manager.ts +45 -21
- package/src/core/skills.ts +222 -293
- package/src/core/slash-commands.ts +34 -165
- package/src/core/system-prompt.ts +58 -65
- package/src/core/timings.ts +2 -2
- package/src/core/tools/lsp/config.ts +38 -17
- package/src/core/tools/task/artifacts.ts +1 -1
- package/src/core/tools/task/commands.ts +30 -107
- package/src/core/tools/task/discovery.ts +54 -66
- package/src/core/tools/task/executor.ts +9 -9
- package/src/core/tools/task/index.ts +10 -10
- package/src/core/tools/task/model-resolver.ts +27 -25
- package/src/core/tools/task/types.ts +2 -2
- package/src/core/tools/web-fetch.ts +3 -3
- package/src/core/tools/web-search/auth.ts +40 -34
- package/src/core/tools/web-search/index.ts +1 -1
- package/src/core/tools/web-search/providers/anthropic.ts +1 -1
- package/src/discovery/agents-md.ts +75 -0
- package/src/discovery/builtin.ts +646 -0
- package/src/discovery/claude.ts +623 -0
- package/src/discovery/cline.ts +102 -0
- package/src/discovery/codex.ts +571 -0
- package/src/discovery/cursor.ts +264 -0
- package/src/discovery/gemini.ts +368 -0
- package/src/discovery/github.ts +120 -0
- package/src/discovery/helpers.test.ts +127 -0
- package/src/discovery/helpers.ts +249 -0
- package/src/discovery/index.ts +84 -0
- package/src/discovery/mcp-json.ts +127 -0
- package/src/discovery/vscode.ts +99 -0
- package/src/discovery/windsurf.ts +216 -0
- package/src/main.ts +14 -13
- package/src/migrations.ts +24 -3
- package/src/modes/interactive/components/hook-editor.ts +1 -1
- package/src/modes/interactive/components/plugin-settings.ts +1 -1
- package/src/modes/interactive/components/settings-defs.ts +38 -2
- package/src/modes/interactive/components/settings-selector.ts +1 -0
- package/src/modes/interactive/components/welcome.ts +2 -2
- package/src/modes/interactive/interactive-mode.ts +211 -16
- package/src/modes/interactive/theme/theme-schema.json +1 -1
- package/src/utils/clipboard.ts +1 -1
- package/src/utils/shell-snapshot.ts +2 -2
- package/src/utils/shell.ts +7 -7
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import * as fs from "node:fs";
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as path from "node:path";
|
|
9
|
+
import { basename } from "node:path";
|
|
9
10
|
import type { AgentMessage, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
10
11
|
import type { AssistantMessage, ImageContent, Message, OAuthProvider } from "@oh-my-pi/pi-ai";
|
|
11
12
|
import type { SlashCommand } from "@oh-my-pi/pi-tui";
|
|
@@ -23,6 +24,10 @@ import {
|
|
|
23
24
|
TUI,
|
|
24
25
|
visibleWidth,
|
|
25
26
|
} from "@oh-my-pi/pi-tui";
|
|
27
|
+
import { contextFileCapability } from "../../capability/context-file";
|
|
28
|
+
import { instructionCapability } from "../../capability/instruction";
|
|
29
|
+
import { promptCapability } from "../../capability/prompt";
|
|
30
|
+
import { ruleCapability } from "../../capability/rule";
|
|
26
31
|
import { getAuthPath, getDebugLogPath } from "../../config";
|
|
27
32
|
import type { AgentSession, AgentSessionEvent } from "../../core/agent-session";
|
|
28
33
|
import type { CustomToolSessionEvent, LoadedCustomTool } from "../../core/custom-tools/index";
|
|
@@ -30,9 +35,17 @@ import type { HookUIContext } from "../../core/hooks/index";
|
|
|
30
35
|
import { createCompactionSummaryMessage } from "../../core/messages";
|
|
31
36
|
import { getRecentSessions, type SessionContext, SessionManager } from "../../core/session-manager";
|
|
32
37
|
import { loadSkills } from "../../core/skills";
|
|
33
|
-
import { loadProjectContextFiles } from "../../core/system-prompt";
|
|
34
38
|
import { generateSessionTitle, setTerminalTitle } from "../../core/title-generator";
|
|
35
39
|
import type { TruncationResult } from "../../core/tools/truncate";
|
|
40
|
+
import {
|
|
41
|
+
type ContextFile,
|
|
42
|
+
disableProvider,
|
|
43
|
+
enableProvider,
|
|
44
|
+
type Instruction,
|
|
45
|
+
loadSync,
|
|
46
|
+
type Prompt,
|
|
47
|
+
type Rule,
|
|
48
|
+
} from "../../discovery";
|
|
36
49
|
import { getChangelogPath, parseChangelog } from "../../utils/changelog";
|
|
37
50
|
import { copyToClipboard, readImageFromClipboard } from "../../utils/clipboard";
|
|
38
51
|
import { ArminComponent } from "./components/armin";
|
|
@@ -1535,7 +1548,7 @@ export class InteractiveMode {
|
|
|
1535
1548
|
}
|
|
1536
1549
|
|
|
1537
1550
|
const currentText = this.editor.getText();
|
|
1538
|
-
const tmpFile = path.join(os.tmpdir(), `
|
|
1551
|
+
const tmpFile = path.join(os.tmpdir(), `omp-editor-${Date.now()}.omp.md`);
|
|
1539
1552
|
|
|
1540
1553
|
try {
|
|
1541
1554
|
// Write current content to temp file
|
|
@@ -1729,6 +1742,17 @@ export class InteractiveMode {
|
|
|
1729
1742
|
* This handles side effects and session-specific settings.
|
|
1730
1743
|
*/
|
|
1731
1744
|
private handleSettingChange(id: string, value: string | boolean): void {
|
|
1745
|
+
// Discovery provider toggles
|
|
1746
|
+
if (id.startsWith("discovery.")) {
|
|
1747
|
+
const providerId = id.replace("discovery.", "");
|
|
1748
|
+
if (value) {
|
|
1749
|
+
enableProvider(providerId);
|
|
1750
|
+
} else {
|
|
1751
|
+
disableProvider(providerId);
|
|
1752
|
+
}
|
|
1753
|
+
return;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1732
1756
|
switch (id) {
|
|
1733
1757
|
// Session-managed settings (not in SettingsManager)
|
|
1734
1758
|
case "autoCompact":
|
|
@@ -2369,13 +2393,91 @@ export class InteractiveMode {
|
|
|
2369
2393
|
private handleStatusCommand(): void {
|
|
2370
2394
|
const sections: string[] = [];
|
|
2371
2395
|
|
|
2396
|
+
type StatusSource =
|
|
2397
|
+
| { provider: string; level: string }
|
|
2398
|
+
| { mcpServer: string; provider?: string }
|
|
2399
|
+
| "builtin"
|
|
2400
|
+
| "unknown";
|
|
2401
|
+
|
|
2402
|
+
const capitalize = (value: string): string => value.charAt(0).toUpperCase() + value.slice(1);
|
|
2403
|
+
|
|
2404
|
+
const resolveSourceText = (source: StatusSource): string => {
|
|
2405
|
+
if (source === "builtin") return "builtin";
|
|
2406
|
+
if (source === "unknown") return "unknown";
|
|
2407
|
+
if ("mcpServer" in source) {
|
|
2408
|
+
if (!source.provider) return `mcp:${source.mcpServer}`;
|
|
2409
|
+
return `${source.mcpServer} via ${source.provider}`;
|
|
2410
|
+
}
|
|
2411
|
+
const levelLabel = capitalize(source.level);
|
|
2412
|
+
return `via ${source.provider} (${levelLabel})`;
|
|
2413
|
+
};
|
|
2414
|
+
|
|
2415
|
+
const renderSourceText = (text: string): string => text.replace(/\bvia\b/, theme.italic("via"));
|
|
2416
|
+
|
|
2417
|
+
const truncateText = (text: string, maxLen: number): string => {
|
|
2418
|
+
if (text.length <= maxLen) return text;
|
|
2419
|
+
if (maxLen <= 3) return text.slice(0, Math.max(0, maxLen));
|
|
2420
|
+
return `${text.slice(0, maxLen - 3)}...`;
|
|
2421
|
+
};
|
|
2422
|
+
|
|
2423
|
+
// Helper to format a section with consistent column alignment
|
|
2424
|
+
const formatSection = <T>(
|
|
2425
|
+
title: string,
|
|
2426
|
+
items: readonly T[],
|
|
2427
|
+
getName: (item: T) => string,
|
|
2428
|
+
getDesc: (item: T) => string | undefined,
|
|
2429
|
+
getSource: (item: T) => StatusSource,
|
|
2430
|
+
): string => {
|
|
2431
|
+
if (items.length === 0) return "";
|
|
2432
|
+
|
|
2433
|
+
const lineItems = items.map((item) => {
|
|
2434
|
+
const name = getName(item);
|
|
2435
|
+
const desc = getDesc(item);
|
|
2436
|
+
const sourceText = resolveSourceText(getSource(item));
|
|
2437
|
+
const nameWithSource = sourceText ? `${name} ${sourceText}` : name;
|
|
2438
|
+
return { name, sourceText, nameWithSource, desc };
|
|
2439
|
+
});
|
|
2440
|
+
|
|
2441
|
+
const maxNameWidth = Math.min(60, Math.max(...lineItems.map((line) => line.nameWithSource.length)));
|
|
2442
|
+
const formattedLines = lineItems.map((line) => {
|
|
2443
|
+
let nameText = line.name;
|
|
2444
|
+
let sourceText = line.sourceText;
|
|
2445
|
+
|
|
2446
|
+
if (sourceText) {
|
|
2447
|
+
let availableForName = maxNameWidth - sourceText.length - 1;
|
|
2448
|
+
if (availableForName < 1) {
|
|
2449
|
+
sourceText = truncateText(sourceText, Math.max(0, maxNameWidth - 4));
|
|
2450
|
+
availableForName = maxNameWidth - sourceText.length - 1;
|
|
2451
|
+
}
|
|
2452
|
+
nameText = truncateText(nameText, Math.max(1, availableForName));
|
|
2453
|
+
} else {
|
|
2454
|
+
nameText = truncateText(nameText, maxNameWidth);
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
const nameWithSourcePlain = sourceText ? `${nameText} ${sourceText}` : nameText;
|
|
2458
|
+
const sourceRendered = sourceText ? renderSourceText(sourceText) : "";
|
|
2459
|
+
const nameRendered = sourceText ? `${theme.bold(nameText)} ${sourceRendered}` : theme.bold(nameText);
|
|
2460
|
+
const pad = Math.max(0, maxNameWidth - nameWithSourcePlain.length);
|
|
2461
|
+
const desc = line.desc?.trim();
|
|
2462
|
+
const descPart = desc ? ` ${theme.fg("dim", desc.slice(0, 50) + (desc.length > 50 ? "..." : ""))}` : "";
|
|
2463
|
+
return ` ${nameRendered}${" ".repeat(pad)}${descPart}`;
|
|
2464
|
+
});
|
|
2465
|
+
|
|
2466
|
+
return `${theme.bold(theme.fg("accent", title))}\n${formattedLines.join("\n")}`;
|
|
2467
|
+
};
|
|
2468
|
+
|
|
2372
2469
|
// Loaded context files
|
|
2373
|
-
const
|
|
2470
|
+
const contextFilesResult = loadSync(contextFileCapability.id, { cwd: process.cwd() });
|
|
2471
|
+
const contextFiles = contextFilesResult.items as ContextFile[];
|
|
2374
2472
|
if (contextFiles.length > 0) {
|
|
2375
2473
|
sections.push(
|
|
2376
|
-
|
|
2377
|
-
"
|
|
2378
|
-
contextFiles
|
|
2474
|
+
formatSection(
|
|
2475
|
+
"Context Files",
|
|
2476
|
+
contextFiles,
|
|
2477
|
+
(f) => basename(f.path),
|
|
2478
|
+
() => undefined,
|
|
2479
|
+
(f) => ({ provider: f._source.providerName, level: f.level }),
|
|
2480
|
+
),
|
|
2379
2481
|
);
|
|
2380
2482
|
}
|
|
2381
2483
|
|
|
@@ -2385,9 +2487,13 @@ export class InteractiveMode {
|
|
|
2385
2487
|
const { skills, warnings: skillWarnings } = loadSkills(skillsSettings ?? {});
|
|
2386
2488
|
if (skills.length > 0) {
|
|
2387
2489
|
sections.push(
|
|
2388
|
-
|
|
2389
|
-
"
|
|
2390
|
-
skills
|
|
2490
|
+
formatSection(
|
|
2491
|
+
"Skills",
|
|
2492
|
+
skills,
|
|
2493
|
+
(s) => s.name,
|
|
2494
|
+
(s) => s.description,
|
|
2495
|
+
(s) => (s._source ? { provider: s._source.providerName, level: s._source.level } : "unknown"),
|
|
2496
|
+
),
|
|
2391
2497
|
);
|
|
2392
2498
|
}
|
|
2393
2499
|
if (skillWarnings.length > 0) {
|
|
@@ -2399,14 +2505,103 @@ export class InteractiveMode {
|
|
|
2399
2505
|
}
|
|
2400
2506
|
}
|
|
2401
2507
|
|
|
2402
|
-
// Loaded
|
|
2508
|
+
// Loaded rules
|
|
2509
|
+
const rulesResult = loadSync<Rule>(ruleCapability.id, { cwd: process.cwd() });
|
|
2510
|
+
if (rulesResult.items.length > 0) {
|
|
2511
|
+
sections.push(
|
|
2512
|
+
formatSection(
|
|
2513
|
+
"Rules",
|
|
2514
|
+
rulesResult.items,
|
|
2515
|
+
(r) => r.name,
|
|
2516
|
+
(r) => r.description,
|
|
2517
|
+
(r) => ({ provider: r._source.providerName, level: r._source.level }),
|
|
2518
|
+
),
|
|
2519
|
+
);
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
// Loaded prompts
|
|
2523
|
+
const promptsResult = loadSync<Prompt>(promptCapability.id, { cwd: process.cwd() });
|
|
2524
|
+
if (promptsResult.items.length > 0) {
|
|
2525
|
+
sections.push(
|
|
2526
|
+
formatSection(
|
|
2527
|
+
"Prompts",
|
|
2528
|
+
promptsResult.items,
|
|
2529
|
+
(p) => p.name,
|
|
2530
|
+
() => undefined,
|
|
2531
|
+
(p) => ({ provider: p._source.providerName, level: p._source.level }),
|
|
2532
|
+
),
|
|
2533
|
+
);
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// Loaded instructions
|
|
2537
|
+
const instructionsResult = loadSync<Instruction>(instructionCapability.id, { cwd: process.cwd() });
|
|
2538
|
+
if (instructionsResult.items.length > 0) {
|
|
2539
|
+
sections.push(
|
|
2540
|
+
formatSection(
|
|
2541
|
+
"Instructions",
|
|
2542
|
+
instructionsResult.items,
|
|
2543
|
+
(i) => i.name,
|
|
2544
|
+
(i) => (i.applyTo ? `applies to: ${i.applyTo}` : undefined),
|
|
2545
|
+
(i) => ({ provider: i._source.providerName, level: i._source.level }),
|
|
2546
|
+
),
|
|
2547
|
+
);
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
// Loaded custom tools - split MCP from non-MCP
|
|
2403
2551
|
if (this.customTools.size > 0) {
|
|
2552
|
+
const allTools = Array.from(this.customTools.values());
|
|
2553
|
+
const mcpTools = allTools.filter((ct) => ct.path.startsWith("mcp:"));
|
|
2554
|
+
const customTools = allTools.filter((ct) => !ct.path.startsWith("mcp:"));
|
|
2555
|
+
|
|
2556
|
+
// MCP Tools section
|
|
2557
|
+
if (mcpTools.length > 0) {
|
|
2558
|
+
sections.push(
|
|
2559
|
+
formatSection(
|
|
2560
|
+
"MCP Tools",
|
|
2561
|
+
mcpTools,
|
|
2562
|
+
(ct) => ct.tool.label || ct.tool.name,
|
|
2563
|
+
() => undefined,
|
|
2564
|
+
(ct) => {
|
|
2565
|
+
const match = ct.path.match(/^mcp:(.+?) via (.+)$/);
|
|
2566
|
+
if (match) {
|
|
2567
|
+
const [, serverName, providerName] = match;
|
|
2568
|
+
return { mcpServer: serverName, provider: providerName };
|
|
2569
|
+
}
|
|
2570
|
+
return ct.path.startsWith("mcp:") ? { mcpServer: ct.path.slice(4) } : "unknown";
|
|
2571
|
+
},
|
|
2572
|
+
),
|
|
2573
|
+
);
|
|
2574
|
+
}
|
|
2575
|
+
|
|
2576
|
+
// Custom Tools section
|
|
2577
|
+
if (customTools.length > 0) {
|
|
2578
|
+
sections.push(
|
|
2579
|
+
formatSection(
|
|
2580
|
+
"Custom Tools",
|
|
2581
|
+
customTools,
|
|
2582
|
+
(ct) => ct.tool.label || ct.tool.name,
|
|
2583
|
+
(ct) => ct.tool.description,
|
|
2584
|
+
(ct) => {
|
|
2585
|
+
if (ct.source?.provider === "builtin") return "builtin";
|
|
2586
|
+
if (ct.path === "<exa>") return "builtin";
|
|
2587
|
+
return ct.source ? { provider: ct.source.providerName, level: ct.source.level } : "unknown";
|
|
2588
|
+
},
|
|
2589
|
+
),
|
|
2590
|
+
);
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2594
|
+
// Loaded slash commands (file-based)
|
|
2595
|
+
const fileCommands = this.session.fileCommands;
|
|
2596
|
+
if (fileCommands.length > 0) {
|
|
2404
2597
|
sections.push(
|
|
2405
|
-
|
|
2406
|
-
"
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2598
|
+
formatSection(
|
|
2599
|
+
"Slash Commands",
|
|
2600
|
+
fileCommands,
|
|
2601
|
+
(cmd) => `/${cmd.name}`,
|
|
2602
|
+
(cmd) => cmd.description,
|
|
2603
|
+
(cmd) => (cmd._source ? { provider: cmd._source.providerName, level: cmd._source.level } : "unknown"),
|
|
2604
|
+
),
|
|
2410
2605
|
);
|
|
2411
2606
|
}
|
|
2412
2607
|
|
|
@@ -2416,7 +2611,7 @@ export class InteractiveMode {
|
|
|
2416
2611
|
const hookPaths = hookRunner.getHookPaths();
|
|
2417
2612
|
if (hookPaths.length > 0) {
|
|
2418
2613
|
sections.push(
|
|
2419
|
-
`${theme.bold(theme.fg("accent", "Hooks"))}\n${hookPaths.map((p) => theme.fg("dim",
|
|
2614
|
+
`${theme.bold(theme.fg("accent", "Hooks"))}\n${hookPaths.map((p) => ` ${theme.bold(basename(p))} ${theme.fg("dim", "hook")}`).join("\n")}`,
|
|
2420
2615
|
);
|
|
2421
2616
|
}
|
|
2422
2617
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"title": "Pi Coding Agent Theme",
|
|
4
|
-
"description": "Theme schema for
|
|
4
|
+
"description": "Theme schema for OMP coding agent",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"required": ["name", "colors"],
|
|
7
7
|
"properties": {
|
package/src/utils/clipboard.ts
CHANGED
|
@@ -199,7 +199,7 @@ async function readImageMacOS(timeout: number): Promise<ClipboardImage | null> {
|
|
|
199
199
|
|
|
200
200
|
// Read the actual image data using a temp file approach
|
|
201
201
|
// osascript can't output binary directly, so we write to a temp file
|
|
202
|
-
const tempFile = `/tmp/
|
|
202
|
+
const tempFile = `/tmp/omp-clipboard-${Date.now()}.${imageType === "png" ? "png" : "jpg"}`;
|
|
203
203
|
const clipboardClass = imageType === "png" ? "«class PNGf»" : "«class JPEG»";
|
|
204
204
|
|
|
205
205
|
const readScript = `
|
|
@@ -77,7 +77,7 @@ SNAPSHOT_FILE='${escapedPath}'
|
|
|
77
77
|
${hasRcFile ? `source "${rcFile}" < /dev/null 2>/dev/null` : "# No user config file to source"}
|
|
78
78
|
|
|
79
79
|
# Create/clear the snapshot file
|
|
80
|
-
echo "# Shell snapshot - generated by
|
|
80
|
+
echo "# Shell snapshot - generated by omp agent" >| "$SNAPSHOT_FILE"
|
|
81
81
|
|
|
82
82
|
# Unalias everything first to avoid conflicts when sourced
|
|
83
83
|
echo "unalias -a 2>/dev/null || true" >> "$SNAPSHOT_FILE"
|
|
@@ -127,7 +127,7 @@ export async function getOrCreateSnapshot(
|
|
|
127
127
|
const rcFile = getShellConfigFile(shell);
|
|
128
128
|
|
|
129
129
|
// Create snapshot directory
|
|
130
|
-
const snapshotDir = join(tmpdir(), "
|
|
130
|
+
const snapshotDir = join(tmpdir(), "omp-shell-snapshots");
|
|
131
131
|
try {
|
|
132
132
|
mkdirSync(snapshotDir, { recursive: true });
|
|
133
133
|
} catch {
|
package/src/utils/shell.ts
CHANGED
|
@@ -26,13 +26,13 @@ function isExecutable(path: string): boolean {
|
|
|
26
26
|
* Build the spawn environment (cached).
|
|
27
27
|
*/
|
|
28
28
|
function buildSpawnEnv(shell: string): Record<string, string | undefined> {
|
|
29
|
-
const noCI = process.env.
|
|
29
|
+
const noCI = process.env.OMP_BASH_NO_CI || process.env.CLAUDE_BASH_NO_CI;
|
|
30
30
|
return {
|
|
31
31
|
...process.env,
|
|
32
32
|
SHELL: shell,
|
|
33
33
|
GIT_EDITOR: "true",
|
|
34
34
|
GPG_TTY: "not a tty",
|
|
35
|
-
|
|
35
|
+
OMPCODE: "1",
|
|
36
36
|
CLAUDECODE: "1",
|
|
37
37
|
...(noCI ? {} : { CI: "true" }),
|
|
38
38
|
};
|
|
@@ -40,10 +40,10 @@ function buildSpawnEnv(shell: string): Record<string, string | undefined> {
|
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* Get shell args, optionally including login shell flag.
|
|
43
|
-
* Supports
|
|
43
|
+
* Supports OMP_BASH_NO_LOGIN and CLAUDE_BASH_NO_LOGIN to skip -l.
|
|
44
44
|
*/
|
|
45
45
|
function getShellArgs(): string[] {
|
|
46
|
-
const noLogin = process.env.
|
|
46
|
+
const noLogin = process.env.OMP_BASH_NO_LOGIN || process.env.CLAUDE_BASH_NO_LOGIN;
|
|
47
47
|
return noLogin ? ["-c"] : ["-l", "-c"];
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -51,7 +51,7 @@ function getShellArgs(): string[] {
|
|
|
51
51
|
* Get shell prefix for wrapping commands (profilers, strace, etc.).
|
|
52
52
|
*/
|
|
53
53
|
function getShellPrefix(): string | undefined {
|
|
54
|
-
return process.env.
|
|
54
|
+
return process.env.OMP_SHELL_PREFIX || process.env.CLAUDE_CODE_SHELL_PREFIX;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/**
|
|
@@ -107,7 +107,7 @@ export function getShellConfig(): ShellConfig {
|
|
|
107
107
|
return cachedShellConfig;
|
|
108
108
|
}
|
|
109
109
|
throw new Error(
|
|
110
|
-
`Custom shell path not found: ${customShellPath}\nPlease update shellPath in ~/.
|
|
110
|
+
`Custom shell path not found: ${customShellPath}\nPlease update shellPath in ~/.omp/agent/settings.json`,
|
|
111
111
|
);
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -141,7 +141,7 @@ export function getShellConfig(): ShellConfig {
|
|
|
141
141
|
`No bash shell found. Options:\n` +
|
|
142
142
|
` 1. Install Git for Windows: https://git-scm.com/download/win\n` +
|
|
143
143
|
` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\n` +
|
|
144
|
-
` 3. Set shellPath in ~/.
|
|
144
|
+
` 3. Set shellPath in ~/.omp/agent/settings.json\n\n` +
|
|
145
145
|
`Searched Git Bash in:\n${paths.map((p) => ` ${p}`).join("\n")}`,
|
|
146
146
|
);
|
|
147
147
|
}
|