hyperflash 1.1.1__tar.gz → 1.1.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperflash
3
- Version: 1.1.1
3
+ Version: 1.1.2
4
4
  Summary: Universal Engineering Reliability Runtime & Multi-Agent Verification Guardrails
5
5
  Author: Virat Ghatge
6
6
  License: MIT
@@ -184,7 +184,12 @@ Scaffold your preferred IDE or agent harness in 1 second:
184
184
  # Configure Cursor, Claude Code, Windsurf, Git Hooks, Antigravity, and OpenCode in one command
185
185
  hyperflash init
186
186
 
187
- # Or target your specific harness:
187
+ # Configure globally across ALL workspaces (user home directory):
188
+ # Sets up OpenCode (~/.config/opencode/opencode.json), Claude Code (~/.claude.json), and Antigravity globally
189
+ hyperflash init --global # or: hyperflash init -g
190
+
191
+ # Or target your specific harness globally or locally:
192
+ hyperflash init --target opencode --global
188
193
  hyperflash init --target cursor
189
194
  hyperflash init --target claude
190
195
  hyperflash init --target windsurf
@@ -193,6 +198,14 @@ hyperflash init --target antigravity
193
198
  hyperflash init --target opencode
194
199
  ```
195
200
 
201
+ > [!TIP]
202
+ > **Global Configuration Mode (`--global` / `-g`):**
203
+ > When running `hyperflash init --global` (or `-g`), HyperFlash configures your user home directory rather than the current working folder. This means:
204
+ > - **OpenCode:** Registers HyperFlash agent persona and MCP server in `~/.config/opencode/opencode.json` so `opencode --agent hyperflash` works anywhere on your system.
205
+ > - **Claude Code:** Registers the MCP server in `~/.claude.json` and slash command in `~/.claude/commands/hyperflash.md`.
206
+ > - **Antigravity:** Installs skills, agents, and rules globally in `~/.gemini/config/`.
207
+ > You only need to run this once—no per-repository initialization required!
208
+
196
209
  ### 🚀 Universal Agent Launcher
197
210
  Launch your preferred coding environment with the native HyperFlash agent persona pre-activated:
198
211
 
@@ -352,9 +365,17 @@ OpenCode supports dedicated named agents natively. HyperFlash installs as a firs
352
365
 
353
366
  #### Step 1: Automatic Setup via CLI
354
367
  ```bash
368
+ # Option A: Global setup (recommended) - works across all folders on your system:
369
+ hyperflash init --target opencode --global
370
+
371
+ # Option B: Local workspace setup - configures current repository:
355
372
  hyperflash init --target opencode
356
373
  ```
357
- This configures:
374
+
375
+ **Global Setup (`--global`) configures:**
376
+ - `~/.config/opencode/opencode.json`: Declares the global `hyperflash` agent persona and registers the stdio MCP server without overwriting existing agents or servers.
377
+
378
+ **Local Setup configures:**
358
379
  - `OPENCODE.md`: OpenCode engineering constitution.
359
380
  - `.opencode/agents/hyperflash.json`: Dedicated agent persona definition.
360
381
  - `opencode.json`: Declares `agent: "hyperflash"`, registers agent configuration, and wires the `hyperflash` stdio MCP server.
@@ -159,7 +159,12 @@ Scaffold your preferred IDE or agent harness in 1 second:
159
159
  # Configure Cursor, Claude Code, Windsurf, Git Hooks, Antigravity, and OpenCode in one command
160
160
  hyperflash init
161
161
 
162
- # Or target your specific harness:
162
+ # Configure globally across ALL workspaces (user home directory):
163
+ # Sets up OpenCode (~/.config/opencode/opencode.json), Claude Code (~/.claude.json), and Antigravity globally
164
+ hyperflash init --global # or: hyperflash init -g
165
+
166
+ # Or target your specific harness globally or locally:
167
+ hyperflash init --target opencode --global
163
168
  hyperflash init --target cursor
164
169
  hyperflash init --target claude
165
170
  hyperflash init --target windsurf
@@ -168,6 +173,14 @@ hyperflash init --target antigravity
168
173
  hyperflash init --target opencode
169
174
  ```
170
175
 
176
+ > [!TIP]
177
+ > **Global Configuration Mode (`--global` / `-g`):**
178
+ > When running `hyperflash init --global` (or `-g`), HyperFlash configures your user home directory rather than the current working folder. This means:
179
+ > - **OpenCode:** Registers HyperFlash agent persona and MCP server in `~/.config/opencode/opencode.json` so `opencode --agent hyperflash` works anywhere on your system.
180
+ > - **Claude Code:** Registers the MCP server in `~/.claude.json` and slash command in `~/.claude/commands/hyperflash.md`.
181
+ > - **Antigravity:** Installs skills, agents, and rules globally in `~/.gemini/config/`.
182
+ > You only need to run this once—no per-repository initialization required!
183
+
171
184
  ### 🚀 Universal Agent Launcher
172
185
  Launch your preferred coding environment with the native HyperFlash agent persona pre-activated:
173
186
 
@@ -327,9 +340,17 @@ OpenCode supports dedicated named agents natively. HyperFlash installs as a firs
327
340
 
328
341
  #### Step 1: Automatic Setup via CLI
329
342
  ```bash
343
+ # Option A: Global setup (recommended) - works across all folders on your system:
344
+ hyperflash init --target opencode --global
345
+
346
+ # Option B: Local workspace setup - configures current repository:
330
347
  hyperflash init --target opencode
331
348
  ```
332
- This configures:
349
+
350
+ **Global Setup (`--global`) configures:**
351
+ - `~/.config/opencode/opencode.json`: Declares the global `hyperflash` agent persona and registers the stdio MCP server without overwriting existing agents or servers.
352
+
353
+ **Local Setup configures:**
333
354
  - `OPENCODE.md`: OpenCode engineering constitution.
334
355
  - `.opencode/agents/hyperflash.json`: Dedicated agent persona definition.
335
356
  - `opencode.json`: Declares `agent: "hyperflash"`, registers agent configuration, and wires the `hyperflash` stdio MCP server.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hyperflash"
7
- version = "1.1.1"
7
+ version = "1.1.2"
8
8
  description = "Universal Engineering Reliability Runtime & Multi-Agent Verification Guardrails"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -14,7 +14,7 @@ from hyperflash.core import (
14
14
  save_contract,
15
15
  )
16
16
 
17
- __version__: str = "1.1.1"
17
+ __version__: str = "1.1.2"
18
18
 
19
19
  __all__: list[str] = [
20
20
  "__version__",
@@ -36,37 +36,39 @@ def cmd_init(args: argparse.Namespace) -> int:
36
36
  """Handles 'hyperflash init' command."""
37
37
  target: str = args.target.lower()
38
38
  workspace: str = args.workspace
39
+ is_global: bool = getattr(args, "is_global", False)
39
40
 
40
- print(f"⚡ HyperFlash: Initializing reliability runtime for target '{target}' in '{workspace}'...")
41
+ target_desc: str = "globally in user home" if is_global else f"in '{workspace}'"
42
+ print(f"⚡ HyperFlash: Initializing reliability runtime for target '{target}' {target_desc}...")
41
43
 
42
44
  if target == "all":
43
- results = setup_all(workspace)
45
+ results = setup_all(workspace, is_global=is_global)
44
46
  for platform, files in results.items():
45
47
  print(f" • {platform.capitalize()}:")
46
48
  for f in files:
47
49
  print(f" - Configured: {f}")
48
50
  elif target == "cursor":
49
- files = setup_cursor(workspace)
51
+ files = setup_cursor(workspace, is_global=is_global)
50
52
  for f in files:
51
53
  print(f" • Configured Cursor: {f}")
52
54
  elif target == "claude":
53
- files = setup_claude(workspace)
55
+ files = setup_claude(workspace, is_global=is_global)
54
56
  for f in files:
55
57
  print(f" • Configured Claude Code: {f}")
56
58
  elif target == "windsurf":
57
- files = setup_windsurf(workspace)
59
+ files = setup_windsurf(workspace, is_global=is_global)
58
60
  for f in files:
59
61
  print(f" • Configured Windsurf: {f}")
60
62
  elif target == "git":
61
- files = setup_git_hooks(workspace)
63
+ files = setup_git_hooks(workspace, is_global=is_global)
62
64
  for f in files:
63
65
  print(f" • Configured Git pre-commit hook: {f}")
64
66
  elif target == "antigravity":
65
- files = setup_antigravity(workspace)
67
+ files = setup_antigravity(workspace, is_global=is_global)
66
68
  for f in files:
67
69
  print(f" • Configured Antigravity: {f}")
68
70
  elif target == "opencode":
69
- files = setup_opencode(workspace)
71
+ files = setup_opencode(workspace, is_global=is_global)
70
72
  for f in files:
71
73
  print(f" • Configured OpenCode: {f}")
72
74
  else:
@@ -244,6 +246,13 @@ def build_parser() -> argparse.ArgumentParser:
244
246
  default=".",
245
247
  help="Workspace root directory (default: .)",
246
248
  )
249
+ p_init.add_argument(
250
+ "-g",
251
+ "--global",
252
+ dest="is_global",
253
+ action="store_true",
254
+ help="Configure globally in user home directory across all workspaces",
255
+ )
247
256
 
248
257
  # launch
249
258
  p_launch = subparsers.add_parser("launch", help="Launch your preferred coding harness with HyperFlash agent active")
@@ -144,6 +144,31 @@ OPENCODE_CONFIG_DICT: dict[str, Any] = {
144
144
  },
145
145
  }
146
146
 
147
+ OPENCODE_GLOBAL_CONFIG_DICT: dict[str, Any] = {
148
+ "agent": {
149
+ "hyperflash": {
150
+ "name": "HyperFlash",
151
+ "description": "Universal Engineering Reliability & Multi-Agent Verification Runtime",
152
+ "system": (
153
+ "You are HYPERFLASH, the Principal Multi-Agent Engineering Reliability Orchestrator. "
154
+ "You operate strictly under the 8 HyperFlash Invariants: 1. Ground before mutating. "
155
+ "2. Stay in declared scope. 3. Fresh evidence required before completion. "
156
+ "4. Never exact-retry failed modifications. 5. Satisfy acceptance criteria. "
157
+ "6. Report reality only. 7. ZERO code elision. 8. Exhaustive static typing. "
158
+ "Always use hyperflash_safe_patch to mutate files, and run hyperflash_verify before claiming a task is done."
159
+ ),
160
+ }
161
+ },
162
+ "mcp": {
163
+ "servers": {
164
+ "hyperflash": {
165
+ "type": "local",
166
+ "command": ["hyperflash", "mcp"],
167
+ }
168
+ }
169
+ },
170
+ }
171
+
147
172
  GIT_PRE_COMMIT_CONTENT: str = """#!/usr/bin/env bash
148
173
  # HyperFlash Zero-Elision & Integrity Gate
149
174
  set -e
@@ -208,86 +233,129 @@ def merge_json_config(file_path: Path, new_data: dict[str, Any]) -> None:
208
233
  else:
209
234
  existing["agents"] = new_data["agents"]
210
235
 
236
+ # Merge nested 'agent' dict if both are dicts
237
+ if "agent" in new_data:
238
+ if isinstance(new_data["agent"], dict):
239
+ agent_dict = existing.get("agent", {})
240
+ if isinstance(agent_dict, dict):
241
+ agent_dict.update(new_data["agent"])
242
+ existing["agent"] = agent_dict
243
+ else:
244
+ existing["agent"] = new_data["agent"]
245
+ else:
246
+ existing["agent"] = new_data["agent"]
247
+
248
+ # Merge nested 'mcp' dict (OpenCode global config schema: {"mcp": {"servers": {...}}})
249
+ if "mcp" in new_data:
250
+ if isinstance(new_data["mcp"], dict):
251
+ mcp_dict = existing.get("mcp", {})
252
+ if isinstance(mcp_dict, dict):
253
+ servers = mcp_dict.get("servers", {})
254
+ new_servers = new_data["mcp"].get("servers", {})
255
+ if isinstance(servers, dict) and isinstance(new_servers, dict):
256
+ servers.update(new_servers)
257
+ mcp_dict["servers"] = servers
258
+ else:
259
+ mcp_dict.update(new_data["mcp"])
260
+ existing["mcp"] = mcp_dict
261
+ else:
262
+ existing["mcp"] = new_data["mcp"]
263
+ else:
264
+ existing["mcp"] = new_data["mcp"]
265
+
211
266
  for k, v in new_data.items():
212
- if k not in ("mcpServers", "agents"):
267
+ if k not in ("mcpServers", "agents", "agent", "mcp"):
213
268
  existing[k] = v
214
269
 
215
270
  file_path.write_text(json.dumps(existing, indent=2), encoding="utf-8")
216
271
 
217
272
 
218
- def setup_cursor(workspace_dir: Path | str = ".") -> list[str]:
273
+ def setup_cursor(workspace_dir: Path | str = ".", is_global: bool = False) -> list[str]:
219
274
  """
220
275
  Configures HyperFlash rules, agent rule mdc, and stdio MCP server for Cursor.
221
276
  """
222
- workspace = Path(workspace_dir).resolve()
277
+ target_root = Path.home() if is_global else Path(workspace_dir).resolve()
223
278
  created_files: list[str] = []
224
279
 
225
- rules_path = workspace / ".cursorrules"
280
+ rules_path = target_root / ".cursorrules"
226
281
  rules_path.write_text(CURSOR_RULES_CONTENT, encoding="utf-8")
227
282
  created_files.append(str(rules_path))
228
283
 
229
- rules_dir = workspace / ".cursor" / "rules"
284
+ rules_dir = target_root / ".cursor" / "rules"
230
285
  rules_dir.mkdir(parents=True, exist_ok=True)
231
286
  mdc_path = rules_dir / "hyperflash.mdc"
232
287
  mdc_path.write_text(CURSOR_RULE_MDC_CONTENT, encoding="utf-8")
233
288
  created_files.append(str(mdc_path))
234
289
 
235
- mcp_path = workspace / ".cursor" / "mcp.json"
290
+ mcp_path = target_root / ".cursor" / "mcp.json"
236
291
  merge_json_config(mcp_path, MCP_CONFIG_DICT)
237
292
  created_files.append(str(mcp_path))
238
293
 
239
294
  return created_files
240
295
 
241
296
 
242
- def setup_claude(workspace_dir: Path | str = ".") -> list[str]:
297
+ def setup_claude(workspace_dir: Path | str = ".", is_global: bool = False) -> list[str]:
243
298
  """
244
299
  Configures HyperFlash rules, slash command, and stdio MCP server for Claude Code.
245
300
  """
246
- workspace = Path(workspace_dir).resolve()
247
301
  created_files: list[str] = []
248
302
 
249
- claude_md = workspace / "CLAUDE.md"
250
- claude_md.write_text(CLAUDE_MD_CONTENT, encoding="utf-8")
251
- created_files.append(str(claude_md))
252
-
253
- commands_dir = workspace / ".claude" / "commands"
254
- commands_dir.mkdir(parents=True, exist_ok=True)
255
- cmd_file = commands_dir / "hyperflash.md"
256
- cmd_file.write_text(CLAUDE_COMMAND_MD_CONTENT, encoding="utf-8")
257
- created_files.append(str(cmd_file))
258
-
259
- claude_json = workspace / ".claude.json"
260
- merge_json_config(claude_json, MCP_CONFIG_DICT)
261
- created_files.append(str(claude_json))
303
+ if is_global:
304
+ home = Path.home()
305
+ commands_dir = home / ".claude" / "commands"
306
+ commands_dir.mkdir(parents=True, exist_ok=True)
307
+ cmd_file = commands_dir / "hyperflash.md"
308
+ cmd_file.write_text(CLAUDE_COMMAND_MD_CONTENT, encoding="utf-8")
309
+ created_files.append(str(cmd_file))
310
+
311
+ claude_json = home / ".claude.json"
312
+ merge_json_config(claude_json, MCP_CONFIG_DICT)
313
+ created_files.append(str(claude_json))
314
+ else:
315
+ workspace = Path(workspace_dir).resolve()
316
+
317
+ claude_md = workspace / "CLAUDE.md"
318
+ claude_md.write_text(CLAUDE_MD_CONTENT, encoding="utf-8")
319
+ created_files.append(str(claude_md))
320
+
321
+ commands_dir = workspace / ".claude" / "commands"
322
+ commands_dir.mkdir(parents=True, exist_ok=True)
323
+ cmd_file = commands_dir / "hyperflash.md"
324
+ cmd_file.write_text(CLAUDE_COMMAND_MD_CONTENT, encoding="utf-8")
325
+ created_files.append(str(cmd_file))
326
+
327
+ claude_json = workspace / ".claude.json"
328
+ merge_json_config(claude_json, MCP_CONFIG_DICT)
329
+ created_files.append(str(claude_json))
262
330
 
263
331
  return created_files
264
332
 
265
333
 
266
- def setup_windsurf(workspace_dir: Path | str = ".") -> list[str]:
334
+ def setup_windsurf(workspace_dir: Path | str = ".", is_global: bool = False) -> list[str]:
267
335
  """
268
336
  Configures HyperFlash rules, agent persona rule, and stdio MCP server for Windsurf.
269
337
  """
270
- workspace = Path(workspace_dir).resolve()
338
+ target_root = Path.home() if is_global else Path(workspace_dir).resolve()
271
339
  created_files: list[str] = []
272
340
 
273
- rules_path = workspace / ".windsurfrules"
341
+ rules_path = target_root / ".windsurfrules"
274
342
  rules_path.write_text(WINDSURF_RULES_CONTENT, encoding="utf-8")
275
343
  created_files.append(str(rules_path))
276
344
 
277
- rules_dir = workspace / ".windsurf" / "rules"
345
+ rules_dir = target_root / ".windsurf" / "rules"
278
346
  rules_dir.mkdir(parents=True, exist_ok=True)
279
347
  rule_md_path = rules_dir / "hyperflash.md"
280
348
  rule_md_path.write_text(WINDSURF_RULE_MD_CONTENT, encoding="utf-8")
281
349
  created_files.append(str(rule_md_path))
282
350
 
283
- mcp_path = workspace / ".windsurf" / "mcp.json"
351
+ mcp_path = target_root / ".windsurf" / "mcp.json"
284
352
  merge_json_config(mcp_path, MCP_CONFIG_DICT)
285
353
  created_files.append(str(mcp_path))
286
354
 
287
355
  return created_files
288
356
 
289
357
 
290
- def setup_git_hooks(workspace_dir: Path | str = ".") -> list[str]:
358
+ def setup_git_hooks(workspace_dir: Path | str = ".", is_global: bool = False) -> list[str]:
291
359
  """
292
360
  Installs HyperFlash pre-commit hook into .git/hooks.
293
361
  """
@@ -295,6 +363,9 @@ def setup_git_hooks(workspace_dir: Path | str = ".") -> list[str]:
295
363
  git_hooks_dir = workspace / ".git" / "hooks"
296
364
  created_files: list[str] = []
297
365
 
366
+ if is_global and not (workspace / ".git").exists():
367
+ return created_files
368
+
298
369
  git_hooks_dir.mkdir(parents=True, exist_ok=True)
299
370
 
300
371
  hook_file = git_hooks_dir / "pre-commit"
@@ -309,7 +380,7 @@ def setup_git_hooks(workspace_dir: Path | str = ".") -> list[str]:
309
380
  return created_files
310
381
 
311
382
 
312
- def setup_antigravity(workspace_dir: Path | str = ".") -> list[str]:
383
+ def setup_antigravity(workspace_dir: Path | str = ".", is_global: bool = False) -> list[str]:
313
384
  """
314
385
  Installs or updates HyperFlash skill and agents in Antigravity (~/.gemini/config/).
315
386
  """
@@ -349,39 +420,47 @@ def setup_antigravity(workspace_dir: Path | str = ".") -> list[str]:
349
420
  return created_files
350
421
 
351
422
 
352
- def setup_opencode(workspace_dir: Path | str = ".") -> list[str]:
423
+ def setup_opencode(workspace_dir: Path | str = ".", is_global: bool = False) -> list[str]:
353
424
  """
354
425
  Configures HyperFlash rules, agent persona, and stdio MCP server for OpenCode.
426
+ If is_global is True, writes to user global config: ~/.config/opencode/opencode.json.
427
+ If not purely global, also writes local workspace files: OPENCODE.md, .opencode/agents/hyperflash.json, opencode.json.
355
428
  """
356
- workspace = Path(workspace_dir).resolve()
357
429
  created_files: list[str] = []
358
430
 
359
- opencode_md = workspace / "OPENCODE.md"
360
- opencode_md.write_text(OPENCODE_MD_CONTENT, encoding="utf-8")
361
- created_files.append(str(opencode_md))
431
+ if is_global:
432
+ global_config_path = Path.home() / ".config" / "opencode" / "opencode.json"
433
+ merge_json_config(global_config_path, OPENCODE_GLOBAL_CONFIG_DICT)
434
+ created_files.append(str(global_config_path))
435
+ else:
436
+ workspace = Path(workspace_dir).resolve()
437
+
438
+ opencode_md = workspace / "OPENCODE.md"
439
+ opencode_md.write_text(OPENCODE_MD_CONTENT, encoding="utf-8")
440
+ created_files.append(str(opencode_md))
362
441
 
363
- agent_dir = workspace / ".opencode" / "agents"
364
- agent_dir.mkdir(parents=True, exist_ok=True)
365
- agent_json_path = agent_dir / "hyperflash.json"
366
- agent_json_path.write_text(json.dumps(OPENCODE_AGENT_DICT, indent=2), encoding="utf-8")
367
- created_files.append(str(agent_json_path))
442
+ agent_dir = workspace / ".opencode" / "agents"
443
+ agent_dir.mkdir(parents=True, exist_ok=True)
444
+ agent_json_path = agent_dir / "hyperflash.json"
445
+ agent_json_path.write_text(json.dumps(OPENCODE_AGENT_DICT, indent=2), encoding="utf-8")
446
+ created_files.append(str(agent_json_path))
368
447
 
369
- opencode_json = workspace / "opencode.json"
370
- merge_json_config(opencode_json, OPENCODE_CONFIG_DICT)
371
- created_files.append(str(opencode_json))
448
+ opencode_json = workspace / "opencode.json"
449
+ merge_json_config(opencode_json, OPENCODE_CONFIG_DICT)
450
+ created_files.append(str(opencode_json))
372
451
 
373
452
  return created_files
374
453
 
375
454
 
376
- def setup_all(workspace_dir: Path | str = ".") -> dict[str, list[str]]:
455
+ def setup_all(workspace_dir: Path | str = ".", is_global: bool = False) -> dict[str, list[str]]:
377
456
  """
378
457
  Executes polyglot configuration across all supported platforms.
379
458
  """
380
459
  return {
381
- "cursor": setup_cursor(workspace_dir),
382
- "claude": setup_claude(workspace_dir),
383
- "windsurf": setup_windsurf(workspace_dir),
384
- "git": setup_git_hooks(workspace_dir),
385
- "antigravity": setup_antigravity(workspace_dir),
386
- "opencode": setup_opencode(workspace_dir),
460
+ "cursor": setup_cursor(workspace_dir, is_global=is_global),
461
+ "claude": setup_claude(workspace_dir, is_global=is_global),
462
+ "windsurf": setup_windsurf(workspace_dir, is_global=is_global),
463
+ "git": setup_git_hooks(workspace_dir, is_global=is_global),
464
+ "antigravity": setup_antigravity(workspace_dir, is_global=is_global),
465
+ "opencode": setup_opencode(workspace_dir, is_global=is_global),
387
466
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperflash
3
- Version: 1.1.1
3
+ Version: 1.1.2
4
4
  Summary: Universal Engineering Reliability Runtime & Multi-Agent Verification Guardrails
5
5
  Author: Virat Ghatge
6
6
  License: MIT
@@ -184,7 +184,12 @@ Scaffold your preferred IDE or agent harness in 1 second:
184
184
  # Configure Cursor, Claude Code, Windsurf, Git Hooks, Antigravity, and OpenCode in one command
185
185
  hyperflash init
186
186
 
187
- # Or target your specific harness:
187
+ # Configure globally across ALL workspaces (user home directory):
188
+ # Sets up OpenCode (~/.config/opencode/opencode.json), Claude Code (~/.claude.json), and Antigravity globally
189
+ hyperflash init --global # or: hyperflash init -g
190
+
191
+ # Or target your specific harness globally or locally:
192
+ hyperflash init --target opencode --global
188
193
  hyperflash init --target cursor
189
194
  hyperflash init --target claude
190
195
  hyperflash init --target windsurf
@@ -193,6 +198,14 @@ hyperflash init --target antigravity
193
198
  hyperflash init --target opencode
194
199
  ```
195
200
 
201
+ > [!TIP]
202
+ > **Global Configuration Mode (`--global` / `-g`):**
203
+ > When running `hyperflash init --global` (or `-g`), HyperFlash configures your user home directory rather than the current working folder. This means:
204
+ > - **OpenCode:** Registers HyperFlash agent persona and MCP server in `~/.config/opencode/opencode.json` so `opencode --agent hyperflash` works anywhere on your system.
205
+ > - **Claude Code:** Registers the MCP server in `~/.claude.json` and slash command in `~/.claude/commands/hyperflash.md`.
206
+ > - **Antigravity:** Installs skills, agents, and rules globally in `~/.gemini/config/`.
207
+ > You only need to run this once—no per-repository initialization required!
208
+
196
209
  ### 🚀 Universal Agent Launcher
197
210
  Launch your preferred coding environment with the native HyperFlash agent persona pre-activated:
198
211
 
@@ -352,9 +365,17 @@ OpenCode supports dedicated named agents natively. HyperFlash installs as a firs
352
365
 
353
366
  #### Step 1: Automatic Setup via CLI
354
367
  ```bash
368
+ # Option A: Global setup (recommended) - works across all folders on your system:
369
+ hyperflash init --target opencode --global
370
+
371
+ # Option B: Local workspace setup - configures current repository:
355
372
  hyperflash init --target opencode
356
373
  ```
357
- This configures:
374
+
375
+ **Global Setup (`--global`) configures:**
376
+ - `~/.config/opencode/opencode.json`: Declares the global `hyperflash` agent persona and registers the stdio MCP server without overwriting existing agents or servers.
377
+
378
+ **Local Setup configures:**
358
379
  - `OPENCODE.md`: OpenCode engineering constitution.
359
380
  - `.opencode/agents/hyperflash.json`: Dedicated agent persona definition.
360
381
  - `opencode.json`: Declares `agent: "hyperflash"`, registers agent configuration, and wires the `hyperflash` stdio MCP server.
@@ -30,7 +30,7 @@ def test_cli_version_flag(capsys: pytest.CaptureFixture[str]) -> None:
30
30
  parser.parse_args(["--version"])
31
31
  assert exc_info.value.code == 0
32
32
  captured = capsys.readouterr()
33
- assert "hyperflash 1.1.1" in captured.out
33
+ assert "hyperflash 1.1.2" in captured.out
34
34
 
35
35
 
36
36
  def test_cli_decide_updates_contract(tmp_path: Path) -> None:
@@ -172,6 +172,59 @@ def test_cli_init_all(tmp_path: Path) -> None:
172
172
  assert (tmp_path / "opencode.json").exists()
173
173
 
174
174
 
175
+ def test_cli_init_global_flag_parsing() -> None:
176
+ """Verifies that -g and --global flags correctly set is_global attribute on parsed args."""
177
+ parser = build_parser()
178
+ args_short = parser.parse_args(["init", "-g"])
179
+ assert args_short.is_global is True
180
+
181
+ args_long = parser.parse_args(["init", "--global"])
182
+ assert args_long.is_global is True
183
+
184
+ args_default = parser.parse_args(["init"])
185
+ assert args_default.is_global is False
186
+
187
+
188
+ def test_cli_init_opencode_global(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
189
+ """Verifies that 'hyperflash init --target opencode --global' writes to user global config."""
190
+ fake_home = tmp_path / "fake_home"
191
+ fake_home.mkdir()
192
+ monkeypatch.setattr(Path, "home", lambda: fake_home)
193
+
194
+ parser = build_parser()
195
+ args = parser.parse_args(["init", "--target", "opencode", "--global"])
196
+ exit_code = cmd_init(args)
197
+ assert exit_code == 0
198
+
199
+ global_config = fake_home / ".config" / "opencode" / "opencode.json"
200
+ assert global_config.exists()
201
+ data = json.loads(global_config.read_text(encoding="utf-8"))
202
+ assert "agent" in data
203
+ assert "hyperflash" in data["agent"]
204
+ assert data["agent"]["hyperflash"]["name"] == "HyperFlash"
205
+ assert "mcp" in data
206
+ assert "servers" in data["mcp"]
207
+ assert "hyperflash" in data["mcp"]["servers"]
208
+
209
+
210
+ def test_cli_init_all_global(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
211
+ """Verifies that 'hyperflash init --global' configures harnesses in user home."""
212
+ fake_home = tmp_path / "fake_home"
213
+ fake_home.mkdir()
214
+ monkeypatch.setattr(Path, "home", lambda: fake_home)
215
+
216
+ parser = build_parser()
217
+ args = parser.parse_args(["init", "--global"])
218
+ exit_code = cmd_init(args)
219
+ assert exit_code == 0
220
+
221
+ assert (fake_home / ".config" / "opencode" / "opencode.json").exists()
222
+ assert (fake_home / ".claude.json").exists()
223
+ assert (fake_home / ".claude" / "commands" / "hyperflash.md").exists()
224
+ assert (fake_home / ".cursorrules").exists()
225
+ assert (fake_home / ".windsurfrules").exists()
226
+
227
+
175
228
  def test_cli_launch_missing_harness(capsys: pytest.CaptureFixture[str]) -> None:
176
229
  """Verifies that launching a harness not found in PATH returns 1 and friendly error."""
177
230
  parser = build_parser()
@@ -4,6 +4,7 @@ Tests elision detection, symbol graph generation, contract lifecycle, and verifi
4
4
  """
5
5
  from __future__ import annotations
6
6
 
7
+ import json
7
8
  from pathlib import Path
8
9
 
9
10
  import pytest
@@ -185,3 +186,73 @@ def test_setup_opencode(tmp_path: Path) -> None:
185
186
  assert "mcpServers" in content
186
187
  assert "hyperflash" in content
187
188
  assert '"agent": "hyperflash"' in content
189
+
190
+
191
+ def test_setup_opencode_global(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
192
+ """Verifies that setup_opencode(is_global=True) writes to ~/.config/opencode/opencode.json."""
193
+ fake_home = tmp_path / "home"
194
+ fake_home.mkdir()
195
+ monkeypatch.setattr(Path, "home", lambda: fake_home)
196
+
197
+ created = setup_opencode(is_global=True)
198
+ assert len(created) == 1
199
+
200
+ expected_path = fake_home / ".config" / "opencode" / "opencode.json"
201
+ assert str(expected_path) == created[0]
202
+ assert expected_path.exists()
203
+
204
+ data = json.loads(expected_path.read_text(encoding="utf-8"))
205
+ assert "agent" in data
206
+ assert "hyperflash" in data["agent"]
207
+ hf_agent = data["agent"]["hyperflash"]
208
+ assert hf_agent["name"] == "HyperFlash"
209
+ assert "Universal Engineering Reliability" in hf_agent["description"]
210
+ assert "8 HyperFlash Invariants" in hf_agent["system"]
211
+
212
+ assert "mcp" in data
213
+ assert "servers" in data["mcp"]
214
+ assert "hyperflash" in data["mcp"]["servers"]
215
+ hf_server = data["mcp"]["servers"]["hyperflash"]
216
+ assert hf_server["type"] == "local"
217
+ assert hf_server["command"] == ["hyperflash", "mcp"]
218
+
219
+
220
+ def test_setup_opencode_global_merges_without_overwriting(
221
+ tmp_path: Path,
222
+ monkeypatch: pytest.MonkeyPatch,
223
+ ) -> None:
224
+ """Verifies that global config setup safely merges without deleting existing agents or servers."""
225
+ fake_home = tmp_path / "home"
226
+ config_dir = fake_home / ".config" / "opencode"
227
+ config_dir.mkdir(parents=True)
228
+ target_file = config_dir / "opencode.json"
229
+
230
+ initial_config = {
231
+ "agent": {
232
+ "custom_coder": {
233
+ "name": "Custom Coder",
234
+ "system": "You write code."
235
+ }
236
+ },
237
+ "mcp": {
238
+ "servers": {
239
+ "git_mcp": {
240
+ "type": "local",
241
+ "command": ["git-mcp"]
242
+ }
243
+ }
244
+ },
245
+ "custom_setting": True
246
+ }
247
+ target_file.write_text(json.dumps(initial_config), encoding="utf-8")
248
+ monkeypatch.setattr(Path, "home", lambda: fake_home)
249
+
250
+ created = setup_opencode(is_global=True)
251
+ assert len(created) == 1
252
+
253
+ data = json.loads(target_file.read_text(encoding="utf-8"))
254
+ assert "custom_coder" in data["agent"]
255
+ assert "hyperflash" in data["agent"]
256
+ assert "git_mcp" in data["mcp"]["servers"]
257
+ assert "hyperflash" in data["mcp"]["servers"]
258
+ assert data["custom_setting"] is True
File without changes
File without changes
File without changes