promty-collector 0.1.0 → 0.1.1

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 (2) hide show
  1. package/package.json +5 -1
  2. package/src/cli.py +50 -0
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "promty-collector",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Promty local event collector",
5
5
  "license": "UNLICENSED",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/NaHyeongyu/BuildHub.git"
9
+ },
6
10
  "type": "module",
7
11
  "bin": {
8
12
  "promty": "bin/promty.js",
package/src/cli.py CHANGED
@@ -5,6 +5,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer
5
5
  import json
6
6
  import os
7
7
  import secrets
8
+ import shlex
8
9
  import subprocess
9
10
  import sys
10
11
  import time
@@ -47,6 +48,7 @@ from uploader.client import PromptHubUploader
47
48
  from uploader.queue import JSONLQueue
48
49
 
49
50
  InstallTarget = Literal["all", "claude-code", "codex-cli"]
51
+ Profile = Literal["dev", "prod"]
50
52
  INSTALL_TOOLS: tuple[SupportedTool, ...] = ("codex-cli", "claude-code")
51
53
  INSTALL_TOOL_ALIASES: dict[str, InstallTarget] = {
52
54
  "all": "all",
@@ -55,6 +57,10 @@ INSTALL_TOOL_ALIASES: dict[str, InstallTarget] = {
55
57
  "codex": "codex-cli",
56
58
  "codex-cli": "codex-cli",
57
59
  }
60
+ PROFILE_URLS: dict[Profile, tuple[str, str]] = {
61
+ "dev": ("http://127.0.0.1:5173", "http://127.0.0.1:8011"),
62
+ "prod": ("https://promty.org", "https://api.promty.org"),
63
+ }
58
64
  CODEX_HOOKS: tuple[dict[str, Any], ...] = (
59
65
  {
60
66
  "event": "UserPromptSubmit",
@@ -184,6 +190,26 @@ def _tools_for_install_target(target: InstallTarget) -> tuple[SupportedTool, ...
184
190
  return (target,)
185
191
 
186
192
 
193
+ def _apply_profile_defaults(args: argparse.Namespace) -> None:
194
+ profile = getattr(args, "profile", None)
195
+ if not profile:
196
+ return
197
+
198
+ profile_root = Path("~/.prompthub/profiles").expanduser() / profile
199
+ app_url, api_url = PROFILE_URLS[profile]
200
+ defaults = {
201
+ "app_url": app_url,
202
+ "api_url": api_url,
203
+ "config_path": str(profile_root / "config.json"),
204
+ "queue_path": str(profile_root / "events"),
205
+ "pid_path": str(profile_root / "uploader.pid"),
206
+ "log_path": str(profile_root / "uploader.log"),
207
+ }
208
+ for name, value in defaults.items():
209
+ if hasattr(args, name) and getattr(args, name) is None:
210
+ setattr(args, name, value)
211
+
212
+
187
213
  def _apply_known_session(
188
214
  *,
189
215
  index: SessionIndex,
@@ -615,6 +641,7 @@ def _install_codex_hooks(
615
641
  command_prefix: str,
616
642
  normalized_tool: SupportedTool,
617
643
  repo_root: Path,
644
+ queue_path: str | None = None,
618
645
  ) -> int:
619
646
  hooks_path = repo_root / ".codex" / "hooks.json"
620
647
  config = _read_hooks_config(hooks_path)
@@ -622,6 +649,8 @@ def _install_codex_hooks(
622
649
 
623
650
  for spec in CODEX_HOOKS:
624
651
  command = f"{command_prefix} {spec['subcommand']} --tool {normalized_tool}"
652
+ if queue_path:
653
+ command += f" --queue-path {shlex.quote(str(Path(queue_path).expanduser()))}"
625
654
  hook = {
626
655
  "type": "command",
627
656
  "command": command,
@@ -649,6 +678,7 @@ def _install_claude_hooks(
649
678
  command_prefix: str,
650
679
  normalized_tool: SupportedTool,
651
680
  repo_root: Path,
681
+ queue_path: str | None = None,
652
682
  ) -> int:
653
683
  settings_path = repo_root / ".claude" / "settings.local.json"
654
684
  config = _read_hooks_config(settings_path)
@@ -656,6 +686,8 @@ def _install_claude_hooks(
656
686
 
657
687
  for spec in CLAUDE_HOOKS:
658
688
  command = f"{command_prefix} {spec['subcommand']} --tool {normalized_tool}"
689
+ if queue_path:
690
+ command += f" --queue-path {shlex.quote(str(Path(queue_path).expanduser()))}"
659
691
  hook = {
660
692
  "type": "command",
661
693
  "command": command,
@@ -687,6 +719,8 @@ def install_hooks(args: argparse.Namespace) -> int:
687
719
  command_prefix = quote_command_path(launcher_path)
688
720
  print(f"Promty runtime ready: {launcher_path}")
689
721
 
722
+ queue_path = getattr(args, "queue_path", None)
723
+
690
724
  failures: list[tuple[SupportedTool, Exception]] = []
691
725
  for normalized_tool in _tools_for_install_target(target):
692
726
  try:
@@ -695,12 +729,14 @@ def install_hooks(args: argparse.Namespace) -> int:
695
729
  command_prefix=command_prefix,
696
730
  normalized_tool=normalized_tool,
697
731
  repo_root=repo_root,
732
+ queue_path=queue_path,
698
733
  )
699
734
  elif normalized_tool == "claude-code":
700
735
  _install_claude_hooks(
701
736
  command_prefix=command_prefix,
702
737
  normalized_tool=normalized_tool,
703
738
  repo_root=repo_root,
739
+ queue_path=queue_path,
704
740
  )
705
741
  else:
706
742
  raise AssertionError(f"Unexpected hook tool: {normalized_tool}")
@@ -757,6 +793,8 @@ def start_uploader(args: argparse.Namespace) -> int:
757
793
  "--interval",
758
794
  str(max(args.interval, 0.25)),
759
795
  ]
796
+ if getattr(args, "queue_path", None):
797
+ command.extend(["--queue-path", str(Path(args.queue_path).expanduser())])
760
798
  process = subprocess.Popen(
761
799
  command,
762
800
  stdout=log_file,
@@ -910,6 +948,7 @@ def init(args: argparse.Namespace) -> int:
910
948
  source=None,
911
949
  repo_root=args.repo_root,
912
950
  hook_command=args.hook_command,
951
+ queue_path=args.queue_path,
913
952
  )
914
953
  hooks_result = install_hooks(install_args)
915
954
 
@@ -920,6 +959,7 @@ def init(args: argparse.Namespace) -> int:
920
959
  interval=args.upload_interval,
921
960
  log_path=args.log_path,
922
961
  pid_path=args.pid_path,
962
+ queue_path=args.queue_path,
923
963
  token=args.token,
924
964
  )
925
965
  start_uploader(uploader_args)
@@ -997,6 +1037,7 @@ def build_parser() -> argparse.ArgumentParser:
997
1037
  upload_parser.add_argument("--token", default=None)
998
1038
  upload_parser.add_argument("--config-path")
999
1039
  upload_parser.add_argument("--queue-path")
1040
+ upload_parser.add_argument("--profile", choices=sorted(PROFILE_URLS))
1000
1041
  upload_parser.add_argument("--limit", type=int, default=100)
1001
1042
  upload_parser.add_argument("--timeout", type=float, default=10)
1002
1043
  upload_parser.add_argument(
@@ -1017,6 +1058,7 @@ def build_parser() -> argparse.ArgumentParser:
1017
1058
  login_parser.add_argument("--api-url")
1018
1059
  login_parser.add_argument("--callback-port", type=int, default=0)
1019
1060
  login_parser.add_argument("--config-path")
1061
+ login_parser.add_argument("--profile", choices=sorted(PROFILE_URLS))
1020
1062
  login_parser.add_argument("--no-browser", action="store_true")
1021
1063
  login_parser.add_argument("--timeout", type=float, default=180)
1022
1064
  login_parser.add_argument("--token")
@@ -1036,6 +1078,8 @@ def build_parser() -> argparse.ArgumentParser:
1036
1078
  help="Deprecated alias for --tool",
1037
1079
  )
1038
1080
  install_hooks_parser.add_argument("--repo-root")
1081
+ install_hooks_parser.add_argument("--profile", choices=sorted(PROFILE_URLS))
1082
+ install_hooks_parser.add_argument("--queue-path")
1039
1083
  install_hooks_parser.add_argument(
1040
1084
  "--hook-command",
1041
1085
  help="Command prefix that the AI tool should call before the hook subcommand.",
@@ -1048,6 +1092,8 @@ def build_parser() -> argparse.ArgumentParser:
1048
1092
  start_uploader_parser.add_argument("--interval", type=float, default=2)
1049
1093
  start_uploader_parser.add_argument("--log-path")
1050
1094
  start_uploader_parser.add_argument("--pid-path")
1095
+ start_uploader_parser.add_argument("--profile", choices=sorted(PROFILE_URLS))
1096
+ start_uploader_parser.add_argument("--queue-path")
1051
1097
  start_uploader_parser.add_argument("--token")
1052
1098
  start_uploader_parser.set_defaults(func=start_uploader)
1053
1099
 
@@ -1059,6 +1105,7 @@ def build_parser() -> argparse.ArgumentParser:
1059
1105
  doctor_parser.add_argument("--repo-root")
1060
1106
  doctor_parser.add_argument("--timeout", type=float, default=3)
1061
1107
  doctor_parser.add_argument("--token")
1108
+ doctor_parser.add_argument("--profile", choices=sorted(PROFILE_URLS))
1062
1109
  doctor_parser.add_argument(
1063
1110
  "--tool",
1064
1111
  choices=sorted(INSTALL_TOOL_ALIASES),
@@ -1076,6 +1123,8 @@ def build_parser() -> argparse.ArgumentParser:
1076
1123
  init_parser.add_argument("--log-path")
1077
1124
  init_parser.add_argument("--no-browser", action="store_true")
1078
1125
  init_parser.add_argument("--pid-path")
1126
+ init_parser.add_argument("--profile", choices=sorted(PROFILE_URLS))
1127
+ init_parser.add_argument("--queue-path")
1079
1128
  init_parser.add_argument("--repo-root")
1080
1129
  init_parser.add_argument("--skip-login", action="store_true")
1081
1130
  init_parser.add_argument("--skip-uploader", action="store_true")
@@ -1096,6 +1145,7 @@ def build_parser() -> argparse.ArgumentParser:
1096
1145
  def main(argv: Sequence[str] | None = None) -> int:
1097
1146
  parser = build_parser()
1098
1147
  args = parser.parse_args(argv)
1148
+ _apply_profile_defaults(args)
1099
1149
  try:
1100
1150
  return args.func(args)
1101
1151
  except KeyboardInterrupt: