aiwcli 0.15.5 → 0.15.7
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/README.md +6 -3
- package/dist/capabilities/branch/adapters.d.ts +2 -0
- package/dist/capabilities/branch/adapters.js +21 -0
- package/dist/capabilities/branch/contracts.d.ts +57 -0
- package/dist/capabilities/branch/contracts.js +1 -0
- package/dist/capabilities/branch/control-plane.d.ts +2 -0
- package/dist/capabilities/branch/control-plane.js +343 -0
- package/dist/capabilities/branch/runtime-core.d.ts +5 -0
- package/dist/capabilities/branch/runtime-core.js +36 -0
- package/dist/capabilities/installation/control-plane/clean-command.d.ts +41 -0
- package/dist/capabilities/installation/control-plane/clean-command.js +196 -0
- package/dist/capabilities/installation/control-plane/clear-command.d.ts +160 -0
- package/dist/capabilities/installation/control-plane/clear-command.js +1220 -0
- package/dist/capabilities/installation/control-plane/init-command.d.ts +81 -0
- package/dist/capabilities/installation/control-plane/init-command.js +449 -0
- package/dist/capabilities/launch/contracts.d.ts +51 -0
- package/dist/capabilities/launch/contracts.js +1 -0
- package/dist/capabilities/launch/control-plane/execute-launch.d.ts +2 -0
- package/dist/capabilities/launch/control-plane/execute-launch.js +222 -0
- package/dist/capabilities/launch/runtime-core/launch-options.d.ts +14 -0
- package/dist/capabilities/launch/runtime-core/launch-options.js +69 -0
- package/dist/cli/base-command.d.ts +18 -0
- package/dist/cli/base-command.js +55 -0
- package/dist/commands/branch.d.ts +0 -20
- package/dist/commands/branch.js +24 -416
- package/dist/commands/clean.d.ts +1 -41
- package/dist/commands/clean.js +1 -196
- package/dist/commands/clear.d.ts +1 -161
- package/dist/commands/clear.js +1 -1121
- package/dist/commands/init/index.d.ts +1 -98
- package/dist/commands/init/index.js +4 -478
- package/dist/commands/launch.d.ts +36 -11
- package/dist/commands/launch.js +135 -159
- package/dist/lib/base-command.d.ts +1 -114
- package/dist/lib/base-command.js +1 -153
- package/dist/lib/claude-settings-types.d.ts +31 -19
- package/dist/lib/context/context-formatter.d.ts +74 -0
- package/dist/lib/context/context-formatter.js +493 -0
- package/dist/lib/context/context-selector.d.ts +42 -0
- package/dist/lib/context/context-selector.js +451 -0
- package/dist/lib/context/context-store.d.ts +100 -0
- package/dist/lib/context/context-store.js +618 -0
- package/dist/lib/context/plan-manager.d.ts +54 -0
- package/dist/lib/context/plan-manager.js +282 -0
- package/dist/lib/context/task-tracker.d.ts +44 -0
- package/dist/lib/context/task-tracker.js +146 -0
- package/dist/lib/core-ide-base.d.ts +4 -0
- package/dist/lib/core-ide-base.js +77 -0
- package/dist/lib/core-installer.d.ts +5 -0
- package/dist/lib/core-installer.js +54 -0
- package/dist/lib/git-exclude-manager.d.ts +2 -2
- package/dist/lib/git-exclude-manager.js +3 -3
- package/dist/lib/hooks/hook-utils.d.ts +143 -0
- package/dist/lib/hooks/hook-utils.js +609 -0
- package/dist/lib/hooks/session-end-logic.d.ts +5 -0
- package/dist/lib/hooks/session-end-logic.js +63 -0
- package/dist/lib/hooks-merger.js +25 -19
- package/dist/lib/ide-path-resolver.d.ts +19 -7
- package/dist/lib/ide-path-resolver.js +25 -9
- package/dist/lib/install-state.d.ts +34 -0
- package/dist/lib/install-state.js +161 -0
- package/dist/lib/launch-options.d.ts +1 -0
- package/dist/lib/launch-options.js +1 -0
- package/dist/lib/lsp-patch.d.ts +12 -0
- package/dist/lib/lsp-patch.js +156 -0
- package/dist/lib/multiplexer.d.ts +57 -0
- package/dist/lib/multiplexer.js +19 -0
- package/dist/lib/multiplexers/psmux.d.ts +75 -0
- package/dist/lib/multiplexers/psmux.js +384 -0
- package/dist/lib/multiplexers/tmux.d.ts +44 -0
- package/dist/lib/multiplexers/tmux.js +262 -0
- package/dist/lib/mux-utils.d.ts +5 -0
- package/dist/lib/mux-utils.js +42 -0
- package/dist/lib/paths.d.ts +2 -2
- package/dist/lib/paths.js +2 -2
- package/dist/lib/platform-commands.d.ts +27 -0
- package/dist/lib/platform-commands.js +49 -0
- package/dist/lib/runtime/aiw-cli.d.ts +37 -0
- package/dist/lib/runtime/aiw-cli.js +74 -0
- package/dist/lib/runtime/atomic-write.d.ts +19 -0
- package/dist/lib/runtime/atomic-write.js +121 -0
- package/dist/lib/runtime/cli-args.d.ts +55 -0
- package/dist/lib/runtime/cli-args.js +185 -0
- package/dist/lib/runtime/constants.d.ts +56 -0
- package/dist/lib/runtime/constants.js +230 -0
- package/dist/lib/runtime/executable-policy.d.ts +16 -0
- package/dist/lib/runtime/executable-policy.js +57 -0
- package/dist/lib/runtime/git-state.d.ts +9 -0
- package/dist/lib/runtime/git-state.js +59 -0
- package/dist/lib/runtime/inference.d.ts +37 -0
- package/dist/lib/runtime/inference.js +262 -0
- package/dist/lib/runtime/lint-dispatch.d.ts +40 -0
- package/dist/lib/runtime/lint-dispatch.js +285 -0
- package/dist/lib/runtime/logger.d.ts +66 -0
- package/dist/lib/runtime/logger.js +201 -0
- package/dist/lib/runtime/models.d.ts +14 -0
- package/dist/lib/runtime/models.js +14 -0
- package/dist/lib/runtime/platform-adapter.d.ts +7 -0
- package/dist/lib/runtime/platform-adapter.js +21 -0
- package/dist/lib/runtime/preflight.d.ts +24 -0
- package/dist/lib/runtime/preflight.js +65 -0
- package/dist/lib/runtime/sentinel-ipc.d.ts +14 -0
- package/dist/lib/runtime/sentinel-ipc.js +67 -0
- package/dist/lib/runtime/state-io.d.ts +30 -0
- package/dist/lib/runtime/state-io.js +174 -0
- package/dist/lib/runtime/stop-words.d.ts +20 -0
- package/dist/lib/runtime/stop-words.js +150 -0
- package/dist/lib/runtime/subprocess-utils.d.ts +29 -0
- package/dist/lib/runtime/subprocess-utils.js +96 -0
- package/dist/lib/runtime/tmux-preflight.d.ts +13 -0
- package/dist/lib/runtime/tmux-preflight.js +78 -0
- package/dist/lib/runtime/utils.d.ts +54 -0
- package/dist/lib/runtime/utils.js +162 -0
- package/dist/lib/sentinel-wrapper.d.ts +9 -0
- package/dist/lib/sentinel-wrapper.js +20 -0
- package/dist/lib/shell-quoting.d.ts +5 -0
- package/dist/lib/shell-quoting.js +17 -0
- package/dist/lib/spawn-errors.d.ts +6 -0
- package/dist/lib/spawn-errors.js +15 -0
- package/dist/lib/spawn.js +5 -11
- package/dist/lib/template-installer.d.ts +4 -5
- package/dist/lib/template-installer.js +36 -34
- package/dist/lib/template-resolver.d.ts +6 -7
- package/dist/lib/template-resolver.js +26 -21
- package/dist/lib/template-settings-reconstructor.d.ts +7 -2
- package/dist/lib/template-settings-reconstructor.js +76 -45
- package/dist/lib/terminal-strategy.d.ts +11 -0
- package/dist/lib/terminal-strategy.js +49 -0
- package/dist/lib/terminal.d.ts +28 -0
- package/dist/lib/terminal.js +162 -112
- package/dist/lib/tmux-pane-placement.d.ts +17 -0
- package/dist/lib/tmux-pane-placement.js +58 -0
- package/dist/lib/tmux-primitives.d.ts +5 -0
- package/dist/lib/tmux-primitives.js +15 -0
- package/dist/lib/tmux-session.d.ts +32 -0
- package/dist/lib/tmux-session.js +86 -0
- package/dist/lib/tty-detection.js +1 -1
- package/dist/lib/types.d.ts +168 -0
- package/dist/lib/types.js +6 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/platform/launch.d.ts +10 -0
- package/dist/platform/launch.js +10 -0
- package/dist/templates/CLAUDE.md +31 -40
- package/dist/templates/cc-native/.claude/settings.json +27 -27
- package/dist/templates/cc-native/CC-NATIVE-README.md +1 -1
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +10 -9
- package/dist/templates/cc-native/_cc-native/CLAUDE.md +18 -18
- package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +3 -3
- package/dist/templates/cc-native/_cc-native/artifacts/lib/format.ts +14 -14
- package/dist/templates/cc-native/_cc-native/artifacts/lib/tracker.ts +1 -1
- package/dist/templates/cc-native/_cc-native/artifacts/lib/write.ts +3 -3
- package/dist/templates/cc-native/_cc-native/cc-native.config.json +3 -3
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +16 -15
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +3 -3
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +2 -2
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +2 -2
- package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +3 -3
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +2 -2
- package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +3 -3
- package/dist/templates/cc-native/_cc-native/lib-ts/CLAUDE.md +8 -8
- package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +1 -1
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +4 -4
- package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +1 -1
- package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +1 -1
- package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +1 -1
- package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +1 -1
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +2 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +1 -1
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +2 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +1 -1
- package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +8 -8
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +3 -3
- package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +2 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +3 -3
- package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +3 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/agent-selection.test.ts +345 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/preflight.test.ts +344 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +37 -15
- package/dist/templates/cc-native/_cc-native/plan-review/lib/corroboration.ts +16 -69
- package/dist/templates/cc-native/_cc-native/plan-review/lib/orchestrator.ts +1 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/output-builder.ts +1 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/plan-questions.ts +2 -2
- package/dist/templates/cc-native/_cc-native/plan-review/lib/preflight.ts +56 -26
- package/dist/templates/cc-native/_cc-native/plan-review/lib/review-pipeline.ts +7 -7
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/agent.ts +4 -4
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/base/base-agent.ts +3 -3
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/index.ts +1 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/claude-agent.ts +2 -2
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/codex-agent.ts +4 -4
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/gemini-agent.ts +1 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/orchestrator-claude-agent.ts +5 -6
- package/dist/templates/core/.codex/workflows/codex.md +17 -0
- package/dist/templates/core/.codex/workflows/handoff.md +5 -0
- package/dist/templates/core/.codex/workflows/meta-plan.md +7 -0
- package/dist/templates/core/.cognition/AGENTS.md +5 -0
- package/dist/templates/core/.cognition/config.json +12 -0
- package/dist/templates/{_shared → core}/.windsurf/workflows/handoff.md +1 -1
- package/dist/templates/{_shared → core}/.windsurf/workflows/meta-plan.md +1 -1
- package/dist/templates/core/hooks-ts/_utils/git-state.ts +2 -0
- package/dist/templates/{_shared → core}/hooks-ts/archive_plan.ts +14 -23
- package/dist/templates/core/hooks-ts/codex_explorer.ts +160 -0
- package/dist/templates/{_shared → core}/hooks-ts/context_monitor.ts +23 -55
- package/dist/templates/{_shared → core}/hooks-ts/file-suggestion.ts +4 -3
- package/dist/templates/{_shared → core}/hooks-ts/lint_after_edit.ts +7 -9
- package/dist/templates/{_shared → core}/hooks-ts/pre_compact.ts +5 -5
- package/dist/templates/{_shared → core}/hooks-ts/session_end.ts +38 -78
- package/dist/templates/{_shared → core}/hooks-ts/session_start.ts +5 -5
- package/dist/templates/core/hooks-ts/task_create_capture.ts +32 -0
- package/dist/templates/{_shared → core}/hooks-ts/task_update_capture.ts +9 -24
- package/dist/templates/core/hooks-ts/user_prompt_submit.ts +46 -0
- package/dist/templates/{_shared → core}/lib-ts/CLAUDE.md +27 -16
- package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/headless.ts +3 -2
- package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/tmux.ts +44 -15
- package/dist/templates/{_shared → core}/lib-ts/agent-exec/base-agent.ts +6 -4
- package/dist/templates/{_shared → core}/lib-ts/agent-exec/execution-backend.ts +1 -1
- package/dist/templates/{_shared → core}/lib-ts/agent-exec/index.ts +2 -2
- package/dist/templates/{_shared → core}/lib-ts/agent-exec/structured-output.ts +4 -5
- package/dist/templates/{_shared → core}/lib-ts/context/CLAUDE.md +9 -6
- package/dist/templates/{_shared → core}/lib-ts/context/context-formatter.ts +16 -21
- package/dist/templates/{_shared → core}/lib-ts/context/context-selector.ts +8 -6
- package/dist/templates/{_shared → core}/lib-ts/context/context-store.ts +32 -20
- package/dist/templates/{_shared → core}/lib-ts/context/plan-manager.ts +19 -15
- package/dist/templates/{_shared → core}/lib-ts/context/task-tracker.ts +3 -3
- package/dist/templates/core/lib-ts/hooks/context-monitor-logic.ts +32 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/hooks}/hook-utils.ts +168 -41
- package/dist/templates/core/lib-ts/hooks/prompt-binding-logic.ts +80 -0
- package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +93 -0
- package/dist/templates/core/lib-ts/package.json +19 -0
- package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +295 -0
- package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +106 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/atomic-write.ts +12 -7
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/cli-args.ts +8 -6
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/constants.ts +326 -324
- package/dist/templates/core/lib-ts/runtime/executable-policy.ts +89 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/git-state.ts +6 -4
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/inference.ts +59 -10
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/lint-dispatch.ts +25 -23
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/logger.ts +32 -29
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/models.ts +2 -2
- package/dist/templates/core/lib-ts/runtime/platform-adapter.ts +33 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/preflight.ts +4 -3
- package/dist/templates/core/lib-ts/runtime/sentinel-ipc.ts +91 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/state-io.ts +11 -7
- package/dist/templates/core/lib-ts/runtime/stop-words.ts +185 -0
- package/dist/templates/core/lib-ts/runtime/subprocess-utils.ts +147 -0
- package/dist/templates/core/lib-ts/runtime/tmux-preflight.ts +93 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/utils.ts +4 -3
- package/dist/templates/{_shared → core}/lib-ts/templates/formatters.ts +7 -5
- package/dist/templates/{_shared → core}/lib-ts/templates/plan-context.ts +2 -1
- package/dist/templates/{_shared → core}/lib-ts/tsconfig.json +3 -1
- package/dist/templates/{_shared → core}/lib-ts/types.ts +78 -77
- package/dist/templates/core/scripts/resolve-run.ts +61 -0
- package/dist/templates/{_shared → core}/scripts/resolve_context.ts +3 -3
- package/dist/templates/{_shared → core}/scripts/status_line.ts +25 -20
- package/dist/templates/core/skills/codex/CLAUDE.md +78 -0
- package/dist/templates/{_shared → core}/skills/codex/SKILL.md +21 -18
- package/dist/templates/{_shared → core}/skills/codex/lib/codex-watcher.ts +76 -103
- package/dist/templates/{_shared → core}/skills/codex/scripts/launch-codex.ts +119 -133
- package/dist/templates/{_shared → core}/skills/codex/scripts/watch-codex.ts +6 -4
- package/dist/templates/core/skills/devin/CLAUDE.md +65 -0
- package/dist/templates/core/skills/devin/SKILL.md +73 -0
- package/dist/templates/core/skills/devin/lib/devin-watcher.ts +280 -0
- package/dist/templates/core/skills/devin/scripts/launch-devin.ts +257 -0
- package/dist/templates/{_shared → core}/skills/handoff-system/CLAUDE.md +436 -433
- package/dist/templates/{_shared → core}/skills/handoff-system/lib/document-generator.ts +9 -7
- package/dist/templates/{_shared → core}/skills/handoff-system/lib/handoff-reader.ts +6 -4
- package/dist/templates/{_shared → core}/skills/handoff-system/scripts/resume_handoff.ts +10 -8
- package/dist/templates/{_shared → core}/skills/handoff-system/scripts/save_handoff.ts +12 -10
- package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff-resume.md +2 -2
- package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff.md +6 -5
- package/dist/templates/{_shared → core}/skills/meta-plan/CLAUDE.md +2 -1
- package/dist/templates/{_shared → core}/skills/meta-plan/workflows/meta-plan.md +8 -7
- package/oclif.manifest.json +89 -13
- package/package.json +13 -12
- package/dist/templates/_shared/.claude/settings.json +0 -120
- package/dist/templates/_shared/.claude/skills/codex/SKILL.md +0 -35
- package/dist/templates/_shared/.claude/skills/handoff/SKILL.md +0 -13
- package/dist/templates/_shared/.claude/skills/handoff-resume/SKILL.md +0 -13
- package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +0 -43
- package/dist/templates/_shared/.codex/workflows/codex.md +0 -11
- package/dist/templates/_shared/.codex/workflows/handoff.md +0 -226
- package/dist/templates/_shared/.codex/workflows/meta-plan.md +0 -347
- package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +0 -2
- package/dist/templates/_shared/hooks-ts/task_create_capture.ts +0 -48
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +0 -93
- package/dist/templates/_shared/lib-ts/base/launchers/tmux-launcher.ts +0 -173
- package/dist/templates/_shared/lib-ts/base/launchers/window-launcher.ts +0 -93
- package/dist/templates/_shared/lib-ts/base/launchers/wt-launcher.ts +0 -64
- package/dist/templates/_shared/lib-ts/base/pane-launcher.ts +0 -55
- package/dist/templates/_shared/lib-ts/base/sentinel-ipc.ts +0 -87
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +0 -184
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +0 -249
- package/dist/templates/_shared/lib-ts/base/tmux-driver.ts +0 -341
- package/dist/templates/_shared/lib-ts/base/tmux-pane-placement.ts +0 -78
- package/dist/templates/_shared/lib-ts/package.json +0 -20
- package/dist/templates/_shared/scripts/resolve-run.ts +0 -62
- package/dist/templates/_shared/skills/codex/CLAUDE.md +0 -70
- /package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/index.ts +0 -0
package/dist/commands/launch.js
CHANGED
|
@@ -1,44 +1,66 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
3
|
import { Flags } from '@oclif/core';
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import { checkVersionCompatibility, getClaudeCodeVersion } from '../lib/version.js';
|
|
9
|
-
import { EXIT_CODES } from '../types/index.js';
|
|
4
|
+
import { executeLaunch } from '../capabilities/launch/control-plane/execute-launch.js';
|
|
5
|
+
import { buildUniqueSessionName, sanitizeSessionName } from '../capabilities/launch/runtime-core/launch-options.js';
|
|
6
|
+
import BaseCommand from '../cli/base-command.js';
|
|
7
|
+
import { quoteForSh, readSentinelExitCode, waitForSentinelFile } from '../platform/launch.js';
|
|
10
8
|
/**
|
|
11
|
-
* Launch Claude Code or
|
|
9
|
+
* Launch Claude Code, Codex, or Devin with AIW configuration.
|
|
12
10
|
*
|
|
13
11
|
* Spawns Claude Code CLI with --dangerously-skip-permissions flag,
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* Codex CLI with --yolo flag, or Devin CLI with --permission-mode dangerous,
|
|
13
|
+
* enabling unattended execution. Supports multiple parallel sessions.
|
|
14
|
+
*
|
|
15
|
+
* ## Multiplexer-first launch (preferred)
|
|
16
|
+
*
|
|
17
|
+
* When a terminal multiplexer is available (psmux on Windows, tmux on Unix),
|
|
18
|
+
* the launch flow is:
|
|
19
|
+
* - **Inside an existing session** → split a new pane in the current session
|
|
20
|
+
* - **Outside any session** → create a new multiplexer session with the REPL
|
|
21
|
+
*
|
|
22
|
+
* This gives persistent sessions, pane splitting, and scrollback.
|
|
23
|
+
* Use `--no-tmux` to bypass the multiplexer and launch inline.
|
|
24
|
+
*
|
|
25
|
+
* ## Inline fallback
|
|
26
|
+
*
|
|
27
|
+
* When no multiplexer is available (or `--no-tmux` is set), the REPL launches
|
|
28
|
+
* directly in the current terminal.
|
|
29
|
+
*
|
|
30
|
+
* ## Install multiplexer
|
|
31
|
+
* - Windows: `winget install psmux` (native ConPTY multiplexer)
|
|
32
|
+
* - Unix: `apt install tmux` / `brew install tmux`
|
|
17
33
|
*/
|
|
18
34
|
export default class LaunchCommand extends BaseCommand {
|
|
19
|
-
static description = 'Launch Claude Code or
|
|
35
|
+
static description = 'Launch Claude Code, Codex, or Devin with AIW configuration (sandbox disabled, tmux-first; Windows opens mintty window first with inline fallback)\n\n' +
|
|
20
36
|
'FLAGS\n' +
|
|
21
37
|
' --codex/-c: Launch Codex instead of Claude Code (uses --yolo flag)\n' +
|
|
38
|
+
' --devin/-e: Launch Devin CLI instead of Claude Code (uses --permission-mode dangerous)\n' +
|
|
22
39
|
' --new/-n: Open a new terminal in the current directory and launch there\n' +
|
|
23
40
|
' --no-tmux/-t: Launch directly in current shell instead of auto-launching tmux\n' +
|
|
24
|
-
' --tmux-session/-s: tmux session name to reuse when auto-launching tmux
|
|
41
|
+
' --tmux-session/-s: tmux session name to reuse when auto-launching tmux\n' +
|
|
42
|
+
' --prompt/-p: Initial prompt to pass to the AI REPL at startup\n' +
|
|
43
|
+
' --wait: Block until launched pane exits (for scripted callers)\n' +
|
|
44
|
+
' --json: JSON output (paneId, backend, exitCode, sentinel)\n' +
|
|
45
|
+
' --split: Split direction when in tmux (auto|h|v, default: auto)\n' +
|
|
46
|
+
' --env: Extra env vars as JSON string\n' +
|
|
47
|
+
' --prompt-path: Path to prompt file for REPL-mode tools\n\n' +
|
|
25
48
|
'EXIT CODES\n' +
|
|
26
49
|
' 0 Success - AI assistant launched and exited successfully\n' +
|
|
27
50
|
' 1 General error - unexpected runtime failure\n' +
|
|
28
51
|
' 2 Invalid usage - check your arguments and flags\n' +
|
|
29
|
-
' 3 Environment error - CLI not found (install Claude Code from https://claude.ai/download, Codex from npm)';
|
|
52
|
+
' 3 Environment error - CLI not found (install Claude Code from https://claude.ai/download, Codex from npm, Devin from https://cli.devin.ai)';
|
|
30
53
|
static examples = [
|
|
31
54
|
'<%= config.bin %> <%= command.id %> # Auto-launches tmux with a fresh session when not already in tmux',
|
|
32
55
|
'<%= config.bin %> <%= command.id %> --codex # Launch Codex with --yolo flag',
|
|
33
|
-
'<%= config.bin %> <%= command.id %>
|
|
56
|
+
'<%= config.bin %> <%= command.id %> --devin # Launch Devin CLI with --permission-mode dangerous',
|
|
34
57
|
'<%= config.bin %> <%= command.id %> --new # Launch in a new terminal window',
|
|
35
|
-
'<%= config.bin %> <%= command.id %> -n # Short form for --new',
|
|
36
|
-
'<%= config.bin %> <%= command.id %> --codex --new # Launch Codex in new terminal',
|
|
37
58
|
'<%= config.bin %> <%= command.id %> --no-tmux # Run directly in current shell',
|
|
38
59
|
'<%= config.bin %> <%= command.id %> --tmux-session aiw-main # Reuse/attach explicit tmux session name',
|
|
60
|
+
'<%= config.bin %> <%= command.id %> --prompt "Fix the login bug" # Launch with initial prompt',
|
|
61
|
+
'<%= config.bin %> <%= command.id %> --wait --json # Block until pane exits, output JSON result',
|
|
62
|
+
'<%= config.bin %> <%= command.id %> --split h # Force horizontal split in tmux',
|
|
39
63
|
'<%= config.bin %> <%= command.id %> --debug # Enable verbose logging',
|
|
40
|
-
'# Check exit code in Bash\n<%= config.bin %> <%= command.id %>\necho $?',
|
|
41
|
-
'# Check exit code in PowerShell\n<%= config.bin %> <%= command.id %>\necho $LASTEXITCODE',
|
|
42
64
|
];
|
|
43
65
|
static flags = {
|
|
44
66
|
...BaseCommand.baseFlags,
|
|
@@ -46,6 +68,21 @@ export default class LaunchCommand extends BaseCommand {
|
|
|
46
68
|
char: 'c',
|
|
47
69
|
description: 'Launch Codex instead of Claude Code (uses --yolo flag for full auto mode)',
|
|
48
70
|
default: false,
|
|
71
|
+
exclusive: ['devin'],
|
|
72
|
+
}),
|
|
73
|
+
devin: Flags.boolean({
|
|
74
|
+
char: 'e',
|
|
75
|
+
description: 'Launch Devin CLI instead of Claude Code (uses --permission-mode dangerous)',
|
|
76
|
+
default: false,
|
|
77
|
+
exclusive: ['codex'],
|
|
78
|
+
}),
|
|
79
|
+
env: Flags.string({
|
|
80
|
+
description: 'Extra env vars as JSON object string (e.g. \'{"FOO":"bar"}\')',
|
|
81
|
+
required: false,
|
|
82
|
+
}),
|
|
83
|
+
json: Flags.boolean({
|
|
84
|
+
description: 'JSON output (paneId, backend, exitCode, sentinel)',
|
|
85
|
+
default: false,
|
|
49
86
|
}),
|
|
50
87
|
new: Flags.boolean({
|
|
51
88
|
char: 'n',
|
|
@@ -57,159 +94,98 @@ export default class LaunchCommand extends BaseCommand {
|
|
|
57
94
|
description: 'Launch directly in current shell instead of auto-launching tmux',
|
|
58
95
|
default: false,
|
|
59
96
|
}),
|
|
97
|
+
prompt: Flags.string({
|
|
98
|
+
char: 'p',
|
|
99
|
+
description: 'Initial prompt to pass to the AI REPL at startup',
|
|
100
|
+
required: false,
|
|
101
|
+
}),
|
|
102
|
+
'prompt-file': Flags.string({
|
|
103
|
+
description: 'Path to file containing initial prompt (internal)',
|
|
104
|
+
required: false,
|
|
105
|
+
hidden: true,
|
|
106
|
+
}),
|
|
107
|
+
'spawned-window': Flags.boolean({
|
|
108
|
+
description: 'Internal: marks launch as re-entered in a spawned terminal window',
|
|
109
|
+
required: false,
|
|
110
|
+
hidden: true,
|
|
111
|
+
default: false,
|
|
112
|
+
}),
|
|
113
|
+
'prompt-path': Flags.string({
|
|
114
|
+
description: 'Path to prompt file for REPL-mode tools',
|
|
115
|
+
required: false,
|
|
116
|
+
}),
|
|
117
|
+
split: Flags.string({
|
|
118
|
+
description: 'Split direction when in tmux (auto|h|v, default: auto)',
|
|
119
|
+
options: ['auto', 'h', 'v'],
|
|
120
|
+
required: false,
|
|
121
|
+
}),
|
|
60
122
|
'tmux-session': Flags.string({
|
|
61
123
|
char: 's',
|
|
62
124
|
description: 'tmux session name to reuse when auto-launching tmux (default: new aiw-<current-dir>-<unique> session)',
|
|
63
125
|
required: false,
|
|
64
126
|
}),
|
|
127
|
+
wait: Flags.boolean({
|
|
128
|
+
description: 'Block until launched pane exits; output result',
|
|
129
|
+
default: false,
|
|
130
|
+
}),
|
|
65
131
|
};
|
|
66
132
|
async run() {
|
|
67
133
|
const { flags } = await this.parse(LaunchCommand);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
// Normal launch flow
|
|
94
|
-
let exitCode;
|
|
95
|
-
try {
|
|
96
|
-
// Version check only applies to Claude Code (not Codex)
|
|
97
|
-
if (useCodex) {
|
|
98
|
-
this.debug('Launching Codex with --yolo flag');
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
// Check Claude Code version compatibility (non-blocking)
|
|
102
|
-
const version = await getClaudeCodeVersion();
|
|
103
|
-
const versionCheck = checkVersionCompatibility(version);
|
|
104
|
-
// Debug logging: show version information
|
|
105
|
-
this.debug(`Claude Code version: ${versionCheck.version ?? 'unknown'}`);
|
|
106
|
-
this.debug(`Compatibility status: ${versionCheck.compatible ? 'compatible' : 'incompatible'}`);
|
|
107
|
-
// Non-blocking warning for incompatibility or unknown version
|
|
108
|
-
if (versionCheck.warning) {
|
|
109
|
-
this.warn(versionCheck.warning);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
// Spawn AI CLI with sandbox permissions disabled
|
|
113
|
-
// AIW hook system provides safety guardrails
|
|
114
|
-
// Continue launch regardless of version check result (graceful degradation)
|
|
115
|
-
if (shouldAutoTmux && this.isTmuxAvailable()) {
|
|
116
|
-
const shellCommand = this.buildTmuxShellCommand(cliCommand, cliArgs);
|
|
117
|
-
const sessionFromFlag = flags['tmux-session']?.trim();
|
|
118
|
-
if (sessionFromFlag && sessionFromFlag.length > 0) {
|
|
119
|
-
const sessionName = this.sanitizeTmuxSessionName(sessionFromFlag);
|
|
120
|
-
this.logInfo(`Launching in tmux session: ${sessionName} (reuse/attach)`);
|
|
121
|
-
exitCode = await spawnProcess('tmux', ['new-session', '-A', '-s', sessionName, shellCommand]);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
const sessionBase = `aiw-${basename(process.cwd())}`;
|
|
125
|
-
const sessionName = this.buildUniqueTmuxSessionName(sessionBase);
|
|
126
|
-
this.logInfo(`Launching in new tmux session: ${sessionName}`);
|
|
127
|
-
exitCode = await spawnProcess('tmux', ['new-session', '-s', sessionName, shellCommand]);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else if (shouldAutoTmux && this.isWindowsTerminalAvailable()) {
|
|
131
|
-
this.logInfo('tmux unavailable; launching in Windows Terminal split pane');
|
|
132
|
-
exitCode = await spawnProcess('wt', ['split-pane', '--', cliCommand, ...cliArgs]);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
if (shouldAutoTmux) {
|
|
136
|
-
this.logInfo('No pane launcher available. Launching directly.');
|
|
137
|
-
}
|
|
138
|
-
else if (disableTmux) {
|
|
139
|
-
this.debug('tmux launch disabled via --no-tmux');
|
|
140
|
-
}
|
|
141
|
-
else if (insideTmux) {
|
|
142
|
-
this.debug('Already inside tmux; launching directly in current pane');
|
|
143
|
-
this.enableTmuxMouseIfPossible();
|
|
144
|
-
}
|
|
145
|
-
else if (!interactiveTty) {
|
|
146
|
-
this.debug('Non-interactive terminal detected; launching directly');
|
|
147
|
-
}
|
|
148
|
-
exitCode = await spawnProcess(cliCommand, cliArgs);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
if (error instanceof ProcessSpawnError) {
|
|
153
|
-
// Actionable error message (already includes installation link)
|
|
154
|
-
this.error(error.message, { exit: EXIT_CODES.ENVIRONMENT_ERROR });
|
|
155
|
-
}
|
|
156
|
-
// Unexpected error
|
|
157
|
-
this.error('Unexpected launch failure.', { exit: EXIT_CODES.GENERAL_ERROR });
|
|
158
|
-
}
|
|
159
|
-
// Pass through Claude Code's exit code (outside try-catch to avoid catching exit)
|
|
160
|
-
this.exit(exitCode);
|
|
134
|
+
await executeLaunch({
|
|
135
|
+
cwd: process.cwd(),
|
|
136
|
+
flags: flags,
|
|
137
|
+
interactiveTty: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
138
|
+
platform: process.platform,
|
|
139
|
+
readPromptFile: (filePath) => (existsSync(filePath) ? readFileSync(filePath, 'utf8') : undefined),
|
|
140
|
+
}, {
|
|
141
|
+
host: {
|
|
142
|
+
debug: (message, ...args) => this.debug([message, ...args.map(String)].join(' ')),
|
|
143
|
+
error: (input, options) => this.error(input, options),
|
|
144
|
+
exit: (code) => this.exit(code),
|
|
145
|
+
log: (message) => this.log(message),
|
|
146
|
+
logInfo: (message) => this.logInfo(message),
|
|
147
|
+
logWarning: (message) => this.logWarning(message),
|
|
148
|
+
warn: (input) => this.warn(input),
|
|
149
|
+
},
|
|
150
|
+
now: () => Date.now(),
|
|
151
|
+
pid: process.pid,
|
|
152
|
+
tempDir: os.tmpdir(),
|
|
153
|
+
writePromptFile(filePath, content) {
|
|
154
|
+
writeFileSync(filePath, content, { encoding: 'utf8', mode: 0o600 });
|
|
155
|
+
},
|
|
156
|
+
});
|
|
161
157
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
158
|
+
// Compatibility wrappers kept on the command prototype while launch
|
|
159
|
+
// orchestration now lives in the capability control-plane.
|
|
160
|
+
buildUniqueSessionName(base) {
|
|
161
|
+
return buildUniqueSessionName(base);
|
|
165
162
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
catch {
|
|
173
|
-
return false;
|
|
163
|
+
async handleJsonOutput(result, wait) {
|
|
164
|
+
let { exitCode } = result;
|
|
165
|
+
if (wait && result.launched && result.sentinelPath) {
|
|
166
|
+
const finished = await waitForSentinelFile(result.sentinelPath, 14_400_000);
|
|
167
|
+
exitCode = finished ? readSentinelExitCode(result.sentinelPath, 1) : -1;
|
|
174
168
|
}
|
|
169
|
+
this.log(JSON.stringify({
|
|
170
|
+
launched: result.launched,
|
|
171
|
+
backend: result.backend,
|
|
172
|
+
paneId: result.paneId ?? null,
|
|
173
|
+
sentinelPath: result.sentinelPath ?? null,
|
|
174
|
+
exitCode: exitCode ?? null,
|
|
175
|
+
reason: result.reason ?? null,
|
|
176
|
+
}));
|
|
177
|
+
this.exit(exitCode ?? 0);
|
|
175
178
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return false;
|
|
179
|
-
try {
|
|
180
|
-
execSync('where wt', { stdio: 'ignore' });
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
catch {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
179
|
+
sanitizeSessionName(input) {
|
|
180
|
+
return sanitizeSessionName(input);
|
|
186
181
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const safe = trimmed
|
|
190
|
-
.replaceAll(/[^a-z0-9_-]/g, '-')
|
|
191
|
-
.replaceAll(/-+/g, '-')
|
|
192
|
-
.replaceAll(/^[-_]+|[-_]+$/g, '');
|
|
193
|
-
return safe || 'aiw';
|
|
194
|
-
}
|
|
195
|
-
buildUniqueTmuxSessionName(base) {
|
|
196
|
-
const safeBase = this.sanitizeTmuxSessionName(base);
|
|
197
|
-
const timestamp = Date.now().toString(36);
|
|
198
|
-
const pid = process.pid.toString(36);
|
|
199
|
-
return this.sanitizeTmuxSessionName(`${safeBase}-${timestamp}-${pid}`);
|
|
182
|
+
shellQuote(input) {
|
|
183
|
+
return quoteForSh(input);
|
|
200
184
|
}
|
|
201
|
-
|
|
202
|
-
if (!
|
|
185
|
+
async waitForSentinel(result) {
|
|
186
|
+
if (!result.sentinelPath)
|
|
203
187
|
return;
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
this.debug('Enabled tmux mouse support (set-option -g mouse on)');
|
|
207
|
-
}
|
|
208
|
-
catch {
|
|
209
|
-
this.debug('Could not enable tmux mouse support automatically');
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
shellQuote(input) {
|
|
213
|
-
return `'${input.replaceAll("'", `'"'"'`)}'`;
|
|
188
|
+
const finished = await waitForSentinelFile(result.sentinelPath, 14_400_000);
|
|
189
|
+
this.exit(finished ? readSentinelExitCode(result.sentinelPath, 1) : 1);
|
|
214
190
|
}
|
|
215
191
|
}
|
|
@@ -1,114 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { type Ora } from 'ora';
|
|
3
|
-
/**
|
|
4
|
-
* Base command class that all AI Workflow CLI commands should extend.
|
|
5
|
-
* Provides global --debug flag support for verbose logging.
|
|
6
|
-
*
|
|
7
|
-
* @example Basic command with debug support
|
|
8
|
-
* import {debug} from '../lib/debug.js'
|
|
9
|
-
*
|
|
10
|
-
* export default class MyCommand extends BaseCommand {
|
|
11
|
-
* static override flags = {
|
|
12
|
-
* ...BaseCommand.baseFlags,
|
|
13
|
-
* // command-specific flags
|
|
14
|
-
* }
|
|
15
|
-
*
|
|
16
|
-
* async run() {
|
|
17
|
-
* // debug mode is already enabled if --debug flag was passed
|
|
18
|
-
* // version info is automatically logged when debug enabled
|
|
19
|
-
* debug('My debug message')
|
|
20
|
-
* }
|
|
21
|
-
* }
|
|
22
|
-
*
|
|
23
|
-
* @example Command with spinner progress feedback
|
|
24
|
-
* import {ux} from '@oclif/core'
|
|
25
|
-
*
|
|
26
|
-
* export default class LongCommand extends BaseCommand {
|
|
27
|
-
* async run() {
|
|
28
|
-
* // Check if output is piped (suppress spinners for piped output)
|
|
29
|
-
* const isPiped = !process.stdout.isTTY
|
|
30
|
-
*
|
|
31
|
-
* if (!isPiped) {
|
|
32
|
-
* // Show spinner for long operations in interactive terminal
|
|
33
|
-
* ux.action.start('Processing')
|
|
34
|
-
* await longRunningOperation()
|
|
35
|
-
* ux.action.stop()
|
|
36
|
-
* } else {
|
|
37
|
-
* // Piped output - suppress spinner
|
|
38
|
-
* await longRunningOperation()
|
|
39
|
-
* }
|
|
40
|
-
* }
|
|
41
|
-
* }
|
|
42
|
-
*
|
|
43
|
-
* @example Spinner with status updates
|
|
44
|
-
* import {ux} from '@oclif/core'
|
|
45
|
-
*
|
|
46
|
-
* export default class MultiStepCommand extends BaseCommand {
|
|
47
|
-
* async run() {
|
|
48
|
-
* if (process.stdout.isTTY) {
|
|
49
|
-
* ux.action.start('Installing packages')
|
|
50
|
-
* await installPackages()
|
|
51
|
-
*
|
|
52
|
-
* // Update spinner status
|
|
53
|
-
* ux.action.status = 'Configuring'
|
|
54
|
-
* await configure()
|
|
55
|
-
*
|
|
56
|
-
* ux.action.stop('Done!')
|
|
57
|
-
* } else {
|
|
58
|
-
* await installPackages()
|
|
59
|
-
* await configure()
|
|
60
|
-
* }
|
|
61
|
-
* }
|
|
62
|
-
* }
|
|
63
|
-
*/
|
|
64
|
-
export default abstract class BaseCommand extends Command {
|
|
65
|
-
/**
|
|
66
|
-
* Global flags inherited by all AI Workflow CLI commands.
|
|
67
|
-
* All command classes should spread these flags into their own flag definitions:
|
|
68
|
-
* `static override flags = { ...BaseCommand.baseFlags, /* command-specific flags *\/ }`
|
|
69
|
-
*
|
|
70
|
-
* @see Command Development Guide in README.md for usage patterns
|
|
71
|
-
*/
|
|
72
|
-
static baseFlags: {
|
|
73
|
-
debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
74
|
-
help: import("@oclif/core/interfaces").BooleanFlag<void>;
|
|
75
|
-
quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
76
|
-
};
|
|
77
|
-
init(): Promise<void>;
|
|
78
|
-
/**
|
|
79
|
-
* Check if quiet mode is enabled.
|
|
80
|
-
* Returns true if --quiet/-q flag was passed.
|
|
81
|
-
*/
|
|
82
|
-
protected isQuiet(): boolean;
|
|
83
|
-
/**
|
|
84
|
-
* Log debug message (stdout, dim in TTY).
|
|
85
|
-
* Debug output is independent of quiet mode.
|
|
86
|
-
*/
|
|
87
|
-
protected logDebug(message: string): void;
|
|
88
|
-
/**
|
|
89
|
-
* Log error message (stderr, red in TTY).
|
|
90
|
-
* Errors are NEVER suppressed, even in quiet mode.
|
|
91
|
-
*/
|
|
92
|
-
protected logError(message: string): void;
|
|
93
|
-
/**
|
|
94
|
-
* Log informational message (stdout, no color).
|
|
95
|
-
* Suppressed in quiet mode.
|
|
96
|
-
*/
|
|
97
|
-
protected logInfo(message: string): void;
|
|
98
|
-
/**
|
|
99
|
-
* Log success message (stdout, green in TTY).
|
|
100
|
-
* Suppressed in quiet mode.
|
|
101
|
-
*/
|
|
102
|
-
protected logSuccess(message: string): void;
|
|
103
|
-
/**
|
|
104
|
-
* Log warning message (stdout, yellow in TTY).
|
|
105
|
-
* Suppressed in quiet mode.
|
|
106
|
-
*/
|
|
107
|
-
protected logWarning(message: string): void;
|
|
108
|
-
abstract run(): Promise<void>;
|
|
109
|
-
/**
|
|
110
|
-
* Create a TTY-aware spinner for long-running operations.
|
|
111
|
-
* Automatically disabled when output is piped, in CI environments, or in quiet mode.
|
|
112
|
-
*/
|
|
113
|
-
protected spinner(text: string): Ora;
|
|
114
|
-
}
|
|
1
|
+
export { default } from '../cli/base-command.js';
|
package/dist/lib/base-command.js
CHANGED
|
@@ -1,153 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { debugVersion, setDebugEnabled } from '../lib/debug.js';
|
|
3
|
-
import { logDebug, logError, logInfo, logSuccess, logWarning } from '../lib/output.js';
|
|
4
|
-
import { isQuietMode, setQuietMode } from '../lib/quiet.js';
|
|
5
|
-
import { createSpinner } from '../lib/spinner.js';
|
|
6
|
-
/**
|
|
7
|
-
* Base command class that all AI Workflow CLI commands should extend.
|
|
8
|
-
* Provides global --debug flag support for verbose logging.
|
|
9
|
-
*
|
|
10
|
-
* @example Basic command with debug support
|
|
11
|
-
* import {debug} from '../lib/debug.js'
|
|
12
|
-
*
|
|
13
|
-
* export default class MyCommand extends BaseCommand {
|
|
14
|
-
* static override flags = {
|
|
15
|
-
* ...BaseCommand.baseFlags,
|
|
16
|
-
* // command-specific flags
|
|
17
|
-
* }
|
|
18
|
-
*
|
|
19
|
-
* async run() {
|
|
20
|
-
* // debug mode is already enabled if --debug flag was passed
|
|
21
|
-
* // version info is automatically logged when debug enabled
|
|
22
|
-
* debug('My debug message')
|
|
23
|
-
* }
|
|
24
|
-
* }
|
|
25
|
-
*
|
|
26
|
-
* @example Command with spinner progress feedback
|
|
27
|
-
* import {ux} from '@oclif/core'
|
|
28
|
-
*
|
|
29
|
-
* export default class LongCommand extends BaseCommand {
|
|
30
|
-
* async run() {
|
|
31
|
-
* // Check if output is piped (suppress spinners for piped output)
|
|
32
|
-
* const isPiped = !process.stdout.isTTY
|
|
33
|
-
*
|
|
34
|
-
* if (!isPiped) {
|
|
35
|
-
* // Show spinner for long operations in interactive terminal
|
|
36
|
-
* ux.action.start('Processing')
|
|
37
|
-
* await longRunningOperation()
|
|
38
|
-
* ux.action.stop()
|
|
39
|
-
* } else {
|
|
40
|
-
* // Piped output - suppress spinner
|
|
41
|
-
* await longRunningOperation()
|
|
42
|
-
* }
|
|
43
|
-
* }
|
|
44
|
-
* }
|
|
45
|
-
*
|
|
46
|
-
* @example Spinner with status updates
|
|
47
|
-
* import {ux} from '@oclif/core'
|
|
48
|
-
*
|
|
49
|
-
* export default class MultiStepCommand extends BaseCommand {
|
|
50
|
-
* async run() {
|
|
51
|
-
* if (process.stdout.isTTY) {
|
|
52
|
-
* ux.action.start('Installing packages')
|
|
53
|
-
* await installPackages()
|
|
54
|
-
*
|
|
55
|
-
* // Update spinner status
|
|
56
|
-
* ux.action.status = 'Configuring'
|
|
57
|
-
* await configure()
|
|
58
|
-
*
|
|
59
|
-
* ux.action.stop('Done!')
|
|
60
|
-
* } else {
|
|
61
|
-
* await installPackages()
|
|
62
|
-
* await configure()
|
|
63
|
-
* }
|
|
64
|
-
* }
|
|
65
|
-
* }
|
|
66
|
-
*/
|
|
67
|
-
export default class BaseCommand extends Command {
|
|
68
|
-
/**
|
|
69
|
-
* Global flags inherited by all AI Workflow CLI commands.
|
|
70
|
-
* All command classes should spread these flags into their own flag definitions:
|
|
71
|
-
* `static override flags = { ...BaseCommand.baseFlags, /* command-specific flags *\/ }`
|
|
72
|
-
*
|
|
73
|
-
* @see Command Development Guide in README.md for usage patterns
|
|
74
|
-
*/
|
|
75
|
-
static baseFlags = {
|
|
76
|
-
debug: Flags.boolean({
|
|
77
|
-
char: 'd',
|
|
78
|
-
description: 'Enable verbose debug logging',
|
|
79
|
-
default: false,
|
|
80
|
-
}),
|
|
81
|
-
help: Flags.help({
|
|
82
|
-
char: 'h',
|
|
83
|
-
description: 'Show help for command',
|
|
84
|
-
}),
|
|
85
|
-
quiet: Flags.boolean({
|
|
86
|
-
char: 'q',
|
|
87
|
-
description: 'Suppress informational output (errors still shown)',
|
|
88
|
-
default: false,
|
|
89
|
-
}),
|
|
90
|
-
};
|
|
91
|
-
async init() {
|
|
92
|
-
await super.init();
|
|
93
|
-
const { flags } = await this.parse(this.constructor);
|
|
94
|
-
const debugEnabled = flags.debug ?? false;
|
|
95
|
-
const quietEnabled = flags.quiet ?? false;
|
|
96
|
-
setDebugEnabled(debugEnabled);
|
|
97
|
-
setQuietMode(quietEnabled);
|
|
98
|
-
// Automatically show version info in debug mode (AC4, FR24)
|
|
99
|
-
if (debugEnabled) {
|
|
100
|
-
debugVersion();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Check if quiet mode is enabled.
|
|
105
|
-
* Returns true if --quiet/-q flag was passed.
|
|
106
|
-
*/
|
|
107
|
-
isQuiet() {
|
|
108
|
-
// Access via module-level state (set in init())
|
|
109
|
-
return isQuietMode();
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Log debug message (stdout, dim in TTY).
|
|
113
|
-
* Debug output is independent of quiet mode.
|
|
114
|
-
*/
|
|
115
|
-
logDebug(message) {
|
|
116
|
-
logDebug(message);
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Log error message (stderr, red in TTY).
|
|
120
|
-
* Errors are NEVER suppressed, even in quiet mode.
|
|
121
|
-
*/
|
|
122
|
-
logError(message) {
|
|
123
|
-
logError(message);
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Log informational message (stdout, no color).
|
|
127
|
-
* Suppressed in quiet mode.
|
|
128
|
-
*/
|
|
129
|
-
logInfo(message) {
|
|
130
|
-
logInfo(message, this.isQuiet());
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Log success message (stdout, green in TTY).
|
|
134
|
-
* Suppressed in quiet mode.
|
|
135
|
-
*/
|
|
136
|
-
logSuccess(message) {
|
|
137
|
-
logSuccess(message, this.isQuiet());
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Log warning message (stdout, yellow in TTY).
|
|
141
|
-
* Suppressed in quiet mode.
|
|
142
|
-
*/
|
|
143
|
-
logWarning(message) {
|
|
144
|
-
logWarning(message, this.isQuiet());
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Create a TTY-aware spinner for long-running operations.
|
|
148
|
-
* Automatically disabled when output is piped, in CI environments, or in quiet mode.
|
|
149
|
-
*/
|
|
150
|
-
spinner(text) {
|
|
151
|
-
return createSpinner(text, { quiet: isQuietMode() });
|
|
152
|
-
}
|
|
153
|
-
}
|
|
1
|
+
export { default } from '../cli/base-command.js';
|