orbit-install 1.0.0__tar.gz

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.
@@ -0,0 +1,18 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
8
+ *.egg
9
+ .venv/
10
+ venv/
11
+ .env
12
+ *.duckdb
13
+ *.duckdb.wal
14
+ *.db-journal
15
+ .DS_Store
16
+ CLAUDE.local.md
17
+ .serena/
18
+ .playwright-mcp/
@@ -0,0 +1,86 @@
1
+ Metadata-Version: 2.4
2
+ Name: orbit-install
3
+ Version: 1.0.0
4
+ Summary: Bootstrap installer for Orbit - the project manager for Claude Code
5
+ Project-URL: Homepage, https://github.com/tomerbr1/claude-orbit
6
+ Project-URL: Repository, https://github.com/tomerbr1/claude-orbit
7
+ Project-URL: Issues, https://github.com/tomerbr1/claude-orbit/issues
8
+ Author-email: Tomer Brami <tomerbrami@gmail.com>
9
+ License-Expression: MIT
10
+ Keywords: bootstrap,claude,installer,orbit,plugin
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: System :: Installation/Setup
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: pyfiglet>=1.0.0
22
+ Requires-Dist: rich>=13.7.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
25
+ Requires-Dist: pytest>=7.0; extra == 'dev'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # orbit-install
29
+
30
+ Bootstrap installer for [Orbit](https://github.com/tomerbr1/claude-orbit), the project manager for Claude Code.
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ uvx orbit-install
36
+ # or
37
+ pipx run orbit-install
38
+ ```
39
+
40
+ The interactive wizard asks which components to install. Default is all:
41
+
42
+ | Component | What it does |
43
+ |----------------|------------------------------------------------------------------------|
44
+ | Plugin | Registers the orbit plugin with Claude Code (slash commands, MCP, hooks) |
45
+ | Dashboard | Installs `orbit-dashboard` pip package + launchd/systemd service on port 8787 |
46
+ | orbit-auto CLI | Installs `orbit-auto` for autonomous task execution |
47
+ | Statusline | Wires `~/.claude/settings.json` to run `orbit-statusline` on every prompt |
48
+ | Rules | Copies rule files into `~/.claude/rules/` |
49
+ | User commands | Copies `/whats-new` and `/optimize-prompt` into `~/.claude/commands/` |
50
+
51
+ ## Non-interactive
52
+
53
+ ```bash
54
+ uvx orbit-install --all # install everything
55
+ uvx orbit-install --dashboard --statusline # install a subset
56
+ uvx orbit-install --update # refresh everything
57
+ uvx orbit-install --uninstall # remove everything (preserves user data)
58
+ ```
59
+
60
+ ## Maintainer mode
61
+
62
+ From a clone of `claude-orbit`:
63
+
64
+ ```bash
65
+ git clone https://github.com/tomerbr1/claude-orbit.git
66
+ cd claude-orbit
67
+ uvx orbit-install --local
68
+ ```
69
+
70
+ `--local` swaps PyPI installs for editable ones and registers the plugin via a local marketplace. Edit files in the clone and see changes live.
71
+
72
+ ## Windows
73
+
74
+ Windows service registration is not yet supported. The installer will register the plugin, pip-install orbit-auto, and print manual instructions for running the dashboard.
75
+
76
+ ## Uninstall
77
+
78
+ ```bash
79
+ uvx orbit-install --uninstall
80
+ ```
81
+
82
+ Removes: plugin registration, pip packages, service units, settings.json entries. Preserves: `~/.claude/orbit/` (projects), `~/.claude/tasks.db` (task history).
83
+
84
+ ## License
85
+
86
+ MIT
@@ -0,0 +1,59 @@
1
+ # orbit-install
2
+
3
+ Bootstrap installer for [Orbit](https://github.com/tomerbr1/claude-orbit), the project manager for Claude Code.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ uvx orbit-install
9
+ # or
10
+ pipx run orbit-install
11
+ ```
12
+
13
+ The interactive wizard asks which components to install. Default is all:
14
+
15
+ | Component | What it does |
16
+ |----------------|------------------------------------------------------------------------|
17
+ | Plugin | Registers the orbit plugin with Claude Code (slash commands, MCP, hooks) |
18
+ | Dashboard | Installs `orbit-dashboard` pip package + launchd/systemd service on port 8787 |
19
+ | orbit-auto CLI | Installs `orbit-auto` for autonomous task execution |
20
+ | Statusline | Wires `~/.claude/settings.json` to run `orbit-statusline` on every prompt |
21
+ | Rules | Copies rule files into `~/.claude/rules/` |
22
+ | User commands | Copies `/whats-new` and `/optimize-prompt` into `~/.claude/commands/` |
23
+
24
+ ## Non-interactive
25
+
26
+ ```bash
27
+ uvx orbit-install --all # install everything
28
+ uvx orbit-install --dashboard --statusline # install a subset
29
+ uvx orbit-install --update # refresh everything
30
+ uvx orbit-install --uninstall # remove everything (preserves user data)
31
+ ```
32
+
33
+ ## Maintainer mode
34
+
35
+ From a clone of `claude-orbit`:
36
+
37
+ ```bash
38
+ git clone https://github.com/tomerbr1/claude-orbit.git
39
+ cd claude-orbit
40
+ uvx orbit-install --local
41
+ ```
42
+
43
+ `--local` swaps PyPI installs for editable ones and registers the plugin via a local marketplace. Edit files in the clone and see changes live.
44
+
45
+ ## Windows
46
+
47
+ Windows service registration is not yet supported. The installer will register the plugin, pip-install orbit-auto, and print manual instructions for running the dashboard.
48
+
49
+ ## Uninstall
50
+
51
+ ```bash
52
+ uvx orbit-install --uninstall
53
+ ```
54
+
55
+ Removes: plugin registration, pip packages, service units, settings.json entries. Preserves: `~/.claude/orbit/` (projects), `~/.claude/tasks.db` (task history).
56
+
57
+ ## License
58
+
59
+ MIT
@@ -0,0 +1,3 @@
1
+ """Orbit installer - bootstrap package for Orbit on Claude Code."""
2
+
3
+ __version__ = "1.0.0"
@@ -0,0 +1,183 @@
1
+ """Entry point for `uvx orbit-install` / `pipx run orbit-install`.
2
+
3
+ Invocation patterns:
4
+ uvx orbit-install # interactive wizard (default)
5
+ uvx orbit-install --all # install all components non-interactively
6
+ uvx orbit-install --dashboard # install only the dashboard
7
+ uvx orbit-install --all --no-statusline
8
+ # install everything except the statusline
9
+ uvx orbit-install --update # refresh whatever is in state.json
10
+ uvx orbit-install --uninstall # remove everything (preserves ~/.claude/orbit/)
11
+ uvx orbit-install --local # maintainer mode: editable installs from clone
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import argparse
17
+ import sys
18
+ from pathlib import Path
19
+
20
+ from . import __version__, installers, state, ui, wizard
21
+
22
+
23
+ DEFAULT_PORT = 8787
24
+
25
+
26
+ def build_parser() -> argparse.ArgumentParser:
27
+ p = argparse.ArgumentParser(
28
+ prog="orbit-install",
29
+ description="Bootstrap installer for Orbit (project manager for Claude Code).",
30
+ )
31
+ p.add_argument(
32
+ "--version", action="version", version=f"%(prog)s {__version__}"
33
+ )
34
+
35
+ action = p.add_mutually_exclusive_group()
36
+ action.add_argument(
37
+ "--all", action="store_true",
38
+ help="Install all components non-interactively.",
39
+ )
40
+ action.add_argument(
41
+ "--update", action="store_true",
42
+ help="Update installed components in place (reads state).",
43
+ )
44
+ action.add_argument(
45
+ "--uninstall", action="store_true",
46
+ help="Remove every component the installer installed.",
47
+ )
48
+
49
+ # Per-component opt-in flags. Any of these triggers non-interactive mode
50
+ # for exactly the components listed (in combination with --no-* opt-outs).
51
+ opt_in = p.add_argument_group(
52
+ "component opt-in (non-interactive)",
53
+ "Install only the components listed. Can be combined with --no-* to "
54
+ "exclude specific ones from --all.",
55
+ )
56
+ for flag, dest in (
57
+ ("--plugin", "plugin"),
58
+ ("--dashboard", "dashboard"),
59
+ ("--orbit-auto", "orbit_auto"),
60
+ ("--statusline", "statusline"),
61
+ ("--rules", "rules"),
62
+ ("--user-commands", "user_commands"),
63
+ ("--orbit-db", "orbit_db"),
64
+ ):
65
+ opt_in.add_argument(flag, dest=dest, action="store_true")
66
+
67
+ opt_out = p.add_argument_group(
68
+ "component opt-out",
69
+ "Exclude specific components from --all (e.g. `--all --no-statusline`).",
70
+ )
71
+ for flag, dest in (
72
+ ("--no-plugin", "no_plugin"),
73
+ ("--no-dashboard", "no_dashboard"),
74
+ ("--no-orbit-auto", "no_orbit_auto"),
75
+ ("--no-statusline", "no_statusline"),
76
+ ("--no-rules", "no_rules"),
77
+ ("--no-user-commands", "no_user_commands"),
78
+ ("--no-orbit-db", "no_orbit_db"),
79
+ ):
80
+ opt_out.add_argument(flag, dest=dest, action="store_true")
81
+
82
+ p.add_argument(
83
+ "--local", action="store_true",
84
+ help="Maintainer mode: editable installs + local marketplace from the "
85
+ "current clone. Auto-detected when run from a repo root.",
86
+ )
87
+ p.add_argument(
88
+ "--no-service", action="store_true",
89
+ help="Skip launchd/systemd service registration (dashboard will not auto-start).",
90
+ )
91
+ p.add_argument(
92
+ "--port", type=int, default=DEFAULT_PORT,
93
+ help=f"Dashboard port (default: {DEFAULT_PORT}).",
94
+ )
95
+ p.add_argument(
96
+ "--yes", "-y", action="store_true",
97
+ help="Skip per-file confirmations (still honors --no-* component opt-outs).",
98
+ )
99
+ return p
100
+
101
+
102
+ def _explicit_components(args: argparse.Namespace) -> list[str]:
103
+ """Components explicitly opted in via --plugin / --dashboard / etc."""
104
+ return [
105
+ c for c in installers.ALL_COMPONENTS
106
+ if getattr(args, c, False)
107
+ ]
108
+
109
+
110
+ def _excluded_components(args: argparse.Namespace) -> set[str]:
111
+ """Components explicitly opted out via --no-*."""
112
+ return {
113
+ c for c in installers.ALL_COMPONENTS
114
+ if getattr(args, f"no_{c}", False)
115
+ }
116
+
117
+
118
+ def _resolve_mode_and_repo(args: argparse.Namespace) -> tuple[str, Path | None]:
119
+ """Decide pypi vs local mode and locate the repo root if local."""
120
+ cwd = Path.cwd()
121
+ marker = cwd / ".claude-plugin" / "plugin.json"
122
+ if args.local:
123
+ if not marker.exists():
124
+ ui.fail(
125
+ f"--local requires running from a claude-orbit clone "
126
+ f"(expected {marker} to exist)."
127
+ )
128
+ return "local", cwd
129
+ if marker.exists():
130
+ # Silent auto-detect: if they're in a clone, assume maintainer workflow.
131
+ return "local", cwd
132
+ return "pypi", None
133
+
134
+
135
+ def main() -> int:
136
+ args = build_parser().parse_args()
137
+ mode, repo_root = _resolve_mode_and_repo(args)
138
+ state.set_mode(mode)
139
+ ctx = installers.InstallContext(
140
+ mode=mode,
141
+ repo_root=repo_root,
142
+ skip_service=args.no_service,
143
+ port=args.port,
144
+ assume_yes=args.yes,
145
+ )
146
+
147
+ if args.uninstall:
148
+ installed = state.installed_components() or list(installers.ALL_COMPONENTS)
149
+ installers.uninstall_components(installed, ctx)
150
+ return 0
151
+
152
+ if args.update:
153
+ installers.update_all(ctx)
154
+ return 0
155
+
156
+ explicit = _explicit_components(args)
157
+ excluded = _excluded_components(args)
158
+
159
+ if args.all or explicit:
160
+ base = list(installers.ALL_COMPONENTS) if args.all else explicit
161
+ selected = [c for c in base if c not in excluded]
162
+ # statusline needs the orbit-statusline entry point, which ships in the
163
+ # orbit-dashboard package. Installing statusline without dashboard wires
164
+ # settings.json to a command that won't resolve. Auto-add dashboard.
165
+ if "statusline" in selected and "dashboard" not in selected and "dashboard" not in excluded:
166
+ ui.warn("statusline depends on orbit-dashboard (provides the orbit-statusline entry point). Adding dashboard to the install.")
167
+ selected.insert(selected.index("statusline"), "dashboard")
168
+ if not selected:
169
+ ui.warn("Component selection is empty after applying --no-* flags.")
170
+ return 0
171
+ ui.banner()
172
+ ui.info(f"Installing: {', '.join(c.replace('_', '-') for c in selected)}")
173
+ installers.install_components(selected, ctx)
174
+ ui.success_banner(selected)
175
+ return 0
176
+
177
+ # Default: interactive wizard.
178
+ wizard.run(ctx)
179
+ return 0
180
+
181
+
182
+ if __name__ == "__main__":
183
+ sys.exit(main())