@ghl-ai/aw 0.1.71 → 0.1.73-beta.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/c4/codexConfig.mjs +17 -9
- package/commands/doctor.mjs +2 -2
- package/commands/init.mjs +6 -0
- package/commands/push.mjs +45 -5
- package/hooks/aw-usage/lib/aw-usage-telemetry.js +26 -17
- package/mcp.mjs +25 -4
- package/package.json +3 -3
package/c4/codexConfig.mjs
CHANGED
|
@@ -27,6 +27,7 @@ import TOML from '@iarna/toml';
|
|
|
27
27
|
|
|
28
28
|
export const MCP_URL_DEFAULT =
|
|
29
29
|
'https://services.leadconnectorhq.com/agentic-workspace/mcp';
|
|
30
|
+
export const CODEX_MCP_BEARER_TOKEN_ENV = 'GHL_AI_MCP_BEARER_TOKEN';
|
|
30
31
|
|
|
31
32
|
const FILE_MODE = 0o600;
|
|
32
33
|
|
|
@@ -76,6 +77,12 @@ function configPathFor(home) {
|
|
|
76
77
|
return join(home, '.codex/config.toml');
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
function removeAuthorizationHeader(table) {
|
|
81
|
+
if (!table || typeof table !== 'object' || Array.isArray(table)) return false;
|
|
82
|
+
delete table.Authorization;
|
|
83
|
+
return Object.keys(table).length === 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
79
86
|
/**
|
|
80
87
|
* Ensure `[features] codex_hooks = true` in ~/.codex/config.toml.
|
|
81
88
|
* Preserves all other keys (round-trip via @iarna/toml).
|
|
@@ -99,11 +106,11 @@ export function ensureCodexHooksFlag(home) {
|
|
|
99
106
|
}
|
|
100
107
|
|
|
101
108
|
/**
|
|
102
|
-
* Ensure `[mcp_servers.ghl-ai]` block with url +
|
|
109
|
+
* Ensure `[mcp_servers.ghl-ai]` block with url + bearer token env var + transport.
|
|
103
110
|
* URL falls back to env MCP_URL → MCP_URL_DEFAULT.
|
|
104
111
|
*
|
|
105
112
|
* @param {string} home
|
|
106
|
-
* @param {string} token
|
|
113
|
+
* @param {string} token Validated by the caller, never persisted into Codex config.
|
|
107
114
|
* @returns {{ changed: boolean }}
|
|
108
115
|
*/
|
|
109
116
|
export function ensureCodexMcpServer(home, token) {
|
|
@@ -132,14 +139,15 @@ export function ensureCodexMcpServer(home, token) {
|
|
|
132
139
|
// Match the canonical `aw init` reference (libs/aw/mcp.mjs::tomlMcpServerBlock)
|
|
133
140
|
// which always sets startup_timeout_sec = 30 for HTTP MCP servers.
|
|
134
141
|
ghlAi.startup_timeout_sec = 30;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
ghlAi.headers
|
|
142
|
+
ghlAi.bearer_token_env_var = CODEX_MCP_BEARER_TOKEN_ENV;
|
|
143
|
+
if (removeAuthorizationHeader(ghlAi.http_headers)) delete ghlAi.http_headers;
|
|
144
|
+
if (removeAuthorizationHeader(ghlAi.env_http_headers)) delete ghlAi.env_http_headers;
|
|
145
|
+
if (ghlAi.headers && typeof ghlAi.headers === 'object' && !Array.isArray(ghlAi.headers)) {
|
|
146
|
+
delete ghlAi.headers.Authorization;
|
|
147
|
+
if (Object.keys(ghlAi.headers).length === 0) {
|
|
148
|
+
delete ghlAi.headers;
|
|
149
|
+
}
|
|
141
150
|
}
|
|
142
|
-
ghlAi.headers.Authorization = `Bearer ${token}`;
|
|
143
151
|
root.mcp_servers['ghl-ai'] = ghlAi;
|
|
144
152
|
|
|
145
153
|
const serialized = TOML.stringify(root);
|
package/commands/doctor.mjs
CHANGED
|
@@ -284,7 +284,7 @@ function tomlMcpHealth(filePath) {
|
|
|
284
284
|
return {
|
|
285
285
|
present: /\[mcp_servers\.ghl-ai\]/.test(content),
|
|
286
286
|
url: /\[mcp_servers\.ghl-ai\][\s\S]*?url\s*=\s*"https?:\/\/[^"]+"/.test(content),
|
|
287
|
-
authorization: /\[mcp_servers\.ghl-ai
|
|
287
|
+
authorization: /\[mcp_servers\.ghl-ai\][\s\S]*?bearer_token_env_var\s*=\s*".+"/.test(content),
|
|
288
288
|
};
|
|
289
289
|
}
|
|
290
290
|
|
|
@@ -891,7 +891,7 @@ function buildDoctorChecks(homeDir, cwd) {
|
|
|
891
891
|
const codexMcp = tomlMcpHealth(codexConfigPath);
|
|
892
892
|
checks.push(
|
|
893
893
|
codexMcp.present && codexMcp.url && codexMcp.authorization
|
|
894
|
-
? makeCheck('codex-mcp', 'Codex MCP config', 'pass', 'Codex has a ghl-ai MCP server with URL and
|
|
894
|
+
? makeCheck('codex-mcp', 'Codex MCP config', 'pass', 'Codex has a ghl-ai MCP server with URL and bearer token env var')
|
|
895
895
|
: makeCheck(
|
|
896
896
|
'codex-mcp',
|
|
897
897
|
'Codex MCP config',
|
package/commands/init.mjs
CHANGED
|
@@ -25,6 +25,7 @@ import * as fmt from '../fmt.mjs';
|
|
|
25
25
|
import { chalk, setSilent } from '../fmt.mjs';
|
|
26
26
|
import { linkWorkspace } from '../link.mjs';
|
|
27
27
|
import { generateCommands, copyInstructions, initAwDocs, syncHomeHarnessInstructions } from '../integrate.mjs';
|
|
28
|
+
import { renderRules } from '../render-rules.mjs';
|
|
28
29
|
import { setupMcp } from '../mcp.mjs';
|
|
29
30
|
import { isContextModeRequested } from '../integrations/context-mode.mjs';
|
|
30
31
|
import { applyStoredStartupPreferences, ensureAwRuntimeHook, isDefaultRoutingEnabled } from '../startup.mjs';
|
|
@@ -150,6 +151,11 @@ function syncHomeAndProjectInstructions(cwd, namespace) {
|
|
|
150
151
|
initAwDocs(HOME);
|
|
151
152
|
if (cwd !== HOME) {
|
|
152
153
|
syncInstructionsAndAwDocs(cwd, namespace);
|
|
154
|
+
} else {
|
|
155
|
+
// Running from $HOME (fresh-laptop flow): render global IDE rules directly.
|
|
156
|
+
// The project branch above is otherwise the only renderRules call site, so
|
|
157
|
+
// init from $HOME used to leave ~/.claude/rules and ~/.cursor/rules empty.
|
|
158
|
+
renderRules(HOME, { homeDir: HOME });
|
|
153
159
|
}
|
|
154
160
|
}
|
|
155
161
|
|
package/commands/push.mjs
CHANGED
|
@@ -153,13 +153,45 @@ function normalizeRelPath(value) {
|
|
|
153
153
|
.replace(/\/+$/, '');
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
// Root namespaces publish at the AW docs root (aw_docs/<ns>/...), mirroring the
|
|
157
|
+
// local .aw_docs/<ns>/... subtree 1:1 — NO per-workspace <repo>/<user> segment
|
|
158
|
+
// and full nested folders. Use for shared, repo-keyed doc trees such as PR
|
|
159
|
+
// reviews (pr-reviews/<owner>/<repo>/pr-<n>/<run>) so they do not land under the
|
|
160
|
+
// reviewer's workspace namespace as one mangled flat slug.
|
|
161
|
+
const AW_DOCS_ROOT_NAMESPACES = ['pr-reviews'];
|
|
162
|
+
|
|
163
|
+
function awDocsRootScope(relPath) {
|
|
164
|
+
const value = normalizeRelPath(relPath);
|
|
165
|
+
const segments = value.split('/');
|
|
166
|
+
// A root scope's delete-then-copy target is the resolved subtree. Require the
|
|
167
|
+
// full pr-reviews/<repo>/pr-<number>/<run> depth so a shallow path (e.g.
|
|
168
|
+
// `pr-reviews` or `pr-reviews/<repo>`) can never resolve to a broad shared
|
|
169
|
+
// subtree and wipe unrelated review runs on the remote.
|
|
170
|
+
if (segments[0] !== 'pr-reviews' || segments.length < 4) {
|
|
171
|
+
throw new Error(
|
|
172
|
+
`Root-scope docs publish must target pr-reviews/<repo>/pr-<number>/<run>, got "${relPath}".`
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
for (const seg of segments) {
|
|
176
|
+
if (!seg || seg === '.' || seg === '..' || !/^[A-Za-z0-9._-]+$/.test(seg)) {
|
|
177
|
+
throw new Error(`Invalid AW docs path segment "${seg}" in "${relPath}". Segments may contain letters, numbers, dot, underscore, and dash only.`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return { type: 'root', relPrefix: value };
|
|
181
|
+
}
|
|
182
|
+
|
|
156
183
|
function featureScopeFromInput(input) {
|
|
157
184
|
const value = normalizeRelPath(input);
|
|
158
185
|
if (!value) return null;
|
|
159
186
|
|
|
187
|
+
const stripped = value.replace(/^\.aw_docs\//, '');
|
|
188
|
+
if (AW_DOCS_ROOT_NAMESPACES.includes(stripped.split('/')[0])) {
|
|
189
|
+
return awDocsRootScope(stripped);
|
|
190
|
+
}
|
|
191
|
+
|
|
160
192
|
const match = value.match(/^(?:\.aw_docs\/)?features\/([^/]+)$/);
|
|
161
193
|
if (!match) {
|
|
162
|
-
throw new Error('Docs-only publish path must be .aw_docs/features/<feature-slug
|
|
194
|
+
throw new Error('Docs-only publish path must be .aw_docs/features/<feature-slug>, .aw_docs/pr-reviews/<...>, or use --feature <feature-slug>.');
|
|
163
195
|
}
|
|
164
196
|
return awDocsFeatureScope(match[1]);
|
|
165
197
|
}
|
|
@@ -701,9 +733,14 @@ async function publishProjectAwDocs(cwd, home, dryRun, scope = null) {
|
|
|
701
733
|
const sourceRepo = await getProjectSourceRepo(projectRoot);
|
|
702
734
|
const repoSlug = repoSlugFromSource(sourceRepo, projectRoot);
|
|
703
735
|
const githubUsername = safePathSegment(await getGitHubUser(), 'unknown');
|
|
736
|
+
// Root-scoped docs mirror to the AW docs root (aw_docs/<relPath>); all other
|
|
737
|
+
// docs are namespaced under <repo>/<user> as before.
|
|
738
|
+
const isRootScope = scope?.type === 'root';
|
|
704
739
|
const docs = files.map(file => ({
|
|
705
740
|
...file,
|
|
706
|
-
publishedPath:
|
|
741
|
+
publishedPath: isRootScope
|
|
742
|
+
? `${publishConfig.dest}/${file.relPath}`
|
|
743
|
+
: `${publishConfig.dest}/${repoSlug}/${githubUsername}/${file.relPath}`,
|
|
707
744
|
}));
|
|
708
745
|
const publishedPaths = docs.map(doc => doc.publishedPath);
|
|
709
746
|
const links = docs.map(doc => ({
|
|
@@ -728,9 +765,11 @@ async function publishProjectAwDocs(cwd, home, dryRun, scope = null) {
|
|
|
728
765
|
s.start(`Publishing ${files.length} AW doc${files.length > 1 ? 's' : ''} to ${publishConfig.repo}...`);
|
|
729
766
|
try {
|
|
730
767
|
const docsRepoDir = await ensureAwDocsRepoClone(home, publishConfig);
|
|
731
|
-
const deleteTarget =
|
|
732
|
-
? join(docsRepoDir, publishConfig.dest,
|
|
733
|
-
:
|
|
768
|
+
const deleteTarget = isRootScope
|
|
769
|
+
? join(docsRepoDir, publishConfig.dest, scope.relPrefix)
|
|
770
|
+
: scope?.relPrefix
|
|
771
|
+
? join(docsRepoDir, publishConfig.dest, repoSlug, githubUsername, scope.relPrefix)
|
|
772
|
+
: join(docsRepoDir, publishConfig.dest, repoSlug, githubUsername);
|
|
734
773
|
rmSync(deleteTarget, {
|
|
735
774
|
recursive: true,
|
|
736
775
|
force: true,
|
|
@@ -1627,6 +1666,7 @@ function groupBy(arr, key) {
|
|
|
1627
1666
|
export const __test__ = {
|
|
1628
1667
|
featureScopeFromInput,
|
|
1629
1668
|
awDocsFeatureScope,
|
|
1669
|
+
awDocsRootScope,
|
|
1630
1670
|
resolveAwDocsScope,
|
|
1631
1671
|
assertDocsOnlyScopeOrAll,
|
|
1632
1672
|
};
|
|
@@ -80,9 +80,9 @@ function isDisabled() {
|
|
|
80
80
|
return cfg.enabled === false;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
// ── AW version
|
|
83
|
+
// ── AW CLI version detection ─────────────────────────────────────────
|
|
84
84
|
|
|
85
|
-
let
|
|
85
|
+
let _awCliVersionDetails = null;
|
|
86
86
|
|
|
87
87
|
function parseVersionString(raw) {
|
|
88
88
|
if (!raw) return null;
|
|
@@ -90,12 +90,20 @@ function parseVersionString(raw) {
|
|
|
90
90
|
return match ? match[1] : null;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
function
|
|
94
|
-
|
|
93
|
+
function readPackageVersion(pkgPath) {
|
|
94
|
+
try {
|
|
95
|
+
return parseVersionString(JSON.parse(fs.readFileSync(pkgPath, 'utf8')).version) || null;
|
|
96
|
+
} catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getAwCliVersionDetails() {
|
|
102
|
+
if (_awCliVersionDetails) return _awCliVersionDetails;
|
|
95
103
|
const envVersion = parseVersionString(process.env.AW_VERSION);
|
|
96
104
|
if (envVersion) {
|
|
97
|
-
|
|
98
|
-
return
|
|
105
|
+
_awCliVersionDetails = { version: envVersion, source: 'env' };
|
|
106
|
+
return _awCliVersionDetails;
|
|
99
107
|
}
|
|
100
108
|
try {
|
|
101
109
|
const cliVersion = parseVersionString(execSync('aw --version', {
|
|
@@ -104,8 +112,8 @@ function getAwVersion() {
|
|
|
104
112
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
105
113
|
}));
|
|
106
114
|
if (cliVersion) {
|
|
107
|
-
|
|
108
|
-
return
|
|
115
|
+
_awCliVersionDetails = { version: cliVersion, source: 'aw_binary' };
|
|
116
|
+
return _awCliVersionDetails;
|
|
109
117
|
}
|
|
110
118
|
} catch { /* ignore */ }
|
|
111
119
|
const candidates = [
|
|
@@ -120,16 +128,15 @@ function getAwVersion() {
|
|
|
120
128
|
const globalPrefix = execSync('npm prefix -g', { encoding: 'utf8', timeout: 3000 }).trim();
|
|
121
129
|
candidates.push(path.join(globalPrefix, 'lib', 'node_modules', '@ghl-ai', 'aw', 'package.json'));
|
|
122
130
|
} catch { /* ignore */ }
|
|
123
|
-
// aw-ecc version as last-resort fallback
|
|
124
|
-
candidates.push(path.join(os.homedir(), '.aw-ecc', 'package.json'));
|
|
125
131
|
for (const pkgPath of candidates) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
const version = readPackageVersion(pkgPath);
|
|
133
|
+
if (version) {
|
|
134
|
+
_awCliVersionDetails = { version, source: 'package_json' };
|
|
135
|
+
return _awCliVersionDetails;
|
|
136
|
+
}
|
|
130
137
|
}
|
|
131
|
-
|
|
132
|
-
return
|
|
138
|
+
_awCliVersionDetails = { version: null, source: 'unavailable' };
|
|
139
|
+
return _awCliVersionDetails;
|
|
133
140
|
}
|
|
134
141
|
|
|
135
142
|
// ── Harness detection ────────────────────────────────────────────────
|
|
@@ -427,6 +434,7 @@ function buildEvent(hookInput, eventType, payload) {
|
|
|
427
434
|
const cfg = loadConfig();
|
|
428
435
|
const git = getGitInfo();
|
|
429
436
|
const harness = detectHarness(input);
|
|
437
|
+
const awCli = getAwCliVersionDetails();
|
|
430
438
|
|
|
431
439
|
// Normalize session_id: Claude/Codex use session_id, Cursor uses conversation_id
|
|
432
440
|
const sessionId = input.session_id
|
|
@@ -458,7 +466,7 @@ function buildEvent(hookInput, eventType, payload) {
|
|
|
458
466
|
github_user: git.user || input.user_email || null,
|
|
459
467
|
github_email: git.email || input.user_email || null,
|
|
460
468
|
project_hash: computeProjectHash(cwd),
|
|
461
|
-
aw_version:
|
|
469
|
+
aw_version: awCli.version,
|
|
462
470
|
event: eventType,
|
|
463
471
|
client_ts: new Date().toISOString(),
|
|
464
472
|
payload: payload || {},
|
|
@@ -497,6 +505,7 @@ module.exports = {
|
|
|
497
505
|
readSessionLastSlashCommand,
|
|
498
506
|
readLastAssistantFromTranscript,
|
|
499
507
|
resolvePromptText,
|
|
508
|
+
getAwCliVersionDetails,
|
|
500
509
|
tryAcquireDedupe,
|
|
501
510
|
isCodexInternalTaskTitlePrompt,
|
|
502
511
|
isCodexInternalTaskTitleCompletion,
|
package/mcp.mjs
CHANGED
|
@@ -17,6 +17,7 @@ const ENABLED_MODE = 'enabled';
|
|
|
17
17
|
const DISABLED_MODE = 'disabled';
|
|
18
18
|
const DISABLE_MCP_ENV = 'AW_DISABLE_MCP';
|
|
19
19
|
const MCP_SERVER_NAME = 'ghl-ai';
|
|
20
|
+
const CODEX_MCP_BEARER_TOKEN_ENV = 'GHL_AI_MCP_BEARER_TOKEN';
|
|
20
21
|
|
|
21
22
|
function mcpPrefsPath(homeDir = HOME) {
|
|
22
23
|
return join(homeDir, '.aw', MCP_PREFS_FILENAME);
|
|
@@ -77,6 +78,18 @@ function detectPaths() {
|
|
|
77
78
|
return { ghlMcpUrl };
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
function resolveCodexBearerTokenEnvVar() {
|
|
82
|
+
if (process.env[CODEX_MCP_BEARER_TOKEN_ENV]) return CODEX_MCP_BEARER_TOKEN_ENV;
|
|
83
|
+
if (process.env.GITHUB_TOKEN) return 'GITHUB_TOKEN';
|
|
84
|
+
return CODEX_MCP_BEARER_TOKEN_ENV;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function warnIfCodexBearerEnvMissing(envVar, silent = false) {
|
|
88
|
+
if (silent || process.env[envVar]) return;
|
|
89
|
+
fmt.logWarn(`Codex MCP auth expects ${envVar} in the Codex environment.`);
|
|
90
|
+
fmt.logWarn(` Fix: export ${envVar}=<token> and restart Codex.`);
|
|
91
|
+
}
|
|
92
|
+
|
|
80
93
|
/**
|
|
81
94
|
* Resolve GitHub token for MCP auth. Zero manual steps.
|
|
82
95
|
*
|
|
@@ -186,7 +199,7 @@ function findExistingClickUpToken() {
|
|
|
186
199
|
} catch { /* corrupt file — skip */ }
|
|
187
200
|
}
|
|
188
201
|
|
|
189
|
-
// TOML
|
|
202
|
+
// Legacy Codex TOML may still carry a ClickUp token in the old headers section.
|
|
190
203
|
const codexToml = join(HOME, '.codex', 'config.toml');
|
|
191
204
|
if (existsSync(codexToml)) {
|
|
192
205
|
try {
|
|
@@ -356,6 +369,11 @@ export async function setupMcp(cwd, namespace, { silent = false } = {}) {
|
|
|
356
369
|
url: mcpUrl,
|
|
357
370
|
headers,
|
|
358
371
|
};
|
|
372
|
+
const ghlAiServerCodex = {
|
|
373
|
+
url: mcpUrl,
|
|
374
|
+
bearer_token_env_var: resolveCodexBearerTokenEnvVar(),
|
|
375
|
+
};
|
|
376
|
+
warnIfCodexBearerEnvMissing(ghlAiServerCodex.bearer_token_env_var, silent);
|
|
359
377
|
|
|
360
378
|
// ── Claude Code: ~/.claude.json (global) ──
|
|
361
379
|
const claudeJsonPath = join(HOME, '.claude.json');
|
|
@@ -375,11 +393,11 @@ export async function setupMcp(cwd, namespace, { silent = false } = {}) {
|
|
|
375
393
|
// survives — without this, each re-init overwrites ~/.codex/config.toml
|
|
376
394
|
// from the ECC source which doesn't have the ghl-ai block.
|
|
377
395
|
const codexTomlPath = join(HOME, '.codex', 'config.toml');
|
|
378
|
-
if (mergeTomlMcpServer(codexTomlPath, MCP_SERVER_NAME,
|
|
396
|
+
if (mergeTomlMcpServer(codexTomlPath, MCP_SERVER_NAME, ghlAiServerCodex)) {
|
|
379
397
|
updatedFiles.push(codexTomlPath);
|
|
380
398
|
}
|
|
381
399
|
const eccCodexTomlPath = join(HOME, '.aw-ecc', '.codex', 'config.toml');
|
|
382
|
-
mergeTomlMcpServer(eccCodexTomlPath, MCP_SERVER_NAME,
|
|
400
|
+
mergeTomlMcpServer(eccCodexTomlPath, MCP_SERVER_NAME, ghlAiServerCodex);
|
|
383
401
|
|
|
384
402
|
// Deduplicate
|
|
385
403
|
const unique = [...new Set(updatedFiles)];
|
|
@@ -454,7 +472,7 @@ function tomlMcpHealth(filePath) {
|
|
|
454
472
|
path: filePath,
|
|
455
473
|
present: new RegExp(`\\[mcp_servers\\.${MCP_SERVER_NAME}\\]`).test(content),
|
|
456
474
|
url: new RegExp(`\\[mcp_servers\\.${MCP_SERVER_NAME}\\][\\s\\S]*?url\\s*=\\s*"https?:\\/\\/[^"]+"`).test(content),
|
|
457
|
-
authorization: new RegExp(`\\[mcp_servers\\.${MCP_SERVER_NAME}
|
|
475
|
+
authorization: new RegExp(`\\[mcp_servers\\.${MCP_SERVER_NAME}\\][\\s\\S]*?bearer_token_env_var\\s*=\\s*".+"`).test(content),
|
|
458
476
|
};
|
|
459
477
|
} catch {
|
|
460
478
|
// Unreadable TOML should behave like an absent optional MCP config.
|
|
@@ -510,6 +528,9 @@ function tomlMcpServerBlock(serverName, serverConfig) {
|
|
|
510
528
|
if (serverConfig.args) {
|
|
511
529
|
block += `args = [${serverConfig.args.map((a) => JSON.stringify(a)).join(', ')}]\n`;
|
|
512
530
|
}
|
|
531
|
+
if (serverConfig.bearer_token_env_var) {
|
|
532
|
+
block += `bearer_token_env_var = ${JSON.stringify(serverConfig.bearer_token_env_var)}\n`;
|
|
533
|
+
}
|
|
513
534
|
block += `startup_timeout_sec = 30\n`;
|
|
514
535
|
if (serverConfig.headers && Object.keys(serverConfig.headers).length > 0) {
|
|
515
536
|
block += `\n[mcp_servers.${serverName}.headers]\n`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ghl-ai/aw",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Agentic Workspace CLI
|
|
3
|
+
"version": "0.1.73-beta.0",
|
|
4
|
+
"description": "Agentic Workspace CLI \u2014 pull, push & manage agents, skills and commands from the registry",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"aw": "bin.js"
|
|
@@ -74,4 +74,4 @@
|
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"vitest": "^4.1.2"
|
|
76
76
|
}
|
|
77
|
-
}
|
|
77
|
+
}
|