Skip to content

Conversation

@appboypov
Copy link
Owner

Summary

  • Adds plx as an alias command for all OpenSpec commands
  • Rebrands the fork as OpenSplx with new logo assets
  • Both plx and openspec commands work identically

Changes

  • New pixel art logos: assets/opensplx_pixel_light.svg, assets/opensplx_pixel_dark.svg
  • Updated README with fork notice and Quick Start section
  • Added plx bin entry to package.json
  • Created bin/plx.js entry point
  • Added src/utils/command-name.ts for dynamic command detection
  • Updated CLI and completion system to support both command names

Test plan

  • plx --version outputs version
  • plx --help shows "plx" as command name
  • openspec --version still works
  • plx completion generate zsh generates correct completions
  • Unit tests pass (399/400 - one unrelated environment failure)

Copilot AI review requested due to automatic review settings December 19, 2025 23:00
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a plx command alias to the OpenSpec CLI and rebrands the fork as OpenSplx. The implementation introduces dynamic command name detection that allows both openspec and plx commands to work identically, with all CLI output, completions, and help text automatically adapting to the command used.

Key Changes:

  • Dynamic command name detection via src/utils/command-name.ts that inspects process.argv[1] to determine if invoked as 'plx' or 'openspec'
  • Shell completion system updated to generate command-specific completion scripts for both aliases
  • New pixel art logo assets for OpenSplx branding with light and dark variants

Reviewed changes

Copilot reviewed 9 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/utils/command-name.ts New utility for detecting command name from invocation path
src/cli/index.ts Updated to use dynamic command name from detection utility
src/core/completions/types.ts Added optional commandName parameter to CompletionGenerator interface
src/core/completions/generators/zsh-generator.ts Updated to generate command-specific completion scripts using provided command name
src/commands/completion.ts Updated to pass detected command name to generators and show command-specific messages
bin/plx.js New entry point for plx command alias
package.json Added plx bin entry alongside existing openspec entry
scripts/postinstall.js Updated completion install messages to reference both commands
test/core/completions/generators/zsh-generator.test.ts Updated test expectation to match lowercase command name in generated comments
README.md Added fork notice, OpenSplx branding, and Quick Start section
assets/opensplx_pixel_light.svg New light theme pixel art logo
assets/opensplx_pixel_dark.svg New dark theme pixel art logo
Comments suppressed due to low confidence (2)

src/core/completions/generators/zsh-generator.ts:90

  • The new commandName parameter functionality is not covered by tests. The existing tests all use the default 'openspec' command name and never test the 'plx' alias behavior. Add test cases that verify the generator correctly produces completions for 'plx', including checking that function names, comments, and command references all use the provided command name.
  generate(commands: CommandDefinition[], commandName: string = 'openspec'): string {
    const script: string[] = [];

    // Header comment
    script.push(`#compdef ${commandName}`);
    script.push('');
    script.push(`# Zsh completion script for ${commandName} CLI`);
    script.push('# Auto-generated - do not edit manually');
    script.push('');

    // Main completion function
    script.push(`_${commandName}() {`);
    script.push('  local context state line');
    script.push('  typeset -A opt_args');
    script.push('');

    // Generate main command argument specification
    script.push('  local -a commands');
    script.push('  commands=(');
    for (const cmd of commands) {
      const escapedDesc = this.escapeDescription(cmd.description);
      script.push(`    '${cmd.name}:${escapedDesc}'`);
    }
    script.push('  )');
    script.push('');

    // Main _arguments call
    script.push('  _arguments -C \\');
    script.push('    "1: :->command" \\');
    script.push('    "*::arg:->args"');
    script.push('');

    // Command dispatch logic
    script.push('  case $state in');
    script.push('    command)');
    script.push(`      _describe "${commandName} command" commands`);
    script.push('      ;;');
    script.push('    args)');
    script.push('      case $words[1] in');

    // Generate completion for each command
    for (const cmd of commands) {
      script.push(`        ${cmd.name})`);
      script.push(`          _${commandName}_${this.sanitizeFunctionName(cmd.name)}`);
      script.push('          ;;');
    }

    script.push('      esac');
    script.push('      ;;');
    script.push('  esac');
    script.push('}');
    script.push('');

    // Generate individual command completion functions
    for (const cmd of commands) {
      script.push(...this.generateCommandFunction(cmd, commandName));
      script.push('');
    }

    // Add dynamic completion helper functions
    script.push(...this.generateDynamicCompletionHelpers(commandName));

    // Register the completion function
    script.push(`compdef _${commandName} ${commandName}`);
    script.push('');

    return script.join('\n');
  }

  /**
   * Generate a single completion function
   *
   * @param functionName - Name of the completion function
   * @param varName - Name of the local array variable

scripts/postinstall.js:24

  • Unused function getCommandName.
function getCommandName() {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 22 to 31
* Detect the command name from the invocation path
*/
function getCommandName() {
const scriptPath = process.argv[1] || '';
const scriptName = path.basename(scriptPath).replace(/\.js$/, '');
// Default to 'openspec' for postinstall context
return scriptName === 'plx' ? 'plx' : 'openspec';
}

/**
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getCommandName() function is defined but never called in this file. This creates dead code that could confuse future maintainers. Either use this function to pass the command name to the generator on line 91, or remove it if it's not needed in the postinstall context. If the intention is to always use 'openspec' for postinstall, the function should be removed.

Suggested change
* Detect the command name from the invocation path
*/
function getCommandName() {
const scriptPath = process.argv[1] || '';
const scriptName = path.basename(scriptPath).replace(/\.js$/, '');
// Default to 'openspec' for postinstall context
return scriptName === 'plx' ? 'plx' : 'openspec';
}
/**

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Removed the unused getCommandName() function. In the postinstall context, the script always runs via npm (not via plx or openspec commands), so command name detection is not applicable here.

- Add `plx` as an alias command alongside `openspec`
- Create OpenSplx pixel art logo assets (light/dark themes)
- Update README with fork notice and Quick Start section
- Make CLI command name dynamic based on invocation
- Update completion system to support both command names
- Add command-name utility for detecting invoked command
@appboypov appboypov merged commit 0f01f04 into main Dec 19, 2025
appboypov added a commit that referenced this pull request Dec 21, 2025
- Add `plx` as an alias command alongside `openspec`
- Create OpenSplx pixel art logo assets (light/dark themes)
- Update README with fork notice and Quick Start section
- Make CLI command name dynamic based on invocation
- Update completion system to support both command names
- Add command-name utility for detecting invoked command
appboypov added a commit that referenced this pull request Dec 21, 2025
* fix(global-config): respect XDG_CONFIG_HOME on all platforms (Fission-AI#378)

Prioritize XDG_CONFIG_HOME on Windows to fix test environment overrides.
Previously, Windows would always use APPDATA regardless of XDG_CONFIG_HOME,
causing tests to fail. Now XDG_CONFIG_HOME is checked first on all platforms
before falling back to platform-specific defaults.

Also update the Windows APPDATA test to explicitly clear XDG_CONFIG_HOME
when testing the fallback behavior.

* fix(cli): prevent hang in pre-commit hooks by using dynamic imports (Fission-AI#380)

Fixes Fission-AI#367

The CLI was hanging when run as a pre-commit hook because @inquirer/prompts
was statically imported at module load time. Even when prompts were never
called (e.g., `openspec validate --specs --no-interactive`), the import
itself could set up stdin references that prevented clean process exit
when stdin was piped.

Changes:
- Convert all static `@inquirer/prompts` imports to dynamic imports
- Dynamically import `InitCommand` (which uses `@inquirer/core`)
- Update `isInteractive()` to accept options object with both
  `noInteractive` and Commander's negated `interactive` property
- Handle empty validation queue with proper exit code

Now when running in non-interactive mode, the inquirer modules are never
loaded, allowing the process to exit cleanly after completion.

* feat(cli): add plx command alias and rebrand as OpenSplx (OpenSplx-#1)

- Add `plx` as an alias command alongside `openspec`
- Create OpenSplx pixel art logo assets (light/dark themes)
- Update README with fork notice and Quick Start section
- Make CLI command name dynamic based on invocation
- Update completion system to support both command names
- Add command-name utility for detecting invoked command

* feat(cli): add external issue tracking support

- Add YAML frontmatter parsing for tracked issues in proposal.md
- Display issue identifiers in `openspec list` output
- Include trackedIssues in `openspec show --json` output
- Report tracked issues when archiving changes
- Add External Issue Tracking section to AGENTS.md template
- Add TrackedIssue schema and type exports

* fix(cli): address PR review feedback and archive external issue tracking

- Fix list.ts alignment to include issue display in width calculation
- Fix command-name.ts to handle Windows extensions and cross-platform paths
- Fix postinstall.js to install completions for both openspec and plx
- Fix change.ts issue display format (after title in long format)
- Add comprehensive unit tests for all fixes
- Archive add-external-issue-tracking change with spec updates

---------

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
appboypov added a commit that referenced this pull request Dec 21, 2025
- Add `plx` as an alias command alongside `openspec`
- Create OpenSplx pixel art logo assets (light/dark themes)
- Update README with fork notice and Quick Start section
- Make CLI command name dynamic based on invocation
- Update completion system to support both command names
- Add command-name utility for detecting invoked command
appboypov added a commit that referenced this pull request Dec 21, 2025
* fix(global-config): respect XDG_CONFIG_HOME on all platforms (Fission-AI#378)

Prioritize XDG_CONFIG_HOME on Windows to fix test environment overrides.
Previously, Windows would always use APPDATA regardless of XDG_CONFIG_HOME,
causing tests to fail. Now XDG_CONFIG_HOME is checked first on all platforms
before falling back to platform-specific defaults.

Also update the Windows APPDATA test to explicitly clear XDG_CONFIG_HOME
when testing the fallback behavior.

* fix(cli): prevent hang in pre-commit hooks by using dynamic imports (Fission-AI#380)

Fixes Fission-AI#367

The CLI was hanging when run as a pre-commit hook because @inquirer/prompts
was statically imported at module load time. Even when prompts were never
called (e.g., `openspec validate --specs --no-interactive`), the import
itself could set up stdin references that prevented clean process exit
when stdin was piped.

Changes:
- Convert all static `@inquirer/prompts` imports to dynamic imports
- Dynamically import `InitCommand` (which uses `@inquirer/core`)
- Update `isInteractive()` to accept options object with both
  `noInteractive` and Commander's negated `interactive` property
- Handle empty validation queue with proper exit code

Now when running in non-interactive mode, the inquirer modules are never
loaded, allowing the process to exit cleanly after completion.

* feat(cli): add plx command alias and rebrand as OpenSplx (OpenSplx-#1)

- Add `plx` as an alias command alongside `openspec`
- Create OpenSplx pixel art logo assets (light/dark themes)
- Update README with fork notice and Quick Start section
- Make CLI command name dynamic based on invocation
- Update completion system to support both command names
- Add command-name utility for detecting invoked command

* feat(cli): add external issue tracking support

- Add YAML frontmatter parsing for tracked issues in proposal.md
- Display issue identifiers in `openspec list` output
- Include trackedIssues in `openspec show --json` output
- Report tracked issues when archiving changes
- Add External Issue Tracking section to AGENTS.md template
- Add TrackedIssue schema and type exports

* fix(cli): address PR review feedback and archive external issue tracking

- Fix list.ts alignment to include issue display in width calculation
- Fix command-name.ts to handle Windows extensions and cross-platform paths
- Fix postinstall.js to install completions for both openspec and plx
- Fix change.ts issue display format (after title in long format)
- Add comprehensive unit tests for all fixes
- Archive add-external-issue-tracking change with spec updates

---------

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
@appboypov appboypov deleted the feature/plx-alias branch December 24, 2025 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants