@oh-my-pi/pi-coding-agent 13.11.1 → 13.12.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 +95 -0
- package/package.json +7 -7
- package/src/capability/context-file.ts +2 -0
- package/src/capability/extension-module.ts +1 -0
- package/src/capability/hook.ts +1 -0
- package/src/capability/index.ts +21 -10
- package/src/capability/instruction.ts +1 -0
- package/src/capability/mcp.ts +1 -0
- package/src/capability/prompt.ts +1 -0
- package/src/capability/rule.ts +5 -0
- package/src/capability/skill.ts +1 -0
- package/src/capability/slash-command.ts +1 -0
- package/src/capability/tool.ts +1 -0
- package/src/capability/types.ts +10 -0
- package/src/cli/commands/init-xdg.ts +27 -0
- package/src/cli/config-cli.ts +8 -3
- package/src/cli/shell-cli.ts +1 -1
- package/src/commands/config.ts +1 -1
- package/src/config/model-registry.ts +63 -10
- package/src/config/model-resolver.ts +84 -21
- package/src/config/settings-schema.ts +977 -769
- package/src/discovery/helpers.ts +8 -2
- package/src/exec/bash-executor.ts +62 -25
- package/src/extensibility/custom-tools/types.ts +2 -3
- package/src/extensibility/extensions/loader.ts +5 -1
- package/src/extensibility/extensions/types.ts +2 -0
- package/src/extensibility/hooks/types.ts +2 -0
- package/src/extensibility/plugins/loader.ts +23 -5
- package/src/extensibility/plugins/manager.ts +14 -0
- package/src/extensibility/plugins/types.ts +4 -0
- package/src/extensibility/skills.ts +7 -1
- package/src/index.ts +6 -6
- package/src/internal-urls/docs-index.generated.ts +2 -2
- package/src/ipy/kernel.ts +4 -5
- package/src/memories/index.ts +20 -7
- package/src/memories/storage.ts +46 -32
- package/src/modes/components/agent-dashboard.ts +23 -35
- package/src/modes/components/assistant-message.ts +25 -2
- package/src/modes/components/btw-panel.ts +104 -0
- package/src/modes/components/diff.ts +2 -7
- package/src/modes/components/extensions/state-manager.ts +3 -2
- package/src/modes/components/settings-defs.ts +56 -6
- package/src/modes/components/settings-selector.ts +11 -6
- package/src/modes/controllers/btw-controller.ts +193 -0
- package/src/modes/controllers/command-controller.ts +9 -3
- package/src/modes/controllers/event-controller.ts +4 -0
- package/src/modes/controllers/input-controller.ts +10 -1
- package/src/modes/interactive-mode.ts +22 -0
- package/src/modes/prompt-action-autocomplete.ts +17 -3
- package/src/modes/rpc/rpc-client.ts +30 -19
- package/src/modes/theme/theme.ts +28 -36
- package/src/modes/types.ts +4 -0
- package/src/modes/utils/ui-helpers.ts +3 -0
- package/src/patch/diff.ts +9 -1
- package/src/patch/index.ts +56 -9
- package/src/prompts/system/btw-user.md +8 -0
- package/src/prompts/system/custom-system-prompt.md +1 -1
- package/src/prompts/system/system-prompt.md +1 -0
- package/src/sdk.ts +23 -26
- package/src/session/agent-session.ts +65 -37
- package/src/session/blob-store.ts +32 -0
- package/src/session/compaction/compaction.ts +37 -6
- package/src/session/history-storage.ts +2 -2
- package/src/session/session-manager.ts +129 -49
- package/src/slash-commands/builtin-registry.ts +11 -0
- package/src/system-prompt.ts +4 -17
- package/src/task/agents.ts +1 -1
- package/src/task/index.ts +9 -8
- package/src/tools/browser.ts +11 -0
- package/src/tools/output-meta.ts +103 -3
- package/src/tools/path-utils.ts +11 -0
- package/src/utils/title-generator.ts +70 -92
- package/src/utils/tools-manager.ts +1 -1
- package/src/web/scrapers/index.ts +7 -7
- package/src/web/scrapers/utils.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,100 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [13.12.2] - 2026-03-15
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `compaction.thresholdTokens` setting as a fixed token limit alternative to percentage-based compaction threshold
|
|
10
|
+
- Added more artifact spill threshold options (1 KB to 1 MB) with size descriptions
|
|
11
|
+
- Added more artifact tail bytes and tail lines options with descriptions
|
|
12
|
+
- Added `toExtensionId` capability method to enable granular disabling of individual capabilities by ID
|
|
13
|
+
- Added support for disabling specific capabilities (skills, tools, hooks, rules, prompts, instructions, slash commands, MCP servers, extension modules, and context files) via `disabledExtensions` setting
|
|
14
|
+
- Added `includeDisabled` and `disabledExtensions` options to `LoadOptions` for capability loading
|
|
15
|
+
- Added plugin manifest support for `extensions` entry points to allow plugins to contribute extension modules
|
|
16
|
+
- Added `extensions` field to plugin features for feature-specific extension entry points
|
|
17
|
+
- Added automatic discovery of extension modules from installed plugins during extension loading
|
|
18
|
+
- Added `disabledExtensions` setting to allow disabling specific extensions and skills by ID
|
|
19
|
+
- Added support for filtering skills by disabled extension IDs with `skill:` prefix
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Changed capability loading to filter out disabled items based on extension IDs before returning results
|
|
24
|
+
- Changed plugin loader to support `extensions` as a manifest entry type alongside tools, hooks, and commands
|
|
25
|
+
- Changed extension discovery to include extension entry points from all enabled plugins
|
|
26
|
+
- Changed context file path handling to use `path.basename()` for consistent cross-platform filename extraction
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Fixed skill loading to properly respect disabled skill names when loading from custom directories
|
|
31
|
+
|
|
32
|
+
## [13.12.1] - 2026-03-15
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- Support for move-only operations that preserve exact bytes including binary files
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- Fixed handling of file moves when no edits are specified, now correctly preserves binary content
|
|
40
|
+
- Fixed validation to reject move operations where source and destination paths are identical
|
|
41
|
+
|
|
42
|
+
## [13.12.0] - 2026-03-14
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- Added per-rule TTSR interrupt mode override via `interruptMode` field in rule frontmatter to allow fine-grained control over when TTSR interrupts stream processing
|
|
47
|
+
- Added `task` model role to allow configuring a dedicated model for subtask execution via `modelRoles.task` setting
|
|
48
|
+
- Added `moveCursorToMessageEnd` and `moveCursorToMessageStart` prompt actions to navigate to the beginning and end of the entire message
|
|
49
|
+
- Added support for provider-level `compat` configuration to apply OpenAI compatibility settings across all models from a provider
|
|
50
|
+
- Added `reasoningEffortMap` configuration option to map reasoning effort levels to provider-specific values
|
|
51
|
+
- Added support for `supportsUsageInStreaming`, `requiresToolResultName`, `requiresAssistantAfterToolResult`, `requiresThinkingAsText`, `thinkingFormat`, and `supportsStrictMode` OpenAI compatibility options
|
|
52
|
+
- Added support for provider-configurable `OpenAICompat.extraBody` to inject request-body fields for custom gateway/proxy routing
|
|
53
|
+
- Added `close()` method to SessionManager for properly closing persistent writers after flushing pending data
|
|
54
|
+
- Added `omp config init-xdg` command to initialize XDG Base Directory structure on Linux
|
|
55
|
+
- Added `getHistoryDbPath()`, `getModelDbPath()`, `getMemoriesDir()`, `getTerminalSessionsDir()` path helpers
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
- Path resolution on Linux redirects to XDG locations when `XDG_DATA_HOME` / `XDG_STATE_HOME` / `XDG_CACHE_HOME` environment variables are set
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- Changed TTSR interrupt logic to respect per-rule `interruptMode` settings, falling back to global `ttsr.interruptMode` when rule-level override is not specified
|
|
64
|
+
- Reorganized settings tabs from 12 tabs (display, agent, input, tools, config, services, bash, lsp, ttsr, status) to 8 focused tabs (appearance, model, interaction, context, editing, tools, tasks, providers) for improved discoverability
|
|
65
|
+
- Consolidated status line settings into the Appearance tab instead of a separate Status tab
|
|
66
|
+
- Reorganized sampling parameters (temperature, topP, topK, minP, presencePenalty, repetitionPenalty) into the Model tab
|
|
67
|
+
- Moved edit tool settings (mode, fuzzyMatch, fuzzyThreshold, streamingAbort) to the Editing tab
|
|
68
|
+
- Moved read tool settings (readLineNumbers, readHashLines, read.defaultLimit) to the Editing tab
|
|
69
|
+
- Moved LSP settings (lsp.enabled, lsp.formatOnWrite, lsp.diagnosticsOnWrite, lsp.diagnosticsOnEdit) to the Editing tab
|
|
70
|
+
- Moved bash interceptor settings to the Editing tab
|
|
71
|
+
- Moved Python settings (python.toolMode, python.kernelMode, python.sharedGateway) to the Editing tab
|
|
72
|
+
- Moved task delegation settings (task.isolation.*, task.eager, task.maxConcurrency, task.maxRecursionDepth) to the Tasks tab
|
|
73
|
+
- Moved skill and command settings to the Tasks tab
|
|
74
|
+
- Moved provider selection settings (providers.webSearch, providers.codeSearch, providers.image, etc.) to the Providers tab
|
|
75
|
+
- Moved Exa settings to the Providers tab
|
|
76
|
+
- Moved secret handling settings to the Providers tab
|
|
77
|
+
- Moved speech-to-text settings to the Interaction tab
|
|
78
|
+
- Moved context promotion, compaction, branch summary, memories, and TTSR settings to the Context tab
|
|
79
|
+
- Updated tab icon symbols across unicode, nerd, and ASCII presets to match new tab structure
|
|
80
|
+
- Changed default agent model from `default` to `pi/task` to enable independent model configuration for subtasks
|
|
81
|
+
- Changed agent model resolution to support single-pattern inheritance fallback, allowing `pi/task` agents to inherit the active session model when the task role is unconfigured
|
|
82
|
+
- Changed system prompt to use ISO 8601 date format (YYYY-MM-DD) instead of locale-specific formatting
|
|
83
|
+
- Changed system prompt template to use `{{date}}` instead of `{{dateTime}}` for current date display
|
|
84
|
+
- Changed tool download timeout from 15 seconds to 120 seconds to accommodate slower network conditions
|
|
85
|
+
- Changed working directory paths in system prompt to use forward slashes for consistency across platforms
|
|
86
|
+
- Modified bash executor to fall back to one-shot shell execution after a persistent session hard timeout, preventing subsequent commands from hanging
|
|
87
|
+
|
|
88
|
+
### Removed
|
|
89
|
+
|
|
90
|
+
- Removed bash executor hard timeout recovery test file (functionality already documented in existing entries)
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
|
|
94
|
+
- Fixed bash execution to fall back to one-shot shell runs after a persistent session hard timeout, preventing later commands from hanging until restart
|
|
95
|
+
- Fixed timeout handling in RpcClient to properly clear timeouts and prevent resource leaks
|
|
96
|
+
- Fixed AgentSession disposal to call SessionManager's `close()` method when available, ensuring proper cleanup of persistent writers
|
|
97
|
+
- Removed redundant `path.join()` call wrapping `getHistoryDbPath()` in history-storage.ts
|
|
98
|
+
|
|
5
99
|
## [13.11.1] - 2026-03-13
|
|
6
100
|
|
|
7
101
|
### Added
|
|
@@ -46,6 +140,7 @@
|
|
|
46
140
|
- Added `buildNamedToolChoice` utility function to build provider-aware tool choice constraints for named tools
|
|
47
141
|
- Support for comma/space-separated path lists in `find`, `grep`, `ast_grep`, and `ast_edit` tools (e.g., `apps/,packages/,phases/` or `apps/ packages/ phases/`)
|
|
48
142
|
- New `resolveMultiSearchPath` and `resolveMultiFindPattern` functions to handle multi-path search inputs with automatic common base path detection
|
|
143
|
+
- Added `display.showTokenUsage` setting to show per-turn token usage (input, output, cache) on assistant messages
|
|
49
144
|
|
|
50
145
|
### Changed
|
|
51
146
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "13.
|
|
4
|
+
"version": "13.12.3",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@mozilla/readability": "^0.6",
|
|
44
|
-
"@oh-my-pi/omp-stats": "13.
|
|
45
|
-
"@oh-my-pi/pi-agent-core": "13.
|
|
46
|
-
"@oh-my-pi/pi-ai": "13.
|
|
47
|
-
"@oh-my-pi/pi-natives": "13.
|
|
48
|
-
"@oh-my-pi/pi-tui": "13.
|
|
49
|
-
"@oh-my-pi/pi-utils": "13.
|
|
44
|
+
"@oh-my-pi/omp-stats": "13.12.3",
|
|
45
|
+
"@oh-my-pi/pi-agent-core": "13.12.3",
|
|
46
|
+
"@oh-my-pi/pi-ai": "13.12.3",
|
|
47
|
+
"@oh-my-pi/pi-natives": "13.12.3",
|
|
48
|
+
"@oh-my-pi/pi-tui": "13.12.3",
|
|
49
|
+
"@oh-my-pi/pi-utils": "13.12.3",
|
|
50
50
|
"@sinclair/typebox": "^0.34",
|
|
51
51
|
"@xterm/headless": "^6.0",
|
|
52
52
|
"ajv": "^8.18",
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* System instruction files (CLAUDE.md, AGENTS.md, GEMINI.md, etc.) that provide
|
|
5
5
|
* persistent guidance to the agent.
|
|
6
6
|
*/
|
|
7
|
+
import * as path from "node:path";
|
|
7
8
|
import { defineCapability } from ".";
|
|
8
9
|
import type { SourceMeta } from "./types";
|
|
9
10
|
|
|
@@ -33,6 +34,7 @@ export const contextFileCapability = defineCapability<ContextFile>({
|
|
|
33
34
|
// Clamp depth >= 0: files inside config subdirectories of an ancestor (e.g. .claude/, .github/)
|
|
34
35
|
// are same-scope as the ancestor itself.
|
|
35
36
|
key: file => (file.level === "user" ? "user" : `project:${Math.max(0, file.depth ?? 0)}`),
|
|
37
|
+
toExtensionId: file => `context-file:${file.level}:${path.basename(file.path)}`,
|
|
36
38
|
validate: file => {
|
|
37
39
|
if (!file.path) return "Missing path";
|
|
38
40
|
if (file.content === undefined) return "Missing content";
|
|
@@ -25,6 +25,7 @@ export const extensionModuleCapability = defineCapability<ExtensionModule>({
|
|
|
25
25
|
displayName: "Extension Modules",
|
|
26
26
|
description: "TypeScript/JavaScript extension modules loaded by the extension system",
|
|
27
27
|
key: ext => ext.name,
|
|
28
|
+
toExtensionId: ext => `extension-module:${ext.name}`,
|
|
28
29
|
validate: ext => {
|
|
29
30
|
if (!ext.name) return "Missing name";
|
|
30
31
|
if (!ext.path) return "Missing path";
|
package/src/capability/hook.ts
CHANGED
|
@@ -29,6 +29,7 @@ export const hookCapability = defineCapability<Hook>({
|
|
|
29
29
|
displayName: "Hooks",
|
|
30
30
|
description: "Pre/post tool execution hooks",
|
|
31
31
|
key: hook => `${hook.type}:${hook.tool}:${hook.name}`,
|
|
32
|
+
toExtensionId: hook => `hook:${hook.type}:${hook.tool}:${hook.name}`,
|
|
32
33
|
validate: hook => {
|
|
33
34
|
if (!hook.name) return "Missing name";
|
|
34
35
|
if (!hook.path) return "Missing path";
|
package/src/capability/index.ts
CHANGED
|
@@ -107,6 +107,9 @@ async function loadImpl<T>(
|
|
|
107
107
|
const allItems: Array<T & { _source: SourceMeta; _shadowed?: boolean }> = [];
|
|
108
108
|
const allWarnings: string[] = [];
|
|
109
109
|
const contributingProviders: string[] = [];
|
|
110
|
+
const disabledExtensionIds = options.includeDisabled
|
|
111
|
+
? new Set<string>()
|
|
112
|
+
: new Set<string>(options.disabledExtensions ?? settings?.get("disabledExtensions") ?? []);
|
|
110
113
|
|
|
111
114
|
const results = await Promise.all(
|
|
112
115
|
providers.map(async provider => {
|
|
@@ -136,18 +139,26 @@ async function loadImpl<T>(
|
|
|
136
139
|
allWarnings.push(...result.warnings.map(w => `[${provider.displayName}] ${w}`));
|
|
137
140
|
}
|
|
138
141
|
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
let contributedItemCount = 0;
|
|
143
|
+
for (const item of result.items) {
|
|
144
|
+
const itemWithSource = item as T & { _source: SourceMeta };
|
|
145
|
+
if (!itemWithSource._source) {
|
|
146
|
+
allWarnings.push(`[${provider.displayName}] Item missing _source metadata, skipping`);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
141
149
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
itemWithSource._source.providerName = provider.displayName;
|
|
146
|
-
allItems.push(itemWithSource as T & { _source: SourceMeta; _shadowed?: boolean });
|
|
147
|
-
} else {
|
|
148
|
-
allWarnings.push(`[${provider.displayName}] Item missing _source metadata, skipping`);
|
|
149
|
-
}
|
|
150
|
+
const extensionId = capability.toExtensionId?.(itemWithSource);
|
|
151
|
+
if (extensionId && disabledExtensionIds.has(extensionId)) {
|
|
152
|
+
continue;
|
|
150
153
|
}
|
|
154
|
+
|
|
155
|
+
itemWithSource._source.providerName = provider.displayName;
|
|
156
|
+
allItems.push(itemWithSource as T & { _source: SourceMeta; _shadowed?: boolean });
|
|
157
|
+
contributedItemCount += 1;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (contributedItemCount > 0) {
|
|
161
|
+
contributingProviders.push(provider.id);
|
|
151
162
|
}
|
|
152
163
|
}
|
|
153
164
|
|
|
@@ -27,6 +27,7 @@ export const instructionCapability = defineCapability<Instruction>({
|
|
|
27
27
|
displayName: "Instructions",
|
|
28
28
|
description: "File-specific instructions with glob pattern matching (GitHub Copilot format)",
|
|
29
29
|
key: inst => inst.name,
|
|
30
|
+
toExtensionId: inst => `instruction:${inst.name}`,
|
|
30
31
|
validate: inst => {
|
|
31
32
|
if (!inst.name) return "Missing name";
|
|
32
33
|
if (!inst.path) return "Missing path";
|
package/src/capability/mcp.ts
CHANGED
|
@@ -48,6 +48,7 @@ export const mcpCapability = defineCapability<MCPServer>({
|
|
|
48
48
|
displayName: "MCP Servers",
|
|
49
49
|
description: "Model Context Protocol server configurations for external tool integrations",
|
|
50
50
|
key: server => server.name,
|
|
51
|
+
toExtensionId: server => `mcp:${server.name}`,
|
|
51
52
|
validate: server => {
|
|
52
53
|
if (!server.name) return "Missing server name";
|
|
53
54
|
if (!server.command && !server.url) return "Must have command or url";
|
package/src/capability/prompt.ts
CHANGED
|
@@ -25,6 +25,7 @@ export const promptCapability = defineCapability<Prompt>({
|
|
|
25
25
|
displayName: "Prompts",
|
|
26
26
|
description: "Reusable prompt templates available via /prompts: menu",
|
|
27
27
|
key: prompt => prompt.name,
|
|
28
|
+
toExtensionId: prompt => `prompt:${prompt.name}`,
|
|
28
29
|
validate: prompt => {
|
|
29
30
|
if (!prompt.name) return "Missing name";
|
|
30
31
|
if (!prompt.path) return "Missing path";
|
package/src/capability/rule.ts
CHANGED
|
@@ -20,6 +20,8 @@ export interface RuleFrontmatter {
|
|
|
20
20
|
condition?: string | string[];
|
|
21
21
|
/** New key for TTSR stream scope. */
|
|
22
22
|
scope?: string | string[];
|
|
23
|
+
/** Per-rule TTSR interrupt mode override. */
|
|
24
|
+
interruptMode?: "never" | "prose-only" | "tool-only" | "always";
|
|
23
25
|
[key: string]: unknown;
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -43,6 +45,8 @@ export interface Rule {
|
|
|
43
45
|
condition?: string[];
|
|
44
46
|
/** Optional stream scope tokens (for example: text, thinking, tool:edit(*.ts)). */
|
|
45
47
|
scope?: string[];
|
|
48
|
+
/** Per-rule TTSR interrupt mode override (falls back to global ttsr.interruptMode). */
|
|
49
|
+
interruptMode?: "never" | "prose-only" | "tool-only" | "always";
|
|
46
50
|
/** Source metadata */
|
|
47
51
|
_source: SourceMeta;
|
|
48
52
|
}
|
|
@@ -210,6 +214,7 @@ export const ruleCapability = defineCapability<Rule>({
|
|
|
210
214
|
displayName: "Rules",
|
|
211
215
|
description: "Project-specific rules and constraints (Cursor MDC, Windsurf, Cline formats)",
|
|
212
216
|
key: rule => rule.name,
|
|
217
|
+
toExtensionId: rule => `rule:${rule.name}`,
|
|
213
218
|
validate: rule => {
|
|
214
219
|
if (!rule.name) return "Missing rule name";
|
|
215
220
|
if (!rule.path) return "Missing rule path";
|
package/src/capability/skill.ts
CHANGED
|
@@ -40,6 +40,7 @@ export const skillCapability = defineCapability<Skill>({
|
|
|
40
40
|
displayName: "Skills",
|
|
41
41
|
description: "Specialized knowledge and workflow files that extend agent capabilities",
|
|
42
42
|
key: skill => skill.name,
|
|
43
|
+
toExtensionId: skill => `skill:${skill.name}`,
|
|
43
44
|
validate: skill => {
|
|
44
45
|
if (!skill.name) return "Missing skill name";
|
|
45
46
|
if (!skill.path) return "Missing skill path";
|
|
@@ -27,6 +27,7 @@ export const slashCommandCapability = defineCapability<SlashCommand>({
|
|
|
27
27
|
displayName: "Slash Commands",
|
|
28
28
|
description: "Custom slash commands defined as markdown files",
|
|
29
29
|
key: cmd => cmd.name,
|
|
30
|
+
toExtensionId: cmd => `slash-command:${cmd.name}`,
|
|
30
31
|
validate: cmd => {
|
|
31
32
|
if (!cmd.name) return "Missing name";
|
|
32
33
|
if (!cmd.path) return "Missing path";
|
package/src/capability/tool.ts
CHANGED
|
@@ -29,6 +29,7 @@ export const toolCapability = defineCapability<CustomTool>({
|
|
|
29
29
|
displayName: "Custom Tools",
|
|
30
30
|
description: "User-defined tools that extend agent capabilities",
|
|
31
31
|
key: tool => tool.name,
|
|
32
|
+
toExtensionId: tool => `tool:${tool.name}`,
|
|
32
33
|
validate: tool => {
|
|
33
34
|
if (!tool.name) return "Missing name";
|
|
34
35
|
if (!tool.path) return "Missing path";
|
package/src/capability/types.ts
CHANGED
|
@@ -68,6 +68,10 @@ export interface LoadOptions {
|
|
|
68
68
|
cwd?: string;
|
|
69
69
|
/** Include items even if they fail validation. Default: false */
|
|
70
70
|
includeInvalid?: boolean;
|
|
71
|
+
/** Include items disabled via settings. Default: false */
|
|
72
|
+
includeDisabled?: boolean;
|
|
73
|
+
/** Explicit disabled extension IDs to apply instead of settings. */
|
|
74
|
+
disabledExtensions?: string[];
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
/**
|
|
@@ -123,6 +127,12 @@ export interface Capability<T> {
|
|
|
123
127
|
*/
|
|
124
128
|
validate?(item: T): string | undefined;
|
|
125
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Optional disabledExtensions ID for this item.
|
|
132
|
+
* When present, loadCapability() can hide items disabled via settings.
|
|
133
|
+
*/
|
|
134
|
+
toExtensionId?(item: T): string | undefined;
|
|
135
|
+
|
|
126
136
|
/** Registered providers, sorted by priority (highest first) */
|
|
127
137
|
providers: Provider<T>[];
|
|
128
138
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
|
|
5
|
+
const APP_NAME = "omp";
|
|
6
|
+
|
|
7
|
+
export async function initXdg(): Promise<void> {
|
|
8
|
+
if (process.platform !== "linux" && process.platform !== "darwin") {
|
|
9
|
+
console.error("XDG directory setup is only supported on Linux and macOS.");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const dataHome = process.env.XDG_DATA_HOME || path.join(os.homedir(), ".local/share");
|
|
14
|
+
const stateHome = process.env.XDG_STATE_HOME || path.join(os.homedir(), ".local/state");
|
|
15
|
+
const cacheHome = process.env.XDG_CACHE_HOME || path.join(os.homedir(), ".cache");
|
|
16
|
+
|
|
17
|
+
const dirs = [path.join(dataHome, APP_NAME), path.join(stateHome, APP_NAME), path.join(cacheHome, APP_NAME)];
|
|
18
|
+
|
|
19
|
+
for (const dir of dirs) {
|
|
20
|
+
await fs.mkdir(dir, { recursive: true });
|
|
21
|
+
console.log(`Created ${dir.replace(os.homedir(), "~")}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log("\nXDG directories initialized.");
|
|
25
|
+
console.log("Ensure XDG_DATA_HOME, XDG_STATE_HOME, and XDG_CACHE_HOME");
|
|
26
|
+
console.log("are set in your shell profile for omp to use them.");
|
|
27
|
+
}
|
package/src/cli/config-cli.ts
CHANGED
|
@@ -19,12 +19,13 @@ import {
|
|
|
19
19
|
} from "../config/settings";
|
|
20
20
|
import { SETTINGS_SCHEMA } from "../config/settings-schema";
|
|
21
21
|
import { theme } from "../modes/theme/theme";
|
|
22
|
+
import { initXdg } from "./commands/init-xdg";
|
|
22
23
|
|
|
23
24
|
// =============================================================================
|
|
24
25
|
// Types
|
|
25
26
|
// =============================================================================
|
|
26
27
|
|
|
27
|
-
export type ConfigAction = "list" | "get" | "set" | "reset" | "path";
|
|
28
|
+
export type ConfigAction = "list" | "get" | "set" | "reset" | "path" | "init-xdg";
|
|
28
29
|
|
|
29
30
|
export interface ConfigCommandArgs {
|
|
30
31
|
action: ConfigAction;
|
|
@@ -34,7 +35,6 @@ export interface ConfigCommandArgs {
|
|
|
34
35
|
json?: boolean;
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
|
-
|
|
38
38
|
// =============================================================================
|
|
39
39
|
// Setting Filtering
|
|
40
40
|
// =============================================================================
|
|
@@ -73,7 +73,7 @@ function getSettingValues(def: CliSettingDef): readonly string[] | undefined {
|
|
|
73
73
|
// Argument Parser
|
|
74
74
|
// =============================================================================
|
|
75
75
|
|
|
76
|
-
const VALID_ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path"];
|
|
76
|
+
const VALID_ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path", "init-xdg"];
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
79
|
* Parse config subcommand arguments.
|
|
@@ -251,6 +251,9 @@ export async function runConfigCommand(cmd: ConfigCommandArgs): Promise<void> {
|
|
|
251
251
|
case "path":
|
|
252
252
|
handlePath();
|
|
253
253
|
break;
|
|
254
|
+
case "init-xdg":
|
|
255
|
+
await initXdg();
|
|
256
|
+
break;
|
|
254
257
|
}
|
|
255
258
|
}
|
|
256
259
|
|
|
@@ -394,6 +397,7 @@ ${chalk.bold("Commands:")}
|
|
|
394
397
|
set <key> <value> Set a setting value
|
|
395
398
|
reset <key> Reset a setting to its default value
|
|
396
399
|
path Print the config directory path
|
|
400
|
+
init-xdg Initialize XDG Base Directory structure
|
|
397
401
|
|
|
398
402
|
${chalk.bold("Options:")}
|
|
399
403
|
--json Output as JSON
|
|
@@ -406,6 +410,7 @@ ${chalk.bold("Examples:")}
|
|
|
406
410
|
${APP_NAME} config set defaultThinkingLevel medium
|
|
407
411
|
${APP_NAME} config reset steeringMode
|
|
408
412
|
${APP_NAME} config list --json
|
|
413
|
+
${APP_NAME} config init-xdg
|
|
409
414
|
|
|
410
415
|
${chalk.bold("Boolean Values:")}
|
|
411
416
|
true, false, yes, no, on, off, 1, 0
|
package/src/cli/shell-cli.ts
CHANGED
package/src/commands/config.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Args, Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
|
5
5
|
import { type ConfigAction, type ConfigCommandArgs, runConfigCommand } from "../cli/config-cli";
|
|
6
6
|
import { initTheme } from "../modes/theme/theme";
|
|
7
7
|
|
|
8
|
-
const ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path"];
|
|
8
|
+
const ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path", "init-xdg"];
|
|
9
9
|
|
|
10
10
|
export default class Config extends Command {
|
|
11
11
|
static description = "Manage configuration settings";
|