Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions Documentation/ExtensionAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,11 @@ name. `delete` and `erase` require at least one workspace name and `--yes`.
`open` and `workspace paths` without a name use the current workspace. Every
integration attribute command requires an explicit integration identifier, and
`set` also requires an explicit value. `integrations raycast install` requires
an explicit `app` or `script-command` component. Script Command installation
also requires `--directory` unless an installed configuration already records
the directory.
an explicit `app`, `extension`, or `script-command` component. Script Command
installation also requires `--directory` unless an installed configuration
already records the directory; this component is deprecated in favor of the
extension. Extension installation requires `--yes` when Raycast is absent, or
`--open-in-browser` to bypass Raycast installation.

## Stable workspace identities

Expand All @@ -117,7 +119,7 @@ fxcodex open \
```

The ID and workspace name are mutually exclusive for `open`. Other workspace
mutation commands continue to accept names in 0.2.1.
mutation commands continue to accept names in 0.3.0.

`workspace paths` also accepts either a workspace name or `--workspace-id`.
Its response identifies the selected workspace and includes
Expand Down Expand Up @@ -172,14 +174,17 @@ resulting component status:

```sh
fxcodex integrations raycast install app --json
fxcodex integrations raycast install extension --open-in-browser --json
fxcodex integrations raycast install script-command \
--directory "$HOME/.config/raycast/script-commands" \
--json
```

Application outcomes are `already-installed`, `installed`, or
`download-opened`. Script Command installation returns `installed` together
with `script_commands`.
`download-opened`. Extension installation returns `extension-opened` when its
Raycast deep link is opened or `store-page-opened` when the browser is used.
Script Command installation returns `installed` together with
`script_commands`.

`rename` requests the `Codex.app` name and returns a
`CodexApplicationRenameResult`. `rename --undo` requests `ChatGPT.app`. The
Expand Down Expand Up @@ -214,13 +219,13 @@ Set a scoped environment variable to `-1` to exclude that section even when
all sections are enabled. On the command line, use the corresponding
`--no-list-...` flag.

The following commands are intentionally outside the 0.2.1 machine API:
The following commands are intentionally outside the 0.3.0 machine API:

- `cli` and `exec` replace the fxcodex process with Codex CLI, whose session or
output may be interactive.
- The root `uninstall` command removes the current executable.
- `integrations raycast sync` and `integrations raycast uninstall` are
terminal-only maintenance commands in 0.2.1.
terminal-only maintenance commands in 0.3.0.

A frontend should use the supported workspace and status commands and refresh
its state after mutations. Raycast Script Commands remain an optional
Expand Down
30 changes: 25 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,22 @@ otherwise, `set` stores the input as a string.

## Raycast integration

Run either command without a trailing action to choose interactively:

```sh
fxcodex integrations
fxcodex integrations raycast
```

The Raycast menu offers status and installation actions. Installation then
offers Raycast, Raycast Beta, the fxcodex extension, and the deprecated Script
Commands integration.

### Script Commands

`fxcodex` can install and maintain Raycast Script Commands for quickly opening
workspaces. Start the guided setup with:
Raycast Script Commands are deprecated in favor of the extension, but `fxcodex`
continues to install and maintain them for quickly opening workspaces. Choose a
component interactively with:

```sh
fxcodex integrations raycast install
Expand All @@ -345,9 +357,17 @@ later-selected workspaces are not added automatically. Reinstall without
### Extension

A companion Raycast extension provides workspace navigation, management,
custom icons, executable selection, and preferences. It is prepared separately
for [Raycast Store submission](https://github.com/raycast/extensions/pull/29538); the Script Commands
above are available without it.
custom icons, executable selection, and preferences. Install it with:

```sh
fxcodex integrations raycast install extension
```

When both Raycast and Raycast Beta are installed, `fxcodex` asks which edition
should open the extension deep link. When neither is installed, the guided flow
recommends installing Raycast before offering the browser as a fallback. Use
`--open-in-browser` to open the [fxcodex Raycast Store page](https://www.raycast.com/maximkrouk/fxcodex)
directly. The Script Commands above remain available without the extension.

## Machine-readable output

Expand Down
2 changes: 1 addition & 1 deletion Sources/fxcodex-cli/AppCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import FXCodexClient

@main
internal struct AppCommand: AsyncParsableCommand {
internal static let version: String = "0.2.1"
internal static let version: String = "0.3.0"
internal static let machineEncodingFailureResponse: String = """
{
"api_version": 1,
Expand Down
42 changes: 38 additions & 4 deletions Sources/fxcodex-cli/Commands/Integrations/IntegrationCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,20 @@ extension AppCommand {
"Choose an integration area:",
[
.init(value: "attributes", label: "Attributes", hint: "Read or modify integration data"),
.init(value: "raycast", label: "Raycast", hint: "Show Raycast integration status"),
.init(value: "raycast", label: "Raycast", hint: "Manage Raycast integration components"),
]
)
else { return }

switch area {
case "attributes":
try await Attributes().run()
let command: Attributes = try .parse([])
try await command.run()

case "raycast":
try await Raycast.Status().run()
let command: Raycast = try .parse([])
try await command.run()

default:
throw ValidationError("Unsupported integration area.")
}
Expand Down Expand Up @@ -319,9 +323,39 @@ extension AppCommand.IntegrationsCommand {
Sync.self,
Uninstall.self,
],
defaultSubcommand: Status.self
defaultSubcommand: nil
)

internal init() {}

internal func run() async throws {
guard !globalMachineOutputRequested() else {
throw ValidationError("Choose status or install when using --json.")
}

@Dependency(\._fxcodexTerminalPrompts)
var prompts: TerminalPromptsClient

guard let action = try prompts.select(
"Choose a Raycast action:",
[
.init(value: "status", label: "Status", hint: "Show installed components"),
.init(value: "install", label: "Install", hint: "Install a component"),
]
) else { return }

switch action {
case "status":
let command: Status = try .parse([])
try await command.run()

case "install":
let command: Install = try .parse([])
try await command.run()

default:
throw ValidationError("Unsupported Raycast action.")
}
}
}
}
Loading