codex-flow 2.1.13__py3-none-any.whl
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.
- codex_flow/__init__.py +28 -0
- codex_flow/__main__.py +9 -0
- codex_flow/cli.py +242 -0
- codex_flow/data/LICENSE +21 -0
- codex_flow/data/README.en.md +303 -0
- codex_flow/data/README.md +305 -0
- codex_flow/data/VERSION +1 -0
- codex_flow/data/apps/chatgpt-mcp/README.md +86 -0
- codex_flow/data/apps/chatgpt-mcp/__init__.py +1 -0
- codex_flow/data/apps/chatgpt-mcp/adapter.py +458 -0
- codex_flow/data/apps/chatgpt-mcp/server.py +358 -0
- codex_flow/data/apps/chatgpt-mcp/widget.html +927 -0
- codex_flow/data/apps/macos-overlay/README.en.md +121 -0
- codex_flow/data/apps/macos-overlay/README.md +123 -0
- codex_flow/data/apps/macos-overlay/Sources/Controllers/OverlayRuntimeState.swift +126 -0
- codex_flow/data/apps/macos-overlay/Sources/Controllers/OverlayScreenGeometry.swift +82 -0
- codex_flow/data/apps/macos-overlay/Sources/Controllers/OverlayWindowController.swift +1052 -0
- codex_flow/data/apps/macos-overlay/Sources/Localization.swift +197 -0
- codex_flow/data/apps/macos-overlay/Sources/Models/TelemetryData.swift +1557 -0
- codex_flow/data/apps/macos-overlay/Sources/Services/AccountSnapshotService.swift +1101 -0
- codex_flow/data/apps/macos-overlay/Sources/Services/FlowPilotInstanceLock.swift +153 -0
- codex_flow/data/apps/macos-overlay/Sources/Services/IPCServer.swift +298 -0
- codex_flow/data/apps/macos-overlay/Sources/Services/TelemetryQueryEngine.swift +800 -0
- codex_flow/data/apps/macos-overlay/Sources/Services/TelemetryWatcher.swift +135 -0
- codex_flow/data/apps/macos-overlay/Sources/Services/UpdateService.swift +610 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/AccountView.swift +610 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/AnalyticsView.swift +566 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/AutostartView.swift +293 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/BubbleView.swift +317 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/HistoryView.swift +1124 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/HoverRevealText.swift +165 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/InspectorSkillsToolsView.swift +121 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/LogoView.swift +182 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/SleekSwitch.swift +117 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/StrategyModeView.swift +561 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/SummaryView.swift +1273 -0
- codex_flow/data/apps/macos-overlay/Sources/Views/UpdateView.swift +352 -0
- codex_flow/data/apps/macos-overlay/Sources/main.swift +340 -0
- codex_flow/data/apps/macos-overlay/Tests/OverlayScreenGeometryTests.swift +163 -0
- codex_flow/data/apps/macos-overlay/Tests/TelemetryPhase1ContractTests.swift +357 -0
- codex_flow/data/apps/macos-overlay/Tests/TelemetryQueryEngineConcurrencyTests.swift +221 -0
- codex_flow/data/apps/macos-overlay/Tests/TelemetryQuotaSelectionTests.swift +158 -0
- codex_flow/data/apps/macos-overlay/Tests/TelemetryWorkerTokenTests.swift +122 -0
- codex_flow/data/apps/macos-overlay/build.sh +75 -0
- codex_flow/data/benchmark/corpus.json +103 -0
- codex_flow/data/benchmark/manifest.example.json +41 -0
- codex_flow/data/benchmark/manifest.schema.json +137 -0
- codex_flow/data/benchmark/prices/gpt-5.6-2026-08-30.json +5 -0
- codex_flow/data/benchmark/profiles.json +90 -0
- codex_flow/data/benchmark/schema.json +77 -0
- codex_flow/data/benchmark/tasks.json +50 -0
- codex_flow/data/completions/codex-flow.bash +34 -0
- codex_flow/data/completions/codex-flow.zsh +52 -0
- codex_flow/data/glama.json +6 -0
- codex_flow/data/install-release.ps1 +126 -0
- codex_flow/data/install-release.sh +155 -0
- codex_flow/data/install.ps1 +349 -0
- codex_flow/data/install.sh +362 -0
- codex_flow/data/policy/benchmark.toml +49 -0
- codex_flow/data/policy/defaults.toml +70 -0
- codex_flow/data/scripts/analyze-benchmark.py +510 -0
- codex_flow/data/scripts/benchmark-local.py +171 -0
- codex_flow/data/scripts/check-recommendation.py +277 -0
- codex_flow/data/scripts/doctor.py +449 -0
- codex_flow/data/scripts/generate-release-manifest.py +74 -0
- codex_flow/data/scripts/localization.py +192 -0
- codex_flow/data/scripts/manage-hooks.py +448 -0
- codex_flow/data/scripts/manage-instructions.py +389 -0
- codex_flow/data/scripts/manage-shell.py +151 -0
- codex_flow/data/scripts/materialize-corpus.py +193 -0
- codex_flow/data/scripts/menu.py +646 -0
- codex_flow/data/scripts/migrations/0001_update_settings.py +80 -0
- codex_flow/data/scripts/package-release.py +132 -0
- codex_flow/data/scripts/render-benchmark-report.py +292 -0
- codex_flow/data/scripts/run-benchmark.py +829 -0
- codex_flow/data/scripts/strategies/__init__.py +28 -0
- codex_flow/data/scripts/strategies/balanced.py +115 -0
- codex_flow/data/scripts/strategies/base.py +363 -0
- codex_flow/data/scripts/strategies/efficient.py +158 -0
- codex_flow/data/scripts/strategies/lifecycle_runtime.py +590 -0
- codex_flow/data/scripts/strategies/quality.py +209 -0
- codex_flow/data/scripts/strategies/speed.py +108 -0
- codex_flow/data/scripts/strategies/task_budget_runtime.py +644 -0
- codex_flow/data/scripts/strategies/task_phase_runtime.py +341 -0
- codex_flow/data/scripts/strategies/work_unit_runtime.py +421 -0
- codex_flow/data/scripts/strategy_runtime.py +1091 -0
- codex_flow/data/scripts/telemetry.py +400 -0
- codex_flow/data/scripts/telemetry_core/__init__.py +192 -0
- codex_flow/data/scripts/telemetry_core/app_server.py +1192 -0
- codex_flow/data/scripts/telemetry_core/collector.py +1247 -0
- codex_flow/data/scripts/telemetry_core/common.py +421 -0
- codex_flow/data/scripts/telemetry_core/latency.py +593 -0
- codex_flow/data/scripts/telemetry_core/query.py +427 -0
- codex_flow/data/scripts/telemetry_core/quota_ledger.py +598 -0
- codex_flow/data/scripts/telemetry_core/render.py +460 -0
- codex_flow/data/scripts/telemetry_core/repair.py +223 -0
- codex_flow/data/scripts/ui.py +266 -0
- codex_flow/data/scripts/update-homebrew-formula.py +146 -0
- codex_flow/data/scripts/update_runtime_config.py +134 -0
- codex_flow/data/scripts/updater.py +1718 -0
- codex_flow/data/smithery.yaml +18 -0
- codex_flow/data/templates/agents/worker-explorer.toml +24 -0
- codex_flow/data/templates/agents/worker-implementer.toml +49 -0
- codex_flow/data/templates/agents/worker-reviewer.toml +25 -0
- codex_flow/data/templates/flow-pilot-instructions.md +35 -0
- codex_flow/data/templates/skills/flow-pilot/SKILL.md +577 -0
- codex_flow/mcp.py +35 -0
- codex_flow-2.1.13.dist-info/METADATA +342 -0
- codex_flow-2.1.13.dist-info/RECORD +113 -0
- codex_flow-2.1.13.dist-info/WHEEL +5 -0
- codex_flow-2.1.13.dist-info/entry_points.txt +3 -0
- codex_flow-2.1.13.dist-info/licenses/LICENSE +21 -0
- codex_flow-2.1.13.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#compdef codex-flow
|
|
2
|
+
|
|
3
|
+
_codex_flow() {
|
|
4
|
+
local -a commands
|
|
5
|
+
commands=(
|
|
6
|
+
'status:Show installed version and effective FlowPilot strategy'
|
|
7
|
+
'strategy:Inspect or configure the multi-strategy runtime'
|
|
8
|
+
'language:Show or set UI language (auto/zh/en)'
|
|
9
|
+
'update:Pull the checkout and refresh recommendations'
|
|
10
|
+
'doctor:Verify installation, strategy runtime, and telemetry'
|
|
11
|
+
'overlay:Manage the native macOS floating widget'
|
|
12
|
+
'usage:Show deterministic FlowPilot usage summaries and history'
|
|
13
|
+
'telemetry:Telemetry collection, inspection, and historical repair'
|
|
14
|
+
'benchmark-local:Run the built-in benchmark through the local Codex login'
|
|
15
|
+
'benchmark-corpus:Materialize the built-in corpus'
|
|
16
|
+
'benchmark:Run a reproducible benchmark manifest'
|
|
17
|
+
'benchmark-analyze:Analyze benchmark JSONL results'
|
|
18
|
+
'uninstall:Remove codex-flow-managed files'
|
|
19
|
+
'help:Show command help'
|
|
20
|
+
)
|
|
21
|
+
if (( CURRENT == 2 )); then
|
|
22
|
+
_describe 'command' commands
|
|
23
|
+
elif (( CURRENT == 3 )) && [[ "${words[2]}" == strategy ]]; then
|
|
24
|
+
_describe 'strategy command' '(show profiles enabled enable disable set routing plan)'
|
|
25
|
+
elif (( CURRENT == 4 )) && [[ "${words[2]}" == strategy && "${words[3]}" == set ]]; then
|
|
26
|
+
_describe 'strategy profile' '(efficient balanced quality speed)'
|
|
27
|
+
elif (( CURRENT == 4 )) && [[ "${words[2]}" == strategy && "${words[3]}" == routing ]]; then
|
|
28
|
+
_describe 'routing mode' '(adaptive direct delegate)'
|
|
29
|
+
elif (( CURRENT >= 4 )) && [[ "${words[2]}" == strategy && "${words[3]}" == plan ]]; then
|
|
30
|
+
_describe 'plan option' '(--profile --routing --review --fanout --complexity --uncertainty --risk --scope --parallelism --write-conflict --exploration-need --verification-cost --iteration-intensity --writable-workstreams --quality-intent --quota-pressure --max-threads --max-repairs)'
|
|
31
|
+
elif (( CURRENT == 3 )) && [[ "${words[2]}" == language ]]; then
|
|
32
|
+
_describe 'language' '(auto zh en)'
|
|
33
|
+
elif (( CURRENT == 3 )) && [[ "${words[2]}" == benchmark-local || "${words[2]}" == benchmark-corpus ]]; then
|
|
34
|
+
_describe 'profile' '(quick full)'
|
|
35
|
+
elif (( CURRENT == 3 )) && [[ "${words[2]}" == usage || "${words[2]}" == telemetry ]]; then
|
|
36
|
+
_describe 'usage command' '(last list show stats summary repair)'
|
|
37
|
+
elif (( CURRENT >= 4 )) && [[ "${words[2]}" == usage || "${words[2]}" == telemetry ]]; then
|
|
38
|
+
case "${words[3]}" in
|
|
39
|
+
last|show) _describe 'usage option' '(--json)' ;;
|
|
40
|
+
list) _describe 'list option' '(--json --today -n --limit -p --project)' ;;
|
|
41
|
+
stats|summary) _describe 'stats option' '(--json -d --days -p --project)' ;;
|
|
42
|
+
repair) _describe 'repair option' '(--dry-run --json)' ;;
|
|
43
|
+
esac
|
|
44
|
+
fi
|
|
45
|
+
}
|
|
46
|
+
if (( $+functions[compdef] )); then
|
|
47
|
+
compdef _codex_flow codex-flow
|
|
48
|
+
else
|
|
49
|
+
autoload -Uz compinit
|
|
50
|
+
compinit -i >/dev/null 2>&1 || true
|
|
51
|
+
(( $+functions[compdef] )) && compdef _codex_flow codex-flow
|
|
52
|
+
fi
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
$ErrorActionPreference = 'Stop'
|
|
2
|
+
Set-StrictMode -Version 2.0
|
|
3
|
+
|
|
4
|
+
$Repo = if ($env:CODEX_FLOW_REPO) { $env:CODEX_FLOW_REPO } else { 'ParsifalC/codex-flow' }
|
|
5
|
+
$Channel = if ($env:CODEX_FLOW_UPDATE_CHANNEL) { $env:CODEX_FLOW_UPDATE_CHANNEL } else { 'stable' }
|
|
6
|
+
$CodexHome = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $HOME '.codex' }
|
|
7
|
+
$StateDir = Join-Path $CodexHome 'codex-flow'
|
|
8
|
+
$VersionsDir = Join-Path $StateDir 'versions'
|
|
9
|
+
$TempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ('codex-flow-install-' + [Guid]::NewGuid().ToString('N'))
|
|
10
|
+
|
|
11
|
+
function Fail([string]$Message) { throw "codex-flow installer: $Message" }
|
|
12
|
+
function Say([string]$Message) { Write-Host $Message }
|
|
13
|
+
|
|
14
|
+
if ($Channel -ne 'stable') {
|
|
15
|
+
Fail "first-install bootstrap currently supports the stable channel only; install stable first, then switch update.channel to $Channel"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# Windows PowerShell 5 can otherwise negotiate an obsolete TLS version on older systems.
|
|
19
|
+
try {
|
|
20
|
+
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
|
|
21
|
+
} catch {}
|
|
22
|
+
|
|
23
|
+
$archName = if ($env:PROCESSOR_ARCHITEW6432) { $env:PROCESSOR_ARCHITEW6432 } else { $env:PROCESSOR_ARCHITECTURE }
|
|
24
|
+
switch -Regex ($archName) {
|
|
25
|
+
'^(ARM64|arm64)$' { $Arch = 'arm64'; break }
|
|
26
|
+
'^(AMD64|x86_64|amd64)$' { $Arch = 'x86_64'; break }
|
|
27
|
+
default { Fail "unsupported CPU architecture: $archName" }
|
|
28
|
+
}
|
|
29
|
+
$Platform = "windows-$Arch"
|
|
30
|
+
|
|
31
|
+
New-Item -ItemType Directory -Force -Path $TempRoot,$VersionsDir | Out-Null
|
|
32
|
+
try {
|
|
33
|
+
$ManifestPath = Join-Path $TempRoot 'codex-flow-update.json'
|
|
34
|
+
$ManifestUrl = "https://github.com/$Repo/releases/latest/download/codex-flow-update.json"
|
|
35
|
+
Say "-> Resolving latest codex-flow release for $Platform"
|
|
36
|
+
try {
|
|
37
|
+
Invoke-WebRequest -UseBasicParsing -Uri $ManifestUrl -OutFile $ManifestPath
|
|
38
|
+
} catch {
|
|
39
|
+
Fail 'no OTA-enabled stable release is available yet; publish a stable release containing codex-flow-update.json before using the release bootstrap'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
$Manifest = Get-Content -Raw -Encoding UTF8 $ManifestPath | ConvertFrom-Json
|
|
43
|
+
if ($Manifest.channel -ne 'stable') { Fail 'latest release manifest is not stable' }
|
|
44
|
+
$Artifacts = $Manifest.artifacts
|
|
45
|
+
if (-not $Artifacts) { Fail 'release manifest does not contain artifacts' }
|
|
46
|
+
$ArtifactProperty = $Artifacts.PSObject.Properties[$Platform]
|
|
47
|
+
$Artifact = if ($ArtifactProperty) { $ArtifactProperty.Value } else { $null }
|
|
48
|
+
if (-not $Artifact) { Fail "release does not contain artifact for $Platform" }
|
|
49
|
+
if (-not $Artifact.url -or -not $Artifact.sha256 -or -not $Artifact.format) { Fail 'release manifest contains an incomplete artifact entry' }
|
|
50
|
+
if ($Artifact.format -ne 'zip') { Fail "unsupported Windows release archive format: $($Artifact.format)" }
|
|
51
|
+
|
|
52
|
+
$Version = [string]$Manifest.version
|
|
53
|
+
if (-not $Version) { Fail 'release manifest does not contain a version' }
|
|
54
|
+
$Archive = Join-Path $TempRoot 'codex-flow.zip'
|
|
55
|
+
Say "-> Downloading codex-flow v$Version"
|
|
56
|
+
Invoke-WebRequest -UseBasicParsing -Uri ([string]$Artifact.url) -OutFile $Archive
|
|
57
|
+
|
|
58
|
+
$ActualSha = (Get-FileHash -Algorithm SHA256 -Path $Archive).Hash.ToLowerInvariant()
|
|
59
|
+
$ExpectedSha = ([string]$Artifact.sha256).Trim().ToLowerInvariant()
|
|
60
|
+
if ($ActualSha -ne $ExpectedSha) { Fail 'SHA-256 mismatch for downloaded release' }
|
|
61
|
+
Say 'OK SHA-256 verified'
|
|
62
|
+
|
|
63
|
+
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
64
|
+
$ExtractDir = Join-Path $TempRoot 'package'
|
|
65
|
+
New-Item -ItemType Directory -Force -Path $ExtractDir | Out-Null
|
|
66
|
+
$ExtractRoot = [System.IO.Path]::GetFullPath($ExtractDir + [System.IO.Path]::DirectorySeparatorChar)
|
|
67
|
+
$Zip = [System.IO.Compression.ZipFile]::OpenRead($Archive)
|
|
68
|
+
try {
|
|
69
|
+
foreach ($Entry in $Zip.Entries) {
|
|
70
|
+
$Target = [System.IO.Path]::GetFullPath((Join-Path $ExtractDir $Entry.FullName))
|
|
71
|
+
if (-not $Target.StartsWith($ExtractRoot, [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
72
|
+
Fail "unsafe archive member: $($Entry.FullName)"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} finally {
|
|
76
|
+
$Zip.Dispose()
|
|
77
|
+
}
|
|
78
|
+
[System.IO.Compression.ZipFile]::ExtractToDirectory($Archive, $ExtractDir)
|
|
79
|
+
|
|
80
|
+
$PackageRoot = Join-Path $ExtractDir "codex-flow-$Version"
|
|
81
|
+
$Installer = Join-Path $PackageRoot 'install.ps1'
|
|
82
|
+
if (-not (Test-Path -LiteralPath $Installer -PathType Leaf)) { Fail 'release package does not contain install.ps1 at the expected root' }
|
|
83
|
+
|
|
84
|
+
$VersionDir = Join-Path $VersionsDir $Version
|
|
85
|
+
$StageDir = Join-Path $VersionsDir ('.install-' + $Version + '-' + [Guid]::NewGuid().ToString('N'))
|
|
86
|
+
Move-Item -LiteralPath $PackageRoot -Destination $StageDir
|
|
87
|
+
|
|
88
|
+
if (Test-Path -LiteralPath $VersionDir) {
|
|
89
|
+
$ExistingSource = Join-Path $StateDir 'source'
|
|
90
|
+
$CurrentSource = if (Test-Path $ExistingSource) { (Get-Content -Raw -Encoding UTF8 $ExistingSource).Trim() } else { '' }
|
|
91
|
+
if ($CurrentSource -and ([System.IO.Path]::GetFullPath($CurrentSource) -eq [System.IO.Path]::GetFullPath($VersionDir))) {
|
|
92
|
+
$BackupDir = Join-Path $VersionsDir ('.previous-install-' + $Version + '-' + [Guid]::NewGuid().ToString('N'))
|
|
93
|
+
Move-Item -LiteralPath $VersionDir -Destination $BackupDir
|
|
94
|
+
try {
|
|
95
|
+
Move-Item -LiteralPath $StageDir -Destination $VersionDir
|
|
96
|
+
Remove-Item -LiteralPath $BackupDir -Recurse -Force -ErrorAction SilentlyContinue
|
|
97
|
+
} catch {
|
|
98
|
+
if (-not (Test-Path $VersionDir) -and (Test-Path $BackupDir)) { Move-Item -LiteralPath $BackupDir -Destination $VersionDir }
|
|
99
|
+
throw
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
Remove-Item -LiteralPath $VersionDir -Recurse -Force
|
|
103
|
+
Move-Item -LiteralPath $StageDir -Destination $VersionDir
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
Move-Item -LiteralPath $StageDir -Destination $VersionDir
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
$PersistentInstaller = Join-Path $VersionDir 'install.ps1'
|
|
110
|
+
Say "-> Installing codex-flow v$Version"
|
|
111
|
+
& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $PersistentInstaller
|
|
112
|
+
if ($LASTEXITCODE -ne 0) { Fail "install.ps1 exited with code $LASTEXITCODE" }
|
|
113
|
+
|
|
114
|
+
$Doctor = Join-Path $StateDir 'doctor.py'
|
|
115
|
+
if (Test-Path $Doctor) {
|
|
116
|
+
Say '-> Running doctor'
|
|
117
|
+
& python3 $Doctor
|
|
118
|
+
if ($LASTEXITCODE -ne 0) { Fail "doctor exited with code $LASTEXITCODE" }
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
Say ''
|
|
122
|
+
Say "OK codex-flow v$Version installation complete"
|
|
123
|
+
Say ' Fully restart Codex to activate the new Agent / Skill / Hook / policy snapshot.'
|
|
124
|
+
} finally {
|
|
125
|
+
Remove-Item -LiteralPath $TempRoot -Recurse -Force -ErrorAction SilentlyContinue
|
|
126
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
REPO="${CODEX_FLOW_REPO:-ParsifalC/codex-flow}"
|
|
5
|
+
CHANNEL="${CODEX_FLOW_UPDATE_CHANNEL:-stable}"
|
|
6
|
+
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
|
|
7
|
+
STATE_DIR="$CODEX_HOME/codex-flow"
|
|
8
|
+
TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/codex-flow-install.XXXXXX")"
|
|
9
|
+
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
10
|
+
|
|
11
|
+
say() { printf '%s\n' "$*"; }
|
|
12
|
+
fail() { printf 'codex-flow installer: %s\n' "$*" >&2; exit 1; }
|
|
13
|
+
|
|
14
|
+
command -v curl >/dev/null 2>&1 || fail "curl is required"
|
|
15
|
+
command -v python3 >/dev/null 2>&1 || fail "python3 is required"
|
|
16
|
+
|
|
17
|
+
case "$(uname -s)" in
|
|
18
|
+
Darwin) os="darwin" ;;
|
|
19
|
+
Linux) os="linux" ;;
|
|
20
|
+
*) fail "unsupported operating system: $(uname -s)" ;;
|
|
21
|
+
esac
|
|
22
|
+
|
|
23
|
+
case "$(uname -m)" in
|
|
24
|
+
arm64|aarch64) arch="arm64" ;;
|
|
25
|
+
x86_64|amd64) arch="x86_64" ;;
|
|
26
|
+
*) fail "unsupported CPU architecture: $(uname -m)" ;;
|
|
27
|
+
esac
|
|
28
|
+
|
|
29
|
+
platform="$os-$arch"
|
|
30
|
+
|
|
31
|
+
if [[ "$CHANNEL" != "stable" ]]; then
|
|
32
|
+
fail "first-install bootstrap currently supports the stable channel only; install stable first, then switch update.channel to $CHANNEL"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
manifest_url="https://github.com/$REPO/releases/latest/download/codex-flow-update.json"
|
|
36
|
+
manifest="$TMP_DIR/codex-flow-update.json"
|
|
37
|
+
say "→ Resolving latest codex-flow release for $platform"
|
|
38
|
+
if ! curl -fL --retry 3 --connect-timeout 15 "$manifest_url" -o "$manifest"; then
|
|
39
|
+
fail "no OTA-enabled stable release is available yet; publish a stable release containing codex-flow-update.json before using the release bootstrap"
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
IFS=$'\t' read -r version artifact_url expected_sha archive_format < <(python3 - "$manifest" "$platform" <<'PY'
|
|
43
|
+
import json, sys
|
|
44
|
+
from pathlib import Path
|
|
45
|
+
manifest_path, platform = Path(sys.argv[1]), sys.argv[2]
|
|
46
|
+
data = json.loads(manifest_path.read_text(encoding="utf-8"))
|
|
47
|
+
if data.get("channel") != "stable":
|
|
48
|
+
raise SystemExit("latest release manifest is not stable")
|
|
49
|
+
artifact = (data.get("artifacts") or {}).get(platform)
|
|
50
|
+
if not artifact:
|
|
51
|
+
raise SystemExit(f"release does not contain artifact for {platform}")
|
|
52
|
+
for key in ("url", "sha256", "format"):
|
|
53
|
+
if not artifact.get(key):
|
|
54
|
+
raise SystemExit(f"artifact is missing {key}")
|
|
55
|
+
print("\t".join((
|
|
56
|
+
data.get("version") or "unknown",
|
|
57
|
+
artifact["url"],
|
|
58
|
+
artifact["sha256"].lower(),
|
|
59
|
+
artifact["format"],
|
|
60
|
+
)))
|
|
61
|
+
PY
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
[[ -n "${version:-}" && -n "${artifact_url:-}" && -n "${expected_sha:-}" && -n "${archive_format:-}" ]] || fail "invalid release manifest"
|
|
65
|
+
|
|
66
|
+
case "$archive_format" in
|
|
67
|
+
tar.gz) archive="$TMP_DIR/codex-flow.tar.gz" ;;
|
|
68
|
+
zip) archive="$TMP_DIR/codex-flow.zip" ;;
|
|
69
|
+
*) fail "unsupported release archive format: $archive_format" ;;
|
|
70
|
+
esac
|
|
71
|
+
|
|
72
|
+
say "→ Downloading codex-flow v$version"
|
|
73
|
+
curl -fL --retry 3 --connect-timeout 15 "$artifact_url" -o "$archive"
|
|
74
|
+
|
|
75
|
+
actual_sha="$(python3 - "$archive" <<'PY'
|
|
76
|
+
import hashlib, sys
|
|
77
|
+
h = hashlib.sha256()
|
|
78
|
+
with open(sys.argv[1], "rb") as f:
|
|
79
|
+
for chunk in iter(lambda: f.read(1024 * 1024), b""):
|
|
80
|
+
h.update(chunk)
|
|
81
|
+
print(h.hexdigest())
|
|
82
|
+
PY
|
|
83
|
+
)"
|
|
84
|
+
[[ "$actual_sha" == "$expected_sha" ]] || fail "SHA-256 mismatch for downloaded release"
|
|
85
|
+
say "✓ SHA-256 verified"
|
|
86
|
+
|
|
87
|
+
package_dir="$TMP_DIR/package"
|
|
88
|
+
mkdir -p "$package_dir"
|
|
89
|
+
case "$archive_format" in
|
|
90
|
+
tar.gz)
|
|
91
|
+
command -v tar >/dev/null 2>&1 || fail "tar is required"
|
|
92
|
+
tar -xzf "$archive" -C "$package_dir"
|
|
93
|
+
;;
|
|
94
|
+
zip)
|
|
95
|
+
command -v unzip >/dev/null 2>&1 || fail "unzip is required"
|
|
96
|
+
unzip -q "$archive" -d "$package_dir"
|
|
97
|
+
;;
|
|
98
|
+
esac
|
|
99
|
+
|
|
100
|
+
install_script="$(find "$package_dir" -type f -name install.sh -print | head -n 1)"
|
|
101
|
+
[[ -n "$install_script" ]] || fail "release package does not contain install.sh"
|
|
102
|
+
extracted_root="$(cd "$(dirname "$install_script")" && pwd)"
|
|
103
|
+
|
|
104
|
+
versions_dir="$STATE_DIR/versions"
|
|
105
|
+
version_dir="$versions_dir/$version"
|
|
106
|
+
staged_version_dir="$versions_dir/.${version}.installing.$$"
|
|
107
|
+
mkdir -p "$versions_dir"
|
|
108
|
+
rm -rf "$staged_version_dir"
|
|
109
|
+
mkdir -p "$staged_version_dir"
|
|
110
|
+
cp -R "$extracted_root"/. "$staged_version_dir"/
|
|
111
|
+
[[ -f "$staged_version_dir/install.sh" ]] || fail "staged release package is incomplete"
|
|
112
|
+
rm -rf "$version_dir"
|
|
113
|
+
mv "$staged_version_dir" "$version_dir"
|
|
114
|
+
|
|
115
|
+
say "→ Installing codex-flow v$version"
|
|
116
|
+
(
|
|
117
|
+
cd "$version_dir"
|
|
118
|
+
bash ./install.sh
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
if [[ "$os" == "darwin" ]]; then
|
|
122
|
+
flowpilot="$STATE_DIR/bin/FlowPilot"
|
|
123
|
+
legacy_overlay="$STATE_DIR/bin/codex-flow-overlay"
|
|
124
|
+
if [[ -s "$flowpilot" && -x "$flowpilot" ]]; then
|
|
125
|
+
overlay_bin="$flowpilot"
|
|
126
|
+
elif [[ -s "$legacy_overlay" && -x "$legacy_overlay" ]]; then
|
|
127
|
+
overlay_bin="$legacy_overlay"
|
|
128
|
+
else
|
|
129
|
+
fail "macOS release installed successfully, but no prebuilt FlowPilot binary was found"
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
say "→ Starting FlowPilot"
|
|
133
|
+
"$overlay_bin" stop >/dev/null 2>&1 || true
|
|
134
|
+
pkill -f "FlowPilot.*start|codex-flow-overlay.*start|bin/FlowPilot" 2>/dev/null || true
|
|
135
|
+
sleep 0.2
|
|
136
|
+
nohup "$overlay_bin" start >/dev/null 2>&1 &
|
|
137
|
+
disown $! 2>/dev/null || true
|
|
138
|
+
sleep 0.4
|
|
139
|
+
|
|
140
|
+
if pgrep -f "FlowPilot.*start|codex-flow-overlay.*start|bin/FlowPilot" >/dev/null 2>&1; then
|
|
141
|
+
say "✓ FlowPilot is running in the background"
|
|
142
|
+
else
|
|
143
|
+
say "! codex-flow installed, but FlowPilot did not stay running. Retry with: codex-flow overlay start" >&2
|
|
144
|
+
fi
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
doctor="$STATE_DIR/doctor.py"
|
|
148
|
+
if [[ -f "$doctor" ]]; then
|
|
149
|
+
say "→ Running doctor"
|
|
150
|
+
python3 "$doctor"
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
say ""
|
|
154
|
+
say "✓ codex-flow v$version installation complete"
|
|
155
|
+
say " Fully restart Codex to activate the new Agent / Skill / Hook / policy snapshot."
|