@mcptoolshop/sovereign 1.0.0
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.
- package/CHANGELOG.md +126 -0
- package/LICENSE +21 -0
- package/README.es.md +158 -0
- package/README.fr.md +158 -0
- package/README.hi.md +158 -0
- package/README.it.md +158 -0
- package/README.ja.md +158 -0
- package/README.md +158 -0
- package/README.pt-BR.md +158 -0
- package/README.zh.md +158 -0
- package/SECURITY.md +61 -0
- package/bin/sovereign.js +167 -0
- package/package.json +56 -0
- package/release/00-START-HERE.html +333 -0
- package/release/CHANGELOG.md +126 -0
- package/release/README.txt +144 -0
- package/release/balance-evidence/README.txt +81 -0
- package/release/balance-evidence/raw-data/sovereign-batch-v0.10-canonical-400.json +72134 -0
- package/release/balance-evidence/raw-data/sovereign-batch-v0.10-canonical-slot-swap.json +18137 -0
- package/release/balance-evidence/raw-data/sovereign-batch-v0.10-canonical.json +18137 -0
- package/release/balance-evidence/raw-data/sovereign-batch-v0.10-mc-mirror.json +18089 -0
- package/release/balance-evidence/raw-data/sovereign-batch-v0.10-mfg-mirror.json +18089 -0
- package/release/balance-evidence/raw-data/sovereign-batch-v0.10-tf-mirror.json +18089 -0
- package/release/balance-evidence/sovereign-batch-v0.10-canonical-400.html +1 -0
- package/release/balance-evidence/sovereign-batch-v0.10-canonical-slot-swap.html +1 -0
- package/release/balance-evidence/sovereign-batch-v0.10-canonical.html +1 -0
- package/release/balance-evidence/sovereign-batch-v0.10-mc-mirror.html +1 -0
- package/release/balance-evidence/sovereign-batch-v0.10-mfg-mirror.html +1 -0
- package/release/balance-evidence/sovereign-batch-v0.10-summary.html +2 -0
- package/release/balance-evidence/sovereign-batch-v0.10-tf-mirror.html +1 -0
- package/release/board-game/README.txt +48 -0
- package/release/board-game/sovereign-economy-audit.html +501 -0
- package/release/board-game/sovereign-print-audit.html +479 -0
- package/release/board-game/sovereign-prototype.html +1939 -0
- package/release/design-history/01-phase1-concept.html +632 -0
- package/release/design-history/02-phase2-prototype.html +1026 -0
- package/release/design-history/03-phase3-audit.html +268 -0
- package/release/design-history/04-phase4-audit.html +274 -0
- package/release/design-history/05-phase5-audit.html +305 -0
- package/release/design-history/README.txt +66 -0
- package/release/digital-mode/README.txt +89 -0
- package/release/digital-mode/sovereign-solo.html +3884 -0
- package/release/digital-mode/sovereign-v0.10-freeze-audit.html +67 -0
package/README.zh.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="README.ja.md">日本語</a> | <a href="README.md">English</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português (BR)</a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<div align="center">
|
|
6
|
+
|
|
7
|
+
<img src="https://raw.githubusercontent.com/mcp-tool-shop-org/brand/main/logos/sovereign/readme.png" alt="Sovereign — The Hamilton System Board Game" width="400" />
|
|
8
|
+
|
|
9
|
+
**Hamilton 系统桌游 · 单人/数字版**
|
|
10
|
+
|
|
11
|
+
*奠基信贷 · 偿还债务。 建立银行。 推动工业化,建设共和国。*
|
|
12
|
+
|
|
13
|
+
[](https://github.com/mcp-tool-shop-org/sovereign/actions/workflows/ci.yml)
|
|
14
|
+
[](https://www.npmjs.com/package/@mcptoolshop/sovereign)
|
|
15
|
+
[](https://opensource.org/licenses/MIT)
|
|
16
|
+
[](https://mcp-tool-shop-org.github.io/sovereign/)
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 简介
|
|
23
|
+
|
|
24
|
+
Sovereign 是一款 **基于 Hamilton 系统的单多米诺骨牌游戏**,讲述的是美国公共信贷的建立,同时还提供一个 **完整的单人/数字版**,它可以在浏览器中本地运行,与两个预设的、可预测的对手进行游戏。
|
|
25
|
+
|
|
26
|
+
- **桌游** — 包含 34 页的打印原型。 包含 40 个格子,22 处地产 + 4 条路线 + 2 个机构,8 个颜色系统,7 项国会法案按照固定的历史顺序排列,4 个玩家角色,3 条共享进度条(公共信贷 · 公众抵制 · 工业能力),12+12 张事件卡。 除了财政部之外,还有两种可行的经济发展路径:商人路径和制造商路径。
|
|
27
|
+
- **数字模式** — 单个独立的 HTML 文件。 完整的状态机,使用可预测的 mulberry32 随机数生成器,预设的 AI 对手(财政部/金融、商人/基础设施、制造商/工业),支持保存/加载,并具有哈希完整性校验,回放功能,批量模拟工具,以及本地平衡性数据统计。
|
|
28
|
+
- **平衡性基准** — v0.10 版本,在经过九个版本的迭代后冻结,该迭代基于 1000 多个可预测的模拟游戏。 财政部:59%;商人:25%;制造商:16%(符合规范的 100 倍,所有三种模式都达到了目标范围)。
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 快速开始
|
|
33
|
+
|
|
34
|
+
### 在浏览器中直接玩(无需安装)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx @mcptoolshop/sovereign
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
CLI 命令会在您的默认浏览器中打开游戏。 无需安装程序,无需服务器,无需互联网连接。
|
|
41
|
+
|
|
42
|
+
其他模式:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx @mcptoolshop/sovereign --print # Open the printable 34-sheet board game
|
|
46
|
+
npx @mcptoolshop/sovereign --start # Open the audience-routed landing page
|
|
47
|
+
npx @mcptoolshop/sovereign --path # Print the playable HTML file path
|
|
48
|
+
npx @mcptoolshop/sovereign --help # All flags
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 在线玩
|
|
52
|
+
|
|
53
|
+
打开托管的页面 **<https://mcp-tool-shop-org.github.io/sovereign/>**,然后点击进入数字游戏。
|
|
54
|
+
|
|
55
|
+
### 打印并玩
|
|
56
|
+
|
|
57
|
+
桌游原型是一个独立的 34 页 HTML 文档。 打开 `release/board-game/sovereign-prototype.html` 文件(或从下载的文件中打开),然后使用 `Cmd/Ctrl-P → 保存为 PDF → US Letter → 100% 比例`。 裁剪并开始游戏。
|
|
58
|
+
|
|
59
|
+
### 离线发布包
|
|
60
|
+
|
|
61
|
+
每个版本都会在 GitHub 发布页面上附加一个 `sovereign-vX.Y.Z-release.zip` 的发布包。 下载它,解压缩,然后打开 `00-START-HERE.html` 文件,该文件会引导您进入游戏。 所有内容都可以在离线状态下运行。
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 设计理念
|
|
66
|
+
|
|
67
|
+
Sovereign 的核心思想是,**公共信贷 + 联邦财政** 是亚历山大·汉密尔顿最重要的经济杠杆。 但是,一款基于 Hamilton 系统的游戏必须允许 **商业** 和 **工业** 成为通往胜利的可行途径。 从 v0.2 到 v0.10 的平衡性迭代是一个持续九个版本的、以证据为导向的过程,旨在保持财政部作为最强大的模式(符合历史),同时避免游戏设计陷入单一策略。
|
|
68
|
+
|
|
69
|
+
请查看 [`CHANGELOG.md`](./CHANGELOG.md) 文件,了解每个版本的详细变化。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 可预测性
|
|
74
|
+
|
|
75
|
+
相同的种子 + 相同的玩家决策 = 跨运行、浏览器和操作系统,完全相同的游戏记录。
|
|
76
|
+
|
|
77
|
+
- 单个随机数生成器:`mulberry32(state.rngSeed)`。
|
|
78
|
+
- 电脑决策:是基于可见状态的纯函数,并且每个决策都会记录到游戏记录中,并附带触发规则。
|
|
79
|
+
- 保存/加载功能会保留状态哈希值。
|
|
80
|
+
- 回放功能会从 `initialState(seed) + decisionLog` 重新构建游戏。
|
|
81
|
+
- 在 v0.2 到 v0.10 的平衡性迭代过程中,通过 1000 多个可预测的游戏进行了验证。
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 威胁模型与数据处理
|
|
86
|
+
|
|
87
|
+
Sovereign 是一款独立的、基于浏览器的棋盘游戏。命令行界面会在您的默认浏览器中打开一个本地 HTML 文件。它没有服务器,没有网络调用,没有账户,也没有云同步。
|
|
88
|
+
|
|
89
|
+
- **涉及的数据:** `release/` 目录中的 HTML 文件(只读),以及 `sovereign.autosave` 键下的 `localStorage`(仅用于游戏存档)。
|
|
90
|
+
- **未涉及的数据:** 不会访问包目录之外的文件系统,不会进行任何类型的网络请求,不会收集任何遥测数据,不会进行任何分析,不会存储任何凭据。
|
|
91
|
+
- **所需权限:** 能够启动操作系统默认浏览器,能够读取包自身的配置文件,以及可选的浏览器 `localStorage` 访问权限。
|
|
92
|
+
- **绝不收集任何遥测数据。** 模拟器的“遥测”功能指的是从浏览器中的账本中提取的本地游戏分析报告,这些报告永远不会离开您的设备。
|
|
93
|
+
|
|
94
|
+
请参阅 [`SECURITY.md`](./SECURITY.md) 以获取漏洞报告和完整的安全策略。
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 功能
|
|
99
|
+
|
|
100
|
+
- **单人 7 轮游戏:** 对抗两个预设的对手(默认情况下为财政/金融和商人/基础设施;制造商/工业模式可用于批量游戏)。
|
|
101
|
+
- **确定性人工智能:** 每一个对手的决策都是基于可见状态的纯函数,并带有账本记录的理由。没有 LLM,没有不透明的魔法。
|
|
102
|
+
- **8 个游戏界面:** 棋盘、财政面板、资产检查器、事件面板、国会法案、共享轨道、回合日志/账本、游戏结束报告。
|
|
103
|
+
- **拍卖:** 未被选择的资产将进入多玩家拍卖,采用基于配置文件的预设竞标策略。
|
|
104
|
+
- **保存/加载:** 每回合自动保存到 `localStorage`,支持手动导出/导入 JSON 文件,加载时进行哈希完整性检查,并根据版本进行限制。
|
|
105
|
+
- **回放:** 可以对任何已完成的游戏进行完整的回放。只读。通过种子数据和决策日志进行重建,并带有绿色的完整性验证标志。
|
|
106
|
+
- **批量模拟:** 运行 10/50/100 轮确定性游戏,针对任何配置组合,并导出 JSON 和 HTML 报告以进行平衡性分析。
|
|
107
|
+
- **历史叙述:** 从账本中提取的 25 条条目(默认情况下为 40-60 个单词,扩展版本为 150-200 个单词,游戏结束时为约 300-500 个单词的概要)。不会改变游戏状态。
|
|
108
|
+
- **可访问性:** 完整的键盘导航,焦点指示器,屏幕阅读器友好的标签,可以以文本形式读取的数值(而不仅仅是标记),最小字体为 14px,尊重减少动画设置。
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 配置组合 (v0.10)
|
|
113
|
+
|
|
114
|
+
| 配置 | 资产优先级 | 优势 | 劣势 |
|
|
115
|
+
|--------------------------------|---------------------------------------------------------------|----------------------|-------------------------------------|
|
|
116
|
+
| **Treasury / Finance** | NF > 州债务 > 营收债务 > 银行 > 铸币厂 | 公共信用增长 | 无基础设施收入 |
|
|
117
|
+
| **Merchant / Infrastructure** | 航线 (全部 4 条) > 商业 > 改善 > 收入 | 航线等级 | 无工业产能评分 |
|
|
118
|
+
| **Manufacturer / Industry** | 制造业 > 战略工业 > 改善 > 银行 | 产能倍数 | 开局较慢;获得初始特许权 |
|
|
119
|
+
|
|
120
|
+
第四个概念性配置文件(机会主义者/现金)已推迟。当前 v0.10 版本中可用的竞争配置组合为三个。
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 已知问题
|
|
125
|
+
|
|
126
|
+
- **产能阈值在标准游戏中仍然很少出现。** 最终平均产能为 3.49;只有在 4/100 游戏中达到 ≥ 6。游戏结束时的工业产能评分是一个上限,而不是常规的路径。
|
|
127
|
+
- **财政/金融配置仍然是最强的,** 处于目标范围内。这符合历史论证:公共信用和联邦财政是汉密尔顿的主要经济杠杆。
|
|
128
|
+
- **失败事件在 v0.10 版本的测试中从未触发过(0/400 次)。** 默认/叛乱/破产威胁目前只是装饰性的;未来的版本可能会重新考虑失败状态的压力。
|
|
129
|
+
- **仅进行模拟测试。** 平衡性是根据 v0.3 → v0.10 版本中的 1000 多个确定性游戏进行验证的。尚未进行人类游戏测试;战略偏差可能会改变这些数值。
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 构建与贡献
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
git clone https://github.com/mcp-tool-shop-org/sovereign
|
|
137
|
+
cd sovereign
|
|
138
|
+
npm install
|
|
139
|
+
npm test # smoke tests
|
|
140
|
+
npm run verify # full verify (smoke + pack-dry-run + CLI flag check)
|
|
141
|
+
npm run play # open the game locally
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
发布版本会通过 GitHub Actions (`release.yml`) 推送到 npm,并在 `v*` 标签推送时进行 Sigstore 来源证明。 权威版本位于 `main` 分支。
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 许可证
|
|
149
|
+
|
|
150
|
+
MIT © mcp-tool-shop。 参见 [`LICENSE`](./LICENSE)。
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
<div align="center">
|
|
155
|
+
|
|
156
|
+
由 <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a> 构建。
|
|
157
|
+
|
|
158
|
+
</div>
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
|---------|-----------|
|
|
7
|
+
| 1.x | Yes |
|
|
8
|
+
| < 1.0 | No |
|
|
9
|
+
|
|
10
|
+
## Reporting a Vulnerability
|
|
11
|
+
|
|
12
|
+
Email: **64996768+mcp-tool-shop@users.noreply.github.com**
|
|
13
|
+
|
|
14
|
+
Include:
|
|
15
|
+
- Description of the vulnerability
|
|
16
|
+
- Steps to reproduce
|
|
17
|
+
- Version affected
|
|
18
|
+
- Potential impact
|
|
19
|
+
|
|
20
|
+
### Response timeline
|
|
21
|
+
|
|
22
|
+
| Action | Target |
|
|
23
|
+
|--------------------|----------|
|
|
24
|
+
| Acknowledge report | 48 hours |
|
|
25
|
+
| Assess severity | 7 days |
|
|
26
|
+
| Release fix | 30 days |
|
|
27
|
+
|
|
28
|
+
## Threat model
|
|
29
|
+
|
|
30
|
+
Sovereign is a self-contained browser-based board game. The CLI opens a local HTML file in the user's default browser. There is no server, no network call, no account, no cloud sync.
|
|
31
|
+
|
|
32
|
+
**Data touched:**
|
|
33
|
+
- The included HTML files in `release/` (read-only, served from package).
|
|
34
|
+
- `localStorage` under the `sovereign.autosave` key (game save state only — game ledger and decision log).
|
|
35
|
+
|
|
36
|
+
**Data NOT touched:**
|
|
37
|
+
- No filesystem access outside the package directory.
|
|
38
|
+
- No network requests of any kind.
|
|
39
|
+
- No telemetry, analytics, or remote logging.
|
|
40
|
+
- No credentials, tokens, or secrets handling — the package does not read, store, or transmit credentials.
|
|
41
|
+
|
|
42
|
+
**Permissions required:**
|
|
43
|
+
- Ability to spawn the OS default browser (`open` / `start` / `xdg-open`).
|
|
44
|
+
- Ability to read the package's own files.
|
|
45
|
+
- Browser `localStorage` access for save / load (optional — the game runs without it).
|
|
46
|
+
|
|
47
|
+
**Threats outside scope:**
|
|
48
|
+
- Compromise of the user's local browser, OS, or shell.
|
|
49
|
+
- Attacks on the GitHub-hosted source repository (covered by GitHub's own controls).
|
|
50
|
+
- npm registry compromise affecting package supply chain — mitigated by Sigstore provenance attestation on every published version (see `publishConfig.provenance: true` in `package.json`).
|
|
51
|
+
|
|
52
|
+
## Default safety posture
|
|
53
|
+
|
|
54
|
+
- The CLI takes no destructive actions. It opens an HTML file in a browser. That is the entire operation.
|
|
55
|
+
- No file write outside `localStorage` (which is browser-scoped, not filesystem-scoped).
|
|
56
|
+
- No background process — the CLI spawns the browser and exits.
|
|
57
|
+
- No flags exist for destructive operations. There are no `--allow-*` flags because there is nothing dangerous to allow.
|
|
58
|
+
|
|
59
|
+
## Telemetry
|
|
60
|
+
|
|
61
|
+
**None.** Sovereign collects no usage data, sends no events, and contacts no server. The simulator's "telemetry" feature (Phase 6) refers to local game-analysis reports derived from the in-browser ledger — these never leave the browser and never leave the user's machine.
|
package/bin/sovereign.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Sovereign — Hamilton-system board game · CLI entry point
|
|
4
|
+
*
|
|
5
|
+
* Opens the digital board game in the user's default browser.
|
|
6
|
+
* All gameplay is local. No network. The simulator is the included
|
|
7
|
+
* release/digital-mode/sovereign-solo.html file.
|
|
8
|
+
*
|
|
9
|
+
* Flags:
|
|
10
|
+
* --print Open the printable 34-sheet board game prototype instead.
|
|
11
|
+
* --start Open the START-HERE landing page (audience-routed entry).
|
|
12
|
+
* --path Print the file path of the playable HTML and exit.
|
|
13
|
+
* --quiet Silent on success (only errors print).
|
|
14
|
+
* --debug Include stack traces and verbose diagnostic output.
|
|
15
|
+
* --version Print version and exit.
|
|
16
|
+
* --help Print this help.
|
|
17
|
+
*
|
|
18
|
+
* Exit codes:
|
|
19
|
+
* 0 Success
|
|
20
|
+
* 1 User error (e.g. unknown flag, missing target)
|
|
21
|
+
* 2 Runtime error (e.g. browser spawn failed)
|
|
22
|
+
* 3 Partial success (reserved)
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { fileURLToPath } from 'node:url';
|
|
26
|
+
import { dirname, resolve } from 'node:path';
|
|
27
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
28
|
+
import { spawn } from 'node:child_process';
|
|
29
|
+
|
|
30
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
31
|
+
const PKG_ROOT = resolve(HERE, '..');
|
|
32
|
+
|
|
33
|
+
const TARGETS = {
|
|
34
|
+
game: resolve(PKG_ROOT, 'release', 'digital-mode', 'sovereign-solo.html'),
|
|
35
|
+
print: resolve(PKG_ROOT, 'release', 'board-game', 'sovereign-prototype.html'),
|
|
36
|
+
start: resolve(PKG_ROOT, 'release', '00-START-HERE.html'),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// --- Logging levels: silent / normal / verbose / debug -------------------
|
|
40
|
+
const LOG = { quiet: false, debug: false };
|
|
41
|
+
const info = (...args) => { if (!LOG.quiet) console.log(...args); };
|
|
42
|
+
const dbg = (...args) => { if (LOG.debug) console.error('[debug]', ...args); };
|
|
43
|
+
|
|
44
|
+
// --- Structured error printer: { code, message, hint, cause?, retryable? }
|
|
45
|
+
function fail(err, exitCode = 2) {
|
|
46
|
+
// Always: ERROR [code] message
|
|
47
|
+
console.error(`ERROR [${err.code}] ${err.message}`);
|
|
48
|
+
if (err.hint) console.error(` hint: ${err.hint}`);
|
|
49
|
+
if (err.path) console.error(` path: ${err.path}`);
|
|
50
|
+
if (err.retryable) console.error(` retryable: ${err.retryable}`);
|
|
51
|
+
if (LOG.debug && err.cause) {
|
|
52
|
+
console.error(' cause:', err.cause);
|
|
53
|
+
if (err.cause.stack) console.error(err.cause.stack);
|
|
54
|
+
}
|
|
55
|
+
process.exit(exitCode);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function readVersion() {
|
|
59
|
+
try {
|
|
60
|
+
const pkg = JSON.parse(readFileSync(resolve(PKG_ROOT, 'package.json'), 'utf8'));
|
|
61
|
+
return pkg.version;
|
|
62
|
+
} catch (e) {
|
|
63
|
+
dbg('readVersion failed:', e);
|
|
64
|
+
return 'unknown';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function help() {
|
|
69
|
+
console.log(`Sovereign · The Hamilton System Board Game · v${readVersion()}
|
|
70
|
+
|
|
71
|
+
Usage:
|
|
72
|
+
sovereign Open the digital board game in your browser.
|
|
73
|
+
sovereign --print Open the printable 34-sheet board game prototype.
|
|
74
|
+
sovereign --start Open the START-HERE landing page.
|
|
75
|
+
sovereign --path Print the playable HTML file path and exit.
|
|
76
|
+
sovereign --quiet Silent on success.
|
|
77
|
+
sovereign --debug Verbose diagnostic output.
|
|
78
|
+
sovereign --version Print version and exit.
|
|
79
|
+
sovereign --help Print this help.
|
|
80
|
+
|
|
81
|
+
Local-only. No network calls. No accounts. Deterministic (mulberry32).
|
|
82
|
+
Source: https://github.com/mcp-tool-shop-org/sovereign
|
|
83
|
+
`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function openInBrowser(absPath) {
|
|
87
|
+
if (!existsSync(absPath)) {
|
|
88
|
+
fail({
|
|
89
|
+
code: 'E_FILE_NOT_FOUND',
|
|
90
|
+
message: 'Sovereign HTML file not found in package.',
|
|
91
|
+
hint: 'Reinstall with `npm install -g @mcptoolshop/sovereign`',
|
|
92
|
+
path: absPath,
|
|
93
|
+
retryable: false,
|
|
94
|
+
}, 2);
|
|
95
|
+
}
|
|
96
|
+
const url = `file://${absPath.replace(/\\/g, '/')}`;
|
|
97
|
+
info(`Sovereign · opening ${absPath}`);
|
|
98
|
+
dbg('url:', url);
|
|
99
|
+
|
|
100
|
+
const platform = process.platform;
|
|
101
|
+
let cmd, args;
|
|
102
|
+
if (platform === 'darwin') {
|
|
103
|
+
cmd = 'open'; args = [url];
|
|
104
|
+
} else if (platform === 'win32') {
|
|
105
|
+
cmd = 'cmd'; args = ['/c', 'start', '""', url];
|
|
106
|
+
} else {
|
|
107
|
+
cmd = 'xdg-open'; args = [url];
|
|
108
|
+
}
|
|
109
|
+
dbg('spawn:', cmd, args);
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const child = spawn(cmd, args, { detached: true, stdio: 'ignore' });
|
|
113
|
+
child.unref();
|
|
114
|
+
} catch (err) {
|
|
115
|
+
fail({
|
|
116
|
+
code: 'E_BROWSER_SPAWN_FAILED',
|
|
117
|
+
message: `Could not open the OS default browser (${platform}).`,
|
|
118
|
+
hint: `Open this file manually: ${absPath}`,
|
|
119
|
+
cause: err,
|
|
120
|
+
retryable: true,
|
|
121
|
+
}, 2);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// --- CLI dispatch --------------------------------------------------------
|
|
126
|
+
const args = process.argv.slice(2);
|
|
127
|
+
|
|
128
|
+
// Flag parsing
|
|
129
|
+
LOG.quiet = args.includes('--quiet') || args.includes('-q');
|
|
130
|
+
LOG.debug = args.includes('--debug');
|
|
131
|
+
|
|
132
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
133
|
+
help();
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
136
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
137
|
+
console.log(readVersion());
|
|
138
|
+
process.exit(0);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Validate unknown flags (user-error vs. runtime-error distinction)
|
|
142
|
+
const KNOWN = new Set([
|
|
143
|
+
'--print', '--start', '--path',
|
|
144
|
+
'--quiet', '-q', '--debug',
|
|
145
|
+
'--version', '-v', '--help', '-h',
|
|
146
|
+
]);
|
|
147
|
+
for (const a of args) {
|
|
148
|
+
if (a.startsWith('-') && !KNOWN.has(a)) {
|
|
149
|
+
fail({
|
|
150
|
+
code: 'E_UNKNOWN_FLAG',
|
|
151
|
+
message: `Unknown flag: ${a}`,
|
|
152
|
+
hint: 'Run `sovereign --help` for the flag list.',
|
|
153
|
+
retryable: false,
|
|
154
|
+
}, 1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
let target = TARGETS.game;
|
|
159
|
+
if (args.includes('--print')) target = TARGETS.print;
|
|
160
|
+
else if (args.includes('--start')) target = TARGETS.start;
|
|
161
|
+
|
|
162
|
+
if (args.includes('--path')) {
|
|
163
|
+
console.log(target);
|
|
164
|
+
process.exit(0);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
openInBrowser(target);
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcptoolshop/sovereign",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Sovereign — a Hamilton-system economic board game and its solo / digital adaptation. Browser-based, deterministic, self-contained.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "bin/sovereign.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"sovereign": "bin/sovereign.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/",
|
|
12
|
+
"release/",
|
|
13
|
+
"README.md",
|
|
14
|
+
"README.*.md",
|
|
15
|
+
"CHANGELOG.md",
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"SECURITY.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"verify": "bash verify.sh",
|
|
21
|
+
"test": "node test/smoke.test.mjs",
|
|
22
|
+
"coverage": "c8 --reporter=text --reporter=lcov --include='bin/**' node test/smoke.test.mjs",
|
|
23
|
+
"play": "node bin/sovereign.js"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"c8": "^10.1.3"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"board-game",
|
|
30
|
+
"game",
|
|
31
|
+
"hamilton",
|
|
32
|
+
"economic-strategy",
|
|
33
|
+
"browser-game",
|
|
34
|
+
"print-and-play",
|
|
35
|
+
"solo-game",
|
|
36
|
+
"deterministic",
|
|
37
|
+
"html5"
|
|
38
|
+
],
|
|
39
|
+
"author": "mcp-tool-shop <64996768+mcp-tool-shop@users.noreply.github.com>",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"homepage": "https://mcp-tool-shop-org.github.io/sovereign/",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+https://github.com/mcp-tool-shop-org/sovereign.git"
|
|
45
|
+
},
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/mcp-tool-shop-org/sovereign/issues"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public",
|
|
54
|
+
"provenance": true
|
|
55
|
+
}
|
|
56
|
+
}
|