@desplega.ai/agent-env 0.0.0-stage → 0.3.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/LICENSE +21 -0
- package/README.md +343 -2
- package/assets/icon.svg +5 -0
- package/bin/agent-env.mjs +210 -0
- package/docs/agent-swarm.md +146 -0
- package/docs/releases.md +207 -0
- package/docs/screenshots/dashboard-desktop.png +0 -0
- package/docs/screenshots/dashboard-mobile.png +0 -0
- package/docs/snapshots-and-worktrees.md +221 -0
- package/examples/agent-swarm/README.md +5 -0
- package/examples/agent-swarm/agent-env.json +11 -0
- package/examples/agent-swarm/compose.agent-env.yaml +101 -0
- package/examples/agent-swarm/verify.mjs +55 -0
- package/examples/compose/.dockerignore +3 -0
- package/examples/compose/Dockerfile +4 -0
- package/examples/compose/README.md +109 -0
- package/examples/compose/compose.yaml +36 -0
- package/examples/compose/server.mjs +6 -0
- package/examples/hello/agent-env.json +20 -0
- package/examples/hello/index.html +12 -0
- package/package.json +49 -4
- package/src/cloud.mjs +314 -0
- package/src/config.mjs +133 -0
- package/src/daemon.mjs +484 -0
- package/src/environments.mjs +207 -0
- package/src/goodies.mjs +71 -0
- package/src/init.mjs +68 -0
- package/src/locks.mjs +56 -0
- package/src/maintenance.mjs +74 -0
- package/src/paths.mjs +5 -0
- package/src/providers/CLOUD_SANDBOX.md +240 -0
- package/src/providers/README.md +62 -0
- package/src/providers/compose.mjs +460 -0
- package/src/providers/docker.mjs +207 -0
- package/src/providers/index.mjs +13 -0
- package/src/providers/sandbox.mjs +170 -0
- package/src/proxy.mjs +149 -0
- package/src/runtime.mjs +83 -0
- package/src/snapshots.mjs +394 -0
- package/src/source-paths.mjs +15 -0
- package/src/system.mjs +39 -0
- package/src/tls.mjs +57 -0
- package/src/ui-client.js +51 -0
- package/src/ui.html +12 -0
- package/src/ui.mjs +32 -0
- package/src/watch.mjs +20 -0
- package/src/worktrees.mjs +154 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
x-workspace: &workspace
|
|
2
|
+
- .:/workspace
|
|
3
|
+
- dependencies:/workspace/node_modules
|
|
4
|
+
- ui-dependencies:/workspace/apps/ui/node_modules
|
|
5
|
+
- templates-dependencies:/workspace/apps/templates-ui/node_modules
|
|
6
|
+
- evals-dependencies:/workspace/apps/evals/node_modules
|
|
7
|
+
- catalog-dependencies:/workspace/packages/model-catalog/node_modules
|
|
8
|
+
- routing-dependencies:/workspace/packages/model-routing/node_modules
|
|
9
|
+
- e2e-dependencies:/workspace/packages/ui-e2e/node_modules
|
|
10
|
+
- bun-cache:/root/.bun/install/cache
|
|
11
|
+
|
|
12
|
+
services:
|
|
13
|
+
setup:
|
|
14
|
+
image: oven/bun:1.4.4
|
|
15
|
+
working_dir: /workspace
|
|
16
|
+
command: ["bun", "--no-env-file", "install", "--frozen-lockfile", "--ignore-scripts"]
|
|
17
|
+
volumes: *workspace
|
|
18
|
+
api:
|
|
19
|
+
image: oven/bun:1.4.4
|
|
20
|
+
working_dir: /workspace
|
|
21
|
+
command: ["bun", "--no-env-file", "--expose-gc", "src/http.ts"]
|
|
22
|
+
depends_on:
|
|
23
|
+
setup:
|
|
24
|
+
condition: service_completed_successfully
|
|
25
|
+
environment:
|
|
26
|
+
AGENT_SWARM_API_KEY: ${AGENT_SWARM_API_KEY:?Provide a test-only API key through a private env file}
|
|
27
|
+
DATABASE_PATH: /data/agent-swarm.sqlite
|
|
28
|
+
AGENT_FS_LOCAL_DIR: /data/files
|
|
29
|
+
NODE_ENV: development
|
|
30
|
+
PORT: "3013"
|
|
31
|
+
MCP_BASE_URL: http://api:3013
|
|
32
|
+
APP_URL: http://localhost:4574
|
|
33
|
+
CORS_ALLOWED_ORIGINS: http://localhost:4574,http://${AGENT_SWARM_INSTANCE:-swarm-example}.localhost:4574
|
|
34
|
+
DESPLEGA_TELEMETRY_ENV: test
|
|
35
|
+
ANONYMIZED_TELEMETRY: "false"
|
|
36
|
+
CAPABILITIES: core,task,kv,skills,repo
|
|
37
|
+
HEARTBEAT_DISABLE: "true"
|
|
38
|
+
HEARTBEAT_CHECKLIST_DISABLE: "true"
|
|
39
|
+
TASK_AUTO_TITLE_ENABLED: "false"
|
|
40
|
+
RUNTIME_POOLS_ENABLED: "false"
|
|
41
|
+
CHAT_SDK_ENABLED: "false"
|
|
42
|
+
SLACK_DISABLE: "true"
|
|
43
|
+
GITHUB_DISABLE: "true"
|
|
44
|
+
GITLAB_DISABLE: "true"
|
|
45
|
+
AZURE_DEVOPS_DISABLE: "true"
|
|
46
|
+
BITBUCKET_DISABLE: "true"
|
|
47
|
+
AGENTMAIL_DISABLE: "true"
|
|
48
|
+
LINEAR_DISABLE: "true"
|
|
49
|
+
JIRA_DISABLE: "true"
|
|
50
|
+
OAUTH_KEEPALIVE_DISABLE: "true"
|
|
51
|
+
OAUTH_REFRESH_SWEEP_DISABLE: "true"
|
|
52
|
+
volumes:
|
|
53
|
+
- .:/workspace:ro
|
|
54
|
+
- dependencies:/workspace/node_modules
|
|
55
|
+
- ui-dependencies:/workspace/apps/ui/node_modules
|
|
56
|
+
- templates-dependencies:/workspace/apps/templates-ui/node_modules
|
|
57
|
+
- evals-dependencies:/workspace/apps/evals/node_modules
|
|
58
|
+
- catalog-dependencies:/workspace/packages/model-catalog/node_modules
|
|
59
|
+
- routing-dependencies:/workspace/packages/model-routing/node_modules
|
|
60
|
+
- e2e-dependencies:/workspace/packages/ui-e2e/node_modules
|
|
61
|
+
- data:/data
|
|
62
|
+
ports: ["127.0.0.1:4313:3013"]
|
|
63
|
+
healthcheck:
|
|
64
|
+
test: ["CMD", "bun", "--no-env-file", "-e", "fetch('http://127.0.0.1:3013/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))"]
|
|
65
|
+
interval: 2s
|
|
66
|
+
timeout: 3s
|
|
67
|
+
retries: 25
|
|
68
|
+
ui:
|
|
69
|
+
image: oven/bun:1.4.4
|
|
70
|
+
working_dir: /workspace/apps/ui
|
|
71
|
+
command:
|
|
72
|
+
- bun
|
|
73
|
+
- --no-env-file
|
|
74
|
+
- -e
|
|
75
|
+
- "import {createServer} from 'vite'; const server = await createServer({envDir: false, server: {host: '0.0.0.0', port: 5274, strictPort: true}}); await server.listen(); server.printUrls();"
|
|
76
|
+
depends_on:
|
|
77
|
+
setup:
|
|
78
|
+
condition: service_completed_successfully
|
|
79
|
+
api:
|
|
80
|
+
condition: service_healthy
|
|
81
|
+
environment:
|
|
82
|
+
VITE_PROXY_TARGET: http://api:3013
|
|
83
|
+
VITE_ALLOWED_HOSTS: .localhost
|
|
84
|
+
VITE_PLAUSIBLE_ANALYTICS: "false"
|
|
85
|
+
volumes: *workspace
|
|
86
|
+
ports: ["127.0.0.1:4574:5274"]
|
|
87
|
+
healthcheck:
|
|
88
|
+
test: ["CMD", "bun", "--no-env-file", "-e", "fetch('http://127.0.0.1:5274').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))"]
|
|
89
|
+
interval: 2s
|
|
90
|
+
timeout: 3s
|
|
91
|
+
retries: 25
|
|
92
|
+
volumes:
|
|
93
|
+
data: {}
|
|
94
|
+
dependencies: {}
|
|
95
|
+
ui-dependencies: {}
|
|
96
|
+
templates-dependencies: {}
|
|
97
|
+
evals-dependencies: {}
|
|
98
|
+
catalog-dependencies: {}
|
|
99
|
+
routing-dependencies: {}
|
|
100
|
+
e2e-dependencies: {}
|
|
101
|
+
bun-cache: {}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import http from 'node:http';
|
|
3
|
+
|
|
4
|
+
const instance = process.env.AGENT_SWARM_INSTANCE ?? 'swarm-example';
|
|
5
|
+
const apiKey = process.env.AGENT_SWARM_API_KEY;
|
|
6
|
+
assert.ok(apiKey, 'Provide a test-only AGENT_SWARM_API_KEY.');
|
|
7
|
+
const readOnly = process.argv.includes('--read-only');
|
|
8
|
+
const path = '/api/kv/_/agent-env-example/persistence';
|
|
9
|
+
const value = 'agent-env-local-persistence-check';
|
|
10
|
+
|
|
11
|
+
function request(port, path, { method = 'GET', authenticated = false, body, named = true } = {}) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const req = http.request({
|
|
14
|
+
hostname: '127.0.0.1', port, path, method,
|
|
15
|
+
headers: {
|
|
16
|
+
host: `${named ? `${instance}.localhost` : 'localhost'}:${port}`,
|
|
17
|
+
...(authenticated ? { authorization: `Bearer ${apiKey}` } : {}),
|
|
18
|
+
...(body ? { 'content-type': 'application/json' } : {}),
|
|
19
|
+
},
|
|
20
|
+
}, response => {
|
|
21
|
+
let text = '';
|
|
22
|
+
response.setEncoding('utf8');
|
|
23
|
+
response.on('data', chunk => { text += chunk; });
|
|
24
|
+
response.on('end', () => resolve({ status: response.statusCode, text, headers: response.headers }));
|
|
25
|
+
});
|
|
26
|
+
req.setTimeout(15000, () => req.destroy(new Error('The local HTTP request timed out.')));
|
|
27
|
+
req.on('error', reject);
|
|
28
|
+
req.end(body ? JSON.stringify(body) : undefined);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for (const named of [true, false]) {
|
|
33
|
+
const health = await request(4313, '/health', { named });
|
|
34
|
+
assert.equal(health.status, 200, 'The API health request must succeed.');
|
|
35
|
+
assert.equal(JSON.parse(health.text).status, 'ok');
|
|
36
|
+
}
|
|
37
|
+
assert.equal((await request(4313, path)).status, 401, 'The API must require authentication.');
|
|
38
|
+
if (!readOnly) {
|
|
39
|
+
const write = await request(4313, path, { method: 'PUT', authenticated: true, body: { value } });
|
|
40
|
+
assert.equal(write.status, 200, 'The API write must succeed.');
|
|
41
|
+
assert.equal(JSON.parse(write.text).value, value);
|
|
42
|
+
}
|
|
43
|
+
for (const port of [4313, 4574]) {
|
|
44
|
+
const read = await request(port, path, { authenticated: true });
|
|
45
|
+
assert.equal(read.status, 200, 'The direct or proxied API read must succeed.');
|
|
46
|
+
assert.equal(JSON.parse(read.text).value, value);
|
|
47
|
+
}
|
|
48
|
+
const ui = await request(4574, '/');
|
|
49
|
+
assert.equal(ui.status, 200, 'The dashboard document must load.');
|
|
50
|
+
assert.match(ui.text, /\/src\/main\.tsx/);
|
|
51
|
+
const module = await request(4574, '/src/main.tsx');
|
|
52
|
+
assert.equal(module.status, 200, 'Vite must transform the real application entry.');
|
|
53
|
+
assert.match(module.headers['content-type'], /javascript/);
|
|
54
|
+
assert.equal((await request(4574, '/health')).status, 200, 'The dashboard proxy must reach the API.');
|
|
55
|
+
console.log(`PASS: ${readOnly ? 'retained KV value' : 'KV write/read'}, authentication, named and selected localhost API routes, dashboard HTML, transformed entry, and dashboard API proxy.`);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Compose example
|
|
2
|
+
|
|
3
|
+
This project builds a Node web service and starts Postgres after its health check succeeds.
|
|
4
|
+
The `tools` service requires the `tools` profile.
|
|
5
|
+
|
|
6
|
+
Use these commands from this directory:
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
agent-env init
|
|
10
|
+
agent-env env set POSTGRES_PASSWORD < /path/to/private/password-file
|
|
11
|
+
agent-env up --name compose-one
|
|
12
|
+
agent-env up --name compose-two --profile tools
|
|
13
|
+
agent-env exec compose-one --service db -- psql -U postgres -d app -c 'select 1'
|
|
14
|
+
agent-env rm compose-one --purge
|
|
15
|
+
agent-env rm compose-two --purge
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The source Compose file stays unchanged. Each instance has its own containers, network, build image, and data volume.
|
|
19
|
+
The web service retains public port 3000 in its metadata. Docker assigns a private loopback port.
|
|
20
|
+
Postgres has no published port and receives no HTTP route.
|
|
21
|
+
|
|
22
|
+
`loadSpec` accepts one environment name through `env`, as a string or a one-element array.
|
|
23
|
+
The `profile`, `compose-file`, and `env-file` options accept a string or an array of strings.
|
|
24
|
+
Arrays preserve order. Later Compose files and environment files override earlier files.
|
|
25
|
+
|
|
26
|
+
Named environments use this public configuration:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"provider": "compose",
|
|
31
|
+
"compose": { "files": ["compose.yaml"] },
|
|
32
|
+
"environments": {
|
|
33
|
+
"review": {
|
|
34
|
+
"compose": { "profiles": ["tools"] },
|
|
35
|
+
"envFiles": [".env.review"],
|
|
36
|
+
"env": { "POSTGRES_PASSWORD": { "secret": "POSTGRES_PASSWORD" } }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
An environment value can be a literal string, `{ "secret": "PRIVATE_KEY" }`, or `{ "env": "PROCESS_VARIABLE" }`.
|
|
43
|
+
Store secret values through stdin or a process variable reference. The private store uses mode 0600 outside the checkout.
|
|
44
|
+
Environment files support `export`, comments, quoted values, and multiline quoted values. Their values remain literal, without shell execution or variable expansion.
|
|
45
|
+
Global environment values apply to Docker services and Compose interpolation. Service `environment` entries control which variables enter Compose containers.
|
|
46
|
+
|
|
47
|
+
For multiple published ports, define one alias for each port:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"compose": {
|
|
52
|
+
"files": ["compose.yaml"],
|
|
53
|
+
"routes": {
|
|
54
|
+
"web": { "service": "web", "target": 3000, "port": 3000, "protocol": "http" },
|
|
55
|
+
"admin": { "service": "web", "target": 9090, "port": 9090, "protocol": "http" }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Services without published ports remain internal, including services with `expose` entries.
|
|
62
|
+
Use explicit protocols for ports that do not match common HTTP ports.
|
|
63
|
+
UDP, replicas, host namespaces, static addresses, custom network allocation, and volume driver options require separate support.
|
|
64
|
+
The provider rejects these features. External networks and volumes remain external and survive purge.
|
|
65
|
+
Remote bind and build paths must resolve inside the checkout. Remote binds cannot use files excluded from synchronization.
|
|
66
|
+
The daemon implements Compose volume forks through verified snapshots.
|
|
67
|
+
|
|
68
|
+
## Integration contract
|
|
69
|
+
|
|
70
|
+
Import `ComposeProvider` from `src/providers/compose.mjs` and register it under `compose`.
|
|
71
|
+
Docker Compose must support `config --format json`, `config --variables`, and `up --wait`.
|
|
72
|
+
The class implements the Docker provider interface. It uses the Docker helpers for commands, synchronization, SSH, and tunnels.
|
|
73
|
+
`create`, `start`, and `wait` retain desired public ports and discover private backend ports.
|
|
74
|
+
The daemon coordinates snapshot-based forks. Direct provider `fork` calls remain unsupported.
|
|
75
|
+
|
|
76
|
+
Each `spec.services` and `handle.services` entry has `composeService`.
|
|
77
|
+
Internal entries have `internal: true` and no `port`, `protocol`, or HTTP URL.
|
|
78
|
+
The parent must exclude internal entries when it reserves listeners, changes route focus, and formats URLs.
|
|
79
|
+
Published entries have `port`, `containerPort`, `protocol`, and `transport`.
|
|
80
|
+
Handle entries also have `container` and `hostPort`. Several aliases can refer to one container.
|
|
81
|
+
|
|
82
|
+
The initialization exports are `createInitialConfig(options)` and `initialize(options)` from `src/init.mjs`.
|
|
83
|
+
Both accept `cwd`, `command`, `port`, and `image`.
|
|
84
|
+
The first returns public configuration. The second writes a new file and returns `{ filename, config }`.
|
|
85
|
+
`initialize` also accepts `config` for the output filename. It never replaces an existing file.
|
|
86
|
+
|
|
87
|
+
The environment command exports come from `src/environments.mjs`:
|
|
88
|
+
|
|
89
|
+
- `setEnvironmentSecret({ cwd, environment, key, stdin })` reads a readable stream.
|
|
90
|
+
- `setEnvironmentSecret({ cwd, environment, key, fromEnv })` reads a process variable reference.
|
|
91
|
+
- `listEnvironmentSecrets({ cwd, environment })` returns sorted variable names.
|
|
92
|
+
- `unsetEnvironmentSecret({ cwd, environment, key })` returns whether the variable existed.
|
|
93
|
+
|
|
94
|
+
These helpers also accept `home` to select the private state directory.
|
|
95
|
+
`setEnvironmentSecret` accepts `env` for an explicit source environment. It rejects a literal `value` argument.
|
|
96
|
+
`readEnvironmentSecrets` and `loadEnvironment` return private values for runtime integration only.
|
|
97
|
+
`parseEnvFile`, `resolveEnvironment`, and `stringList` provide parsing and configuration helpers.
|
|
98
|
+
|
|
99
|
+
`redactEnvironment(output, values)` accepts an array or an object with private values.
|
|
100
|
+
Compose logs and execution output already use this helper.
|
|
101
|
+
The daemon applies it to Docker logs, execution output, and errors.
|
|
102
|
+
Keep specification values in private daemon state. Never print the full specification or write it into generated public configuration.
|
|
103
|
+
`spec.compose.model` captures the resolved source configuration. It can contain private values.
|
|
104
|
+
This snapshot preserves shell interpolation when the daemon has a different environment.
|
|
105
|
+
It also lets the daemon detect changes to commands, builds, health checks, and other Compose settings.
|
|
106
|
+
`spec.compose.environment` contains private values needed for runtime secrets and redaction.
|
|
107
|
+
|
|
108
|
+
Run `node test/compose.e2e.mjs` for the provider E2E. It creates and removes only its own resources.
|
|
109
|
+
Run `npm run test:features` for the integrated Compose CLI, snapshot, and worktree flow.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
services:
|
|
2
|
+
web:
|
|
3
|
+
build: .
|
|
4
|
+
container_name: existing-web-name
|
|
5
|
+
ports:
|
|
6
|
+
- "3000:3000"
|
|
7
|
+
environment:
|
|
8
|
+
PORT: "3000"
|
|
9
|
+
depends_on:
|
|
10
|
+
db:
|
|
11
|
+
condition: service_healthy
|
|
12
|
+
healthcheck:
|
|
13
|
+
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000').then(r => { if (!r.ok) process.exit(1) }).catch(() => process.exit(1))"]
|
|
14
|
+
interval: 2s
|
|
15
|
+
timeout: 2s
|
|
16
|
+
retries: 30
|
|
17
|
+
db:
|
|
18
|
+
image: postgres:16-alpine
|
|
19
|
+
environment:
|
|
20
|
+
POSTGRES_USER: postgres
|
|
21
|
+
POSTGRES_DB: app
|
|
22
|
+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD through agent-env env or an explicit env file}
|
|
23
|
+
volumes:
|
|
24
|
+
- data:/var/lib/postgresql/data
|
|
25
|
+
healthcheck:
|
|
26
|
+
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U postgres -d app"]
|
|
27
|
+
interval: 2s
|
|
28
|
+
timeout: 2s
|
|
29
|
+
retries: 30
|
|
30
|
+
tools:
|
|
31
|
+
image: busybox:1.37
|
|
32
|
+
profiles: [tools]
|
|
33
|
+
command: ["sh", "-c", "while :; do sleep 3600; done"]
|
|
34
|
+
volumes:
|
|
35
|
+
data:
|
|
36
|
+
name: existing-shared-data-name
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"services": {
|
|
3
|
+
"web": {
|
|
4
|
+
"image": "busybox:1.37",
|
|
5
|
+
"port": 3300,
|
|
6
|
+
"command": "httpd -f -p 3000 -h /workspace",
|
|
7
|
+
"containerPort": 3000,
|
|
8
|
+
"volumes": { "data": "/data" }
|
|
9
|
+
},
|
|
10
|
+
"db": {
|
|
11
|
+
"image": "postgres:16-alpine",
|
|
12
|
+
"port": 55432,
|
|
13
|
+
"containerPort": 5432,
|
|
14
|
+
"protocol": "tcp",
|
|
15
|
+
"health": "pg_isready -h 127.0.0.1 -U postgres",
|
|
16
|
+
"env": { "POSTGRES_PASSWORD": "dev-only", "POSTGRES_DB": "app" },
|
|
17
|
+
"volumes": { "data": "/var/lib/postgresql/data" }
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<meta charset="utf-8">
|
|
4
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
5
|
+
<title>agent-env</title>
|
|
6
|
+
<style>body{font:18px system-ui;background:#f7f7f2;color:#242923;max-width:640px;margin:15vh auto;padding:24px}code{background:#e8ebe2;padding:4px 8px;border-radius:5px}h1{font-size:48px;letter-spacing:-2px}</style>
|
|
7
|
+
<h1>Local address. Any machine.</h1>
|
|
8
|
+
<p>This page runs in an isolated Docker container.</p>
|
|
9
|
+
<p>Your address: <code id="address"></code></p>
|
|
10
|
+
<p>Edit this file, then reload. For SSH instances, run <code>agent-env sync NAME</code> first.</p>
|
|
11
|
+
<script>document.getElementById('address').textContent=location.host</script>
|
|
12
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@desplega.ai/agent-env",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Run development services behind stable localhost addresses.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"agent-env": "./bin/agent-env.mjs"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node test/run.mjs",
|
|
11
|
+
"check": "node scripts/check.mjs",
|
|
12
|
+
"test:e2e": "node test/run.mjs",
|
|
13
|
+
"test:core": "node test/run.mjs core",
|
|
14
|
+
"test:docker": "node test/run.mjs docker",
|
|
15
|
+
"test:runtime": "node test/runtime-e2e.mjs",
|
|
16
|
+
"test:features": "node test/run.mjs features",
|
|
17
|
+
"test:compose": "node test/run.mjs compose",
|
|
18
|
+
"test:ssh": "node test/run.mjs ssh",
|
|
19
|
+
"test:s3": "node test/run.mjs s3",
|
|
20
|
+
"test:cloud": "node test/run.mjs cloud"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22"
|
|
24
|
+
},
|
|
25
|
+
"os": [
|
|
26
|
+
"darwin",
|
|
27
|
+
"linux"
|
|
28
|
+
],
|
|
29
|
+
"files": [
|
|
30
|
+
"bin",
|
|
31
|
+
"src",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE",
|
|
34
|
+
"examples",
|
|
35
|
+
"docs",
|
|
36
|
+
"assets"
|
|
37
|
+
],
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"author": "Desplega Labs",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/desplega-ai/agent-env.git"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/desplega-ai/agent-env#readme",
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/desplega-ai/agent-env/issues"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
}
|
|
51
|
+
}
|