powerbase-cli 0.1.4__tar.gz → 0.2.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.
Files changed (38) hide show
  1. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/PKG-INFO +19 -5
  2. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/README.md +18 -4
  3. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/pyproject.toml +1 -4
  4. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/__init__.py +1 -1
  5. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/agent.py +8 -5
  6. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/branch.py +4 -1
  7. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/context.py +4 -1
  8. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/parser.py +3 -16
  9. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/publish.py +13 -3
  10. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/sandbox.py +20 -2
  11. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/shared.py +3 -15
  12. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/config.py +4 -54
  13. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/session.py +1 -20
  14. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/transport.py +1 -15
  15. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli.egg-info/PKG-INFO +19 -5
  16. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli.egg-info/SOURCES.txt +0 -1
  17. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/tests/test_cli_commands.py +5 -26
  18. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/tests/test_cli_help.py +42 -5
  19. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/tests/test_config.py +1 -15
  20. powerbase_cli-0.2.0/tests/test_session.py +97 -0
  21. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/tests/test_transport.py +1 -66
  22. powerbase_cli-0.1.4/src/powerbase_cli/certs/powerbase-test-ca.pem +0 -21
  23. powerbase_cli-0.1.4/tests/test_session.py +0 -194
  24. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/setup.cfg +0 -0
  25. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/__main__.py +0 -0
  26. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/api.py +0 -0
  27. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/cli.py +0 -0
  28. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/__init__.py +0 -0
  29. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/auth.py +0 -0
  30. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/config_cmd.py +0 -0
  31. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/database.py +0 -0
  32. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/instance.py +0 -0
  33. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/org.py +0 -0
  34. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli/commands/sql.py +0 -0
  35. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli.egg-info/dependency_links.txt +0 -0
  36. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli.egg-info/entry_points.txt +0 -0
  37. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/src/powerbase_cli.egg-info/top_level.txt +0 -0
  38. {powerbase_cli-0.1.4 → powerbase_cli-0.2.0}/tests/test_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: powerbase-cli
3
- Version: 0.1.4
3
+ Version: 0.2.0
4
4
  Summary: CLI for operating Powerbase console workflows
5
5
  Author: Powerbase
6
6
  Requires-Python: >=3.11
@@ -41,10 +41,12 @@ Database model:
41
41
  Install from PyPI:
42
42
 
43
43
  ```bash
44
- python -m pip install powerbase-cli
44
+ python -m pip install --upgrade powerbase-cli==0.2.0
45
45
  powerbase --help
46
46
  ```
47
47
 
48
+ Version `0.2.x` is the production-pinned release line and always targets `https://console.appbuild.chat`.
49
+
48
50
  From the repository root during development:
49
51
 
50
52
  ```bash
@@ -121,7 +123,7 @@ powerbase auth token-set \
121
123
  --expires-at 1760000000
122
124
  ```
123
125
 
124
- Use `--base-url` or `--anon-key` here only when you intentionally want to override the built-in deployment defaults.
126
+ The CLI is pinned to the production Powerbase console deployment and no longer exposes endpoint override flags.
125
127
 
126
128
  ### Check Auth State
127
129
 
@@ -240,6 +242,8 @@ powerbase agent login-url --instance-id INSTANCE_ID --provider cursor --json
240
242
 
241
243
  ### Sandbox Agent Chat And Config
242
244
 
245
+ Powerbase provides a coding agent so users can build and evolve Powerbase-hosted apps through chat. `powerbase agent chat` is the default implementation interface for that workflow, while the rest of the CLI supports context, validation, and deployment around it. In the current product workflow, successful `agent chat` runs are also the normal path that produces previewable app changes.
246
+
243
247
  Send one prompt to the sandbox agent and stream events as JSONL:
244
248
 
245
249
  ```bash
@@ -257,6 +261,9 @@ powerbase agent chat \
257
261
  feature branch. `powerbase context use-branch ...` only changes the local default value;
258
262
  it does not switch the remote sandbox by itself.
259
263
 
264
+ Treat `powerbase sandbox files ...`, `powerbase sql run`, and `powerbase publish diff` as inspection and validation tools around the Powerbase coding agent. Treat `powerbase publish run` as an explicit deployment action and do not run it unless the user asks to publish, deploy, release, or promote the result.
265
+ Direct `powerbase sandbox files create-file`, `upload`, or `delete` operations can help inspect or adjust the remote project, but they do not by themselves trigger the preview build flow.
266
+
260
267
  Read and update opencode provider config:
261
268
 
262
269
  ```bash
@@ -278,11 +285,16 @@ When Openclaw or another LLM agent uses `powerbase`:
278
285
  - prefer `--json` on all commands
279
286
  - run discovery commands before write operations
280
287
  - set context for long multi-step tasks
288
+ - treat `powerbase agent chat` as the default implementation interface for Powerbase-hosted apps
289
+ - treat successful `powerbase agent chat` runs as the normal path that produces previewable app changes
281
290
  - use `auth status` before workflows that assume login
282
291
  - use `auth login --json` to generate a login URL, then stop and hand `login_url` to the user
283
292
  - do not have the agent open the browser login URL itself; the user must complete that approval step
284
293
  - after the user confirms approval, run `auth wait --login-id ... --json` to complete login
285
294
  - if a protected command says authentication is missing or expired, rerun `auth login --json` to generate a fresh login URL
295
+ - use `sandbox files`, `sql run`, and `publish diff` for inspection or validation around the Powerbase coding agent
296
+ - do not assume `sandbox files` write operations will trigger preview by themselves
297
+ - do not run `publish run` unless the user explicitly asks to publish, deploy, release, or promote the result
286
298
  - remember that `--json` overrides a saved `config output text` setting for that command
287
299
 
288
300
  Recommended agent sequence:
@@ -296,7 +308,9 @@ Recommended agent sequence:
296
308
  7. Use `powerbase database ...` only for the advanced bring-your-own-database path
297
309
  8. Set context with `powerbase context use-instance ...`
298
310
  9. If you want the sandbox agent preview on a non-main branch, run `powerbase branch switch ...`
299
- 10. Continue with `branch`, `sql`, `publish`, `sandbox files`, or `agent` commands
311
+ 10. Use `powerbase agent chat ...` as the primary implementation step for Powerbase-hosted app changes
312
+ 11. Use `sandbox files`, `sql`, and `publish diff` to inspect or validate the result
313
+ 12. Run `publish run` only when the user explicitly wants deployment or publication
300
314
 
301
315
  ## Testing
302
316
 
@@ -316,7 +330,7 @@ PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src python3 -m py_compile src/powerbase_cli
316
330
 
317
331
  A project skill for Cursor/Openclaw-style agent usage lives in:
318
332
 
319
- `./.cursor/skills/powerbase-cli-openclaw/SKILL.md`
333
+ `./skills/powerbase-cli/SKILL.md`
320
334
 
321
335
  Design and auth review notes live in:
322
336
 
@@ -33,10 +33,12 @@ Database model:
33
33
  Install from PyPI:
34
34
 
35
35
  ```bash
36
- python -m pip install powerbase-cli
36
+ python -m pip install --upgrade powerbase-cli==0.2.0
37
37
  powerbase --help
38
38
  ```
39
39
 
40
+ Version `0.2.x` is the production-pinned release line and always targets `https://console.appbuild.chat`.
41
+
40
42
  From the repository root during development:
41
43
 
42
44
  ```bash
@@ -113,7 +115,7 @@ powerbase auth token-set \
113
115
  --expires-at 1760000000
114
116
  ```
115
117
 
116
- Use `--base-url` or `--anon-key` here only when you intentionally want to override the built-in deployment defaults.
118
+ The CLI is pinned to the production Powerbase console deployment and no longer exposes endpoint override flags.
117
119
 
118
120
  ### Check Auth State
119
121
 
@@ -232,6 +234,8 @@ powerbase agent login-url --instance-id INSTANCE_ID --provider cursor --json
232
234
 
233
235
  ### Sandbox Agent Chat And Config
234
236
 
237
+ Powerbase provides a coding agent so users can build and evolve Powerbase-hosted apps through chat. `powerbase agent chat` is the default implementation interface for that workflow, while the rest of the CLI supports context, validation, and deployment around it. In the current product workflow, successful `agent chat` runs are also the normal path that produces previewable app changes.
238
+
235
239
  Send one prompt to the sandbox agent and stream events as JSONL:
236
240
 
237
241
  ```bash
@@ -249,6 +253,9 @@ powerbase agent chat \
249
253
  feature branch. `powerbase context use-branch ...` only changes the local default value;
250
254
  it does not switch the remote sandbox by itself.
251
255
 
256
+ Treat `powerbase sandbox files ...`, `powerbase sql run`, and `powerbase publish diff` as inspection and validation tools around the Powerbase coding agent. Treat `powerbase publish run` as an explicit deployment action and do not run it unless the user asks to publish, deploy, release, or promote the result.
257
+ Direct `powerbase sandbox files create-file`, `upload`, or `delete` operations can help inspect or adjust the remote project, but they do not by themselves trigger the preview build flow.
258
+
252
259
  Read and update opencode provider config:
253
260
 
254
261
  ```bash
@@ -270,11 +277,16 @@ When Openclaw or another LLM agent uses `powerbase`:
270
277
  - prefer `--json` on all commands
271
278
  - run discovery commands before write operations
272
279
  - set context for long multi-step tasks
280
+ - treat `powerbase agent chat` as the default implementation interface for Powerbase-hosted apps
281
+ - treat successful `powerbase agent chat` runs as the normal path that produces previewable app changes
273
282
  - use `auth status` before workflows that assume login
274
283
  - use `auth login --json` to generate a login URL, then stop and hand `login_url` to the user
275
284
  - do not have the agent open the browser login URL itself; the user must complete that approval step
276
285
  - after the user confirms approval, run `auth wait --login-id ... --json` to complete login
277
286
  - if a protected command says authentication is missing or expired, rerun `auth login --json` to generate a fresh login URL
287
+ - use `sandbox files`, `sql run`, and `publish diff` for inspection or validation around the Powerbase coding agent
288
+ - do not assume `sandbox files` write operations will trigger preview by themselves
289
+ - do not run `publish run` unless the user explicitly asks to publish, deploy, release, or promote the result
278
290
  - remember that `--json` overrides a saved `config output text` setting for that command
279
291
 
280
292
  Recommended agent sequence:
@@ -288,7 +300,9 @@ Recommended agent sequence:
288
300
  7. Use `powerbase database ...` only for the advanced bring-your-own-database path
289
301
  8. Set context with `powerbase context use-instance ...`
290
302
  9. If you want the sandbox agent preview on a non-main branch, run `powerbase branch switch ...`
291
- 10. Continue with `branch`, `sql`, `publish`, `sandbox files`, or `agent` commands
303
+ 10. Use `powerbase agent chat ...` as the primary implementation step for Powerbase-hosted app changes
304
+ 11. Use `sandbox files`, `sql`, and `publish diff` to inspect or validate the result
305
+ 12. Run `publish run` only when the user explicitly wants deployment or publication
292
306
 
293
307
  ## Testing
294
308
 
@@ -308,7 +322,7 @@ PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src python3 -m py_compile src/powerbase_cli
308
322
 
309
323
  A project skill for Cursor/Openclaw-style agent usage lives in:
310
324
 
311
- `./.cursor/skills/powerbase-cli-openclaw/SKILL.md`
325
+ `./skills/powerbase-cli/SKILL.md`
312
326
 
313
327
  Design and auth review notes live in:
314
328
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "powerbase-cli"
7
- version = "0.1.4"
7
+ version = "0.2.0"
8
8
  description = "CLI for operating Powerbase console workflows"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -17,8 +17,5 @@ powerbase = "powerbase_cli.cli:main"
17
17
  [tool.setuptools]
18
18
  package-dir = { "" = "src" }
19
19
 
20
- [tool.setuptools.package-data]
21
- powerbase_cli = ["certs/*.pem"]
22
-
23
20
  [tool.setuptools.packages.find]
24
21
  where = ["src"]
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.1.0"
5
+ __version__ = "0.2.0"
@@ -115,11 +115,14 @@ def register_agent_commands(subparsers: argparse._SubParsersAction[argparse.Argu
115
115
  "chat",
116
116
  help="Send a prompt to the sandbox agent.",
117
117
  description=(
118
- "Send one prompt to the sandbox agent running in an instance. Use this when you want the sandbox "
119
- "itself to inspect or modify the project. The automatic preview build follows the sandbox's current "
120
- "branch, so run `powerbase branch switch` first when you want a feature-branch preview. By default "
121
- "the command collects all streamed events and prints them as JSON. Use --stream-jsonl to print one "
122
- "JSON event per line as events arrive."
118
+ "Send one prompt to the Powerbase coding agent running in an instance. This is the default "
119
+ "implementation interface when you want to build or evolve a Powerbase-hosted app through chat, "
120
+ "while the rest of the CLI handles context, validation, and deployment around that workflow. "
121
+ "In the current product workflow, successful runs here are also the normal path that produces "
122
+ "previewable app changes. "
123
+ "The automatic preview build follows the sandbox's current branch, so run `powerbase branch switch` "
124
+ "first when you want a feature-branch preview. By default the command collects all streamed events "
125
+ "and prints them as JSON. Use --stream-jsonl to print one JSON event per line as events arrive."
123
126
  ),
124
127
  )
125
128
  p.add_argument("--instance-id", help="Instance ID. Falls back to context.json.")
@@ -67,7 +67,10 @@ def register_branch_commands(subparsers: argparse._SubParsersAction[argparse.Arg
67
67
  p = branch_sub.add_parser(
68
68
  "switch",
69
69
  help="Switch the sandbox branch.",
70
- description="Switch the sandbox branch and update context.json.",
70
+ description=(
71
+ "Switch the remote sandbox branch and update context.json. Use this before `powerbase agent chat` "
72
+ "when you want the coding agent and preview build to target a specific branch."
73
+ ),
71
74
  )
72
75
  p.add_argument("branch_name", help="Branch slug to switch to.")
73
76
  p.add_argument("--instance-id", help="Instance ID. Falls back to context.json.")
@@ -69,7 +69,10 @@ def register_context_commands(subparsers: argparse._SubParsersAction[argparse.Ar
69
69
  p = context_sub.add_parser(
70
70
  "use-branch",
71
71
  help="Set the default branch.",
72
- description="Set the default branch slug, such as main or feature/my-change.",
72
+ description=(
73
+ "Set the default branch slug, such as main or feature/my-change. This updates only the local default "
74
+ "context value; it does not switch the remote sandbox branch used by previews or `powerbase agent chat`."
75
+ ),
73
76
  )
74
77
  p.add_argument("branch")
75
78
  p.set_defaults(handler=lambda args: _save_context_update(args, branch=args.branch))
@@ -19,10 +19,6 @@ from .sql import register_sql_commands
19
19
 
20
20
  GLOBAL_OPTION_ARITY = {
21
21
  "--config-dir": 1,
22
- "--base-url": 1,
23
- "--anon-key": 1,
24
- "--ca-cert": 1,
25
- "--insecure": 0,
26
22
  "--json": 0,
27
23
  }
28
24
 
@@ -62,6 +58,9 @@ def build_parser() -> argparse.ArgumentParser:
62
58
  prog="powerbase",
63
59
  description=(
64
60
  "Operate Powerbase console workflows from the command line. "
61
+ "Powerbase supports agent-driven development for Powerbase-hosted apps, with "
62
+ "`powerbase agent chat` as the default implementation interface and the rest of the CLI "
63
+ "covering auth, context, resources, validation, and publish operations. "
65
64
  "Default instance creation uses the managed Powerbase database flow; "
66
65
  "`powerbase database ...` is the advanced bring-your-own-database path."
67
66
  ),
@@ -71,18 +70,6 @@ def build_parser() -> argparse.ArgumentParser:
71
70
  ),
72
71
  )
73
72
  parser.add_argument("--config-dir", help="Override the config directory. Defaults to ~/.config/powerbase.")
74
- parser.add_argument("--base-url", help="Console base URL. Overrides the built-in default console endpoint.")
75
- parser.add_argument("--anon-key", help="Supabase anon key used for functions and auth requests. Overrides the built-in default.")
76
- parser.add_argument(
77
- "--ca-cert",
78
- dest="ca_cert_file",
79
- help="Path to a CA certificate PEM file to trust for HTTPS requests.",
80
- )
81
- parser.add_argument(
82
- "--insecure",
83
- action="store_true",
84
- help="Disable TLS certificate verification for HTTPS requests. Use only for testing with self-signed certs.",
85
- )
86
73
  parser.add_argument("--json", action="store_true", help="Print JSON output.")
87
74
 
88
75
  subparsers = parser.add_subparsers(dest="command")
@@ -25,9 +25,17 @@ def handle_publish_run(args: argparse.Namespace) -> int:
25
25
 
26
26
 
27
27
  def register_publish_commands(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
28
- publish = subparsers.add_parser("publish", help="Publish commands.", description="Generate diffs and publish an instance.")
28
+ publish = subparsers.add_parser(
29
+ "publish",
30
+ help="Publish commands.",
31
+ description="Inspect publish diffs and publish an instance when the user explicitly wants deployment.",
32
+ )
29
33
  publish_sub = publish.add_subparsers(dest="publish_command")
30
- p = publish_sub.add_parser("diff", help="Show publish diff.", description="Generate publish diff for the current instance.")
34
+ p = publish_sub.add_parser(
35
+ "diff",
36
+ help="Show publish diff.",
37
+ description="Generate publish diff for the current instance as an inspection step before deployment.",
38
+ )
31
39
  p.add_argument("--instance-id", help="Instance ID. Falls back to context.json.")
32
40
  p.add_argument("--target", default="prod", help="Publish target. Default: prod")
33
41
  p.set_defaults(handler=handle_publish_diff)
@@ -35,7 +43,9 @@ def register_publish_commands(subparsers: argparse._SubParsersAction[argparse.Ar
35
43
  "run",
36
44
  help="Run publish flow.",
37
45
  description=(
38
- "Publish the current instance. If --sql is omitted, the command first runs publish diff and uses its SQL."
46
+ "Publish the current instance. Use this only when the user explicitly asks to publish, deploy, "
47
+ "release, or promote the result. If --sql is omitted, the command first runs publish diff and uses "
48
+ "its SQL."
39
49
  ),
40
50
  )
41
51
  p.add_argument("--instance-id", help="Instance ID. Falls back to context.json.")
@@ -48,9 +48,27 @@ def handle_files_delete(args: argparse.Namespace) -> int:
48
48
 
49
49
 
50
50
  def register_sandbox_commands(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
51
- sandbox = subparsers.add_parser("sandbox", help="Sandbox commands.", description="Read or modify sandbox files.")
51
+ sandbox = subparsers.add_parser(
52
+ "sandbox",
53
+ help="Sandbox commands.",
54
+ description=(
55
+ "Inspect or modify the remote sandbox filesystem for a Powerbase instance. Treat this as the "
56
+ "remote inspection and control surface around the Powerbase coding agent, not the default full-app "
57
+ "implementation interface. Direct file operations here do not by themselves trigger the preview "
58
+ "build flow."
59
+ ),
60
+ )
52
61
  sandbox_sub = sandbox.add_subparsers(dest="sandbox_command")
53
- files = sandbox_sub.add_parser("files", help="Sandbox file commands.", description="Read or modify sandbox files.")
62
+ files = sandbox_sub.add_parser(
63
+ "files",
64
+ help="Sandbox file commands.",
65
+ description=(
66
+ "Read or modify files in the remote Powerbase sandbox. Use these commands for inspection, validation, "
67
+ "and targeted file operations around agent-driven development. Successful `powerbase agent chat` runs "
68
+ "are the normal path for previewable app changes; these file operations do not trigger preview by "
69
+ "themselves."
70
+ ),
71
+ )
54
72
  files_sub = files.add_subparsers(dest="files_command")
55
73
  p = files_sub.add_parser("list", help="List a directory.", description="List sandbox files at one path.")
56
74
  p.add_argument("--instance-id", help="Instance ID. Falls back to context.json.")
@@ -8,7 +8,6 @@ from typing import Any
8
8
 
9
9
  from ..api import PowerbaseApi
10
10
  from ..config import (
11
- BUNDLED_CA_CERT_SENTINEL,
12
11
  DEFAULT_ANON_KEY,
13
12
  DEFAULT_BASE_URL,
14
13
  AppConfig,
@@ -16,8 +15,6 @@ from ..config import (
16
15
  AuthState,
17
16
  ConfigStore,
18
17
  ContextState,
19
- load_bundled_ca_cert,
20
- merge_config_with_env,
21
18
  merge_context_with_env,
22
19
  )
23
20
  from ..session import SessionManager
@@ -33,18 +30,11 @@ def build_store(args: argparse.Namespace) -> ConfigStore:
33
30
 
34
31
 
35
32
  def resolve_config(args: argparse.Namespace, store: ConfigStore) -> AppConfig:
36
- config = merge_config_with_env(store.load_config())
37
- saved_auth = store.load_auth()
38
- explicit_ca_cert_file = getattr(args, "ca_cert_file", None) or config.ca_cert_file
33
+ config = store.load_config()
39
34
  return AppConfig(
40
- base_url=args.base_url or config.base_url or (saved_auth.base_url if saved_auth else None) or DEFAULT_BASE_URL,
41
- anon_key=args.anon_key or config.anon_key or (saved_auth.anon_key if saved_auth else None) or DEFAULT_ANON_KEY,
35
+ base_url=DEFAULT_BASE_URL,
36
+ anon_key=DEFAULT_ANON_KEY,
42
37
  output="json" if args.json else config.output,
43
- tls_insecure=bool(getattr(args, "insecure", False) or config.tls_insecure),
44
- # Keep explicit CA settings first. The bundled test CA is only the final fallback for the
45
- # current self-signed test environment and should be removed once the deployment uses a
46
- # publicly trusted certificate.
47
- ca_cert_file=explicit_ca_cert_file or (BUNDLED_CA_CERT_SENTINEL if load_bundled_ca_cert() else None),
48
38
  )
49
39
 
50
40
 
@@ -60,8 +50,6 @@ def build_api(args: argparse.Namespace) -> tuple[ConfigStore, AppConfig, Context
60
50
  store,
61
51
  config.base_url,
62
52
  config.anon_key,
63
- tls_insecure=config.tls_insecure,
64
- ca_cert_file=config.ca_cert_file,
65
53
  )
66
54
  api = PowerbaseApi(PowerbaseTransport(config, session_manager))
67
55
  return store, config, context, session_manager, api
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- import importlib.resources
4
3
  import json
5
4
  import os
6
5
  from dataclasses import asdict, dataclass
@@ -12,13 +11,8 @@ try:
12
11
  except ModuleNotFoundError: # pragma: no cover
13
12
  tomllib = None # type: ignore[assignment]
14
13
 
15
- DEFAULT_BASE_URL = "https://console.6.12.235.165.nip.io"
14
+ DEFAULT_BASE_URL = "https://console.appbuild.chat"
16
15
  DEFAULT_ANON_KEY = "reallyreallyreallyreallyverysafe"
17
- # This bundled CA is only for the self-signed test deployment so `pip install powerbase-cli`
18
- # can work out of the box. Remove it after the deployed console switches to a publicly trusted
19
- # TLS certificate, then delete the bundled PEM file and its package-data entry as well.
20
- BUNDLED_CA_CERT_SENTINEL = "<bundled test CA>"
21
- BUNDLED_CA_CERT_RESOURCE = "certs/powerbase-test-ca.pem"
22
16
 
23
17
 
24
18
  def default_config_dir() -> Path:
@@ -33,8 +27,6 @@ class AppConfig:
33
27
  base_url: str | None = DEFAULT_BASE_URL
34
28
  anon_key: str | None = DEFAULT_ANON_KEY
35
29
  output: str = "text"
36
- tls_insecure: bool = False
37
- ca_cert_file: str | None = None
38
30
 
39
31
 
40
32
  @dataclass
@@ -69,26 +61,6 @@ def _as_path(path: str | Path | None) -> Path:
69
61
  return Path(path).expanduser()
70
62
 
71
63
 
72
- def env_flag(name: str) -> bool:
73
- value = os.environ.get(name)
74
- if value is None:
75
- return False
76
- return value.strip().lower() in {"1", "true", "yes", "on"}
77
-
78
-
79
- def load_bundled_ca_cert() -> str | None:
80
- # The PEM contents are loaded at runtime so test builds can trust the packaged self-signed CA
81
- # without asking end users to pass `--ca-cert`. Once the server uses a trusted certificate,
82
- # this helper and its callers can be removed.
83
- try:
84
- resource = importlib.resources.files("powerbase_cli").joinpath(BUNDLED_CA_CERT_RESOURCE)
85
- if not resource.is_file():
86
- return None
87
- return resource.read_text(encoding="utf-8")
88
- except (FileNotFoundError, ModuleNotFoundError):
89
- return None
90
-
91
-
92
64
  class ConfigStore:
93
65
  def __init__(self, base_dir: str | Path | None = None) -> None:
94
66
  self.base_dir = _as_path(base_dir)
@@ -101,31 +73,19 @@ class ConfigStore:
101
73
 
102
74
  def load_config(self) -> AppConfig:
103
75
  if not self.config_path.exists():
104
- return AppConfig(base_url=None, anon_key=None)
76
+ return AppConfig()
105
77
  if tomllib is None:
106
78
  raise RuntimeError("tomllib is required to read config.toml")
107
79
  data = tomllib.loads(self.config_path.read_text(encoding="utf-8"))
108
80
  return AppConfig(
109
- base_url=data.get("base_url"),
110
- anon_key=data.get("anon_key"),
111
81
  output=data.get("output", "text"),
112
- tls_insecure=bool(data.get("tls_insecure", False)),
113
- ca_cert_file=data.get("ca_cert_file"),
114
82
  )
115
83
 
116
84
  def save_config(self, config: AppConfig) -> None:
117
85
  self.ensure_base_dir()
118
86
  lines = []
119
- if config.base_url and config.base_url != DEFAULT_BASE_URL:
120
- lines.append(f'base_url = "{config.base_url}"')
121
- if config.anon_key and config.anon_key != DEFAULT_ANON_KEY:
122
- lines.append(f'anon_key = "{config.anon_key}"')
123
87
  if config.output:
124
88
  lines.append(f'output = "{config.output}"')
125
- if config.tls_insecure:
126
- lines.append("tls_insecure = true")
127
- if config.ca_cert_file:
128
- lines.append(f'ca_cert_file = "{config.ca_cert_file}"')
129
89
  self.config_path.write_text("\n".join(lines) + ("\n" if lines else ""), encoding="utf-8")
130
90
 
131
91
  def load_auth(self) -> AuthState | None:
@@ -210,8 +170,8 @@ def env_auth_state() -> AuthState | None:
210
170
  expires_at = int(expires_at_raw) if expires_at_raw and expires_at_raw.isdigit() else None
211
171
  return AuthState(
212
172
  source="env",
213
- base_url=os.environ.get("POWERBASE_BASE_URL"),
214
- anon_key=os.environ.get("POWERBASE_ANON_KEY"),
173
+ base_url=DEFAULT_BASE_URL,
174
+ anon_key=DEFAULT_ANON_KEY,
215
175
  session=AuthSession(
216
176
  access_token=access_token,
217
177
  refresh_token=refresh_token,
@@ -220,16 +180,6 @@ def env_auth_state() -> AuthState | None:
220
180
  )
221
181
 
222
182
 
223
- def merge_config_with_env(config: AppConfig) -> AppConfig:
224
- return AppConfig(
225
- base_url=os.environ.get("POWERBASE_BASE_URL") or config.base_url,
226
- anon_key=os.environ.get("POWERBASE_ANON_KEY") or config.anon_key,
227
- output=os.environ.get("POWERBASE_OUTPUT") or config.output,
228
- tls_insecure=env_flag("POWERBASE_TLS_INSECURE") or config.tls_insecure,
229
- ca_cert_file=os.environ.get("POWERBASE_CA_CERT_FILE") or config.ca_cert_file,
230
- )
231
-
232
-
233
183
  def merge_context_with_env(context: ContextState) -> ContextState:
234
184
  return ContextState(
235
185
  instance_id=os.environ.get("POWERBASE_INSTANCE_ID") or context.instance_id,
@@ -11,7 +11,7 @@ from typing import Iterator
11
11
  from urllib import request
12
12
  from urllib.error import HTTPError, URLError
13
13
 
14
- from .config import BUNDLED_CA_CERT_SENTINEL, AuthState, ConfigStore, env_auth_state, load_bundled_ca_cert
14
+ from .config import AuthState, ConfigStore, env_auth_state
15
15
 
16
16
  try:
17
17
  import fcntl
@@ -29,15 +29,10 @@ class SessionManager:
29
29
  store: ConfigStore,
30
30
  base_url: str | None,
31
31
  anon_key: str | None,
32
- *,
33
- tls_insecure: bool = False,
34
- ca_cert_file: str | None = None,
35
32
  ) -> None:
36
33
  self.store = store
37
34
  self.base_url = base_url
38
35
  self.anon_key = anon_key
39
- self.tls_insecure = tls_insecure
40
- self.ca_cert_file = ca_cert_file
41
36
 
42
37
  def _login_guidance(self) -> str:
43
38
  return (
@@ -47,20 +42,6 @@ class SessionManager:
47
42
  )
48
43
 
49
44
  def _urlopen(self, req: request.Request):
50
- if self.tls_insecure:
51
- context = ssl.create_default_context()
52
- context.check_hostname = False
53
- context.verify_mode = ssl.CERT_NONE
54
- return request.urlopen(req, context=context)
55
- if self.ca_cert_file:
56
- if self.ca_cert_file == BUNDLED_CA_CERT_SENTINEL:
57
- bundled_ca_cert = load_bundled_ca_cert()
58
- if not bundled_ca_cert:
59
- raise SessionError("Bundled test CA certificate is unavailable.")
60
- context = ssl.create_default_context(cadata=bundled_ca_cert)
61
- else:
62
- context = ssl.create_default_context(cafile=self.ca_cert_file)
63
- return request.urlopen(req, context=context)
64
45
  return request.urlopen(req)
65
46
 
66
47
  def get_auth_state(self) -> AuthState | None:
@@ -7,7 +7,7 @@ from typing import Any
7
7
  from urllib import request
8
8
  from urllib.error import HTTPError, URLError
9
9
 
10
- from .config import BUNDLED_CA_CERT_SENTINEL, AppConfig, load_bundled_ca_cert
10
+ from .config import AppConfig
11
11
  from .session import SessionError, SessionManager
12
12
 
13
13
 
@@ -35,20 +35,6 @@ class PowerbaseTransport:
35
35
  )
36
36
 
37
37
  def _urlopen(self, req: request.Request):
38
- if self.config.tls_insecure:
39
- context = ssl.create_default_context()
40
- context.check_hostname = False
41
- context.verify_mode = ssl.CERT_NONE
42
- return request.urlopen(req, context=context)
43
- if self.config.ca_cert_file:
44
- if self.config.ca_cert_file == BUNDLED_CA_CERT_SENTINEL:
45
- bundled_ca_cert = load_bundled_ca_cert()
46
- if not bundled_ca_cert:
47
- raise ApiError("Bundled test CA certificate is unavailable.")
48
- context = ssl.create_default_context(cadata=bundled_ca_cert)
49
- else:
50
- context = ssl.create_default_context(cafile=self.config.ca_cert_file)
51
- return request.urlopen(req, context=context)
52
38
  return request.urlopen(req)
53
39
 
54
40
  def _build_headers(