milaidy 2.0.0-alpha.3 → 2.0.0-alpha.6
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/LICENSE +6 -18
- package/README.md +174 -32
- package/dist/build-info.json +3 -3
- package/dist/config-C2tN6BTZ.js +192 -0
- package/dist/{workspace-kNVXl1te.js → config-DTYBj51q.js} +16 -5
- package/dist/config-nxSNbXvy.js +192 -0
- package/dist/{eliza-CLpDAXGp.js → eliza-DThusd2P.js} +674 -566
- package/dist/eliza.js +677 -1080
- package/dist/entry.js +2 -3
- package/dist/index.js +1 -1
- package/dist/{milaidy-root-DpN7CAPw.js → milaidy-root-FGSivVa1.js} +2 -37
- package/dist/onboarding-presets-DH1nrZ13.js +987 -0
- package/dist/{paths-C_7RfANk.js → paths-KHcc73Py.js} +1 -1
- package/dist/plugin-installer-59Qx8E2h.js +306 -0
- package/dist/plugin-installer-Ce68786n.js +306 -0
- package/dist/plugin-installer-CjZUkg-j.js +330 -0
- package/dist/plugins-cli-Blijw_TR.js +158 -0
- package/dist/{program-CQFwHdAm.js → program-DJm1_C04.js} +39 -31
- package/dist/{register.subclis-CGglO3hv.js → register.subclis-CRLp87ti.js} +6 -6
- package/dist/registry-client-CpLDkBo9.js +196 -0
- package/dist/registry-client-Tzpu5cCi.js +196 -0
- package/dist/registry-client-roa9jZYU.js +203 -0
- package/dist/restart-CpnakgH4.js +61 -0
- package/dist/restart-DU02nZrb.js +40 -0
- package/dist/restart-el0bK7NU.js +3 -0
- package/dist/{run-main-D91llcG6.js → run-main-CPNa-_Vb.js} +3 -3
- package/dist/server-DJfJ8ILV.js +3938 -0
- package/dist/server-tWzwVXc4.js +3936 -0
- package/dist/server.js +2011 -432
- package/dist/wallet-1TrMIY4q.js +662 -0
- package/dist/wallet-LIhgbOKG.js +701 -0
- package/dist/workspace-BlqKSBdQ.js +663 -0
- package/dist/{workspace-D0GT9sZy.js → workspace-DzG4aQOe.js} +121 -88
- package/install.ps1 +3 -3
- package/install.sh +3 -3
- package/package.json +64 -52
- package/plugins.json +44 -54
- package/skills/.cache/catalog.json +61983 -53974
- package/dist/config-C0o3Gj5B.js +0 -3
- package/dist/plugins-cli-9jmQC4vc.js +0 -108
- package/docs/reference/templates/AGENTS.md +0 -17
- package/docs/reference/templates/BOOTSTRAP.md +0 -20
- package/docs/reference/templates/HEARTBEAT.md +0 -15
- package/docs/reference/templates/IDENTITY.md +0 -14
- package/docs/reference/templates/TOOLS.md +0 -15
- package/docs/reference/templates/USER.md +0 -13
- /package/dist/{argv-BCBX1v8B.js → argv-fxEsiwqp.js} +0 -0
- /package/dist/{register.models-B9J-A-GK.js → register.models-BiSWzG4I.js} +0 -0
package/LICENSE
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
VIRAL PUBLIC LICENSE
|
|
2
|
+
Copyleft (ɔ) All Rights Reversed
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
This WORK is hereby relinquished of all associated ownership, attribution and copy rights, and redistribution or use of any kind, with or without modification, is permitted without restriction subject to the following conditions:
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
6
|
+
1. Redistributions of this WORK, or ANY work that makes use of ANY of the contents of this WORK by ANY kind of copying, dependency, linkage, or ANY other possible form of DERIVATION or COMBINATION, must retain the ENTIRETY of this license.
|
|
7
|
+
2. No further restrictions of ANY kind may be applied.
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
9
|
+
More information: https://viralpubliclicense.org/
|
package/README.md
CHANGED
|
@@ -5,6 +5,56 @@ The Gateway is the control plane that manages sessions, tools, and events. It co
|
|
|
5
5
|
|
|
6
6
|
If you want a personal, single-user assistant that feels local, fast, and always-on, this is it.
|
|
7
7
|
|
|
8
|
+
## Download
|
|
9
|
+
|
|
10
|
+
### macOS Desktop App
|
|
11
|
+
|
|
12
|
+
Download the latest DMG from **[GitHub Releases](https://github.com/milady-ai/milaidy/releases/latest)**:
|
|
13
|
+
|
|
14
|
+
| Platform | Download |
|
|
15
|
+
|---|---|
|
|
16
|
+
| macOS (Apple Silicon) | [`Milaidy-arm64.dmg`](https://github.com/milady-ai/milaidy/releases/latest) |
|
|
17
|
+
| macOS (Intel) | [`Milaidy-x64.dmg`](https://github.com/milady-ai/milaidy/releases/latest) |
|
|
18
|
+
| Windows | [`Milaidy-Setup.exe`](https://github.com/milady-ai/milaidy/releases/latest) |
|
|
19
|
+
| Linux | [`Milaidy.AppImage`](https://github.com/milady-ai/milaidy/releases/latest) / [`.deb`](https://github.com/milady-ai/milaidy/releases/latest) |
|
|
20
|
+
|
|
21
|
+
The macOS app is signed and notarized — no Gatekeeper warnings on a fresh install.
|
|
22
|
+
|
|
23
|
+
### Verify checksums
|
|
24
|
+
|
|
25
|
+
Every release includes a `SHA256SUMS.txt` file. After downloading, verify integrity:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# macOS / Linux
|
|
29
|
+
cd ~/Downloads
|
|
30
|
+
curl -fsSLO https://github.com/milady-ai/milaidy/releases/latest/download/SHA256SUMS.txt
|
|
31
|
+
shasum -a 256 --check --ignore-missing SHA256SUMS.txt
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```powershell
|
|
35
|
+
# Windows (PowerShell)
|
|
36
|
+
cd ~\Downloads
|
|
37
|
+
Invoke-WebRequest -Uri "https://github.com/milady-ai/milaidy/releases/latest/download/SHA256SUMS.txt" -OutFile SHA256SUMS.txt
|
|
38
|
+
# Compare manually:
|
|
39
|
+
Get-FileHash .\Milaidy-Setup.exe -Algorithm SHA256
|
|
40
|
+
Get-Content .\SHA256SUMS.txt
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick Start — Zero Config
|
|
44
|
+
|
|
45
|
+
Get an agent running in seconds. No config files needed.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx milaidy
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
That's it. On first run, Milaidy walks you through:
|
|
52
|
+
1. **Pick a name** for your agent (or use a random one)
|
|
53
|
+
2. **Choose a personality** style
|
|
54
|
+
3. **Connect a model** provider (or skip to configure later)
|
|
55
|
+
|
|
56
|
+
The agent starts immediately after onboarding. The web dashboard opens at `http://localhost:18789`.
|
|
57
|
+
|
|
8
58
|
## Install
|
|
9
59
|
|
|
10
60
|
Runtime: **Node >= 22**. Works with npm or bun.
|
|
@@ -14,13 +64,13 @@ Runtime: **Node >= 22**. Works with npm or bun.
|
|
|
14
64
|
macOS / Linux / WSL:
|
|
15
65
|
|
|
16
66
|
```bash
|
|
17
|
-
curl -fsSL https://
|
|
67
|
+
curl -fsSL https://milady-ai.github.io/milaidy/install.sh | bash
|
|
18
68
|
```
|
|
19
69
|
|
|
20
70
|
Windows (PowerShell):
|
|
21
71
|
|
|
22
72
|
```powershell
|
|
23
|
-
irm https://
|
|
73
|
+
irm https://milady-ai.github.io/milaidy/install.ps1 | iex
|
|
24
74
|
```
|
|
25
75
|
|
|
26
76
|
The installer checks for Node.js, installs it if needed, then installs milaidy globally and runs initial setup.
|
|
@@ -29,66 +79,111 @@ The installer checks for Node.js, installs it if needed, then installs milaidy g
|
|
|
29
79
|
|
|
30
80
|
```bash
|
|
31
81
|
npm install -g milaidy
|
|
32
|
-
# or
|
|
33
|
-
npx milaidy
|
|
34
|
-
# or
|
|
35
|
-
bunx milaidy
|
|
36
82
|
```
|
|
37
83
|
|
|
38
|
-
Then
|
|
84
|
+
Then start the agent:
|
|
39
85
|
|
|
40
86
|
```bash
|
|
41
|
-
milaidy
|
|
87
|
+
milaidy start
|
|
42
88
|
```
|
|
43
89
|
|
|
44
|
-
|
|
90
|
+
### npx (no install)
|
|
91
|
+
|
|
92
|
+
Run directly without installing globally:
|
|
45
93
|
|
|
46
94
|
```bash
|
|
47
|
-
milaidy
|
|
95
|
+
npx milaidy
|
|
96
|
+
```
|
|
48
97
|
|
|
49
|
-
|
|
98
|
+
Or with bun:
|
|
50
99
|
|
|
51
|
-
|
|
52
|
-
milaidy
|
|
100
|
+
```bash
|
|
101
|
+
bunx milaidy
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Usage
|
|
53
105
|
|
|
54
|
-
|
|
55
|
-
milaidy
|
|
106
|
+
```bash
|
|
107
|
+
milaidy start # Start the agent runtime (default command)
|
|
108
|
+
milaidy setup # Initialize workspace and config
|
|
109
|
+
milaidy dashboard # Open the Control UI in your browser
|
|
110
|
+
milaidy configure # Configuration guidance
|
|
111
|
+
milaidy config get <key> # Read a config value
|
|
112
|
+
milaidy models # Show configured model providers
|
|
113
|
+
milaidy plugins list # List available plugins
|
|
114
|
+
milaidy --help # Show all commands
|
|
56
115
|
```
|
|
57
116
|
|
|
58
|
-
Upgrading? Run `milaidy
|
|
117
|
+
Upgrading? Run `milaidy setup` after updating to refresh the workspace.
|
|
59
118
|
|
|
60
119
|
## Models
|
|
61
120
|
|
|
62
|
-
|
|
121
|
+
Pick any AI provider during onboarding, or configure later.
|
|
63
122
|
|
|
64
|
-
|
|
65
|
-
- **[OpenAI](https://openai.com/)** (ChatGPT/Codex)
|
|
123
|
+
**Cloud providers:**
|
|
66
124
|
|
|
67
|
-
|
|
125
|
+
| Provider | Env Variable | Notes |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| [Anthropic](https://www.anthropic.com/) (Claude) | `ANTHROPIC_API_KEY` | Recommended — Opus 4.5 for long-context |
|
|
128
|
+
| [OpenAI](https://openai.com/) (GPT) | `OPENAI_API_KEY` | GPT-4o, o1, etc. |
|
|
129
|
+
| [OpenRouter](https://openrouter.ai/) | `OPENROUTER_API_KEY` | Access to 100+ models |
|
|
130
|
+
| [Google Gemini](https://ai.google.dev/) | `GOOGLE_API_KEY` | Gemini Pro/Ultra |
|
|
131
|
+
| [xAI](https://x.ai/) (Grok) | `XAI_API_KEY` | Grok-2 |
|
|
132
|
+
| [Groq](https://groq.com/) | `GROQ_API_KEY` | Fast inference |
|
|
133
|
+
| [DeepSeek](https://deepseek.com/) | `DEEPSEEK_API_KEY` | DeepSeek-V3 |
|
|
68
134
|
|
|
69
|
-
|
|
135
|
+
**Local (free, no API key):**
|
|
70
136
|
|
|
71
|
-
|
|
137
|
+
| Provider | Setup |
|
|
138
|
+
|---|---|
|
|
139
|
+
| [Ollama](https://ollama.ai/) | Install Ollama, then select it during onboarding |
|
|
140
|
+
|
|
141
|
+
**Recommended:** Anthropic Pro/Max (100/200) + Opus 4.5 for long-context strength and better prompt-injection resistance.
|
|
142
|
+
|
|
143
|
+
## Wallet Setup (Web3)
|
|
144
|
+
|
|
145
|
+
Milaidy has first-class EVM and Solana wallet support. Wallets are generated automatically and managed through the config.
|
|
146
|
+
|
|
147
|
+
### Auto-generated wallets
|
|
148
|
+
|
|
149
|
+
On first run, Milaidy can generate fresh EVM (Ethereum/Base/Arbitrum/Optimism/Polygon) and Solana keypairs. Private keys are stored locally in your config — never sent anywhere.
|
|
150
|
+
|
|
151
|
+
### Configure wallet keys
|
|
152
|
+
|
|
153
|
+
Set your own keys in `~/.milaidy/milaidy.json` or via environment variables:
|
|
72
154
|
|
|
73
155
|
```bash
|
|
74
|
-
|
|
75
|
-
|
|
156
|
+
# EVM (Ethereum, Base, Arbitrum, etc.)
|
|
157
|
+
export EVM_PRIVATE_KEY="0x..."
|
|
76
158
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
159
|
+
# Solana
|
|
160
|
+
export SOLANA_PRIVATE_KEY="..." # base58-encoded
|
|
161
|
+
```
|
|
80
162
|
|
|
81
|
-
|
|
163
|
+
### Portfolio & NFT viewing
|
|
82
164
|
|
|
83
|
-
|
|
84
|
-
|
|
165
|
+
To view token balances and NFTs in the dashboard, configure API keys:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# EVM chains (Alchemy)
|
|
169
|
+
export ALCHEMY_API_KEY="..."
|
|
170
|
+
|
|
171
|
+
# Solana (Helius)
|
|
172
|
+
export HELIUS_API_KEY="..."
|
|
85
173
|
```
|
|
86
174
|
|
|
87
|
-
|
|
175
|
+
Or set them in the dashboard under the Wallet/Inventory tab.
|
|
176
|
+
|
|
177
|
+
### Supported chains
|
|
178
|
+
|
|
179
|
+
- **EVM:** Ethereum, Base, Arbitrum, Optimism, Polygon
|
|
180
|
+
- **Solana:** Mainnet (SPL tokens + NFTs via Helius DAS)
|
|
88
181
|
|
|
89
182
|
## Configuration
|
|
90
183
|
|
|
91
|
-
|
|
184
|
+
Config file: `~/.milaidy/milaidy.json`
|
|
185
|
+
|
|
186
|
+
Minimal example:
|
|
92
187
|
|
|
93
188
|
```json5
|
|
94
189
|
{
|
|
@@ -98,6 +193,16 @@ Minimal `~/.milaidy/milaidy.json`:
|
|
|
98
193
|
}
|
|
99
194
|
```
|
|
100
195
|
|
|
196
|
+
Environment variables can also be set in `~/.milaidy/.env` or in the `env` section of the config:
|
|
197
|
+
|
|
198
|
+
```json5
|
|
199
|
+
{
|
|
200
|
+
env: {
|
|
201
|
+
ANTHROPIC_API_KEY: "sk-ant-...",
|
|
202
|
+
},
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
101
206
|
## Agent workspace + skills
|
|
102
207
|
|
|
103
208
|
- Workspace root: `~/.milaidy/workspace` (configurable via `agents.defaults.workspace`).
|
|
@@ -119,6 +224,43 @@ Minimal `~/.milaidy/milaidy.json`:
|
|
|
119
224
|
- `/usage off|tokens|full` — per-response usage footer
|
|
120
225
|
- `/restart` — restart the gateway
|
|
121
226
|
|
|
227
|
+
## From source (development)
|
|
228
|
+
|
|
229
|
+
Prefer `pnpm` for builds from source. Bun is optional for running TypeScript directly.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
git clone https://github.com/milady-ai/milaidy.git
|
|
233
|
+
cd milaidy
|
|
234
|
+
|
|
235
|
+
pnpm install
|
|
236
|
+
pnpm ui:build # auto-installs UI deps on first run
|
|
237
|
+
pnpm build
|
|
238
|
+
|
|
239
|
+
pnpm milaidy start
|
|
240
|
+
|
|
241
|
+
# Dev loop (auto-reload on TS changes)
|
|
242
|
+
pnpm dev
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
`pnpm milaidy ...` runs TypeScript directly (via `tsx`). `pnpm build` produces `dist/` for running via Node / the packaged `milaidy` binary.
|
|
246
|
+
|
|
247
|
+
### Building the desktop app
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
pnpm build:desktop
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Release builds (signed & notarized)
|
|
254
|
+
|
|
255
|
+
Release builds are automated via GitHub Actions. See `.github/workflows/release.yml`.
|
|
256
|
+
|
|
257
|
+
Required repository secrets for signed macOS builds:
|
|
258
|
+
- `CSC_LINK` — base64-encoded .p12 signing certificate
|
|
259
|
+
- `CSC_KEY_PASSWORD` — certificate password
|
|
260
|
+
- `APPLE_ID` — Apple Developer account email
|
|
261
|
+
- `APPLE_APP_SPECIFIC_PASSWORD` — app-specific password from [appleid.apple.com](https://appleid.apple.com)
|
|
262
|
+
- `APPLE_TEAM_ID` — Apple Developer Team ID
|
|
263
|
+
|
|
122
264
|
## License
|
|
123
265
|
|
|
124
266
|
MIT
|
package/dist/build-info.json
CHANGED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import JSON5 from "json5";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
|
|
6
|
+
//#region src/config/paths.ts
|
|
7
|
+
const STATE_DIRNAME = ".milaidy";
|
|
8
|
+
const CONFIG_FILENAME = "milaidy.json";
|
|
9
|
+
function stateDir(homedir = os.homedir) {
|
|
10
|
+
return path.join(homedir(), STATE_DIRNAME);
|
|
11
|
+
}
|
|
12
|
+
function resolveUserPath(input) {
|
|
13
|
+
const trimmed = input.trim();
|
|
14
|
+
if (!trimmed) return trimmed;
|
|
15
|
+
if (trimmed.startsWith("~")) {
|
|
16
|
+
const expanded = trimmed.replace(/^~(?=$|[\\/])/, os.homedir());
|
|
17
|
+
return path.resolve(expanded);
|
|
18
|
+
}
|
|
19
|
+
return path.resolve(trimmed);
|
|
20
|
+
}
|
|
21
|
+
function resolveStateDir(env = process.env, homedir = os.homedir) {
|
|
22
|
+
const override = env.MILAIDY_STATE_DIR?.trim();
|
|
23
|
+
if (override) return resolveUserPath(override);
|
|
24
|
+
return stateDir(homedir);
|
|
25
|
+
}
|
|
26
|
+
function resolveConfigPath(env = process.env, stateDirPath = resolveStateDir(env, os.homedir)) {
|
|
27
|
+
const override = env.MILAIDY_CONFIG_PATH?.trim();
|
|
28
|
+
if (override) return resolveUserPath(override);
|
|
29
|
+
return path.join(stateDirPath, CONFIG_FILENAME);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/config/object-utils.ts
|
|
34
|
+
function isPlainObject(value) {
|
|
35
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/config/includes.ts
|
|
40
|
+
/**
|
|
41
|
+
* $include directive for modular configs.
|
|
42
|
+
*
|
|
43
|
+
* ```json5
|
|
44
|
+
* { "$include": "./base.json5" }
|
|
45
|
+
* { "$include": ["./a.json5", "./b.json5"] }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
const INCLUDE_KEY = "$include";
|
|
49
|
+
const MAX_INCLUDE_DEPTH = 10;
|
|
50
|
+
var ConfigIncludeError = class extends Error {
|
|
51
|
+
constructor(message, includePath, cause) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.includePath = includePath;
|
|
54
|
+
this.cause = cause;
|
|
55
|
+
this.name = "ConfigIncludeError";
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var CircularIncludeError = class extends ConfigIncludeError {
|
|
59
|
+
constructor(chain) {
|
|
60
|
+
super(`Circular include detected: ${chain.join(" -> ")}`, chain[chain.length - 1]);
|
|
61
|
+
this.chain = chain;
|
|
62
|
+
this.name = "CircularIncludeError";
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
function deepMerge(target, source) {
|
|
66
|
+
if (Array.isArray(target) && Array.isArray(source)) return [...target, ...source];
|
|
67
|
+
if (isPlainObject(target) && isPlainObject(source)) {
|
|
68
|
+
const result = { ...target };
|
|
69
|
+
for (const key of Object.keys(source)) result[key] = key in result ? deepMerge(result[key], source[key]) : source[key];
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
return source;
|
|
73
|
+
}
|
|
74
|
+
var IncludeProcessor = class IncludeProcessor {
|
|
75
|
+
constructor(basePath, resolver) {
|
|
76
|
+
this.basePath = basePath;
|
|
77
|
+
this.resolver = resolver;
|
|
78
|
+
this.visited = /* @__PURE__ */ new Set();
|
|
79
|
+
this.depth = 0;
|
|
80
|
+
this.visited.add(path.normalize(basePath));
|
|
81
|
+
}
|
|
82
|
+
process(obj) {
|
|
83
|
+
if (Array.isArray(obj)) return obj.map((item) => this.process(item));
|
|
84
|
+
if (!isPlainObject(obj)) return obj;
|
|
85
|
+
if (!(INCLUDE_KEY in obj)) return this.processObject(obj);
|
|
86
|
+
return this.processInclude(obj);
|
|
87
|
+
}
|
|
88
|
+
processObject(obj) {
|
|
89
|
+
const result = {};
|
|
90
|
+
for (const [key, value] of Object.entries(obj)) result[key] = this.process(value);
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
processInclude(obj) {
|
|
94
|
+
const includeValue = obj[INCLUDE_KEY];
|
|
95
|
+
const otherKeys = Object.keys(obj).filter((k) => k !== INCLUDE_KEY);
|
|
96
|
+
const included = this.resolveInclude(includeValue);
|
|
97
|
+
if (otherKeys.length === 0) return included;
|
|
98
|
+
if (!isPlainObject(included)) throw new ConfigIncludeError("Sibling keys require included content to be an object", typeof includeValue === "string" ? includeValue : INCLUDE_KEY);
|
|
99
|
+
const rest = {};
|
|
100
|
+
for (const key of otherKeys) rest[key] = this.process(obj[key]);
|
|
101
|
+
return deepMerge(included, rest);
|
|
102
|
+
}
|
|
103
|
+
resolveInclude(value) {
|
|
104
|
+
if (typeof value === "string") return this.loadFile(value);
|
|
105
|
+
if (Array.isArray(value)) return value.reduce((merged, item) => {
|
|
106
|
+
if (typeof item !== "string") throw new ConfigIncludeError(`Invalid $include array item: expected string, got ${typeof item}`, String(item));
|
|
107
|
+
return deepMerge(merged, this.loadFile(item));
|
|
108
|
+
}, {});
|
|
109
|
+
throw new ConfigIncludeError(`Invalid $include value: expected string or array of strings, got ${typeof value}`, String(value));
|
|
110
|
+
}
|
|
111
|
+
loadFile(includePath) {
|
|
112
|
+
const resolvedPath = path.isAbsolute(includePath) ? includePath : path.resolve(path.dirname(this.basePath), includePath);
|
|
113
|
+
const normalized = path.normalize(resolvedPath);
|
|
114
|
+
if (this.visited.has(normalized)) throw new CircularIncludeError([...this.visited, normalized]);
|
|
115
|
+
if (this.depth >= MAX_INCLUDE_DEPTH) throw new ConfigIncludeError(`Maximum include depth (${MAX_INCLUDE_DEPTH}) exceeded at: ${includePath}`, includePath);
|
|
116
|
+
let raw;
|
|
117
|
+
try {
|
|
118
|
+
raw = this.resolver.readFile(normalized);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
throw new ConfigIncludeError(`Failed to read include file: ${includePath} (resolved: ${normalized})`, includePath, err instanceof Error ? err : void 0);
|
|
121
|
+
}
|
|
122
|
+
let parsed;
|
|
123
|
+
try {
|
|
124
|
+
parsed = this.resolver.parseJson(raw);
|
|
125
|
+
} catch (err) {
|
|
126
|
+
throw new ConfigIncludeError(`Failed to parse include file: ${includePath} (resolved: ${normalized})`, includePath, err instanceof Error ? err : void 0);
|
|
127
|
+
}
|
|
128
|
+
const nested = new IncludeProcessor(normalized, this.resolver);
|
|
129
|
+
nested.visited = new Set([...this.visited, normalized]);
|
|
130
|
+
nested.depth = this.depth + 1;
|
|
131
|
+
return nested.process(parsed);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const defaultResolver = {
|
|
135
|
+
readFile: (p) => fs.readFileSync(p, "utf-8"),
|
|
136
|
+
parseJson: (raw) => JSON5.parse(raw)
|
|
137
|
+
};
|
|
138
|
+
function resolveConfigIncludes(obj, configPath, resolver = defaultResolver) {
|
|
139
|
+
return new IncludeProcessor(configPath, resolver).process(obj);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region src/config/env-vars.ts
|
|
144
|
+
function collectConfigEnvVars(cfg) {
|
|
145
|
+
const envConfig = cfg?.env;
|
|
146
|
+
if (!envConfig) return {};
|
|
147
|
+
const entries = {};
|
|
148
|
+
if (envConfig.vars) for (const [key, value] of Object.entries(envConfig.vars)) {
|
|
149
|
+
if (!value) continue;
|
|
150
|
+
entries[key] = value;
|
|
151
|
+
}
|
|
152
|
+
for (const [key, value] of Object.entries(envConfig)) {
|
|
153
|
+
if (key === "shellEnv" || key === "vars") continue;
|
|
154
|
+
if (typeof value !== "string" || !value.trim()) continue;
|
|
155
|
+
entries[key] = value;
|
|
156
|
+
}
|
|
157
|
+
return entries;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/config/config.ts
|
|
162
|
+
function loadMilaidyConfig() {
|
|
163
|
+
const configPath = resolveConfigPath();
|
|
164
|
+
let raw;
|
|
165
|
+
try {
|
|
166
|
+
raw = fs.readFileSync(configPath, "utf-8");
|
|
167
|
+
} catch {
|
|
168
|
+
return {};
|
|
169
|
+
}
|
|
170
|
+
const resolved = resolveConfigIncludes(JSON5.parse(raw), configPath);
|
|
171
|
+
const envVars = collectConfigEnvVars(resolved);
|
|
172
|
+
for (const [key, value] of Object.entries(envVars)) if (process.env[key] === void 0) process.env[key] = value;
|
|
173
|
+
return resolved;
|
|
174
|
+
}
|
|
175
|
+
function saveMilaidyConfig(config) {
|
|
176
|
+
const configPath = resolveConfigPath();
|
|
177
|
+
const dir = path.dirname(configPath);
|
|
178
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, {
|
|
179
|
+
recursive: true,
|
|
180
|
+
mode: 448
|
|
181
|
+
});
|
|
182
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, {
|
|
183
|
+
encoding: "utf-8",
|
|
184
|
+
mode: 384
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
function configFileExists() {
|
|
188
|
+
return fs.existsSync(resolveConfigPath());
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
//#endregion
|
|
192
|
+
export { resolveStateDir as i, loadMilaidyConfig as n, saveMilaidyConfig as r, configFileExists as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
|
|
2
|
+
import { n as resolveConfigPath } from "./paths-KHcc73Py.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import JSON5 from "json5";
|
|
@@ -133,6 +133,11 @@ function collectConfigEnvVars(cfg) {
|
|
|
133
133
|
|
|
134
134
|
//#endregion
|
|
135
135
|
//#region src/config/config.ts
|
|
136
|
+
var config_exports = /* @__PURE__ */ __exportAll({
|
|
137
|
+
configFileExists: () => configFileExists,
|
|
138
|
+
loadMilaidyConfig: () => loadMilaidyConfig,
|
|
139
|
+
saveMilaidyConfig: () => saveMilaidyConfig
|
|
140
|
+
});
|
|
136
141
|
function loadMilaidyConfig() {
|
|
137
142
|
const configPath = resolveConfigPath();
|
|
138
143
|
let raw;
|
|
@@ -143,7 +148,7 @@ function loadMilaidyConfig() {
|
|
|
143
148
|
}
|
|
144
149
|
const resolved = resolveConfigIncludes(JSON5.parse(raw), configPath);
|
|
145
150
|
const envVars = collectConfigEnvVars(resolved);
|
|
146
|
-
for (const [key, value] of Object.entries(envVars)) if (
|
|
151
|
+
for (const [key, value] of Object.entries(envVars)) if (process.env[key] === void 0) process.env[key] = value;
|
|
147
152
|
return resolved;
|
|
148
153
|
}
|
|
149
154
|
function saveMilaidyConfig(config) {
|
|
@@ -153,8 +158,14 @@ function saveMilaidyConfig(config) {
|
|
|
153
158
|
recursive: true,
|
|
154
159
|
mode: 448
|
|
155
160
|
});
|
|
156
|
-
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`,
|
|
161
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, {
|
|
162
|
+
encoding: "utf-8",
|
|
163
|
+
mode: 384
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function configFileExists() {
|
|
167
|
+
return fs.existsSync(resolveConfigPath());
|
|
157
168
|
}
|
|
158
169
|
|
|
159
170
|
//#endregion
|
|
160
|
-
export {
|
|
171
|
+
export { saveMilaidyConfig as i, config_exports as n, loadMilaidyConfig as r, configFileExists as t };
|