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
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.7
0.0.8
1 change: 1 addition & 0 deletions config/sources.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ chatgpt-download distribution https://persistent.oaistatic.com/codex-app-prod/Co
chatgpt-distribution distribution https://persistent.oaistatic.com/codex-app-prod/
chatgpt-releases metadata https://persistent.oaistatic.com/codex-app-prod/appcast.xml
kiro-distribution distribution https://prod.download.desktop.kiro.dev/
kiro-releases metadata https://prod.download.desktop.kiro.dev/stable/metadata-dmg-darwin-arm64-stable.json
kiro-cli-distribution distribution https://prod.download.cli.kiro.dev/stable/
kiro-cli-releases metadata https://prod.download.cli.kiro.dev/stable/latest/manifest.json
claude-releases metadata https://downloads.claude.ai/claude-code-releases/latest
Expand Down
6 changes: 3 additions & 3 deletions docs/sources.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Sources and update procedure

Source baseline reviewed 2026-09-28. [`config/sources.tsv`](../config/sources.tsv) is the only executable allowlist for native installers, distributions, metadata endpoints, and the Powerlevel10k repository. Editing a link in this document does not change installer behavior. Any source change must also update the manifest fixture and pass the repository checks.
Source baseline reviewed 2026-10-27. [`config/sources.tsv`](../config/sources.tsv) is the only executable allowlist for native installers, distributions, metadata endpoints, and the Powerlevel10k repository. Editing a link in this document does not change installer behavior. Any source change must also update the manifest fixture and pass the repository checks.

Homebrew formulae and casks use the source declared by their official definitions. The default Doubao flow reads current cask metadata from Homebrew's official JSON API, while optional `--with-sogou` reads the local cask metadata. Both additionally restrict the resolved URL to its official distribution prefix in `sources.tsv` and download the fixed-checksum ZIP without installing it.
Homebrew formulae and casks use the source declared by their official definitions. The default Doubao flow reads current cask metadata from Homebrew's official JSON API, accepts both its original build-only filename and its current build-plus-release filename, and requires every filename component to match the corresponding cask version field. Optional `--with-sogou` reads the local cask metadata. Both additionally restrict the resolved URL to its official distribution prefix in `sources.tsv` and download the fixed-checksum ZIP without installing it.

## Installer and configuration sources

Expand Down Expand Up @@ -34,7 +34,7 @@ Homebrew formulae and casks use the source declared by their official definition

Default mode checks each selected desktop app and downloads an official DMG when it is absent. Docker Desktop requires `--with-docker` after the user reviews the current vendor terms. iTerm2 and VS Code use casks. AI CLIs prefer official scripts. `--managed-desktop` enables app placement and managed Kiro hooks without selecting Docker.

ChatGPT uses the fixed official DMG path and its appcast. Kiro selects the stable arm64 DMG from the official download page. Claude Desktop is accessed only with `--with-claude`, first through the vendor's latest-DMG redirect and then through the official release feed as a fallback. Chrome and selected Docker Desktop use official rolling DMG addresses. A normal rerun reuses selected packages whose digests still match; `--update` refreshes them.
ChatGPT uses the fixed official DMG path and its appcast. Kiro selects the exact current stable arm64 DMG from the vendor's architecture-specific release metadata. Claude Desktop is accessed only with `--with-claude`, first through the vendor's latest-DMG redirect and then through the official release feed as a fallback. Chrome and selected Docker Desktop use official rolling DMG addresses. A normal rerun reuses selected packages whose digests still match; `--update` refreshes them.

Claude Code and Codex use their own native installers and metadata. Default Kiro CLI runs the vendor installer and preserves its replacement prompt and onboarding. Managed Kiro resolves a digest from the official stable manifest. Recorded hashes support caching and audit; they do not represent an independent vendor signature.

Expand Down
2 changes: 1 addition & 1 deletion scripts/battery.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
set -euo pipefail

BATTERY_TOOL_VERSION=0.0.7
BATTERY_TOOL_VERSION=0.0.8
BATTERY_SCHEMA_VERSION=1
MAX_RETAINED_EVENTS=256

Expand Down
27 changes: 17 additions & 10 deletions scripts/official_ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,24 @@ def release(name, catalog=None, fetch=fetch_text):
_, _, version, build = max(entries)
return dict(version=version, build=build, url=catalog['chatgpt-download'])
if name == 'kiro':
entries = []
data = json.loads(fetch(catalog['kiro-releases']))
if not isinstance(data, dict):
raise ValueError('Unexpected Kiro stable release metadata')
version = data.get('currentRelease')
releases = data.get('releases')
if (not isinstance(version, str) or not re.fullmatch(r'\d+\.\d+\.\d+', version)
or not isinstance(releases, list) or not all(isinstance(item, dict) for item in releases)):
raise ValueError('Unexpected Kiro stable release metadata')
version_key(version)
entries = [item['updateTo'] for item in releases
if item.get('version') == version and isinstance(item.get('updateTo'), dict)]
if len(entries) != 1 or entries[0].get('version') != version:
raise ValueError('Unexpected Kiro stable release metadata')
prefix = catalog['kiro-distribution']
for url in re.findall(r'https://[^\s"<>\\]+', fetch(catalog['kiro'])):
if not url.startswith(prefix):
continue
match = re.fullmatch(r'releases/stable/darwin-arm64/signed/(\d+\.\d+\.\d+)/kiro-ide-\1-stable-darwin-arm64\.dmg', url[len(prefix):])
if match:
entries.append((version_key(match[1]), match[1], official_url(url, prefix)))
if not entries:
raise ValueError('No stable Apple Silicon Kiro DMG on official download page')
_, version, url = max(entries)
url = official_url(entries[0].get('url', ''), prefix)
expected = f'releases/stable/darwin-arm64/signed/{version}/kiro-ide-{version}-stable-darwin-arm64.dmg'
if url[len(prefix):] != expected:
raise ValueError('Unexpected Kiro stable Apple Silicon DMG')
return dict(version=version, url=url)
if name == 'kiro-cli':
data = json.loads(fetch(catalog['kiro-cli-releases']))
Expand Down
9 changes: 7 additions & 2 deletions scripts/prepare-doubao.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,15 @@ def metadata():
prefix = sources['doubao-input-download']
match = re.fullmatch(
r'https://lf-wave\.doubaocdn\.com/obj/doubao-ime/app/macos/'
r'DoubaoImeInstaller_v([0-9]+)_release\.zip', item['url'])
r'DoubaoImeInstaller_v([0-9]+)_release'
r'(?:_([0-9]+(?:_[0-9]+)*))?\.zip', item['url'])
versions = item['version'].split(',')
release = match.group(2) if match else None
release_matches = ((len(versions) == 2 and release is None)
or (len(versions) == 3 and release == versions[2]
and re.fullmatch(r'[0-9]+(?:_[0-9]+)*', versions[2])))
if (item['token'] != 'doubaoime' or not item['url'].startswith(prefix) or not match
or len(versions) != 2 or not re.fullmatch(r'[0-9]+(?:\.[0-9]+)+', versions[0])
or not release_matches or not re.fullmatch(r'[0-9]+(?:\.[0-9]+)+', versions[0])
or not re.fullmatch(r'[0-9]+', versions[1]) or match.group(1) != versions[1]
or not re.fullmatch(r'[a-f0-9]{64}', item['sha256'])):
raise ValueError('Doubao source/checksum format changed; review the official cask before updating.')
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/config-golden.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"obsidian-vault/_templates/.gitkeep": "\n",
"repository-files.txt": ".gitignore\n.github/pull_request_template.md\n.github/workflows/quality.yml\n1bite\nAGENTS.md\nLICENSE\nMakefile\nREADME.md\nVERSION\napps/README.md\napps/qbittorrent/README.md\napps/qbittorrent/compose.yaml\napps/qbittorrent/qbt.py\napps/qbittorrent/qbt.sh\napps/qbittorrent/smoke-test.py\nassets/logo.png\nconfig/casks.tsv\nconfig/claude-settings.json\nconfig/codex-config.toml\nconfig/download.curlrc\nconfig/env.zsh\nconfig/font-casks.tsv\nconfig/formulae.txt\nconfig/git-defaults.json\nconfig/gitignore-global\nconfig/iterm2-profile.json\nconfig/kiro-permissions.json\nconfig/obsidian-vault/.gitignore\nconfig/obsidian-vault/.obsidian/app.json\nconfig/obsidian-vault/.obsidian/appearance.json\nconfig/obsidian-vault/.obsidian/core-plugins.json\nconfig/obsidian-vault/.obsidian/graph.json\nconfig/obsidian-vault/.obsidian/snippets/wide.css\nconfig/obsidian-vault/.obsidian/templates.json\nconfig/obsidian-vault/.obsidian/themes/Tokyo Night/LICENSE\nconfig/obsidian-vault/.obsidian/themes/Tokyo Night/manifest.json\nconfig/obsidian-vault/.obsidian/themes/Tokyo Night/theme.css\nconfig/obsidian-vault/_attachments/.gitkeep\nconfig/obsidian-vault/_templates/.gitkeep\nconfig/repository-files.txt\nconfig/shell.zsh\nconfig/sources.tsv\nconfig/vimrc\nconfig/vscode-extensions.txt\nconfig/vscode-settings.json\nconfig/zsh/development.zsh\nconfig/zsh/framework.zsh\nconfig/zsh/git-functions.zsh\nconfig/zsh/media.zsh\nconfig/zsh/options.zsh\nconfig/zsh/terminal.zsh\nconfig/zsh/tools.zsh\nconfig/zsh/utilities.zsh\ndocs/automation.md\ndocs/battery.md\ndocs/battery.schema.json\ndocs/development.md\ndocs/installation.md\ndocs/maintenance.md\ndocs/obsidian.md\ndocs/result.schema.json\ndocs/shell-editor.md\ndocs/sources.md\ndocs/troubleshooting.md\ndocs/updates.schema.json\nscripts/battery.sh\nscripts/check-change.py\nscripts/check-format.py\nscripts/check-repository.py\nscripts/check-updates.py\nscripts/configure.py\nscripts/desktop.py\nscripts/docker-smoke.sh\nscripts/editor.sh\nscripts/inventory.py\nscripts/kiro-shell.py\nscripts/manual.py\nscripts/ob.py\nscripts/official_ai.py\nscripts/plain-log.awk\nscripts/prepare-doubao.py\nscripts/prepare-sogou.py\nscripts/quality.sh\nscripts/runtime-smoke.py\nscripts/session.sh\nscripts/welcome.sh\nscripts/verify.sh\ntests/fixtures/battery/pmset-log-batt-uppercase.txt\ntests/fixtures/battery/pmset-log-batt.txt\ntests/fixtures/config-golden.json\ntests/test_battery.py\ntests/test_desktop.py\ntests/test_doubao.py\ntests/test_editor.py\ntests/test_interruptions.py\ntests/test_kiro_shell.py\ntests/test_maintenance.py\ntests/test_obsidian.py\ntests/test_official_ai.py\ntests/test_qbittorrent.py\ntests/test_repository.py\ntests/test_session.py\ntests/test_setup.py\ntests/test_sogou.py\ntests/test_welcome.py\n",
"shell.zsh": "# Managed by 1bite. Personal overrides belong after the source in .zshrc.\nsource \"${${(%):-%N}:A:h}/env.zsh\"\n[[ -o interactive ]] || return 0\n\nsetup_shell_directory=\"${${(%):-%N}:A:h}\"\nfor setup_shell_module in framework options tools development utilities media git-functions terminal; do\n setup_shell_path=\"$setup_shell_directory/zsh/$setup_shell_module.zsh\"\n [[ -r \"$setup_shell_path\" ]] || { print -u2 \"1bite: missing Zsh module: $setup_shell_path\"; return 1; }\n source \"$setup_shell_path\" || return\ndone\nunset setup_shell_directory setup_shell_module setup_shell_path\n",
"sources.tsv": "homebrew\tinstaller\thttps://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh\nclaude\tinstaller\thttps://claude.ai/install.sh\ncodex\tinstaller\thttps://chatgpt.com/codex/install.sh\nkiro-cli\tinstaller\thttps://cli.kiro.dev/install\nchatgpt\tdocumentation\thttps://learn.chatgpt.com/docs/app\nkiro\tdocumentation\thttps://kiro.dev/downloads/\nchatgpt-download\tdistribution\thttps://persistent.oaistatic.com/codex-app-prod/Codex.dmg\nchatgpt-distribution\tdistribution\thttps://persistent.oaistatic.com/codex-app-prod/\nchatgpt-releases\tmetadata\thttps://persistent.oaistatic.com/codex-app-prod/appcast.xml\nkiro-distribution\tdistribution\thttps://prod.download.desktop.kiro.dev/\nkiro-cli-distribution\tdistribution\thttps://prod.download.cli.kiro.dev/stable/\nkiro-cli-releases\tmetadata\thttps://prod.download.cli.kiro.dev/stable/latest/manifest.json\nclaude-releases\tmetadata\thttps://downloads.claude.ai/claude-code-releases/latest\ncodex-releases\tmetadata\thttps://releases.openai.com/codex/channels/latest\nohmyzsh\tinstaller\thttps://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh\npowerlevel10k\tgit\thttps://github.com/romkatv/powerlevel10k.git\nneofetch\tinstaller\thttps://raw.githubusercontent.com/dylanaraps/neofetch/7.1.0/neofetch\nneofetch-sha256\tchecksum\t3dc33493e54029fb1528251552093a9f9a2894fcf94f9c3a6f809136a42348c7\ndoubao-input-download\tdistribution\thttps://lf-wave.doubaocdn.com/obj/doubao-ime/app/macos/\ndoubao-input-metadata\tmetadata\thttps://formulae.brew.sh/api/cask/doubaoime.json\nsogou-download\tdistribution\thttps://ime.gtimg.com/pc/\nhomebrew-api\tconnectivity\thttps://formulae.brew.sh/api/formula/go.json\ngithub\tconnectivity\thttps://github.com\nghcr\tconnectivity\thttps://ghcr.io/v2/\nnpm\tconnectivity\thttps://registry.npmjs.org/\nanthropic\tconnectivity\thttps://claude.ai/install.sh\nopenai\tconnectivity\thttps://chatgpt.com/codex/install.sh\nmaintenance-catalog\tmetadata\thttps://formulae.brew.sh/api/\nmaintenance-aliases\tmetadata\thttps://raw.githubusercontent.com/Homebrew/homebrew-core/HEAD/Aliases/\nmaintenance-gallery\tmetadata\thttps://marketplace.visualstudio.com/_apis/public/gallery/extensionquery\nmaintenance-homebrew\tmetadata\thttps://api.github.com/repos/Homebrew/brew/releases/latest\nmaintenance-homebrew-release\tmetadata\thttps://github.com/Homebrew/brew/releases/latest\nmaintenance-one-bite\tgit\thttps://github.com/1set/1bite.git\nmaintenance-ohmyzsh\tgit\thttps://github.com/ohmyzsh/ohmyzsh.git\nmaintenance-charm\tmetadata\thttps://raw.githubusercontent.com/charmbracelet/homebrew-tap/master/\ngoogle-chrome-download\tdistribution\thttps://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg\ndocker-desktop-download\tdistribution\thttps://desktop.docker.com/mac/main/arm64/Docker.dmg\nclaude-desktop-releases\tmetadata\thttps://downloads.claude.ai/releases/darwin/universal/RELEASES.json\nclaude-desktop-distribution\tdistribution\thttps://downloads.claude.ai/releases/darwin/universal/\nclaude-desktop-download\tdistribution\thttps://claude.ai/api/desktop/darwin/universal/dmg/latest/redirect\n",
"sources.tsv": "homebrew\tinstaller\thttps://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh\nclaude\tinstaller\thttps://claude.ai/install.sh\ncodex\tinstaller\thttps://chatgpt.com/codex/install.sh\nkiro-cli\tinstaller\thttps://cli.kiro.dev/install\nchatgpt\tdocumentation\thttps://learn.chatgpt.com/docs/app\nkiro\tdocumentation\thttps://kiro.dev/downloads/\nchatgpt-download\tdistribution\thttps://persistent.oaistatic.com/codex-app-prod/Codex.dmg\nchatgpt-distribution\tdistribution\thttps://persistent.oaistatic.com/codex-app-prod/\nchatgpt-releases\tmetadata\thttps://persistent.oaistatic.com/codex-app-prod/appcast.xml\nkiro-distribution\tdistribution\thttps://prod.download.desktop.kiro.dev/\nkiro-releases\tmetadata\thttps://prod.download.desktop.kiro.dev/stable/metadata-dmg-darwin-arm64-stable.json\nkiro-cli-distribution\tdistribution\thttps://prod.download.cli.kiro.dev/stable/\nkiro-cli-releases\tmetadata\thttps://prod.download.cli.kiro.dev/stable/latest/manifest.json\nclaude-releases\tmetadata\thttps://downloads.claude.ai/claude-code-releases/latest\ncodex-releases\tmetadata\thttps://releases.openai.com/codex/channels/latest\nohmyzsh\tinstaller\thttps://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh\npowerlevel10k\tgit\thttps://github.com/romkatv/powerlevel10k.git\nneofetch\tinstaller\thttps://raw.githubusercontent.com/dylanaraps/neofetch/7.1.0/neofetch\nneofetch-sha256\tchecksum\t3dc33493e54029fb1528251552093a9f9a2894fcf94f9c3a6f809136a42348c7\ndoubao-input-download\tdistribution\thttps://lf-wave.doubaocdn.com/obj/doubao-ime/app/macos/\ndoubao-input-metadata\tmetadata\thttps://formulae.brew.sh/api/cask/doubaoime.json\nsogou-download\tdistribution\thttps://ime.gtimg.com/pc/\nhomebrew-api\tconnectivity\thttps://formulae.brew.sh/api/formula/go.json\ngithub\tconnectivity\thttps://github.com\nghcr\tconnectivity\thttps://ghcr.io/v2/\nnpm\tconnectivity\thttps://registry.npmjs.org/\nanthropic\tconnectivity\thttps://claude.ai/install.sh\nopenai\tconnectivity\thttps://chatgpt.com/codex/install.sh\nmaintenance-catalog\tmetadata\thttps://formulae.brew.sh/api/\nmaintenance-aliases\tmetadata\thttps://raw.githubusercontent.com/Homebrew/homebrew-core/HEAD/Aliases/\nmaintenance-gallery\tmetadata\thttps://marketplace.visualstudio.com/_apis/public/gallery/extensionquery\nmaintenance-homebrew\tmetadata\thttps://api.github.com/repos/Homebrew/brew/releases/latest\nmaintenance-homebrew-release\tmetadata\thttps://github.com/Homebrew/brew/releases/latest\nmaintenance-one-bite\tgit\thttps://github.com/1set/1bite.git\nmaintenance-ohmyzsh\tgit\thttps://github.com/ohmyzsh/ohmyzsh.git\nmaintenance-charm\tmetadata\thttps://raw.githubusercontent.com/charmbracelet/homebrew-tap/master/\ngoogle-chrome-download\tdistribution\thttps://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg\ndocker-desktop-download\tdistribution\thttps://desktop.docker.com/mac/main/arm64/Docker.dmg\nclaude-desktop-releases\tmetadata\thttps://downloads.claude.ai/releases/darwin/universal/RELEASES.json\nclaude-desktop-distribution\tdistribution\thttps://downloads.claude.ai/releases/darwin/universal/\nclaude-desktop-download\tdistribution\thttps://claude.ai/api/desktop/darwin/universal/dmg/latest/redirect\n",
"vimrc": "\" Managed by 1bite. Personal overrides belong after the source line in ~/.vimrc.\nscriptencoding utf-8\nset encoding=utf-8\n\nset modelines=0\n\nset backspace=2\nset nocompatible\n\nset nobackup\nset nowritebackup\nset noswapfile\nset noundofile\n\nsyntax on\nset number\n\nset ruler\nset smartindent shiftwidth=4\nset tabstop=4\nset expandtab\n\nset list\nset listchars=tab:»·,trail:·,extends:>,precedes:<\n\ncom E e.\n\ncab W! w!\ncab Q! q!\ncab Wq wq\ncab Wa wa\ncab wQ wq\ncab WQ wq\ncab W w\ncab Q q\n",
"vscode-extensions.txt": "golang.go\nms-python.python\ncharliermarsh.ruff\ndbaeumer.vscode-eslint\nesbenp.prettier-vscode\nredhat.vscode-yaml\ntimonwong.shellcheck\nms-vscode.sublime-keybindings\n",
"vscode-settings.json": "{\n \"terminal.integrated.defaultProfile.osx\": \"zsh\",\n \"terminal.integrated.profiles.osx\": {\n \"zsh\": {\n \"path\": \"/bin/zsh\",\n \"args\": [\"-l\"]\n }\n },\n \"workbench.colorTheme\": \"Default Dark Modern\"\n}\n",
Expand Down
Loading
Loading