@dhzh/foundry 0.2.2 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -102
- package/package.json +43 -30
- package/dist/index.js +0 -1
package/README.md
CHANGED
|
@@ -1,135 +1,74 @@
|
|
|
1
1
|
# Foundry
|
|
2
2
|
|
|
3
|
-
Foundry
|
|
3
|
+
Foundry provides a CLI-managed local web interface backed by a loopback-only Hono server. It is distributed as an ESM-only Node.js package.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Usage
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Start the local web interface with:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- Store Provider names, Base URLs, API keys, model mappings, remarks, websites, and optional avatars locally.
|
|
13
|
-
- Test Provider connectivity before or after saving.
|
|
14
|
-
- View Provider health and Runtime status from the dashboard.
|
|
15
|
-
- Select a Provider or restore Official Default settings for each Runtime.
|
|
16
|
-
- Preview every managed configuration field before writing to disk, with secrets redacted by default.
|
|
17
|
-
- Preserve settings outside Foundry's managed fields and keep a backup of the previous configuration.
|
|
18
|
-
- Automatically reapply an in-use Provider after a Runtime-effective edit.
|
|
19
|
-
- Show persistent restart guidance after every successful configuration write.
|
|
20
|
-
- On macOS, optionally restart an already-running ChatGPT desktop app so its hosted Codex experience reloads the configuration.
|
|
21
|
-
|
|
22
|
-
## Supported Runtimes
|
|
23
|
-
|
|
24
|
-
| Runtime | Configuration file | Managed configuration | Reload behavior |
|
|
25
|
-
| --- | --- | --- | --- |
|
|
26
|
-
| Codex | `~/.codex/config.toml` | Model selection and a Foundry-managed `model_providers` entry | Foundry can gracefully restart an already-running ChatGPT desktop app on macOS. Existing Codex CLI sessions must be restarted manually. |
|
|
27
|
-
| Claude Code | `~/.claude/settings.json` | Anthropic endpoint, token, model-role mappings, fallback model, and subagent model under `env` | Existing Claude Code CLI sessions must be restarted manually. |
|
|
28
|
-
|
|
29
|
-
Restoring Official Default removes the Runtime selection overrides managed by Foundry. It does not delete saved Provider records or unrelated Runtime settings.
|
|
30
|
-
|
|
31
|
-
## Typical Workflow
|
|
32
|
-
|
|
33
|
-
1. Open **Agent Runtime > Providers** and add a Provider for Codex or Claude Code.
|
|
34
|
-
2. Enter the endpoint, API key, and Runtime-specific model settings.
|
|
35
|
-
3. Run **Test Connection** to verify that the endpoint responds successfully.
|
|
36
|
-
4. Open **Agent Runtime > Runtimes**, select the desired Provider, and choose **Apply**.
|
|
37
|
-
5. Review the exact field-level changes in the preview dialog and confirm the write.
|
|
38
|
-
6. Follow the result dialog to restart the affected desktop application or CLI session.
|
|
39
|
-
|
|
40
|
-
When an in-use Provider is edited, Foundry saves the Provider first and reapplies it only when a Runtime-effective field changed. If the reapply fails, the saved Provider remains available and the dialog offers the existing Apply retry flow.
|
|
41
|
-
|
|
42
|
-
## Connection Tests
|
|
43
|
-
|
|
44
|
-
Provider tests run in the Electron main process with a 15-second timeout and do not follow redirects.
|
|
45
|
-
|
|
46
|
-
- Codex sends `GET <base-url>/models` and uses `Authorization: Bearer <api-key>` when a key is configured.
|
|
47
|
-
- Claude Code sends `GET <base-url>/v1/models`, or `GET <base-url>/models` when the Base URL already ends in `/v1`. It sends `anthropic-version: 2023-06-01` and uses `x-api-key` when configured.
|
|
48
|
-
- Any `2xx` response passes. Network, TLS, timeout, redirect, and non-`2xx` outcomes are recorded as sanitized connection failures.
|
|
49
|
-
|
|
50
|
-
## Configuration Safety
|
|
51
|
-
|
|
52
|
-
Foundry treats configuration writes as a previewed and recoverable operation:
|
|
53
|
-
|
|
54
|
-
- Existing TOML or JSON is parsed before any change is offered.
|
|
55
|
-
- Only the documented Runtime fields are modified; unrelated settings are preserved.
|
|
56
|
-
- The proposed output is generated, parsed again, and validated before replacing the active file.
|
|
57
|
-
- Writes use same-directory temporary files with restrictive `0600` permissions.
|
|
58
|
-
- The latest previous file content is stored beside the Runtime configuration as `<filename>.foundry-backup`.
|
|
59
|
-
- If the configuration is written but Foundry cannot record the new application state, it restores the previous file content.
|
|
60
|
-
- Concurrent writes to the same Runtime are rejected.
|
|
61
|
-
|
|
62
|
-
Provider records, including API keys and avatars, are stored in a local SQLite database named `foundry.sqlite` under Electron's platform-specific `userData` directory. Applied API keys are also written to the target Runtime configuration because the Runtime requires them. Treat both the Foundry user-data directory and Runtime configuration files as sensitive local data.
|
|
63
|
-
|
|
64
|
-
## ChatGPT Restart Behavior
|
|
65
|
-
|
|
66
|
-
Automatic restart is intentionally narrow and available only on macOS:
|
|
9
|
+
```bash
|
|
10
|
+
pnpm dlx @dhzh/foundry ui
|
|
11
|
+
```
|
|
67
12
|
|
|
68
|
-
|
|
69
|
-
- Foundry offers restart only after confirming that ChatGPT is already running.
|
|
70
|
-
- Restart requests a normal application termination and never force-quits ChatGPT.
|
|
71
|
-
- Foundry waits up to 15 seconds for exit, reopens the same bundle, and waits up to another 15 seconds to confirm startup.
|
|
72
|
-
- If detection, quit, or reopen fails, the applied configuration remains intact and Foundry shows manual guidance without an automatic retry action.
|
|
73
|
-
- Foundry never launches ChatGPT when it was not already running and never starts or terminates Codex CLI or Claude Code CLI processes.
|
|
13
|
+
The server listens on `http://127.0.0.1:54321` and opens the interface in the default browser. Use a different port or keep the browser closed when needed:
|
|
74
14
|
|
|
75
|
-
|
|
15
|
+
```bash
|
|
16
|
+
pnpm dlx @dhzh/foundry ui --port 61234 --no-open
|
|
17
|
+
```
|
|
76
18
|
|
|
77
19
|
## Development
|
|
78
20
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
- Node.js `24.18.0`
|
|
82
|
-
- pnpm `11.9.0`
|
|
21
|
+
The repository is a pnpm workspace containing the published server and CLI package, a private React app, and a private API contract package.
|
|
83
22
|
|
|
84
|
-
|
|
23
|
+
Install dependencies from the repository root:
|
|
85
24
|
|
|
86
25
|
```bash
|
|
87
26
|
pnpm install
|
|
88
|
-
pnpm dev
|
|
89
27
|
```
|
|
90
28
|
|
|
91
|
-
|
|
29
|
+
Start the Hono server:
|
|
92
30
|
|
|
93
31
|
```bash
|
|
94
|
-
pnpm
|
|
95
|
-
pnpm typecheck
|
|
96
|
-
pnpm lint
|
|
97
|
-
pnpm build
|
|
32
|
+
pnpm dev:server
|
|
98
33
|
```
|
|
99
34
|
|
|
100
|
-
|
|
35
|
+
In another terminal, start the React app at [http://localhost:3000](http://localhost:3000):
|
|
101
36
|
|
|
102
37
|
```bash
|
|
103
|
-
pnpm
|
|
104
|
-
pnpm build:win
|
|
105
|
-
pnpm build:linux
|
|
38
|
+
pnpm dev:app
|
|
106
39
|
```
|
|
107
40
|
|
|
108
|
-
|
|
41
|
+
Rsbuild proxies `/api` requests to the Hono server at `http://127.0.0.1:54321`.
|
|
109
42
|
|
|
110
|
-
##
|
|
43
|
+
## Health Endpoint
|
|
111
44
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
45
|
+
`GET /api/health` returns HTTP 200 with the shared response envelope:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"status": "SUCCESS",
|
|
50
|
+
"data": true,
|
|
51
|
+
"message": "Service is healthy."
|
|
52
|
+
}
|
|
120
53
|
```
|
|
121
54
|
|
|
122
|
-
|
|
55
|
+
Unexpected query parameters are rejected with HTTP 400.
|
|
56
|
+
|
|
57
|
+
## Workspace Layout
|
|
123
58
|
|
|
124
|
-
|
|
59
|
+
- `src/cli/` - CLI entry point and the `foundry ui` command.
|
|
60
|
+
- `src/server/` - Hono server, health handler, static app serving, and lifecycle management.
|
|
61
|
+
- `app/` - React and Rsbuild local web interface.
|
|
62
|
+
- `packages/api-contract/` - Shared response constants and TypeScript types.
|
|
63
|
+
- `test/` - Vitest test suite.
|
|
125
64
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
65
|
+
## Verification
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pnpm test
|
|
69
|
+
pnpm --filter @dhzh/foundry-app typecheck
|
|
70
|
+
pnpm build
|
|
71
|
+
```
|
|
133
72
|
|
|
134
73
|
## License
|
|
135
74
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhzh/foundry",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.0-beta.1",
|
|
5
5
|
"devEngines": {
|
|
6
6
|
"packageManager": {
|
|
7
7
|
"name": "pnpm",
|
|
8
|
-
"version": "^11.
|
|
8
|
+
"version": "^11.22.0",
|
|
9
9
|
"onFail": "download"
|
|
10
10
|
},
|
|
11
11
|
"runtime": {
|
|
@@ -23,9 +23,19 @@
|
|
|
23
23
|
"homepage": "https://github.com/tinywaves/foundry",
|
|
24
24
|
"keywords": [
|
|
25
25
|
"agent",
|
|
26
|
-
"cli",
|
|
27
26
|
"ai"
|
|
28
27
|
],
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.mts",
|
|
31
|
+
"import": "./dist/index.mjs"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"main": "./dist/index.mjs",
|
|
35
|
+
"types": "./dist/index.d.mts",
|
|
36
|
+
"bin": {
|
|
37
|
+
"foundry": "./dist/cli.mjs"
|
|
38
|
+
},
|
|
29
39
|
"files": [
|
|
30
40
|
"dist"
|
|
31
41
|
],
|
|
@@ -35,45 +45,48 @@
|
|
|
35
45
|
},
|
|
36
46
|
"sideEffects": false,
|
|
37
47
|
"devDependencies": {
|
|
38
|
-
"@
|
|
39
|
-
"@commitlint/
|
|
40
|
-
"@
|
|
41
|
-
"@dhzh/
|
|
42
|
-
"@types/node": "^26.
|
|
43
|
-
"@vitest/coverage-v8": "^4.1.
|
|
44
|
-
"bumpp": "^
|
|
45
|
-
"changelogithub": "^
|
|
46
|
-
"eslint": "^10.
|
|
48
|
+
"@commitlint/cli": "^21.2.2",
|
|
49
|
+
"@commitlint/config-conventional": "^21.2.2",
|
|
50
|
+
"@dhzh/eslint-config": "^2.4.3",
|
|
51
|
+
"@dhzh/foundry-api-contract": "0.0.0",
|
|
52
|
+
"@types/node": "^26.2.0",
|
|
53
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
54
|
+
"bumpp": "^12.2.1",
|
|
55
|
+
"changelogithub": "^15.0.4",
|
|
56
|
+
"eslint": "^10.9.0",
|
|
47
57
|
"husky": "^9.1.7",
|
|
48
|
-
"lint-staged": "^17.0
|
|
49
|
-
"
|
|
50
|
-
"
|
|
58
|
+
"lint-staged": "^17.3.0",
|
|
59
|
+
"taze": "^21.1.0",
|
|
60
|
+
"tsdown": "^0.22.14",
|
|
61
|
+
"tsx": "^4.23.12",
|
|
51
62
|
"typescript": "^6.0.3",
|
|
52
|
-
"vitest": "^4.1.
|
|
63
|
+
"vitest": "^4.1.11",
|
|
53
64
|
"node": "runtime:^24.18.0"
|
|
54
65
|
},
|
|
55
66
|
"dependencies": {
|
|
56
|
-
"@hono/node-server": "^2.
|
|
67
|
+
"@hono/node-server": "^2.1.1",
|
|
57
68
|
"@hono/zod-validator": "^0.9.0",
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"terminal-link": "^5.0.0",
|
|
63
|
-
"zod": "^4.4.3"
|
|
69
|
+
"citty": "^0.2.2",
|
|
70
|
+
"hono": "^4.13.5",
|
|
71
|
+
"open": "^11.0.2",
|
|
72
|
+
"zod": "^4.5.4"
|
|
64
73
|
},
|
|
65
74
|
"scripts": {
|
|
66
|
-
"build": "pnpm run build:
|
|
67
|
-
"build:
|
|
68
|
-
"build:
|
|
69
|
-
"dev:
|
|
70
|
-
"dev:
|
|
75
|
+
"build": "pnpm run build:server && pnpm run build:app",
|
|
76
|
+
"build:app": "pnpm --filter @dhzh/foundry-app build",
|
|
77
|
+
"build:server": "tsdown",
|
|
78
|
+
"dev:app": "pnpm --filter @dhzh/foundry-app dev",
|
|
79
|
+
"dev:cli": "tsx src/cli/index.ts ui",
|
|
80
|
+
"dev:server": "tsx watch --clear-screen=false src/server/dev.ts",
|
|
71
81
|
"lint": "eslint",
|
|
72
|
-
"lint-fix": "eslint --fix
|
|
82
|
+
"lint-fix": "eslint --fix",
|
|
73
83
|
"release": "bumpp",
|
|
74
84
|
"release:publish": "pnpm release && pnpm publish --access public",
|
|
75
85
|
"test": "vitest run",
|
|
76
86
|
"test:coverage": "pnpm run test --coverage",
|
|
77
|
-
"test:dev": "vitest"
|
|
87
|
+
"test:dev": "vitest",
|
|
88
|
+
"typecheck": "tsc --noEmit",
|
|
89
|
+
"version:update": "taze major",
|
|
90
|
+
"version:update:w": "taze major -w"
|
|
78
91
|
}
|
|
79
92
|
}
|
package/dist/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function Test() {}
|