PlanOpticon
refactor(cli): simplify companion access - planopticon --chat or planopticon -I launches companion directly - planopticon companion launches without needing extra flags - No more redundant planopticon companion --chat
Commit
620a9d858559b7f17a202aa47de41de1f70222139306b52a8fe410b0c75909bd
Parent
6fcb9f3c95d3b6b…
2 files changed
+3
-8
+29
-32
+3
-8
| --- tests/test_cli.py | ||
| +++ tests/test_cli.py | ||
| @@ -25,10 +25,13 @@ | ||
| 25 | 25 | assert "gws" in result.output |
| 26 | 26 | assert "m365" in result.output |
| 27 | 27 | assert "recordings" in result.output |
| 28 | 28 | assert "ingest" in result.output |
| 29 | 29 | assert "batch" in result.output |
| 30 | + assert "--chat" in result.output | |
| 31 | + assert "--interactive" in result.output | |
| 32 | + assert "companion" in result.output | |
| 30 | 33 | |
| 31 | 34 | |
| 32 | 35 | class TestAnalyzeHelp: |
| 33 | 36 | def test_help(self): |
| 34 | 37 | runner = CliRunner() |
| @@ -245,13 +248,5 @@ | ||
| 245 | 248 | result = runner.invoke(cli, ["companion", "--help"]) |
| 246 | 249 | assert result.exit_code == 0 |
| 247 | 250 | assert "--kb" in result.output |
| 248 | 251 | assert "--provider" in result.output |
| 249 | 252 | assert "--chat-model" in result.output |
| 250 | - assert "--interactive" in result.output | |
| 251 | - assert "--chat" in result.output | |
| 252 | - | |
| 253 | - def test_no_flag_shows_usage(self): | |
| 254 | - runner = CliRunner() | |
| 255 | - result = runner.invoke(cli, ["companion"]) | |
| 256 | - assert result.exit_code == 0 | |
| 257 | - assert "--interactive" in result.output | |
| 258 | 253 |
| --- tests/test_cli.py | |
| +++ tests/test_cli.py | |
| @@ -25,10 +25,13 @@ | |
| 25 | assert "gws" in result.output |
| 26 | assert "m365" in result.output |
| 27 | assert "recordings" in result.output |
| 28 | assert "ingest" in result.output |
| 29 | assert "batch" in result.output |
| 30 | |
| 31 | |
| 32 | class TestAnalyzeHelp: |
| 33 | def test_help(self): |
| 34 | runner = CliRunner() |
| @@ -245,13 +248,5 @@ | |
| 245 | result = runner.invoke(cli, ["companion", "--help"]) |
| 246 | assert result.exit_code == 0 |
| 247 | assert "--kb" in result.output |
| 248 | assert "--provider" in result.output |
| 249 | assert "--chat-model" in result.output |
| 250 | assert "--interactive" in result.output |
| 251 | assert "--chat" in result.output |
| 252 | |
| 253 | def test_no_flag_shows_usage(self): |
| 254 | runner = CliRunner() |
| 255 | result = runner.invoke(cli, ["companion"]) |
| 256 | assert result.exit_code == 0 |
| 257 | assert "--interactive" in result.output |
| 258 |
| --- tests/test_cli.py | |
| +++ tests/test_cli.py | |
| @@ -25,10 +25,13 @@ | |
| 25 | assert "gws" in result.output |
| 26 | assert "m365" in result.output |
| 27 | assert "recordings" in result.output |
| 28 | assert "ingest" in result.output |
| 29 | assert "batch" in result.output |
| 30 | assert "--chat" in result.output |
| 31 | assert "--interactive" in result.output |
| 32 | assert "companion" in result.output |
| 33 | |
| 34 | |
| 35 | class TestAnalyzeHelp: |
| 36 | def test_help(self): |
| 37 | runner = CliRunner() |
| @@ -245,13 +248,5 @@ | |
| 248 | result = runner.invoke(cli, ["companion", "--help"]) |
| 249 | assert result.exit_code == 0 |
| 250 | assert "--kb" in result.output |
| 251 | assert "--provider" in result.output |
| 252 | assert "--chat-model" in result.output |
| 253 |
+29
-32
| --- video_processor/cli/commands.py | ||
| +++ video_processor/cli/commands.py | ||
| @@ -34,19 +34,38 @@ | ||
| 34 | 34 | root_logger.addHandler(console_handler) |
| 35 | 35 | |
| 36 | 36 | |
| 37 | 37 | @click.group(invoke_without_command=True) |
| 38 | 38 | @click.option("--verbose", "-v", is_flag=True, help="Enable verbose output") |
| 39 | +@click.option( | |
| 40 | + "--chat", | |
| 41 | + "-C", | |
| 42 | + is_flag=True, | |
| 43 | + help="Launch interactive companion REPL", | |
| 44 | +) | |
| 45 | +@click.option( | |
| 46 | + "--interactive", | |
| 47 | + "-I", | |
| 48 | + "interactive_flag", | |
| 49 | + is_flag=True, | |
| 50 | + help="Launch interactive companion REPL", | |
| 51 | +) | |
| 39 | 52 | @click.version_option("0.4.0", prog_name="PlanOpticon") |
| 40 | 53 | @click.pass_context |
| 41 | -def cli(ctx, verbose): | |
| 54 | +def cli(ctx, verbose, chat, interactive_flag): | |
| 42 | 55 | """PlanOpticon - Comprehensive Video Analysis & Knowledge Extraction Tool.""" |
| 43 | 56 | ctx.ensure_object(dict) |
| 44 | 57 | ctx.obj["verbose"] = verbose |
| 45 | 58 | setup_logging(verbose) |
| 46 | 59 | |
| 47 | - if ctx.invoked_subcommand is None: | |
| 60 | + if (chat or interactive_flag) and ctx.invoked_subcommand is None: | |
| 61 | + from video_processor.cli.companion import CompanionREPL | |
| 62 | + | |
| 63 | + repl = CompanionREPL() | |
| 64 | + repl.run() | |
| 65 | + ctx.exit(0) | |
| 66 | + elif ctx.invoked_subcommand is None: | |
| 48 | 67 | _interactive_menu(ctx) |
| 49 | 68 | |
| 50 | 69 | |
| 51 | 70 | @cli.command() |
| 52 | 71 | @click.option( |
| @@ -2018,24 +2037,10 @@ | ||
| 2018 | 2037 | f"{len(ex.relationships)} relationships)" |
| 2019 | 2038 | ) |
| 2020 | 2039 | |
| 2021 | 2040 | |
| 2022 | 2041 | @cli.command() |
| 2023 | -@click.option( | |
| 2024 | - "--interactive", | |
| 2025 | - "-I", | |
| 2026 | - "interactive_mode", | |
| 2027 | - is_flag=True, | |
| 2028 | - help="Launch interactive REPL", | |
| 2029 | -) | |
| 2030 | -@click.option( | |
| 2031 | - "--chat", | |
| 2032 | - "-C", | |
| 2033 | - "chat_mode", | |
| 2034 | - is_flag=True, | |
| 2035 | - help="Launch interactive REPL (alias for --interactive)", | |
| 2036 | -) | |
| 2037 | 2042 | @click.option( |
| 2038 | 2043 | "--kb", |
| 2039 | 2044 | multiple=True, |
| 2040 | 2045 | type=click.Path(exists=True), |
| 2041 | 2046 | help="Knowledge base paths", |
| @@ -2052,29 +2057,21 @@ | ||
| 2052 | 2057 | type=str, |
| 2053 | 2058 | default=None, |
| 2054 | 2059 | help="Chat model override", |
| 2055 | 2060 | ) |
| 2056 | 2061 | @click.pass_context |
| 2057 | -def companion(ctx, interactive_mode, chat_mode, kb, provider, chat_model): | |
| 2058 | - """Planning companion with workspace awareness. | |
| 2059 | - | |
| 2060 | - Use --interactive or --chat to start the REPL. | |
| 2062 | +def companion(ctx, kb, provider, chat_model): | |
| 2063 | + """Interactive planning companion with workspace awareness. | |
| 2061 | 2064 | |
| 2062 | 2065 | Examples: |
| 2063 | 2066 | |
| 2064 | - planopticon companion --interactive | |
| 2065 | - | |
| 2066 | - planopticon companion --chat --kb ./results | |
| 2067 | - | |
| 2068 | - planopticon companion -I -p anthropic | |
| 2069 | - """ | |
| 2070 | - if not interactive_mode and not chat_mode: | |
| 2071 | - click.echo("Use --interactive or --chat to start the companion REPL.") | |
| 2072 | - click.echo("Example: planopticon companion --interactive") | |
| 2073 | - click.echo("\nRun 'planopticon companion --help' for options.") | |
| 2074 | - return | |
| 2075 | - | |
| 2067 | + planopticon companion | |
| 2068 | + | |
| 2069 | + planopticon companion --kb ./results | |
| 2070 | + | |
| 2071 | + planopticon companion -p anthropic | |
| 2072 | + """ | |
| 2076 | 2073 | from video_processor.cli.companion import CompanionREPL |
| 2077 | 2074 | |
| 2078 | 2075 | repl = CompanionREPL( |
| 2079 | 2076 | kb_paths=list(kb), |
| 2080 | 2077 | provider=provider, |
| 2081 | 2078 |
| --- video_processor/cli/commands.py | |
| +++ video_processor/cli/commands.py | |
| @@ -34,19 +34,38 @@ | |
| 34 | root_logger.addHandler(console_handler) |
| 35 | |
| 36 | |
| 37 | @click.group(invoke_without_command=True) |
| 38 | @click.option("--verbose", "-v", is_flag=True, help="Enable verbose output") |
| 39 | @click.version_option("0.4.0", prog_name="PlanOpticon") |
| 40 | @click.pass_context |
| 41 | def cli(ctx, verbose): |
| 42 | """PlanOpticon - Comprehensive Video Analysis & Knowledge Extraction Tool.""" |
| 43 | ctx.ensure_object(dict) |
| 44 | ctx.obj["verbose"] = verbose |
| 45 | setup_logging(verbose) |
| 46 | |
| 47 | if ctx.invoked_subcommand is None: |
| 48 | _interactive_menu(ctx) |
| 49 | |
| 50 | |
| 51 | @cli.command() |
| 52 | @click.option( |
| @@ -2018,24 +2037,10 @@ | |
| 2018 | f"{len(ex.relationships)} relationships)" |
| 2019 | ) |
| 2020 | |
| 2021 | |
| 2022 | @cli.command() |
| 2023 | @click.option( |
| 2024 | "--interactive", |
| 2025 | "-I", |
| 2026 | "interactive_mode", |
| 2027 | is_flag=True, |
| 2028 | help="Launch interactive REPL", |
| 2029 | ) |
| 2030 | @click.option( |
| 2031 | "--chat", |
| 2032 | "-C", |
| 2033 | "chat_mode", |
| 2034 | is_flag=True, |
| 2035 | help="Launch interactive REPL (alias for --interactive)", |
| 2036 | ) |
| 2037 | @click.option( |
| 2038 | "--kb", |
| 2039 | multiple=True, |
| 2040 | type=click.Path(exists=True), |
| 2041 | help="Knowledge base paths", |
| @@ -2052,29 +2057,21 @@ | |
| 2052 | type=str, |
| 2053 | default=None, |
| 2054 | help="Chat model override", |
| 2055 | ) |
| 2056 | @click.pass_context |
| 2057 | def companion(ctx, interactive_mode, chat_mode, kb, provider, chat_model): |
| 2058 | """Planning companion with workspace awareness. |
| 2059 | |
| 2060 | Use --interactive or --chat to start the REPL. |
| 2061 | |
| 2062 | Examples: |
| 2063 | |
| 2064 | planopticon companion --interactive |
| 2065 | |
| 2066 | planopticon companion --chat --kb ./results |
| 2067 | |
| 2068 | planopticon companion -I -p anthropic |
| 2069 | """ |
| 2070 | if not interactive_mode and not chat_mode: |
| 2071 | click.echo("Use --interactive or --chat to start the companion REPL.") |
| 2072 | click.echo("Example: planopticon companion --interactive") |
| 2073 | click.echo("\nRun 'planopticon companion --help' for options.") |
| 2074 | return |
| 2075 | |
| 2076 | from video_processor.cli.companion import CompanionREPL |
| 2077 | |
| 2078 | repl = CompanionREPL( |
| 2079 | kb_paths=list(kb), |
| 2080 | provider=provider, |
| 2081 |
| --- video_processor/cli/commands.py | |
| +++ video_processor/cli/commands.py | |
| @@ -34,19 +34,38 @@ | |
| 34 | root_logger.addHandler(console_handler) |
| 35 | |
| 36 | |
| 37 | @click.group(invoke_without_command=True) |
| 38 | @click.option("--verbose", "-v", is_flag=True, help="Enable verbose output") |
| 39 | @click.option( |
| 40 | "--chat", |
| 41 | "-C", |
| 42 | is_flag=True, |
| 43 | help="Launch interactive companion REPL", |
| 44 | ) |
| 45 | @click.option( |
| 46 | "--interactive", |
| 47 | "-I", |
| 48 | "interactive_flag", |
| 49 | is_flag=True, |
| 50 | help="Launch interactive companion REPL", |
| 51 | ) |
| 52 | @click.version_option("0.4.0", prog_name="PlanOpticon") |
| 53 | @click.pass_context |
| 54 | def cli(ctx, verbose, chat, interactive_flag): |
| 55 | """PlanOpticon - Comprehensive Video Analysis & Knowledge Extraction Tool.""" |
| 56 | ctx.ensure_object(dict) |
| 57 | ctx.obj["verbose"] = verbose |
| 58 | setup_logging(verbose) |
| 59 | |
| 60 | if (chat or interactive_flag) and ctx.invoked_subcommand is None: |
| 61 | from video_processor.cli.companion import CompanionREPL |
| 62 | |
| 63 | repl = CompanionREPL() |
| 64 | repl.run() |
| 65 | ctx.exit(0) |
| 66 | elif ctx.invoked_subcommand is None: |
| 67 | _interactive_menu(ctx) |
| 68 | |
| 69 | |
| 70 | @cli.command() |
| 71 | @click.option( |
| @@ -2018,24 +2037,10 @@ | |
| 2037 | f"{len(ex.relationships)} relationships)" |
| 2038 | ) |
| 2039 | |
| 2040 | |
| 2041 | @cli.command() |
| 2042 | @click.option( |
| 2043 | "--kb", |
| 2044 | multiple=True, |
| 2045 | type=click.Path(exists=True), |
| 2046 | help="Knowledge base paths", |
| @@ -2052,29 +2057,21 @@ | |
| 2057 | type=str, |
| 2058 | default=None, |
| 2059 | help="Chat model override", |
| 2060 | ) |
| 2061 | @click.pass_context |
| 2062 | def companion(ctx, kb, provider, chat_model): |
| 2063 | """Interactive planning companion with workspace awareness. |
| 2064 | |
| 2065 | Examples: |
| 2066 | |
| 2067 | planopticon companion |
| 2068 | |
| 2069 | planopticon companion --kb ./results |
| 2070 | |
| 2071 | planopticon companion -p anthropic |
| 2072 | """ |
| 2073 | from video_processor.cli.companion import CompanionREPL |
| 2074 | |
| 2075 | repl = CompanionREPL( |
| 2076 | kb_paths=list(kb), |
| 2077 | provider=provider, |
| 2078 |