@agentuity/cli 0.0.92 → 0.0.94
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/dist/agents-docs.d.ts +22 -0
- package/dist/agents-docs.d.ts.map +1 -0
- package/dist/agents-docs.js +36 -0
- package/dist/agents-docs.js.map +1 -0
- package/dist/banner.d.ts.map +1 -1
- package/dist/banner.js +11 -4
- package/dist/banner.js.map +1 -1
- package/dist/cmd/build/bundler.js +1 -1
- package/dist/cmd/build/bundler.js.map +1 -1
- package/dist/cmd/cloud/storage/upload.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/upload.js +40 -26
- package/dist/cmd/cloud/storage/upload.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +3 -0
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/index.d.ts.map +1 -1
- package/dist/cmd/index.js +1 -0
- package/dist/cmd/index.js.map +1 -1
- package/dist/cmd/project/download.d.ts.map +1 -1
- package/dist/cmd/project/download.js +173 -55
- package/dist/cmd/project/download.js.map +1 -1
- package/dist/cmd/setup/index.d.ts +2 -0
- package/dist/cmd/setup/index.d.ts.map +1 -0
- package/dist/cmd/setup/index.js +37 -0
- package/dist/cmd/setup/index.js.map +1 -0
- package/dist/cmd/upgrade/index.d.ts.map +1 -1
- package/dist/cmd/upgrade/index.js +6 -1
- package/dist/cmd/upgrade/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/runtime-bootstrap.d.ts +55 -0
- package/dist/runtime-bootstrap.d.ts.map +1 -0
- package/dist/runtime-bootstrap.js +90 -0
- package/dist/runtime-bootstrap.js.map +1 -0
- package/dist/tui.d.ts +16 -0
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +3 -3
- package/dist/tui.js.map +1 -1
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +6 -1
- package/dist/version-check.js.map +1 -1
- package/dist/version.d.ts +17 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +24 -0
- package/dist/version.js.map +1 -1
- package/package.json +3 -3
- package/src/agents-docs.ts +52 -0
- package/src/banner.ts +18 -4
- package/src/cmd/build/bundler.ts +1 -1
- package/src/cmd/cloud/storage/upload.ts +43 -29
- package/src/cmd/dev/index.ts +5 -1
- package/src/cmd/index.ts +1 -0
- package/src/cmd/project/download.ts +194 -59
- package/src/cmd/setup/index.ts +42 -0
- package/src/cmd/upgrade/index.ts +8 -1
- package/src/index.ts +5 -0
- package/src/runtime-bootstrap.md +161 -0
- package/src/runtime-bootstrap.ts +125 -0
- package/src/tui.ts +3 -3
- package/src/version-check.ts +6 -1
- package/src/version.ts +28 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Runtime Bootstrap Utility
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
When running SDK test applications locally (integration-suite, cloud-deployment), they weren't respecting:
|
|
6
|
+
|
|
7
|
+
- Profile-specific `.env` files (`.env.local`, `.env.production`)
|
|
8
|
+
- Profile-specific config files (`agentuity.local.json`, `agentuity.production.json`)
|
|
9
|
+
|
|
10
|
+
This caused tests to fail because:
|
|
11
|
+
|
|
12
|
+
1. `AGENTUITY_SDK_KEY` wasn't loaded from `.env.local`
|
|
13
|
+
2. `AGENTUITY_REGION` wasn't set to `local` for local profile
|
|
14
|
+
3. Services tried to connect to production URLs instead of `*.agentuity.io`
|
|
15
|
+
|
|
16
|
+
## Solution
|
|
17
|
+
|
|
18
|
+
The `bootstrapRuntimeEnv()` function loads profile-aware configuration and environment variables **before** `createApp()` is called.
|
|
19
|
+
|
|
20
|
+
### What it does:
|
|
21
|
+
|
|
22
|
+
1. **Resolves active profile** via `loadConfig()`
|
|
23
|
+
- Checks `AGENTUITY_PROFILE` env var
|
|
24
|
+
- Reads `~/.config/agentuity/profile` file
|
|
25
|
+
- Falls back to `production` profile
|
|
26
|
+
|
|
27
|
+
2. **Loads `.env` files** based on profile:
|
|
28
|
+
- For `local` profile: `.env.local`, `.env.development`, `.env`
|
|
29
|
+
- For `production` profile: `.env.production`, `.env`
|
|
30
|
+
|
|
31
|
+
3. **Sets environment variables**:
|
|
32
|
+
- Only sets if not already defined (existing env wins)
|
|
33
|
+
- For `local` profile: defaults `AGENTUITY_REGION=local`
|
|
34
|
+
- Sets `AGENTUITY_PROFILE` to match active profile
|
|
35
|
+
|
|
36
|
+
4. **Loads project config**:
|
|
37
|
+
- For `local` profile: `agentuity.local.json`
|
|
38
|
+
- For `production` profile: `agentuity.json` or `agentuity.production.json`
|
|
39
|
+
|
|
40
|
+
### Usage
|
|
41
|
+
|
|
42
|
+
Call `bootstrapRuntimeEnv()` at the top of your `app.ts` **before** `createApp()`:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { createApp } from '@agentuity/runtime';
|
|
46
|
+
import { bootstrapRuntimeEnv } from '@agentuity/cli';
|
|
47
|
+
|
|
48
|
+
// Bootstrap runtime environment based on active profile
|
|
49
|
+
await bootstrapRuntimeEnv();
|
|
50
|
+
|
|
51
|
+
// Now createApp() will use the correct env vars
|
|
52
|
+
const app = await createApp();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Options
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
await bootstrapRuntimeEnv({
|
|
59
|
+
projectDir: '/path/to/project', // default: process.cwd()
|
|
60
|
+
profile: 'local', // override active profile
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Local Development Setup
|
|
65
|
+
|
|
66
|
+
To run tests locally with local services:
|
|
67
|
+
|
|
68
|
+
1. **Create local profile** (if not exists):
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
cd ~/.config/agentuity
|
|
72
|
+
touch local.yaml
|
|
73
|
+
echo "name: local" > local.yaml
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
2. **Select local profile**:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
agentuity profile switch local
|
|
80
|
+
# Or set env var:
|
|
81
|
+
export AGENTUITY_PROFILE=local
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
3. **Create `.env.local`** in project root:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
AGENTUITY_SDK_KEY=your-sdk-key-here
|
|
88
|
+
AGENTUITY_REGION=local # Optional, auto-set for local profile
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
4. **(Optional) Create `agentuity.local.json`** for project-specific overrides:
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"projectId": "proj_local_test",
|
|
95
|
+
"orgId": "org_local",
|
|
96
|
+
"region": "local"
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### How it works
|
|
101
|
+
|
|
102
|
+
The bootstrap process follows this precedence (highest to lowest):
|
|
103
|
+
|
|
104
|
+
1. **Explicit env vars** (from shell/CI) - always wins
|
|
105
|
+
2. **Profile-specific .env** (`.env.local` for local profile)
|
|
106
|
+
3. **Development/production .env** (`.env.development` or `.env.production`)
|
|
107
|
+
4. **Default .env** (`.env`)
|
|
108
|
+
|
|
109
|
+
For config files:
|
|
110
|
+
|
|
111
|
+
1. **Profile-specific config** (`agentuity.local.json` for local profile)
|
|
112
|
+
2. **Default config** (`agentuity.json`)
|
|
113
|
+
|
|
114
|
+
### Integration Points
|
|
115
|
+
|
|
116
|
+
This utility is used by:
|
|
117
|
+
|
|
118
|
+
- `sdk/apps/testing/integration-suite/app.ts`
|
|
119
|
+
- `sdk/apps/testing/cloud-deployment/app.ts`
|
|
120
|
+
|
|
121
|
+
It reuses existing infrastructure from the CLI:
|
|
122
|
+
|
|
123
|
+
- `loadConfig()` - Resolves active profile
|
|
124
|
+
- `loadProjectConfig()` - Loads profile-specific project config
|
|
125
|
+
- `getEnvFilePaths()` - Determines which .env files to load
|
|
126
|
+
- `readEnvFile()` - Parses .env files
|
|
127
|
+
|
|
128
|
+
### Design Decisions
|
|
129
|
+
|
|
130
|
+
**Why not embed in `createApp()`?**
|
|
131
|
+
|
|
132
|
+
- `createApp()` is a runtime primitive that should work in any environment
|
|
133
|
+
- CLI config and profile logic is Bun-specific
|
|
134
|
+
- Test harnesses can opt-in to this behavior without forcing it on all SDK users
|
|
135
|
+
|
|
136
|
+
**Why not auto-detect local vs production?**
|
|
137
|
+
|
|
138
|
+
- Profile system is the single source of truth
|
|
139
|
+
- `NODE_ENV` alone is insufficient (can be `development` in production)
|
|
140
|
+
- Region alone is insufficient (multiple regions, not just local vs cloud)
|
|
141
|
+
- Profile explicitly declares intent: "I want local services"
|
|
142
|
+
|
|
143
|
+
### Testing
|
|
144
|
+
|
|
145
|
+
To verify it works:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Set local profile
|
|
149
|
+
export AGENTUITY_PROFILE=local
|
|
150
|
+
|
|
151
|
+
# Build and run
|
|
152
|
+
cd sdk/apps/testing/integration-suite
|
|
153
|
+
bun run build
|
|
154
|
+
cd .agentuity && bun run app.js
|
|
155
|
+
|
|
156
|
+
# Check logs for:
|
|
157
|
+
# [TEST-SUITE] Profile: local
|
|
158
|
+
# [TEST-SUITE] Region: local
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Services should connect to `*.agentuity.io` instead of `*.agentuity.cloud`.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime environment bootstrapping utility
|
|
3
|
+
*
|
|
4
|
+
* Loads configuration and environment variables based on the active profile
|
|
5
|
+
* before createApp() is called. This ensures .env.{profile} files and
|
|
6
|
+
* agentuity.{profile}.json configs are respected.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { loadConfig, loadProjectConfig } from './config';
|
|
10
|
+
import { getEnvFilePaths, readEnvFile, type EnvVars } from './env-util';
|
|
11
|
+
import type { Config, ProjectConfig } from './types';
|
|
12
|
+
|
|
13
|
+
export interface RuntimeBootstrapOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Project directory containing agentuity.json and .env files
|
|
16
|
+
* @default process.cwd()
|
|
17
|
+
*/
|
|
18
|
+
projectDir?: string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Override the active profile (otherwise uses loadConfig())
|
|
22
|
+
*/
|
|
23
|
+
profile?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface RuntimeBootstrapResult {
|
|
27
|
+
/**
|
|
28
|
+
* Resolved CLI config (from ~/.config/agentuity/)
|
|
29
|
+
*/
|
|
30
|
+
config: Config | null;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Resolved project config (agentuity.json or agentuity.{profile}.json)
|
|
34
|
+
*/
|
|
35
|
+
projectConfig: ProjectConfig | null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Bootstrap runtime environment by loading profile-aware config and env files.
|
|
40
|
+
*
|
|
41
|
+
* This function:
|
|
42
|
+
* 1. Resolves the active profile (from AGENTUITY_PROFILE env or profile config)
|
|
43
|
+
* 2. Loads .env.{profile}, .env.development, or .env based on profile
|
|
44
|
+
* 3. Sets AGENTUITY_REGION=local for local profile
|
|
45
|
+
* 4. Loads agentuity.{profile}.json if it exists
|
|
46
|
+
* 5. Does NOT override environment variables already set
|
|
47
|
+
*
|
|
48
|
+
* Call this BEFORE createApp() in your app.ts:
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { bootstrapRuntimeEnv } from '@agentuity/cli/runtime-bootstrap';
|
|
53
|
+
* import { createApp } from '@agentuity/runtime';
|
|
54
|
+
*
|
|
55
|
+
* // Load config and env based on active profile
|
|
56
|
+
* await bootstrapRuntimeEnv();
|
|
57
|
+
*
|
|
58
|
+
* // Now createApp() will use the correct env vars
|
|
59
|
+
* const app = await createApp();
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export async function bootstrapRuntimeEnv(
|
|
63
|
+
options: RuntimeBootstrapOptions = {}
|
|
64
|
+
): Promise<RuntimeBootstrapResult> {
|
|
65
|
+
const projectDir = options.projectDir || process.cwd();
|
|
66
|
+
|
|
67
|
+
// Load CLI config to determine active profile
|
|
68
|
+
let cfg: Config | null = null;
|
|
69
|
+
try {
|
|
70
|
+
cfg = await loadConfig();
|
|
71
|
+
// Override profile if specified
|
|
72
|
+
if (options.profile) {
|
|
73
|
+
cfg = { ...cfg, name: options.profile };
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
// No config found - OK for tests without CLI setup
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Determine which .env files to load based on profile
|
|
80
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
81
|
+
const envPaths = getEnvFilePaths(projectDir, {
|
|
82
|
+
configName: cfg?.name,
|
|
83
|
+
isProduction,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Load and merge env files (later files override earlier ones)
|
|
87
|
+
let fileEnv: EnvVars = {};
|
|
88
|
+
for (const path of envPaths) {
|
|
89
|
+
const vars = await readEnvFile(path);
|
|
90
|
+
// Later files override earlier ones
|
|
91
|
+
fileEnv = { ...fileEnv, ...vars };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Apply to process.env ONLY if not already set
|
|
95
|
+
// This ensures existing env vars (from shell/CI) always win
|
|
96
|
+
for (const [key, value] of Object.entries(fileEnv)) {
|
|
97
|
+
if (process.env[key] === undefined) {
|
|
98
|
+
process.env[key] = value;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// For local profile, default AGENTUITY_REGION to 'local'
|
|
103
|
+
// This makes getServiceUrls() use *.agentuity.io instead of *.agentuity.cloud
|
|
104
|
+
if (cfg?.name === 'local' && !process.env.AGENTUITY_REGION) {
|
|
105
|
+
process.env.AGENTUITY_REGION = 'local';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Propagate profile name into env for consistency
|
|
109
|
+
if (cfg?.name && !process.env.AGENTUITY_PROFILE) {
|
|
110
|
+
process.env.AGENTUITY_PROFILE = cfg.name;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Load project config (agentuity.json or agentuity.{profile}.json)
|
|
114
|
+
let projectConfig: ProjectConfig | null = null;
|
|
115
|
+
try {
|
|
116
|
+
projectConfig = await loadProjectConfig(projectDir, cfg ?? undefined);
|
|
117
|
+
} catch {
|
|
118
|
+
// OK for tests that don't need project config
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
config: cfg,
|
|
123
|
+
projectConfig,
|
|
124
|
+
};
|
|
125
|
+
}
|
package/src/tui.ts
CHANGED
|
@@ -307,7 +307,7 @@ export function link(url: string, title?: string, color = getColor('link')): str
|
|
|
307
307
|
/**
|
|
308
308
|
* Check if terminal supports OSC 8 hyperlinks
|
|
309
309
|
*/
|
|
310
|
-
function supportsHyperlinks(): boolean {
|
|
310
|
+
export function supportsHyperlinks(): boolean {
|
|
311
311
|
const term = process.env.TERM || '';
|
|
312
312
|
const termProgram = process.env.TERM_PROGRAM || '';
|
|
313
313
|
const wtSession = process.env.WT_SESSION || '';
|
|
@@ -361,7 +361,7 @@ export function output(message: string): void {
|
|
|
361
361
|
* which causes incorrect alignment. We strip OSC 8 codes first, then use Bun.stringWidth()
|
|
362
362
|
* to handle regular ANSI codes and unicode characters correctly.
|
|
363
363
|
*/
|
|
364
|
-
function getDisplayWidth(str: string): number {
|
|
364
|
+
export function getDisplayWidth(str: string): number {
|
|
365
365
|
// Remove OSC-8 hyperlink sequences using Unicode escapes (\u001b = ESC, \u0007 = BEL) to satisfy linter
|
|
366
366
|
// eslint-disable-next-line no-control-regex
|
|
367
367
|
const withoutOSC8 = str.replace(/\u001b\]8;;[^\u0007]*\u0007/g, '');
|
|
@@ -371,7 +371,7 @@ function getDisplayWidth(str: string): number {
|
|
|
371
371
|
/**
|
|
372
372
|
* Strip all ANSI escape sequences from a string
|
|
373
373
|
*/
|
|
374
|
-
function stripAnsi(str: string): string {
|
|
374
|
+
export function stripAnsi(str: string): string {
|
|
375
375
|
// eslint-disable-next-line no-control-regex
|
|
376
376
|
return str.replace(/\u001b\[[0-9;]*m/g, '').replace(/\u001b\]8;;[^\u0007]*\u0007/g, '');
|
|
377
377
|
}
|
package/src/version-check.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Config, Logger, CommandDefinition } from './types';
|
|
2
2
|
import { isRunningFromExecutable, fetchLatestVersion } from './cmd/upgrade';
|
|
3
|
-
import { getVersion } from './version';
|
|
3
|
+
import { getVersion, getCompareUrl, getReleaseUrl, toTag } from './version';
|
|
4
4
|
import * as tui from './tui';
|
|
5
5
|
import { saveConfig } from './config';
|
|
6
6
|
import { $ } from 'bun';
|
|
@@ -97,6 +97,11 @@ async function promptUpgrade(currentVersion: string, latestVersion: string): Pro
|
|
|
97
97
|
tui.info(`Current version: ${tui.muted(currentVersion)}`);
|
|
98
98
|
tui.info(`Latest version: ${tui.bold(latestVersion)}`);
|
|
99
99
|
tui.newline();
|
|
100
|
+
if (toTag(currentVersion) !== toTag(latestVersion)) {
|
|
101
|
+
tui.warning(`What's changed: ${tui.link(getCompareUrl(currentVersion, latestVersion))}`);
|
|
102
|
+
}
|
|
103
|
+
tui.success(`Release notes: ${tui.link(getReleaseUrl(latestVersion))}`);
|
|
104
|
+
tui.newline();
|
|
100
105
|
|
|
101
106
|
return await tui.confirm('Would you like to upgrade now?', true);
|
|
102
107
|
}
|
package/src/version.ts
CHANGED
|
@@ -27,3 +27,31 @@ export function getRevision(): string {
|
|
|
27
27
|
// Bun provides git SHA via Bun.revision
|
|
28
28
|
return typeof Bun !== 'undefined' && Bun.revision ? Bun.revision.substring(0, 8) : 'unknown';
|
|
29
29
|
}
|
|
30
|
+
|
|
31
|
+
const GITHUB_REPO_URL = 'https://github.com/agentuity/sdk';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Normalize a version string to a Git tag format (with 'v' prefix)
|
|
35
|
+
*/
|
|
36
|
+
export function toTag(version: string): string {
|
|
37
|
+
return version.startsWith('v') ? version : `v${version}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get the GitHub URL for comparing two versions
|
|
42
|
+
* @param fromVersion - The current/old version
|
|
43
|
+
* @param toVersion - The new/target version
|
|
44
|
+
* @returns GitHub compare URL
|
|
45
|
+
*/
|
|
46
|
+
export function getCompareUrl(fromVersion: string, toVersion: string): string {
|
|
47
|
+
return `${GITHUB_REPO_URL}/compare/${toTag(fromVersion)}...${toTag(toVersion)}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get the GitHub URL for a specific release
|
|
52
|
+
* @param version - The version to get the release URL for
|
|
53
|
+
* @returns GitHub release URL
|
|
54
|
+
*/
|
|
55
|
+
export function getReleaseUrl(version: string): string {
|
|
56
|
+
return `${GITHUB_REPO_URL}/releases/tag/${toTag(version)}`;
|
|
57
|
+
}
|