arc-builder-kit 0.2.0__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.
Files changed (58) hide show
  1. arc_builder_kit/__init__.py +4 -0
  2. arc_builder_kit/__main__.py +6 -0
  3. arc_builder_kit/_paths.py +47 -0
  4. arc_builder_kit/cli.py +277 -0
  5. arc_builder_kit/config/arc_testnet.facts.json +31 -0
  6. arc_builder_kit/doctor.py +936 -0
  7. arc_builder_kit/examples/agent-commerce-components/components.js +200 -0
  8. arc_builder_kit/examples/agent-commerce-components/index.html +120 -0
  9. arc_builder_kit/examples/agent-commerce-flows/flows.js +271 -0
  10. arc_builder_kit/examples/agent-commerce-flows/index.html +114 -0
  11. arc_builder_kit/examples/agent-commerce-live/commerce-live.js +190 -0
  12. arc_builder_kit/examples/agent-commerce-live/index.html +105 -0
  13. arc_builder_kit/examples/agent-commerce-review-packet/index.html +96 -0
  14. arc_builder_kit/examples/agent-commerce-review-packet/packet.js +125 -0
  15. arc_builder_kit/examples/agent-identity-profile-preview/identity.js +126 -0
  16. arc_builder_kit/examples/agent-identity-profile-preview/index.html +104 -0
  17. arc_builder_kit/examples/arc-agent-treasury-lab/index.html +152 -0
  18. arc_builder_kit/examples/arc-agent-treasury-lab/treasury.js +532 -0
  19. arc_builder_kit/examples/arc-testnet-operator-evidence/evidence.example.json +47 -0
  20. arc_builder_kit/examples/arc-testnet-wallet-send-gate/index.html +233 -0
  21. arc_builder_kit/examples/arc-testnet-wallet-send-gate/live-infrastructure-policy.example.json +59 -0
  22. arc_builder_kit/examples/arc-testnet-wallet-send-gate/wallet-send-gate.js +472 -0
  23. arc_builder_kit/examples/circle-wallet-integration/index.html +155 -0
  24. arc_builder_kit/examples/circle-wallet-integration/wallet-lab.js +91 -0
  25. arc_builder_kit/examples/job-escrow-simulator/index.html +121 -0
  26. arc_builder_kit/examples/job-escrow-simulator/simulator.js +162 -0
  27. arc_builder_kit/examples/payment-intent-demo/index.html +132 -0
  28. arc_builder_kit/examples/payment-intent-playground/index.html +301 -0
  29. arc_builder_kit/examples/payment-intent-playground/playground.js +835 -0
  30. arc_builder_kit/examples/payment-intent-receipt-matcher/index.html +157 -0
  31. arc_builder_kit/examples/payment-intent-receipt-matcher/matcher.js +877 -0
  32. arc_builder_kit/examples/receipt-verifier-playground/index.html +120 -0
  33. arc_builder_kit/examples/receipt-verifier-playground/verifier.js +226 -0
  34. arc_builder_kit/examples/receipt-viewer/index.html +138 -0
  35. arc_builder_kit/examples/receipt-viewer/receipt-viewer.js +472 -0
  36. arc_builder_kit/examples/transaction-status-playground/index.html +135 -0
  37. arc_builder_kit/examples/transaction-status-playground/status.js +518 -0
  38. arc_builder_kit/examples/x402-local-challenge-server/.env.example +25 -0
  39. arc_builder_kit/examples/x402-local-challenge-server/README.md +111 -0
  40. arc_builder_kit/examples/x402-local-challenge-server/server.py +711 -0
  41. arc_builder_kit/mcp_server.py +463 -0
  42. arc_builder_kit/release_packet.py +469 -0
  43. arc_builder_kit/templates/README.md +25 -0
  44. arc_builder_kit/templates/job-escrow-starter/README.md +25 -0
  45. arc_builder_kit/templates/job-escrow-starter/index.html +41 -0
  46. arc_builder_kit/templates/job-escrow-starter/index.js +14 -0
  47. arc_builder_kit/templates/payment-intent-starter/README.md +25 -0
  48. arc_builder_kit/templates/payment-intent-starter/index.html +42 -0
  49. arc_builder_kit/templates/payment-intent-starter/index.js +7 -0
  50. arc_builder_kit/templates/x402-agent-starter/README.md +29 -0
  51. arc_builder_kit/templates/x402-agent-starter/server.py +201 -0
  52. arc_builder_kit/validate_repo.py +2212 -0
  53. arc_builder_kit-0.2.0.dist-info/METADATA +543 -0
  54. arc_builder_kit-0.2.0.dist-info/RECORD +58 -0
  55. arc_builder_kit-0.2.0.dist-info/WHEEL +5 -0
  56. arc_builder_kit-0.2.0.dist-info/entry_points.txt +3 -0
  57. arc_builder_kit-0.2.0.dist-info/licenses/LICENSE +21 -0
  58. arc_builder_kit-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,4 @@
1
+ """Arc Builder Kit — installable tooling for the Arc MCP Builder Assistant."""
2
+
3
+ __version__ = "0.2.0"
4
+ __all__ = ["__version__"]
@@ -0,0 +1,6 @@
1
+ """Allow `python -m arc_builder_kit`."""
2
+
3
+ from arc_builder_kit.cli import main
4
+
5
+ if __name__ == "__main__":
6
+ raise SystemExit(main())
@@ -0,0 +1,47 @@
1
+ """Path resolution that works both in editable installs and in wheels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ _PACKAGE_DIR = Path(__file__).resolve().parent
8
+
9
+ # A source checkout has the canonical scripts beside this package. An installed
10
+ # wheel has its reviewed resources inside the package directory instead.
11
+ _SOURCE_ROOT = _PACKAGE_DIR.parent
12
+ IS_SOURCE_CHECKOUT = (
13
+ (_SOURCE_ROOT / "scripts" / "validate_repo.py").is_file()
14
+ and (_SOURCE_ROOT / "config" / "arc_testnet.facts.json").is_file()
15
+ )
16
+ REPO_ROOT = _SOURCE_ROOT if IS_SOURCE_CHECKOUT else _PACKAGE_DIR
17
+ DEFAULT_OUTPUT_ROOT = REPO_ROOT if IS_SOURCE_CHECKOUT else Path.cwd().resolve()
18
+
19
+
20
+ def _resolve_resource_dir(name: str) -> Path:
21
+ """Find a resource directory in installed wheel or editable/development layout.
22
+
23
+ In a built wheel, resources live next to this module under arc_builder_kit/.
24
+ In a clone/editable install, resources live in the repository root, one level
25
+ above this package.
26
+ """
27
+ installed = _PACKAGE_DIR / name
28
+ if installed.exists() and installed.is_dir():
29
+ return installed
30
+ dev = _SOURCE_ROOT / name
31
+ if dev.exists() and dev.is_dir():
32
+ return dev
33
+ raise FileNotFoundError(
34
+ f"Could not locate {name!r} directory. "
35
+ f"Tried {installed} and {dev}."
36
+ )
37
+
38
+
39
+ PACKAGE_DIR = _PACKAGE_DIR
40
+ TEMPLATES_DIR = _resolve_resource_dir("templates")
41
+ CONFIG_DIR = _resolve_resource_dir("config")
42
+ EXAMPLES_DIR = _resolve_resource_dir("examples")
43
+
44
+ # Other scripts live in the repo scripts/ directory. In a wheel they are not
45
+ # shipped as standalone subprocess targets; the CLI/MCP tools import their
46
+ # functions directly.
47
+ SCRIPTS_DIR = REPO_ROOT / "scripts"
arc_builder_kit/cli.py ADDED
@@ -0,0 +1,277 @@
1
+ #!/usr/bin/env python3
2
+ """Arc Builder CLI: unified command-line tooling for the Arc MCP Builder Assistant.
3
+
4
+ This is a dependency-free orchestrator over existing builder-kit scripts and
5
+ resources. It stays local-only by default and never connects a wallet, signs, or
6
+ broadcasts transactions. Network calls happen only through explicit opt-in flags
7
+ passed to underlying scripts.
8
+
9
+ Subcommands:
10
+ doctor Run Arc Builder Doctor and print a structured verdict.
11
+ validate Run repository validation.
12
+ templates List available project starter templates.
13
+ scaffold Copy a starter template into a new project directory.
14
+ facts Print the reviewed Arc Testnet facts object.
15
+ manifest Print the local x402 paid-agent manifest.
16
+ release-packet Generate a local maintainer release packet.
17
+ mcp Start the local Arc Builder MCP server (stdio).
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import argparse
23
+ import json
24
+ import shutil
25
+ import subprocess
26
+ import sys
27
+ from pathlib import Path
28
+ from typing import Any, Sequence
29
+
30
+ from arc_builder_kit import __version__
31
+ from arc_builder_kit._paths import (
32
+ CONFIG_DIR,
33
+ DEFAULT_OUTPUT_ROOT,
34
+ EXAMPLES_DIR,
35
+ REPO_ROOT,
36
+ TEMPLATES_DIR,
37
+ )
38
+ from arc_builder_kit.doctor import main as doctor_main
39
+ from arc_builder_kit.mcp_server import main as mcp_main
40
+ from arc_builder_kit.release_packet import main as release_packet_main
41
+ from arc_builder_kit.validate_repo import main as validate_main
42
+
43
+ X402_SERVER = EXAMPLES_DIR / "x402-local-challenge-server" / "server.py"
44
+
45
+
46
+ class CliError(Exception):
47
+ """User-facing error that should exit with a clean message."""
48
+
49
+ def __init__(self, message: str, exit_code: int = 1) -> None:
50
+ super().__init__(message)
51
+ self.message = message
52
+ self.exit_code = exit_code
53
+
54
+
55
+ def _run_script(
56
+ script: Path,
57
+ args: Sequence[str] = (),
58
+ *,
59
+ capture: bool = True,
60
+ timeout: float | None = 300,
61
+ ) -> subprocess.CompletedProcess[str]:
62
+ """Run a Python script as an argument list.
63
+
64
+ Kept for the x402 manifest example, which is a standalone server file that
65
+ remains easier to invoke as a subprocess than to import.
66
+ """
67
+ if not script.exists():
68
+ raise CliError(f"script not found: {script}")
69
+ cmd = [sys.executable, str(script), *args]
70
+ return subprocess.run(
71
+ cmd,
72
+ capture_output=capture,
73
+ text=True,
74
+ timeout=timeout,
75
+ check=False,
76
+ )
77
+
78
+
79
+ def _load_json(path: Path) -> Any:
80
+ if not path.exists():
81
+ raise CliError(f"file not found: {path}")
82
+ try:
83
+ with path.open("r", encoding="utf-8") as fh:
84
+ return json.load(fh)
85
+ except json.JSONDecodeError as exc:
86
+ raise CliError(f"invalid JSON in {path}: {exc}") from exc
87
+
88
+
89
+ def _list_templates() -> list[str]:
90
+ if not TEMPLATES_DIR.exists():
91
+ return []
92
+ return sorted(
93
+ d.name for d in TEMPLATES_DIR.iterdir() if d.is_dir() and (d / "README.md").exists()
94
+ )
95
+
96
+
97
+ def cmd_doctor(args: argparse.Namespace) -> int:
98
+ flags = ["--json"]
99
+ if args.full:
100
+ flags.append("--full")
101
+ if args.include_arc_rpc:
102
+ flags.append("--include-arc-rpc")
103
+ if args.include_public_site:
104
+ flags.append("--include-public-site")
105
+ return doctor_main(flags)
106
+
107
+
108
+ def cmd_validate(args: argparse.Namespace) -> int:
109
+ validate_main()
110
+ return 0
111
+
112
+
113
+ def cmd_templates(args: argparse.Namespace) -> int:
114
+ names = _list_templates()
115
+ output: dict[str, Any] = {
116
+ "templates": names,
117
+ "templates_dir": str(TEMPLATES_DIR.relative_to(REPO_ROOT) if TEMPLATES_DIR.is_relative_to(REPO_ROOT) else TEMPLATES_DIR),
118
+ "count": len(names),
119
+ }
120
+ for name in names:
121
+ readme = TEMPLATES_DIR / name / "README.md"
122
+ if readme.exists():
123
+ first = readme.read_text(encoding="utf-8").splitlines()[0].lstrip("# ").strip()
124
+ output.setdefault("titles", {})[name] = first
125
+ if args.json:
126
+ print(json.dumps(output, indent=2))
127
+ else:
128
+ print("Available Arc builder starter templates:")
129
+ if not names:
130
+ print(" (none)")
131
+ for name in names:
132
+ title = output.get("titles", {}).get(name, name)
133
+ print(f" - {name}: {title}")
134
+ return 0
135
+
136
+
137
+ def cmd_scaffold(args: argparse.Namespace) -> int:
138
+ available = _list_templates()
139
+ if args.template not in available:
140
+ raise CliError(
141
+ f"unknown template: {args.template}\n"
142
+ f"available: {', '.join(available) if available else '(none)'}"
143
+ )
144
+ source = TEMPLATES_DIR / args.template
145
+ dest = Path(args.output).expanduser().resolve()
146
+ if dest.exists() and not args.force:
147
+ raise CliError(f"output already exists: {dest}; use --force to overwrite")
148
+ if dest.exists() and args.force:
149
+ shutil.rmtree(dest)
150
+ shutil.copytree(source, dest)
151
+ print(f"scaffolded '{args.template}' -> {dest}")
152
+ print(f"next: cd {dest.relative_to(Path.cwd()) if dest.is_relative_to(Path.cwd()) else dest}")
153
+ return 0
154
+
155
+
156
+ def cmd_facts(args: argparse.Namespace) -> int:
157
+ facts = _load_json(CONFIG_DIR / "arc_testnet.facts.json")
158
+ if args.json:
159
+ print(json.dumps(facts, indent=2))
160
+ else:
161
+ print(json.dumps(facts, indent=2))
162
+ return 0
163
+
164
+
165
+ def cmd_manifest(args: argparse.Namespace) -> int:
166
+ result = _run_script(X402_SERVER, ["--print-manifest"], timeout=60)
167
+ if result.stdout:
168
+ sys.stdout.write(result.stdout)
169
+ if result.stderr:
170
+ sys.stderr.write(result.stderr)
171
+ return result.returncode if result.returncode else 0
172
+
173
+
174
+ def cmd_mcp(args: argparse.Namespace) -> int:
175
+ return mcp_main()
176
+
177
+
178
+ def cmd_release_packet(args: argparse.Namespace) -> int:
179
+ out = (
180
+ Path(args.output).expanduser().resolve()
181
+ if args.output
182
+ else DEFAULT_OUTPUT_ROOT / ".arc-release-packet"
183
+ )
184
+ argv = ["--out", str(out)]
185
+ if args.force:
186
+ argv.append("--force")
187
+ return release_packet_main(argv)
188
+
189
+
190
+ def build_parser() -> argparse.ArgumentParser:
191
+ parser = argparse.ArgumentParser(
192
+ prog="arc-builder",
193
+ description="Unified CLI for the Arc MCP Builder Assistant kit.",
194
+ )
195
+ parser.add_argument(
196
+ "--version",
197
+ action="version",
198
+ version=f"%(prog)s {__version__}",
199
+ )
200
+ sub = parser.add_subparsers(dest="command", required=True)
201
+
202
+ doctor = sub.add_parser("doctor", help="Run Arc Builder Doctor.")
203
+ doctor.add_argument("--full", action="store_true", help="Run full local verification.")
204
+ doctor.add_argument(
205
+ "--include-arc-rpc",
206
+ action="store_true",
207
+ help="Opt-in read-only Arc Testnet RPC chain-id check.",
208
+ )
209
+ doctor.add_argument(
210
+ "--include-public-site",
211
+ action="store_true",
212
+ help="Opt-in public GitHub Pages health check.",
213
+ )
214
+
215
+ sub.add_parser("validate", help="Run repository validation.")
216
+
217
+ templates = sub.add_parser("templates", help="List available starter templates.")
218
+ templates.add_argument("--json", action="store_true", help="Output machine-readable JSON.")
219
+
220
+ scaffold = sub.add_parser("scaffold", help="Copy a starter template to a new project.")
221
+ scaffold.add_argument("template", help="Template name (see 'templates').")
222
+ scaffold.add_argument("output", help="Destination directory.")
223
+ scaffold.add_argument("--force", action="store_true", help="Overwrite existing directory.")
224
+
225
+ facts = sub.add_parser("facts", help="Print reviewed Arc Testnet facts.")
226
+ facts.add_argument("--json", action="store_true", help="Output machine-readable JSON.")
227
+
228
+ sub.add_parser("manifest", help="Print the local x402 paid-agent manifest.")
229
+ sub.add_parser("mcp", help="Start the local Arc Builder MCP server (stdio).")
230
+
231
+ release_packet = sub.add_parser(
232
+ "release-packet", help="Generate a local maintainer release packet."
233
+ )
234
+ release_packet.add_argument(
235
+ "--output",
236
+ default="",
237
+ help="Output directory (default: .arc-release-packet/).",
238
+ )
239
+ release_packet.add_argument(
240
+ "--force",
241
+ action="store_true",
242
+ help="Overwrite existing packet directory.",
243
+ )
244
+
245
+ return parser
246
+
247
+
248
+ COMMANDS = {
249
+ "doctor": cmd_doctor,
250
+ "validate": cmd_validate,
251
+ "templates": cmd_templates,
252
+ "scaffold": cmd_scaffold,
253
+ "facts": cmd_facts,
254
+ "manifest": cmd_manifest,
255
+ "mcp": cmd_mcp,
256
+ "release-packet": cmd_release_packet,
257
+ }
258
+
259
+
260
+ def main(argv: Sequence[str] | None = None) -> int:
261
+ parser = build_parser()
262
+ args = parser.parse_args(argv)
263
+ handler = COMMANDS.get(args.command)
264
+ if handler is None:
265
+ parser.error(f"unknown command: {args.command}")
266
+ try:
267
+ return handler(args)
268
+ except CliError as exc:
269
+ print(f"error: {exc.message}", file=sys.stderr)
270
+ return exc.exit_code
271
+ except subprocess.TimeoutExpired as exc:
272
+ print(f"error: timed out running {exc.cmd}", file=sys.stderr)
273
+ return 1
274
+
275
+
276
+ if __name__ == "__main__":
277
+ sys.exit(main())
@@ -0,0 +1,31 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "scope": "arc-testnet-facts",
4
+ "network": {
5
+ "name": "Arc Testnet",
6
+ "chainId": 5042002,
7
+ "chainIdHex": "0x4cef52",
8
+ "rpcUrl": "https://rpc.testnet.arc.network",
9
+ "explorerUrl": "https://testnet.arcscan.app"
10
+ },
11
+ "nativeGas": {
12
+ "symbol": "USDC",
13
+ "decimals": 18
14
+ },
15
+ "erc20Usdc": {
16
+ "symbol": "USDC",
17
+ "address": "0x3600000000000000000000000000000000000000",
18
+ "decimals": 6
19
+ },
20
+ "policy": {
21
+ "mainnetSupported": false,
22
+ "walletRequired": false,
23
+ "networkChecksOptIn": true,
24
+ "recheckBeforePublication": true
25
+ },
26
+ "sources": {
27
+ "connect": "https://docs.arc.io/arc/references/connect-to-arc",
28
+ "contracts": "https://docs.arc.io/arc/references/contract-addresses",
29
+ "deploymentModel": "https://docs.arc.io/arc/concepts/deployment-model"
30
+ }
31
+ }