Commit Graph

36 Commits

Author SHA1 Message Date
can1357 6d07944654 refactor: migrated binary detection to $which() utility across codebase
- Replaced all Bun.which() calls with $which() utility from @oh-my-pi/pi-utils across 22 files.
- Removed findBashOnPath() wrapper function from procmgr.ts, consolidating binary path resolution.
- Updated AGENTS.md documentation to reflect new $which() API usage pattern.
- Centralized binary detection logic through shared utility, reducing code duplication.
2026-04-08 05:28:22 +02:00
can1357 418b6801a0 refactor(coding-agent): migrated git operations to centralized utils module
- Extracted git operations from ControlledGit class into centralized utils/git module with 1276 lines of typed command wrappers.
- Replaced dependency injection of ControlledGit instances with direct cwd string parameters across commit agent tools and workflows.
- Migrated all git command execution from inline shell calls and custom helpers to structured git module API (diff, status, branch, worktree, patch, etc.).
- Removed ControlledGit class, operations.ts, and helper functions (findGitHeadPath, mergeStdoutStderr, joinPatch) now provided by git module.
- Exported git utilities from main package entry point for extension and plugin use.
2026-04-02 07:35:44 +02:00
can1357 5f0944ffe2 feat: added marketplace help command and improved catalog parsing resilience
- Added `/marketplace help` subcommand to display marketplace operations usage guide.
- Enhanced marketplace catalog parsing to skip invalid entries with warnings instead of failing.
- Improved `/marketplace discover` command to suggest official marketplace when no plugins available.
- Fixed marketplace error messages to display error details instead of object stringification.
- Added comprehensive marketplace plugin system documentation covering discovery, installation, and management.
2026-04-01 19:31:48 +02:00
can1357 94edc693cb fix(marketplace): corrected plugin name validation to allow dots
- Corrected plugin name validation regex to allow dots in addition to hyphens.
2026-04-01 19:09:55 +02:00
Miroslav Drbal 5acd56a5e3 fix(coding-agent): only shadow user entry when project install is enabled
listInstalledPlugins() was marking user-scope entries as shadowedBy:
"project" based on plugin ID presence in the project registry alone.
A disabled project copy (enabled: false) is not active in discovery, so
the user copy is the effective install and must not appear shadowed.

activeProjectIds now only includes project plugins where the first entry
does not have enabled: false.
2026-03-31 22:03:03 +02:00
Miroslav Drbal 05966c8910 feat(coding-agent): marketplace plugin project scope
Plugins can now be installed at user scope (global) or project scope
(per-project, higher capability priority). Scope is encoded in registry
file location, not a metadata field:

  user:    ~/.omp/plugins/installed_plugins.json
  project: <nearest-project>/.omp/plugins/installed_plugins.json
  cache:   ~/.omp/plugins/cache/plugins/  (shared, path-referenced)

Project root discovery: resolveActiveProjectRegistryPath(cwd) walks up
from cwd looking for the nearest .omp/ directory, falling back to the
nearest .git root. This is the single resolver used by install, uninstall,
list, upgrade, discovery, and doctor.

Discovery: listClaudePluginRoots(home, cwd?) reads both registries when
cwd is provided. Project entries shadow user entries for the same plugin
ID. Cache key is canonical ("${home}:${resolvedProjectPath}") so nested
cwds within the same project share a cache entry.

Manager changes:
- installPlugin({ scope? }): routes registry reads/writes by scope;
  checks collectReferencedPaths() across both registries before deleting
  any cached plugin dir to prevent cross-scope data loss
- uninstallPlugin(id, scope?), setPluginEnabled(id, enabled, scope?),
  upgradePlugin(id, scope?): throw a disambiguation error when the plugin
  exists in both scopes and no scope is specified
- upgradePluginAcrossScopes(id): new; upgrades all scopes the plugin is
  installed in; returns InstalledPluginEntry[]
- upgradeAllPlugins(): uses upgradePluginAcrossScopes; result includes scope
- listInstalledPlugins(): returns InstalledPluginSummary[] merged from both
  registries; user entries marked shadowedBy: "project" when overridden

CLI: omp plugin install|uninstall|upgrade|enable|disable --scope user|project
Slash: /marketplace install [--scope user|project] name@marketplace
MarketplaceManager constructed with projectInstalledRegistryPath in all
CLI handlers and builtin-registry.ts via resolveActiveProjectRegistryPath.

.gitignore: .omp/plugins/ added (local runtime state, not committed).
preloadPluginRoots/clearClaudePluginRootsCache carry cwd through for LSP.
main.ts passes getProjectDir() at startup.

Tests: 226 pass across 13 files. New: project-scope.test.ts (resolver
walk-up, .git fallback, null return, canonical path, shadow precedence);
manager scope tests (registry isolation, disambiguation errors, cross-scope
cache-ref protection, upgradePluginAcrossScopes, shadowedBy marking).

fixes #581
2026-03-31 17:43:09 +02:00
can1357 d18504d632 fix(coding-agent): corrected marketplace plugin selector error handling and cleanup
- Added error handling for marketplace plugin selector failures with user-facing error messages.
- Fixed marketplace clone promotion timing by extracting logic into separate function and applying consistently across addMarketplace and refreshMarketplace methods.
- Added cleanup of temporary clone directories on source verification failures to prevent orphaned files.
- Improved plugin selector UI rendering by expanding onCancel callback to trigger requestRender after completion.
- Fixed LSP config path handling by replacing hardcoded filename array with variable reference.
- Enhanced error handling for unknown plugin source variants in marketplace validation.
2026-03-30 13:54:31 +02:00
Miroslav Drbal 304158cadb fix: check duplicate marketplace before fetching, reject relative sources for URL marketplaces
- addMarketplace reads registry before fetching; if the fetched catalog
  name collides with an existing entry, cleans up the clone and throws
  before any cache corruption occurs
- installPlugin rejects relative string sources when the marketplace was
  added via URL (only marketplace.json is cached, not the plugin tree)
2026-03-30 13:44:55 +02:00
Miroslav Drbal f65df186b8 fix: refresh slash commands on /reload-plugins, validate string source paths at parse time
- /reload-plugins now calls refreshSlashCommandState() so newly
  installed/removed plugin commands take effect without restart
- parseMarketplaceCatalog rejects string sources that don't start
  with './' at parse time instead of deferring to install-time crash
2026-03-30 13:44:55 +02:00
Miroslav Drbal 9218b1450b fix: guard npm dist-tags in classifier, reject catalog name drift, validate source payloads
- classifyInstallTarget skips known npm dist-tags (latest, next, beta,
  etc.) and semver-like strings before checking marketplace names
- updateMarketplace throws if fetched catalog name differs from the
  registered name, preventing stale data on upstream renames
- parseMarketplaceCatalog validates variant-specific required fields
  (github.repo, url.url, git-subdir.url+path, npm.package) at parse
  time instead of deferring to install-time crashes
2026-03-30 13:44:55 +02:00
Miroslav Drbal 0b85d3a1ad fix: validate plugin names at parse time, atomic cache replacement
- parseMarketplaceCatalog rejects plugin names that fail isValidNameSegment
  instead of deferring the error to install time
- cachePlugin copies to staging dir first, then renames into place;
  a failed copy no longer destroys the active install
- Fix ReturnType<> usage in cloneAndReadCatalog
2026-03-30 13:44:55 +02:00
Miroslav Drbal b134c6628b fix: preserve disabled flag on force-reinstall, re-warm preloaded roots after cache clear
- Carry over enabled:false from existing entries during force reinstall
  and upgrade; disabled plugins stay disabled without user intent change
- After clearing plugin roots cache, fire-and-forget preloadPluginRoots()
  so sync LSP config reads stay valid for the rest of the session
2026-03-30 13:44:54 +02:00
Miroslav Drbal 7a8e4e021e fix: preserve --plugin-dir across cache clears, safe force-reinstall, URL classification
- Store injected --plugin-dir roots in module-level variable; survive
  cache clears by re-merging on next listClaudePluginRoots() call
- Defer old plugin deletion in force-reinstall until new cache succeeds;
  transient failures no longer leave the plugin uninstalled
- Classify HTTP URLs by pathname instead of full string; query params
  no longer cause .json URLs to be misclassified as git
2026-03-30 13:44:54 +02:00
Miroslav Drbal 505b671c77 fix: address Codex review findings
- Honor enabled:false flag in listClaudePluginRoots (skip disabled plugins)
- Normalize local source URIs to absolute paths in addMarketplace
- Resolver returns explicit tempCloneRoot instead of path-based inference
2026-03-30 13:44:53 +02:00
Miroslav Drbal dc98266281 feat: add marketplace auto-update with background catalog refresh
- Add marketplace.autoUpdate setting (off/notify/auto, default notify)
- Background catalog refresh on startup when stale (>24h)
- /marketplace upgrade [name@marketplace] slash command
- omp plugin upgrade CLI command
- checkForUpdates, upgradePlugin, upgradeAllPlugins, refreshStaleMarketplaces
- Semver-aware version comparison with non-semver fallback
- 10 new tests for auto-update methods
2026-03-30 13:44:53 +02:00
Miroslav Drbal 4e199f93f7 feat: add marketplace plugin system
Add Claude Code-compatible marketplace plugin infrastructure:

- Registry: types, ID helpers, atomic read/write for marketplaces.json
  and installed_plugins.json (Claude Code format with version: 2)
- Fetcher: classifySource (6 ordered rules), parseMarketplaceCatalog,
  fetchMarketplace (local sources; git/http stubs for Phase 2)
- Resolver + Cache: resolvePluginSource with pathIsWithin containment,
  cachePlugin, removeCachedPlugin, cleanOrphanedCache
- MarketplaceManager: orchestrates add/remove/update marketplaces,
  install/uninstall/enable plugins, clearPluginRootsCache on mutation
- CLI: omp plugin marketplace add|remove|update|list,
  omp plugin discover, classifyInstallTarget for name@marketplace
- Discovery: listClaudePluginRoots reads OMP registry alongside
  Claude's, OMP authoritative for duplicate plugin IDs
- Args: --plugin-dir repeatable flag (parsing only, runtime wiring TBD)
- Slash command: /reload-plugins clears fs + roots cache
- Test fixtures and 130 tests across 8 test files
2026-03-30 13:44:53 +02:00
can1357 b8e82008e3 feat(coding-agent): added extension filtering and granular capability identification
- Added `toExtensionId()` method to all capability types for granular extension identification and disabling.
- Added `disabledExtensions` and `includeDisabled` options to LoadOptions for filtering disabled capabilities by extension ID.
- Added plugin manifest support for `extensions` entry points with automatic discovery from installed plugins.
- Fixed skill loading to properly respect disabled skill names from custom directories.
- Improved cross-platform path handling by using `path.basename()` instead of string splitting in context file and state manager.
- Refactored capability index loading to validate source metadata and filter disabled extensions before processing.
2026-03-15 17:26:46 +01:00
can1357 85c5fad2bc refactor: replace named re-exports with star re-exports in barrel files
Convert export { A, B, ... } from and export type { ... } from blocks
to export * from across all packages (ai, coding-agent, natives, tui, utils).
2026-02-28 22:34:02 +01:00
can1357 a83175c94c refactor: migrated imports to unified package root and consolidated skill discovery logic
- Consolidated @oh-my-pi/pi-utils subpath imports into single package root import across 100+ files.
- Moved tryParseJson utility from local web scrapers module to @oh-my-pi/pi-utils package for centralized JSON parsing.
- Renamed loadSkillsFromDir to scanSkillsFromDir and refactored skill discovery to use fs.promises.readdir instead of glob-based approach.
- Replaced custom parseJSON with tryParseJson across discovery modules for consistent error handling.
- Removed emitCustomToolSessionEvent method and cleanupSshResources function, consolidating shutdown logic into dispose method.
- Updated glob pattern construction to use GlobBuilder with literal_separator(true) for improved path handling.
2026-02-23 20:59:17 +01:00
can1357 abf8c1efc9 refactor: unslop common utilities 2026-02-22 11:01:11 +01:00
can1357 c12be01a5f fix(coding-agent): backported pi-mono changes (34878e..5133697)
packages/ai:
- fix: hardened OpenAI tool-call JSON parsing for malformed trailing arguments
- feat: routed GitHub Copilot Claude 4.x models through anthropic-messages
- feat: centralized dynamic Copilot headers and anthropic bearer auth handling
- feat: added optional StreamOptions.metadata propagation
- test: added Copilot headers/auth/routing coverage
- fix: updated model generator and models.json for Copilot Claude API mapping

packages/coding-agent:
- fix: made CLI model resolution deterministic with provider-aware pattern parsing
- fix: corrected compaction boundary/context usage handling after compaction
- feat: expanded extension events and terminal input hook integration
- fix: hardened git source parsing to avoid local-path misclassification
- test: added git-url parser coverage and model-resolver cases

packages/tui:
- fix: scoped @ fuzzy autocomplete to typed path prefixes
- feat: added Windows VT input mode support via bun:ffi

docs:
- chore: updated porting sync point to 5133697
2026-02-16 10:08:53 +01:00
can1357 d1e16d2101 refactor: implemented $PWD > cwd to prevent macOS symlink resolution
- Replaced all direct `process.cwd()` calls with `getProjectDir()` utility function across 40+ files to centralize project directory resolution logic.
- Added `getProjectDir()` and `setProjectDir()` functions to `@oh-my-pi/pi-utils/dirs` module to provide abstracted project directory management.
- Made `SessionManager.list()` method asynchronous to support asynchronous session discovery operations.
- Updated default working directory resolution throughout codebase to use `getProjectDir()` instead of `process.cwd()` for improved project directory detection.
2026-02-13 23:40:02 +01:00
can1357 fcd7ff4f84 refactor(dirs): centralized directory path utilities into @oh-my-pi/pi-utils/dirs module
- Extracted directory path utilities from multiple packages into a centralized '@oh-my-pi/pi-utils/dirs' module.
- Moved 30+ path helper functions (getAgentDir, getConfigRootDir, getPluginsDir, getMCPConfigPath, etc.) from scattered locations into a single shared utility module.
- Consolidated APP_NAME, CONFIG_DIR_NAME, and VERSION constants into the centralized dirs module for reuse across packages.
- Updated 70+ import statements across packages/ai, packages/coding-agent, packages/stats, and packages/tui to use the new centralized module.
- Removed local path construction logic and replaced with utility function calls for improved maintainability and consistency.
- Deleted packages/coding-agent/src/extensibility/plugins/paths.ts as its functions were moved to the centralized dirs module.
2026-02-13 15:06:05 +01:00
can1357 acf8ab5225 style: stylistic changes 2026-02-10 07:39:39 +01:00
can1357 9c0828ead5 feat: improved dyn config resolution, git URL parsing, and type safety across packages
- Made shell command execution in configuration values asynchronous to prevent blocking the TUI, improving responsiveness during long-running operations.
- Added deduplication of concurrent shell command executions to prevent redundant processing when the same command is requested multiple times simultaneously.
- Enhanced git URL parsing with credential stripping and validation of URI-encoded hash fragments to improve security and robustness.
- Improved @ prefix normalization for path syntaxes to correctly handle well-known patterns while preserving literal paths like '@my-file.txt'.
- Refactored prompt cache key calculation in OpenAI responses to improve code clarity and ensure cache retention is only set when a cache key exists.
2026-02-06 02:20:41 +01:00
can1357 bfe175fc01 feat(natives): backported fixes from pi-mono (82d7da878..9ce00079) 2026-02-06 01:55:42 +01:00
can1357 89e6479661 refactor: migrated environment variable access from process.env to Bun.env across 71 files
- Migrated all environment variable access from Node.js `process.env` to Bun runtime `Bun.env` API across the entire codebase.
- Updated 71 files including source code, tests, documentation, and configuration to use Bun's native environment variable API.
- Added comprehensive environment variables documentation in `packages/coding-agent/docs/environment-variables.md` covering 100+ environment variables organized by category.
- Updated CHANGELOG entries to reflect migration from `process.env` to `Bun.env` and environment variable prefix changes (PI_* vs OMP_*).
- Maintained identical behavior and logic across all changes - only the environment variable access method was updated.
2026-02-05 04:51:18 +01:00
can1357 7233c4c8af fix: added windowsHide option to child process spawn calls
- Added `windowsHide: true` option to all child process spawn calls to prevent console windows from appearing on Windows systems.
2026-01-31 01:35:10 +01:00
can1357 48b6bb0986 refactor(utils): extracted process management utilities into dedicated procmgr module
- Extracted process management utilities from coding-agent shell module into dedicated procmgr module in utils package.
- Migrated shell configuration retrieval to SettingsManager class with new getGlobalShellConfig() static method.
- Replaced custom killProcessTree() implementation with new terminate() function supporting graceful shutdown with timeout and AbortSignal.
- Updated ptree.ChildProcess to use generic type parameter for input stream masking and delegated process termination to procmgr.terminate().
- Centralized process management across coding-agent modules to use SettingsManager and procmgr utilities instead of standalone shell functions.
2026-01-29 15:07:06 +01:00
can1357 978b93ba62 refactor: migrated native tools to WASM-based implementation
- Consolidated grep, find, and image processing into a new `@oh-my-pi/pi-natives` WASM package.
- Eliminated subprocess overhead and simplified JS tool implementations.
- Updated CI to include Rust workspace, linting, formatting, and WASM build steps.
- Documented `Promise.withResolvers()` and `using` declarations for wasm-bindgen.
2026-01-29 09:29:21 +01:00
can1357 779ca4872b style(deps): migrated from Prettier to Biome and updated formatting rules
- Removed Prettier configuration files (.prettierignore and .prettierrc) and migrated formatting to Biome.
- Updated Biome configuration from version 2.3.11 to 2.3.12 and changed arrowParentheses rule from 'always' to 'asNeeded'.
- Pinned @biomejs/biome dependency to exact version 2.3.12 in package.json and bun.lock.
- Applied consistent arrow function formatting across 489 files by removing unnecessary parentheses around single parameters.
- Removed blank lines after comment blocks and reorganized imports for consistency across the codebase.
2026-01-24 04:20:19 +01:00
can1357 51d39e7eea refactor(imports): migrated node module imports to namespace imports
- Converted named imports from node modules (fs, path, os) to namespace imports across all packages.
- Extended extension loader error handling with isEacces and hasFsCode type guards.
2026-01-24 03:37:59 +01:00
can1357 e22d123009 refactor(fs): migrated remaining sync file operations to async
- Converted readdirSync, readFileSync, and statSync to async readdir, readFile, stat across skills and agent discovery.
- Made scanDirectoryForSkills async and refactored custom directory scanning to use Promise.all for concurrent processing.
- Updated agent discovery to use fs/promises for async file reading and refactored helper patterns.
- Added AgentParsingError exception class for better error handling during agent parsing.
- Added filesystem error type guards (isEnoent, isEacces, isPerm, etc.) to pi-utils for safe error checking.
- Added color manipulation utilities to pi-utils for accessibility features.
- Added color-blind mode setting to settings manager.
- Migrated plugins, settings, and config modules from sync to async file operations.
- Updated error handling to use new pi-utils type guards for type-safe checking.
2026-01-24 03:18:03 +01:00
can1357 f66e5dba9b build(config): refactored build and TypeScript configuration with Bun loaders
- Removed WASM generation script; use Bun `wasm?raw` loader for imports.
- Added bunfig.toml with loaders for `.md`, `.py`, and `.wasm?raw` text imports.
- Added types/assets/index.d.ts for global TypeScript module declarations.
- Unified TypeScript configuration with tsgo-based checking across monorepo.
- Removed build and WASM steps from install and publish pipelines.
2026-01-24 00:03:52 +01:00
can1357 0fe761dc4b build(deps): refactored TypeScript and package configuration across monorepo
- Added tsconfig.publish.json files to all packages with optimized publish-time configuration.
- Updated all package.json scripts with prepublishOnly hooks for correct type checking during publish.
- Added @oh-my-pi/omp-stats path mappings to root tsconfig.json for consistent imports.
- Added WASM generation script for photon module and integrated into install:dev script.
2026-01-23 13:46:06 +01:00
can1357 cb5bbbf382 refactor(coding-agent): flattened directory structure, eliminated core/ folder
- Eliminated core/ directory (252 files, 23 subdirs → distributed)
- Reduced max nesting from 9 levels to 5 levels
- Promoted tool subdirs to top level: exa/, lsp/, patch/, task/, web/
- Merged web-scrapers/ + web-search/ into web/{scrapers,search}/
- Flattened modes/interactive/ to modes/
- Split execution/ into: ipy/ (python), exec/ (bash), ssh/
- Renamed ipy/python-*.ts to ipy/*.ts (executor, kernel, etc.)
- Flattened cursor/exec-bridge.ts to cursor.ts
- Created logical groupings: config/, session/, extensibility/, export/
- Updated all imports across 500+ files
2026-01-23 12:24:47 +01:00