@agentuity/cli 0.0.79 → 0.0.80
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/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +112 -15
- package/dist/cmd/build/ast.js.map +1 -1
- package/dist/cmd/build/bundler.d.ts +3 -1
- package/dist/cmd/build/bundler.d.ts.map +1 -1
- package/dist/cmd/build/bundler.js +11 -9
- package/dist/cmd/build/bundler.js.map +1 -1
- package/dist/cmd/build/index.d.ts.map +1 -1
- package/dist/cmd/build/index.js +5 -2
- package/dist/cmd/build/index.js.map +1 -1
- package/dist/cmd/build/{workbench-templates.d.ts → workbench.d.ts} +3 -1
- package/dist/cmd/build/workbench.d.ts.map +1 -0
- package/dist/cmd/build/{workbench-templates.js → workbench.js} +13 -1
- package/dist/cmd/build/workbench.js.map +1 -0
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +11 -2
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.js +13 -2
- package/dist/cmd/project/template-flow.js.map +1 -1
- package/dist/sound.d.ts.map +1 -1
- package/dist/sound.js +1 -16
- package/dist/sound.js.map +1 -1
- package/package.json +5 -4
- package/src/cmd/build/ast.ts +183 -41
- package/src/cmd/build/bundler.ts +13 -9
- package/src/cmd/build/index.ts +5 -2
- package/src/cmd/build/{workbench-templates.ts → workbench.ts} +13 -0
- package/src/cmd/dev/index.ts +13 -2
- package/src/cmd/project/template-flow.ts +14 -2
- package/src/sound.ts +1 -17
- package/dist/cmd/build/workbench-templates.d.ts.map +0 -1
- package/dist/cmd/build/workbench-templates.js.map +0 -1
package/src/cmd/build/ast.ts
CHANGED
|
@@ -366,10 +366,12 @@ function injectEvalMetadata(
|
|
|
366
366
|
configObj.properties.push(metadataObj);
|
|
367
367
|
}
|
|
368
368
|
|
|
369
|
-
function findAgentVariableAndImport(
|
|
369
|
+
function findAgentVariableAndImport(
|
|
370
|
+
ast: ASTProgram
|
|
371
|
+
): { varName: string; importPath: string } | undefined {
|
|
370
372
|
// First, find what variable is being used in agent.createEval() calls
|
|
371
373
|
let agentVarName: string | undefined;
|
|
372
|
-
|
|
374
|
+
|
|
373
375
|
for (const node of ast.body) {
|
|
374
376
|
if (node.type === 'ExportNamedDeclaration') {
|
|
375
377
|
const exportDecl = node as {
|
|
@@ -379,9 +381,12 @@ function findAgentVariableAndImport(ast: ASTProgram): { varName: string; importP
|
|
|
379
381
|
const variableDeclaration = exportDecl.declaration as {
|
|
380
382
|
declarations: Array<ASTVariableDeclarator>;
|
|
381
383
|
};
|
|
382
|
-
|
|
384
|
+
|
|
383
385
|
for (const vardecl of variableDeclaration.declarations) {
|
|
384
|
-
if (
|
|
386
|
+
if (
|
|
387
|
+
vardecl.type === 'VariableDeclarator' &&
|
|
388
|
+
vardecl.init?.type === 'CallExpression'
|
|
389
|
+
) {
|
|
385
390
|
const call = vardecl.init as ASTCallExpression;
|
|
386
391
|
if (call.callee.type === 'MemberExpression') {
|
|
387
392
|
const memberExpr = call.callee as ASTMemberExpression;
|
|
@@ -402,9 +407,9 @@ function findAgentVariableAndImport(ast: ASTProgram): { varName: string; importP
|
|
|
402
407
|
}
|
|
403
408
|
}
|
|
404
409
|
}
|
|
405
|
-
|
|
410
|
+
|
|
406
411
|
if (!agentVarName) return undefined;
|
|
407
|
-
|
|
412
|
+
|
|
408
413
|
// Now find the import for this variable
|
|
409
414
|
for (const node of ast.body) {
|
|
410
415
|
if (node.type === 'ImportDeclaration') {
|
|
@@ -415,7 +420,7 @@ function findAgentVariableAndImport(ast: ASTProgram): { varName: string; importP
|
|
|
415
420
|
local: ASTNodeIdentifier;
|
|
416
421
|
}>;
|
|
417
422
|
};
|
|
418
|
-
|
|
423
|
+
|
|
419
424
|
// Find default import specifier that matches our variable
|
|
420
425
|
for (const spec of importDecl.specifiers) {
|
|
421
426
|
if (spec.type === 'ImportDefaultSpecifier' && spec.local.name === agentVarName) {
|
|
@@ -427,7 +432,7 @@ function findAgentVariableAndImport(ast: ASTProgram): { varName: string; importP
|
|
|
427
432
|
}
|
|
428
433
|
}
|
|
429
434
|
}
|
|
430
|
-
|
|
435
|
+
|
|
431
436
|
return undefined;
|
|
432
437
|
}
|
|
433
438
|
|
|
@@ -439,17 +444,19 @@ export async function parseEvalMetadata(
|
|
|
439
444
|
deploymentId: string,
|
|
440
445
|
agentId?: string,
|
|
441
446
|
agentMetadata?: Map<string, Map<string, string>>
|
|
442
|
-
): Promise<
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
447
|
+
): Promise<
|
|
448
|
+
[
|
|
449
|
+
string,
|
|
450
|
+
Array<{
|
|
451
|
+
filename: string;
|
|
452
|
+
id: string;
|
|
453
|
+
version: string;
|
|
454
|
+
name: string;
|
|
455
|
+
evalId: string;
|
|
456
|
+
description?: string;
|
|
457
|
+
}>,
|
|
458
|
+
]
|
|
459
|
+
> {
|
|
453
460
|
const logLevel = (process.env.AGENTUITY_LOG_LEVEL || 'info') as
|
|
454
461
|
| 'trace'
|
|
455
462
|
| 'debug'
|
|
@@ -479,8 +486,10 @@ export async function parseEvalMetadata(
|
|
|
479
486
|
if (!resolvedAgentId && agentMetadata) {
|
|
480
487
|
const agentInfo = findAgentVariableAndImport(ast);
|
|
481
488
|
if (agentInfo) {
|
|
482
|
-
logger.trace(
|
|
483
|
-
|
|
489
|
+
logger.trace(
|
|
490
|
+
`[EVAL METADATA] Found agent variable '${agentInfo.varName}' imported from '${agentInfo.importPath}'`
|
|
491
|
+
);
|
|
492
|
+
|
|
484
493
|
// Resolve the import path to actual file path
|
|
485
494
|
let resolvedPath = agentInfo.importPath;
|
|
486
495
|
if (resolvedPath.startsWith('./') || resolvedPath.startsWith('../')) {
|
|
@@ -492,19 +501,23 @@ export async function parseEvalMetadata(
|
|
|
492
501
|
resolvedPath += '.ts';
|
|
493
502
|
}
|
|
494
503
|
}
|
|
495
|
-
|
|
504
|
+
|
|
496
505
|
// Find the agent metadata from the passed agentMetadata map
|
|
497
506
|
for (const [agentFile, metadata] of agentMetadata) {
|
|
498
507
|
// Check if this agent file matches the resolved import path
|
|
499
508
|
if (agentFile.includes(basename(resolvedPath)) && metadata.has('agentId')) {
|
|
500
509
|
resolvedAgentId = metadata.get('agentId');
|
|
501
|
-
logger.trace(
|
|
510
|
+
logger.trace(
|
|
511
|
+
`[EVAL METADATA] Resolved agentId from agent metadata: ${resolvedAgentId} (file: ${agentFile})`
|
|
512
|
+
);
|
|
502
513
|
break;
|
|
503
514
|
}
|
|
504
515
|
}
|
|
505
|
-
|
|
516
|
+
|
|
506
517
|
if (!resolvedAgentId) {
|
|
507
|
-
logger.warn(
|
|
518
|
+
logger.warn(
|
|
519
|
+
`[EVAL METADATA] Could not find agent metadata for import path: ${resolvedPath}`
|
|
520
|
+
);
|
|
508
521
|
}
|
|
509
522
|
}
|
|
510
523
|
}
|
|
@@ -600,7 +613,14 @@ export async function parseEvalMetadata(
|
|
|
600
613
|
|
|
601
614
|
// Inject eval metadata into the AST (same pattern as agents)
|
|
602
615
|
if (configObj) {
|
|
603
|
-
injectEvalMetadata(
|
|
616
|
+
injectEvalMetadata(
|
|
617
|
+
configObj,
|
|
618
|
+
evalId,
|
|
619
|
+
stableEvalId,
|
|
620
|
+
version,
|
|
621
|
+
rel,
|
|
622
|
+
resolvedAgentId
|
|
623
|
+
);
|
|
604
624
|
}
|
|
605
625
|
|
|
606
626
|
evals.push({
|
|
@@ -1919,11 +1939,17 @@ export * from '${runtimeImportPath}/src/index';
|
|
|
1919
1939
|
*/
|
|
1920
1940
|
export function analyzeWorkbench(content: string): WorkbenchAnalysis {
|
|
1921
1941
|
try {
|
|
1942
|
+
if (!content.includes('@agentuity/workbench')) {
|
|
1943
|
+
return {
|
|
1944
|
+
hasWorkbench: false,
|
|
1945
|
+
config: null,
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1922
1948
|
const sourceFile = ts.createSourceFile('app.ts', content, ts.ScriptTarget.Latest, true);
|
|
1923
1949
|
|
|
1924
1950
|
let hasImport = false;
|
|
1925
|
-
|
|
1926
|
-
let
|
|
1951
|
+
const workbenchVariables = new Map<string, WorkbenchConfig>();
|
|
1952
|
+
let usedInServices = false;
|
|
1927
1953
|
|
|
1928
1954
|
function visitNode(node: ts.Node): void {
|
|
1929
1955
|
// Check for import declarations with createWorkbench
|
|
@@ -1937,18 +1963,55 @@ export function analyzeWorkbench(content: string): WorkbenchAnalysis {
|
|
|
1937
1963
|
}
|
|
1938
1964
|
}
|
|
1939
1965
|
|
|
1940
|
-
//
|
|
1941
|
-
if (
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1966
|
+
// Track variables assigned from createWorkbench() calls
|
|
1967
|
+
if (
|
|
1968
|
+
ts.isVariableDeclaration(node) &&
|
|
1969
|
+
node.initializer &&
|
|
1970
|
+
ts.isCallExpression(node.initializer) &&
|
|
1971
|
+
ts.isIdentifier(node.initializer.expression) &&
|
|
1972
|
+
node.initializer.expression.text === 'createWorkbench'
|
|
1973
|
+
) {
|
|
1974
|
+
// Extract variable name
|
|
1975
|
+
if (ts.isIdentifier(node.name)) {
|
|
1945
1976
|
// Extract configuration from the first argument (if any)
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1977
|
+
let varConfig: WorkbenchConfig;
|
|
1978
|
+
if (node.initializer.arguments.length > 0) {
|
|
1979
|
+
const configArg = node.initializer.arguments[0];
|
|
1980
|
+
varConfig = parseConfigObject(configArg) || { route: '/workbench' };
|
|
1949
1981
|
} else {
|
|
1950
1982
|
// Default config if no arguments provided
|
|
1951
|
-
|
|
1983
|
+
varConfig = { route: '/workbench' };
|
|
1984
|
+
}
|
|
1985
|
+
workbenchVariables.set(node.name.text, varConfig);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
// Check if workbench variable is used in createApp's services config
|
|
1990
|
+
if (
|
|
1991
|
+
ts.isCallExpression(node) &&
|
|
1992
|
+
ts.isIdentifier(node.expression) &&
|
|
1993
|
+
node.expression.text === 'createApp' &&
|
|
1994
|
+
node.arguments.length > 0
|
|
1995
|
+
) {
|
|
1996
|
+
const configArg = node.arguments[0];
|
|
1997
|
+
if (ts.isObjectLiteralExpression(configArg)) {
|
|
1998
|
+
// Find the services property
|
|
1999
|
+
for (const prop of configArg.properties) {
|
|
2000
|
+
if (
|
|
2001
|
+
ts.isPropertyAssignment(prop) &&
|
|
2002
|
+
ts.isIdentifier(prop.name) &&
|
|
2003
|
+
prop.name.text === 'services'
|
|
2004
|
+
) {
|
|
2005
|
+
// Check if any workbench variable is referenced in services
|
|
2006
|
+
const foundVariableName = checkForWorkbenchUsage(
|
|
2007
|
+
prop.initializer,
|
|
2008
|
+
workbenchVariables
|
|
2009
|
+
);
|
|
2010
|
+
if (foundVariableName) {
|
|
2011
|
+
usedInServices = true;
|
|
2012
|
+
}
|
|
2013
|
+
break;
|
|
2014
|
+
}
|
|
1952
2015
|
}
|
|
1953
2016
|
}
|
|
1954
2017
|
}
|
|
@@ -1957,15 +2020,94 @@ export function analyzeWorkbench(content: string): WorkbenchAnalysis {
|
|
|
1957
2020
|
ts.forEachChild(node, visitNode);
|
|
1958
2021
|
}
|
|
1959
2022
|
|
|
2023
|
+
// Helper function to check if workbench variable is used in services config
|
|
2024
|
+
// Returns the variable name if found, otherwise null
|
|
2025
|
+
function checkForWorkbenchUsage(
|
|
2026
|
+
node: ts.Node,
|
|
2027
|
+
variables: Map<string, WorkbenchConfig>
|
|
2028
|
+
): string | null {
|
|
2029
|
+
let foundVar: string | null = null;
|
|
2030
|
+
|
|
2031
|
+
function visit(n: ts.Node): void {
|
|
2032
|
+
if (foundVar) return; // Already found
|
|
2033
|
+
|
|
2034
|
+
// Check for identifier references
|
|
2035
|
+
if (ts.isIdentifier(n) && variables.has(n.text)) {
|
|
2036
|
+
foundVar = n.text;
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2040
|
+
// Check for property shorthand: { workbench } in services
|
|
2041
|
+
if (ts.isShorthandPropertyAssignment(n) && variables.has(n.name.text)) {
|
|
2042
|
+
foundVar = n.name.text;
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
// Check for property value: { workbench: workbench } in services
|
|
2047
|
+
if (
|
|
2048
|
+
ts.isPropertyAssignment(n) &&
|
|
2049
|
+
n.initializer &&
|
|
2050
|
+
ts.isIdentifier(n.initializer) &&
|
|
2051
|
+
variables.has(n.initializer.text)
|
|
2052
|
+
) {
|
|
2053
|
+
foundVar = n.initializer.text;
|
|
2054
|
+
return;
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
ts.forEachChild(n, visit);
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
visit(node);
|
|
2061
|
+
return foundVar;
|
|
2062
|
+
}
|
|
2063
|
+
|
|
1960
2064
|
visitNode(sourceFile);
|
|
1961
2065
|
|
|
1962
|
-
//
|
|
1963
|
-
|
|
1964
|
-
|
|
2066
|
+
// Get the config from the first used workbench variable
|
|
2067
|
+
let config: WorkbenchConfig | null = null;
|
|
2068
|
+
if (hasImport && usedInServices) {
|
|
2069
|
+
// Re-check which variable was used
|
|
2070
|
+
const ast = sourceFile;
|
|
2071
|
+
for (const [varName, varConfig] of workbenchVariables.entries()) {
|
|
2072
|
+
// Simple check: walk through and find if this variable is used in services
|
|
2073
|
+
let used = false;
|
|
2074
|
+
function checkUsage(node: ts.Node): void {
|
|
2075
|
+
if (
|
|
2076
|
+
ts.isCallExpression(node) &&
|
|
2077
|
+
ts.isIdentifier(node.expression) &&
|
|
2078
|
+
node.expression.text === 'createApp' &&
|
|
2079
|
+
node.arguments.length > 0
|
|
2080
|
+
) {
|
|
2081
|
+
const configArg = node.arguments[0];
|
|
2082
|
+
if (ts.isObjectLiteralExpression(configArg)) {
|
|
2083
|
+
for (const prop of configArg.properties) {
|
|
2084
|
+
if (
|
|
2085
|
+
ts.isPropertyAssignment(prop) &&
|
|
2086
|
+
ts.isIdentifier(prop.name) &&
|
|
2087
|
+
prop.name.text === 'services'
|
|
2088
|
+
) {
|
|
2089
|
+
const foundVar = checkForWorkbenchUsage(
|
|
2090
|
+
prop.initializer,
|
|
2091
|
+
workbenchVariables
|
|
2092
|
+
);
|
|
2093
|
+
if (foundVar === varName) {
|
|
2094
|
+
used = true;
|
|
2095
|
+
config = varConfig;
|
|
2096
|
+
}
|
|
2097
|
+
break;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
ts.forEachChild(node, checkUsage);
|
|
2103
|
+
}
|
|
2104
|
+
checkUsage(ast);
|
|
2105
|
+
if (used) break;
|
|
2106
|
+
}
|
|
1965
2107
|
}
|
|
1966
2108
|
|
|
1967
2109
|
return {
|
|
1968
|
-
hasWorkbench: hasImport &&
|
|
2110
|
+
hasWorkbench: hasImport && usedInServices,
|
|
1969
2111
|
config: config,
|
|
1970
2112
|
};
|
|
1971
2113
|
} catch (error) {
|
package/src/cmd/build/bundler.ts
CHANGED
|
@@ -11,8 +11,8 @@ import { getVersion } from '../../version';
|
|
|
11
11
|
import type { Project } from '../../types';
|
|
12
12
|
import { fixDuplicateExportsInDirectory } from './fix-duplicate-exports';
|
|
13
13
|
import type { Logger } from '../../types';
|
|
14
|
-
import { generateWorkbenchMainTsx, generateWorkbenchIndexHtml } from './workbench
|
|
15
|
-
import { analyzeWorkbench } from './ast';
|
|
14
|
+
import { generateWorkbenchMainTsx, generateWorkbenchIndexHtml } from './workbench';
|
|
15
|
+
import { analyzeWorkbench, type WorkbenchAnalysis } from './ast';
|
|
16
16
|
import { type DeployOptions } from '../../schemas/deploy';
|
|
17
17
|
|
|
18
18
|
const minBunVersion = '>=1.3.3';
|
|
@@ -64,6 +64,7 @@ export interface BundleOptions extends DeployOptions {
|
|
|
64
64
|
outDir?: string;
|
|
65
65
|
region: string;
|
|
66
66
|
logger: Logger;
|
|
67
|
+
workbench?: WorkbenchAnalysis;
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
type BuildResult = Awaited<ReturnType<typeof Bun.build>>;
|
|
@@ -116,6 +117,7 @@ export async function bundle({
|
|
|
116
117
|
env,
|
|
117
118
|
region,
|
|
118
119
|
logger,
|
|
120
|
+
workbench,
|
|
119
121
|
}: BundleOptions): Promise<{ output: string[] }> {
|
|
120
122
|
const output: string[] = [];
|
|
121
123
|
|
|
@@ -467,13 +469,15 @@ export async function bundle({
|
|
|
467
469
|
|
|
468
470
|
// Bundle workbench app if detected via setupWorkbench
|
|
469
471
|
if (existsSync(appFile)) {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
+
if (!workbench) {
|
|
473
|
+
const appContent = await Bun.file(appFile).text();
|
|
474
|
+
workbench = analyzeWorkbench(appContent);
|
|
475
|
+
}
|
|
472
476
|
|
|
473
|
-
if (
|
|
477
|
+
if (workbench.hasWorkbench) {
|
|
474
478
|
// Create workbench config with proper defaults
|
|
475
479
|
const defaultConfig = { route: '/workbench', headers: {}, port: port || 3500 };
|
|
476
|
-
const config = { ...defaultConfig, ...
|
|
480
|
+
const config = { ...defaultConfig, ...workbench.config };
|
|
477
481
|
try {
|
|
478
482
|
// Generate workbench files on the fly instead of using files from package
|
|
479
483
|
const tempWorkbenchDir = join(outDir, 'temp-workbench');
|
|
@@ -485,7 +489,7 @@ export async function bundle({
|
|
|
485
489
|
await Bun.write(workbenchIndexFile, generateWorkbenchIndexHtml());
|
|
486
490
|
|
|
487
491
|
// Bundle workbench using generated files
|
|
488
|
-
//
|
|
492
|
+
// Disable splitting to avoid CommonJS/ESM module resolution conflicts
|
|
489
493
|
const workbenchBuildConfig: Bun.BuildConfig = {
|
|
490
494
|
entrypoints: [workbenchIndexFile],
|
|
491
495
|
outdir: join(outDir, 'workbench'),
|
|
@@ -493,9 +497,9 @@ export async function bundle({
|
|
|
493
497
|
target: 'browser',
|
|
494
498
|
format: 'esm',
|
|
495
499
|
banner: `// Generated file. DO NOT EDIT`,
|
|
496
|
-
minify:
|
|
500
|
+
minify: !dev,
|
|
497
501
|
drop: isProd ? ['debugger'] : undefined,
|
|
498
|
-
splitting:
|
|
502
|
+
splitting: false,
|
|
499
503
|
packages: 'bundle',
|
|
500
504
|
conditions: ['browser', 'import', 'default'],
|
|
501
505
|
naming: {
|
package/src/cmd/build/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { resolve, join } from 'node:path';
|
|
2
|
+
import { resolve, join, relative } from 'node:path';
|
|
3
3
|
import { getServiceUrls } from '@agentuity/server';
|
|
4
4
|
import { createCommand } from '../../types';
|
|
5
5
|
import { bundle } from './bundler';
|
|
@@ -47,7 +47,10 @@ export const command = createCommand({
|
|
|
47
47
|
const outDir = opts.outdir ? resolve(opts.outdir) : join(absoluteProjectDir, '.agentuity');
|
|
48
48
|
|
|
49
49
|
try {
|
|
50
|
-
|
|
50
|
+
const rel = outDir.startsWith(absoluteProjectDir)
|
|
51
|
+
? relative(absoluteProjectDir, outDir)
|
|
52
|
+
: outDir;
|
|
53
|
+
tui.info(`Bundling project at ${absoluteProjectDir} to ${rel}`);
|
|
51
54
|
|
|
52
55
|
const env: Map<string, string> = new Map();
|
|
53
56
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
1
2
|
import { encodeWorkbenchConfig, type WorkbenchConfig } from '@agentuity/core';
|
|
3
|
+
import { analyzeWorkbench, WorkbenchAnalysis } from './ast';
|
|
2
4
|
|
|
3
5
|
export function generateWorkbenchMainTsx(config: WorkbenchConfig): string {
|
|
4
6
|
const encodedConfig = encodeWorkbenchConfig(config);
|
|
@@ -35,3 +37,14 @@ export function generateWorkbenchIndexHtml(): string {
|
|
|
35
37
|
</body>
|
|
36
38
|
</html>`;
|
|
37
39
|
}
|
|
40
|
+
|
|
41
|
+
export async function getWorkbench(dir: string): Promise<WorkbenchAnalysis> {
|
|
42
|
+
const appFile = Bun.file(join(dir, 'app.ts'));
|
|
43
|
+
if (await appFile.exists()) {
|
|
44
|
+
return analyzeWorkbench(await appFile.text());
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
hasWorkbench: false,
|
|
48
|
+
config: null,
|
|
49
|
+
};
|
|
50
|
+
}
|
package/src/cmd/dev/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { APIClient, getAPIBaseURL, getGravityDevModeURL } from '../../api';
|
|
|
20
20
|
import { download } from './download';
|
|
21
21
|
import { createDevmodeSyncService } from './sync';
|
|
22
22
|
import { getDevmodeDeploymentId } from '../build/ast';
|
|
23
|
+
import { getWorkbench } from '../build/workbench';
|
|
23
24
|
import { BuildMetadata } from '@agentuity/server';
|
|
24
25
|
import { getCommand } from '../../command-prefix';
|
|
25
26
|
import { notifyWorkbenchClients } from '../../utils/workbench-notify';
|
|
@@ -159,16 +160,25 @@ export const command = createCommand({
|
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
|
|
163
|
+
const workbench = await getWorkbench(rootDir);
|
|
164
|
+
|
|
162
165
|
const canDoInput =
|
|
163
166
|
interactive && !!(process.stdin.isTTY && process.stdout.isTTY && !process.env.CI);
|
|
164
167
|
|
|
168
|
+
const padding = 12;
|
|
169
|
+
|
|
165
170
|
const devmodebody =
|
|
166
|
-
tui.muted(tui.padRight('Local:',
|
|
171
|
+
tui.muted(tui.padRight('Local:', padding)) +
|
|
167
172
|
tui.link(`http://127.0.0.1:${opts.port}`) +
|
|
168
173
|
'\n' +
|
|
169
|
-
tui.muted(tui.padRight('Public:',
|
|
174
|
+
tui.muted(tui.padRight('Public:', padding)) +
|
|
170
175
|
(devmode?.hostname ? tui.link(`https://${devmode.hostname}`) : tui.warn('Disabled')) +
|
|
171
176
|
'\n' +
|
|
177
|
+
tui.muted(tui.padRight('Workbench:', padding)) +
|
|
178
|
+
(workbench.hasWorkbench
|
|
179
|
+
? tui.link(`http://127.0.0.1:${opts.port}${workbench.config?.route ?? '/workbench'}`)
|
|
180
|
+
: tui.warn('Disabled')) +
|
|
181
|
+
'\n' +
|
|
172
182
|
(canDoInput
|
|
173
183
|
? '\n' + tui.muted('Press ') + tui.bold('h') + tui.muted(' for keyboard shortcuts')
|
|
174
184
|
: '');
|
|
@@ -520,6 +530,7 @@ export const command = createCommand({
|
|
|
520
530
|
port: opts.port,
|
|
521
531
|
region: project?.region ?? 'local',
|
|
522
532
|
logger,
|
|
533
|
+
workbench,
|
|
523
534
|
});
|
|
524
535
|
building = false;
|
|
525
536
|
buildCompletedAt = Date.now();
|
|
@@ -190,12 +190,24 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<void> {
|
|
|
190
190
|
} else if (skipPrompts) {
|
|
191
191
|
selectedTemplate = templates[0];
|
|
192
192
|
} else {
|
|
193
|
+
let maxLength = 15;
|
|
194
|
+
templates.forEach((t) => {
|
|
195
|
+
if (maxLength < t.name.length) {
|
|
196
|
+
maxLength = t.name.length;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
maxLength = Math.min(maxLength + 1, 40);
|
|
200
|
+
const [_winWidth] = process.stdout.getWindowSize();
|
|
201
|
+
const winWidth = _winWidth - maxLength - 8; // space for the name and left indent
|
|
193
202
|
const templateId = await prompt.select({
|
|
194
203
|
message: 'Select a template:',
|
|
195
204
|
options: templates.map((t) => ({
|
|
196
205
|
value: t.id,
|
|
197
|
-
label: t.name,
|
|
198
|
-
hint:
|
|
206
|
+
label: t.name.padEnd(maxLength),
|
|
207
|
+
hint:
|
|
208
|
+
t.description.length > winWidth
|
|
209
|
+
? t.description.substring(0, winWidth - 3) + '...'
|
|
210
|
+
: t.description,
|
|
199
211
|
})),
|
|
200
212
|
});
|
|
201
213
|
const found = templates.find((t) => t.id === templateId);
|
package/src/sound.ts
CHANGED
|
@@ -1,26 +1,10 @@
|
|
|
1
|
-
import { join } from 'node:path';
|
|
2
|
-
|
|
3
1
|
export function playSound(): void {
|
|
4
2
|
const platform = process.platform;
|
|
5
3
|
|
|
6
4
|
let command: string[];
|
|
7
5
|
switch (platform) {
|
|
8
6
|
case 'darwin': {
|
|
9
|
-
|
|
10
|
-
'Blow.aiff',
|
|
11
|
-
'Bottle.aiff',
|
|
12
|
-
'Frog.aiff',
|
|
13
|
-
'Funk.aiff',
|
|
14
|
-
'Glass.aiff',
|
|
15
|
-
'Hero.aiff',
|
|
16
|
-
'Morse.aiff',
|
|
17
|
-
'Ping.aiff',
|
|
18
|
-
'Pop.aiff',
|
|
19
|
-
'Purr.aiff',
|
|
20
|
-
'Sosumi.aiff',
|
|
21
|
-
] as const;
|
|
22
|
-
const file = items[Math.floor(Math.random() * items.length)];
|
|
23
|
-
command = ['afplay', join('/System/Library/Sounds', file)];
|
|
7
|
+
command = ['afplay', '/System/Library/Sounds/Blow.aiff'];
|
|
24
8
|
break;
|
|
25
9
|
}
|
|
26
10
|
case 'linux':
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workbench-templates.d.ts","sourceRoot":"","sources":["../../../src/cmd/build/workbench-templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE9E,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAmBxE;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CAanD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workbench-templates.js","sourceRoot":"","sources":["../../../src/cmd/build/workbench-templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAwB,MAAM,iBAAiB,CAAC;AAE9E,MAAM,UAAU,wBAAwB,CAAC,MAAuB;IAC/D,MAAM,aAAa,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACpD,OAAO;;;;;;;;;;;;;;gCAcwB,aAAa;iCACZ,aAAa;CAC7C,CAAC;AACF,CAAC;AAED,MAAM,UAAU,0BAA0B;IACzC,OAAO;;;;;;;;;;;QAWA,CAAC;AACT,CAAC"}
|