agdi 3.3.7 → 3.3.8
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/index.js +875 -164
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import "./chunk-4VNS5WPM.js";
|
|
|
11
11
|
|
|
12
12
|
// src/index.ts
|
|
13
13
|
import { Command } from "commander";
|
|
14
|
-
import
|
|
14
|
+
import chalk21 from "chalk";
|
|
15
15
|
import ora7 from "ora";
|
|
16
16
|
|
|
17
17
|
// src/core/llm/index.ts
|
|
@@ -3527,80 +3527,80 @@ var TypeScriptParser = class extends CodeParser {
|
|
|
3527
3527
|
const dependencies = /* @__PURE__ */ new Set();
|
|
3528
3528
|
traverse(ast, {
|
|
3529
3529
|
// Functions
|
|
3530
|
-
FunctionDeclaration(
|
|
3531
|
-
if (
|
|
3530
|
+
FunctionDeclaration(path15) {
|
|
3531
|
+
if (path15.node.id) {
|
|
3532
3532
|
symbols.push({
|
|
3533
|
-
name:
|
|
3533
|
+
name: path15.node.id.name,
|
|
3534
3534
|
type: "function",
|
|
3535
|
-
line:
|
|
3536
|
-
endLine:
|
|
3537
|
-
signature: generateSignature(
|
|
3538
|
-
isExported: isExported(
|
|
3539
|
-
docstring: extractDocstring(
|
|
3535
|
+
line: path15.node.loc?.start.line || 0,
|
|
3536
|
+
endLine: path15.node.loc?.end.line,
|
|
3537
|
+
signature: generateSignature(path15.node),
|
|
3538
|
+
isExported: isExported(path15),
|
|
3539
|
+
docstring: extractDocstring(path15.node)
|
|
3540
3540
|
});
|
|
3541
3541
|
}
|
|
3542
3542
|
},
|
|
3543
3543
|
// Classes
|
|
3544
|
-
ClassDeclaration(
|
|
3545
|
-
if (
|
|
3544
|
+
ClassDeclaration(path15) {
|
|
3545
|
+
if (path15.node.id) {
|
|
3546
3546
|
symbols.push({
|
|
3547
|
-
name:
|
|
3547
|
+
name: path15.node.id.name,
|
|
3548
3548
|
type: "class",
|
|
3549
|
-
line:
|
|
3550
|
-
endLine:
|
|
3551
|
-
signature: `class ${
|
|
3552
|
-
isExported: isExported(
|
|
3553
|
-
docstring: extractDocstring(
|
|
3549
|
+
line: path15.node.loc?.start.line || 0,
|
|
3550
|
+
endLine: path15.node.loc?.end.line,
|
|
3551
|
+
signature: `class ${path15.node.id.name}`,
|
|
3552
|
+
isExported: isExported(path15),
|
|
3553
|
+
docstring: extractDocstring(path15.node)
|
|
3554
3554
|
});
|
|
3555
3555
|
}
|
|
3556
3556
|
},
|
|
3557
3557
|
// Variables (const/let/var)
|
|
3558
|
-
VariableDeclaration(
|
|
3559
|
-
|
|
3558
|
+
VariableDeclaration(path15) {
|
|
3559
|
+
path15.node.declarations.forEach((decl) => {
|
|
3560
3560
|
if (t.isIdentifier(decl.id)) {
|
|
3561
3561
|
symbols.push({
|
|
3562
3562
|
name: decl.id.name,
|
|
3563
3563
|
type: "variable",
|
|
3564
|
-
line:
|
|
3565
|
-
endLine:
|
|
3566
|
-
signature: `${
|
|
3567
|
-
isExported: isExported(
|
|
3568
|
-
docstring: extractDocstring(
|
|
3564
|
+
line: path15.node.loc?.start.line || 0,
|
|
3565
|
+
endLine: path15.node.loc?.end.line,
|
|
3566
|
+
signature: `${path15.node.kind} ${decl.id.name}`,
|
|
3567
|
+
isExported: isExported(path15),
|
|
3568
|
+
docstring: extractDocstring(path15.node)
|
|
3569
3569
|
});
|
|
3570
3570
|
}
|
|
3571
3571
|
});
|
|
3572
3572
|
},
|
|
3573
3573
|
// Interfaces
|
|
3574
|
-
TSInterfaceDeclaration(
|
|
3574
|
+
TSInterfaceDeclaration(path15) {
|
|
3575
3575
|
symbols.push({
|
|
3576
|
-
name:
|
|
3576
|
+
name: path15.node.id.name,
|
|
3577
3577
|
type: "interface",
|
|
3578
|
-
line:
|
|
3579
|
-
endLine:
|
|
3580
|
-
signature: `interface ${
|
|
3581
|
-
isExported: isExported(
|
|
3582
|
-
docstring: extractDocstring(
|
|
3578
|
+
line: path15.node.loc?.start.line || 0,
|
|
3579
|
+
endLine: path15.node.loc?.end.line,
|
|
3580
|
+
signature: `interface ${path15.node.id.name}`,
|
|
3581
|
+
isExported: isExported(path15),
|
|
3582
|
+
docstring: extractDocstring(path15.node)
|
|
3583
3583
|
});
|
|
3584
3584
|
},
|
|
3585
3585
|
// Types
|
|
3586
|
-
TSTypeAliasDeclaration(
|
|
3586
|
+
TSTypeAliasDeclaration(path15) {
|
|
3587
3587
|
symbols.push({
|
|
3588
|
-
name:
|
|
3588
|
+
name: path15.node.id.name,
|
|
3589
3589
|
type: "type",
|
|
3590
|
-
line:
|
|
3591
|
-
endLine:
|
|
3592
|
-
signature: `type ${
|
|
3593
|
-
isExported: isExported(
|
|
3594
|
-
docstring: extractDocstring(
|
|
3590
|
+
line: path15.node.loc?.start.line || 0,
|
|
3591
|
+
endLine: path15.node.loc?.end.line,
|
|
3592
|
+
signature: `type ${path15.node.id.name}`,
|
|
3593
|
+
isExported: isExported(path15),
|
|
3594
|
+
docstring: extractDocstring(path15.node)
|
|
3595
3595
|
});
|
|
3596
3596
|
},
|
|
3597
3597
|
// Imports
|
|
3598
|
-
ImportDeclaration(
|
|
3599
|
-
const source =
|
|
3598
|
+
ImportDeclaration(path15) {
|
|
3599
|
+
const source = path15.node.source.value;
|
|
3600
3600
|
dependencies.add(source);
|
|
3601
3601
|
const names = [];
|
|
3602
3602
|
let isDefault = false;
|
|
3603
|
-
|
|
3603
|
+
path15.node.specifiers.forEach((specifier) => {
|
|
3604
3604
|
if (t.isImportDefaultSpecifier(specifier)) {
|
|
3605
3605
|
isDefault = true;
|
|
3606
3606
|
names.push(specifier.local.name);
|
|
@@ -3618,34 +3618,34 @@ var TypeScriptParser = class extends CodeParser {
|
|
|
3618
3618
|
source,
|
|
3619
3619
|
names,
|
|
3620
3620
|
isDefault,
|
|
3621
|
-
line:
|
|
3621
|
+
line: path15.node.loc?.start.line || 0
|
|
3622
3622
|
});
|
|
3623
3623
|
},
|
|
3624
3624
|
// Exports
|
|
3625
|
-
ExportNamedDeclaration(
|
|
3626
|
-
if (
|
|
3625
|
+
ExportNamedDeclaration(path15) {
|
|
3626
|
+
if (path15.node.declaration) {
|
|
3627
3627
|
} else {
|
|
3628
|
-
|
|
3628
|
+
path15.node.specifiers.forEach((specifier) => {
|
|
3629
3629
|
exports.push({
|
|
3630
3630
|
name: specifier.exported.name,
|
|
3631
3631
|
type: "named",
|
|
3632
|
-
line:
|
|
3632
|
+
line: path15.node.loc?.start.line || 0
|
|
3633
3633
|
});
|
|
3634
3634
|
});
|
|
3635
3635
|
}
|
|
3636
|
-
if (
|
|
3637
|
-
dependencies.add(
|
|
3636
|
+
if (path15.node.source) {
|
|
3637
|
+
dependencies.add(path15.node.source.value);
|
|
3638
3638
|
}
|
|
3639
3639
|
},
|
|
3640
|
-
ExportDefaultDeclaration(
|
|
3640
|
+
ExportDefaultDeclaration(path15) {
|
|
3641
3641
|
let name = "default";
|
|
3642
|
-
if (
|
|
3643
|
-
name =
|
|
3642
|
+
if (path15.node.declaration && path15.node.declaration.id) {
|
|
3643
|
+
name = path15.node.declaration.id.name;
|
|
3644
3644
|
}
|
|
3645
3645
|
exports.push({
|
|
3646
3646
|
name,
|
|
3647
3647
|
type: "default",
|
|
3648
|
-
line:
|
|
3648
|
+
line: path15.node.loc?.start.line || 0
|
|
3649
3649
|
});
|
|
3650
3650
|
}
|
|
3651
3651
|
});
|
|
@@ -3682,8 +3682,8 @@ var TypeScriptParser = class extends CodeParser {
|
|
|
3682
3682
|
return ["ts", "tsx", "js", "jsx", "mjs", "cjs"];
|
|
3683
3683
|
}
|
|
3684
3684
|
};
|
|
3685
|
-
function isExported(
|
|
3686
|
-
return t.isExportDeclaration(
|
|
3685
|
+
function isExported(path15) {
|
|
3686
|
+
return t.isExportDeclaration(path15.parent) || t.isExportNamedDeclaration(path15.parent) || t.isExportDefaultDeclaration(path15.parent);
|
|
3687
3687
|
}
|
|
3688
3688
|
function extractDocstring(node) {
|
|
3689
3689
|
if (node.leadingComments && node.leadingComments.length > 0) {
|
|
@@ -3784,24 +3784,24 @@ var DependencyGraph = class {
|
|
|
3784
3784
|
const cycles = [];
|
|
3785
3785
|
const visited = /* @__PURE__ */ new Set();
|
|
3786
3786
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
3787
|
-
const
|
|
3787
|
+
const path15 = [];
|
|
3788
3788
|
const dfs = (file) => {
|
|
3789
3789
|
visited.add(file);
|
|
3790
3790
|
recursionStack.add(file);
|
|
3791
|
-
|
|
3791
|
+
path15.push(file);
|
|
3792
3792
|
const node = this.nodes.get(file);
|
|
3793
3793
|
if (node) {
|
|
3794
3794
|
for (const dep of node.imports) {
|
|
3795
3795
|
if (!visited.has(dep)) {
|
|
3796
3796
|
dfs(dep);
|
|
3797
3797
|
} else if (recursionStack.has(dep)) {
|
|
3798
|
-
const cycleStart =
|
|
3799
|
-
const cycle =
|
|
3798
|
+
const cycleStart = path15.indexOf(dep);
|
|
3799
|
+
const cycle = path15.slice(cycleStart);
|
|
3800
3800
|
cycles.push([...cycle, dep]);
|
|
3801
3801
|
}
|
|
3802
3802
|
}
|
|
3803
3803
|
}
|
|
3804
|
-
|
|
3804
|
+
path15.pop();
|
|
3805
3805
|
recursionStack.delete(file);
|
|
3806
3806
|
};
|
|
3807
3807
|
for (const file of this.nodes.keys()) {
|
|
@@ -3845,8 +3845,8 @@ var DependencyGraph = class {
|
|
|
3845
3845
|
/**
|
|
3846
3846
|
* Normalize path (remove .., etc.)
|
|
3847
3847
|
*/
|
|
3848
|
-
normalizePath(
|
|
3849
|
-
const parts =
|
|
3848
|
+
normalizePath(path15) {
|
|
3849
|
+
const parts = path15.split("/");
|
|
3850
3850
|
const result = [];
|
|
3851
3851
|
for (const part of parts) {
|
|
3852
3852
|
if (part === "..") {
|
|
@@ -4057,22 +4057,22 @@ var VectorStore = class {
|
|
|
4057
4057
|
/**
|
|
4058
4058
|
* Get stored hash for a file
|
|
4059
4059
|
*/
|
|
4060
|
-
async getFileHash(
|
|
4060
|
+
async getFileHash(path15) {
|
|
4061
4061
|
await this.initialize();
|
|
4062
4062
|
if (!this.db) return null;
|
|
4063
|
-
const row = this.db.prepare("SELECT hash FROM indexed_files WHERE path = ?").get(
|
|
4063
|
+
const row = this.db.prepare("SELECT hash FROM indexed_files WHERE path = ?").get(path15);
|
|
4064
4064
|
return row ? row.hash : null;
|
|
4065
4065
|
}
|
|
4066
4066
|
/**
|
|
4067
4067
|
* Set/Update hash for a file
|
|
4068
4068
|
*/
|
|
4069
|
-
async setFileHash(
|
|
4069
|
+
async setFileHash(path15, hash) {
|
|
4070
4070
|
await this.initialize();
|
|
4071
4071
|
if (!this.db) return;
|
|
4072
4072
|
this.db.prepare(`
|
|
4073
4073
|
INSERT OR REPLACE INTO indexed_files (path, hash, last_indexed)
|
|
4074
4074
|
VALUES (?, ?, ?)
|
|
4075
|
-
`).run(
|
|
4075
|
+
`).run(path15, hash, Date.now());
|
|
4076
4076
|
}
|
|
4077
4077
|
/**
|
|
4078
4078
|
* Add embeddings to store
|
|
@@ -5236,8 +5236,8 @@ function parseGitHubUrl(url) {
|
|
|
5236
5236
|
if (!cleanUrl.startsWith("github.com/")) {
|
|
5237
5237
|
throw new Error("Invalid GitHub URL. Please use format: https://github.com/owner/repo");
|
|
5238
5238
|
}
|
|
5239
|
-
const
|
|
5240
|
-
const parts =
|
|
5239
|
+
const path15 = cleanUrl.replace("github.com/", "");
|
|
5240
|
+
const parts = path15.split("/");
|
|
5241
5241
|
if (parts.length < 2) {
|
|
5242
5242
|
throw new Error("Invalid GitHub URL. Could not extract owner/repo.");
|
|
5243
5243
|
}
|
|
@@ -5662,7 +5662,38 @@ var FILE_COPY_TARGETS = [
|
|
|
5662
5662
|
{ source: "src/channels/allowlist-match.ts", target: "src/channels/allowlist-match.ts" },
|
|
5663
5663
|
{ source: "src/channels/channel-config.ts", target: "src/channels/channel-config.ts" }
|
|
5664
5664
|
];
|
|
5665
|
+
var ALL_DIRECTORY_COPY_TARGETS = [
|
|
5666
|
+
{ source: "dist", target: "dist" },
|
|
5667
|
+
{ source: "skills", target: "skills" },
|
|
5668
|
+
{ source: "extensions", target: "extensions" },
|
|
5669
|
+
{ source: "src", target: "src" },
|
|
5670
|
+
{ source: "scripts", target: "scripts" },
|
|
5671
|
+
{ source: "docs", target: "docs" },
|
|
5672
|
+
{ source: "test", target: "test" },
|
|
5673
|
+
{ source: "apps", target: "apps" },
|
|
5674
|
+
{ source: "assets", target: "assets" },
|
|
5675
|
+
{ source: "prisma", target: "prisma" },
|
|
5676
|
+
{ source: "ui", target: "ui" },
|
|
5677
|
+
{ source: "vendor", target: "vendor" },
|
|
5678
|
+
{ source: "website", target: "website" }
|
|
5679
|
+
];
|
|
5680
|
+
var ALL_FILE_COPY_TARGETS = [
|
|
5681
|
+
{ source: "agdi.mjs", target: "agdi.mjs" },
|
|
5682
|
+
{ source: "README.md", target: "README.md" },
|
|
5683
|
+
{ source: "LICENSE", target: "LICENSE" },
|
|
5684
|
+
{ source: "CHANGELOG.md", target: "CHANGELOG.md" },
|
|
5685
|
+
{ source: "SECURITY.md", target: "SECURITY.md" },
|
|
5686
|
+
{ source: "CONTRIBUTING.md", target: "CONTRIBUTING.md" },
|
|
5687
|
+
{ source: "pnpm-lock.yaml", target: "pnpm-lock.yaml" },
|
|
5688
|
+
{ source: "pnpm-workspace.yaml", target: "pnpm-workspace.yaml" },
|
|
5689
|
+
{ source: "tsconfig.json", target: "tsconfig.json" },
|
|
5690
|
+
{ source: "tsconfig.test.json", target: "tsconfig.test.json" },
|
|
5691
|
+
{ source: "vitest.config.ts", target: "vitest.config.ts" },
|
|
5692
|
+
{ source: "vitest.e2e.config.ts", target: "vitest.e2e.config.ts" },
|
|
5693
|
+
{ source: "vitest.unit.config.ts", target: "vitest.unit.config.ts" }
|
|
5694
|
+
];
|
|
5665
5695
|
var EXCLUDED_PATH_SEGMENTS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", ".next"]);
|
|
5696
|
+
var EXCLUDED_ALL_PATH_SEGMENTS = /* @__PURE__ */ new Set(["node_modules", ".git", ".next"]);
|
|
5666
5697
|
function shouldIncludePath(filePath) {
|
|
5667
5698
|
const normalized = filePath.replace(/\\/g, "/").toLowerCase();
|
|
5668
5699
|
const segments = normalized.split("/");
|
|
@@ -5691,6 +5722,68 @@ async function copyTargetPaths(sourceRepo, targetRoot) {
|
|
|
5691
5722
|
await fsExtra.copy(sourcePath, targetPath, { overwrite: true });
|
|
5692
5723
|
}
|
|
5693
5724
|
}
|
|
5725
|
+
function shouldIncludeAllPath(filePath) {
|
|
5726
|
+
const normalized = filePath.replace(/\\/g, "/").toLowerCase();
|
|
5727
|
+
const segments = normalized.split("/");
|
|
5728
|
+
return !segments.some((segment) => EXCLUDED_ALL_PATH_SEGMENTS.has(segment));
|
|
5729
|
+
}
|
|
5730
|
+
async function copyAllTargetPaths(sourceRepo, targetRoot) {
|
|
5731
|
+
for (const target of ALL_DIRECTORY_COPY_TARGETS) {
|
|
5732
|
+
const sourcePath = join6(sourceRepo, target.source);
|
|
5733
|
+
const targetPath = join6(targetRoot, target.target);
|
|
5734
|
+
if (!await fsExtra.pathExists(sourcePath)) {
|
|
5735
|
+
continue;
|
|
5736
|
+
}
|
|
5737
|
+
await fsExtra.ensureDir(targetPath);
|
|
5738
|
+
await fsExtra.copy(sourcePath, targetPath, {
|
|
5739
|
+
overwrite: true,
|
|
5740
|
+
filter: (source) => shouldIncludeAllPath(source)
|
|
5741
|
+
});
|
|
5742
|
+
}
|
|
5743
|
+
for (const target of ALL_FILE_COPY_TARGETS) {
|
|
5744
|
+
const sourcePath = join6(sourceRepo, target.source);
|
|
5745
|
+
const targetPath = join6(targetRoot, target.target);
|
|
5746
|
+
if (!await fsExtra.pathExists(sourcePath)) {
|
|
5747
|
+
continue;
|
|
5748
|
+
}
|
|
5749
|
+
await fsExtra.ensureDir(join6(targetPath, ".."));
|
|
5750
|
+
await fsExtra.copy(sourcePath, targetPath, { overwrite: true });
|
|
5751
|
+
}
|
|
5752
|
+
}
|
|
5753
|
+
async function writeMirrorPackageJson(targetRoot) {
|
|
5754
|
+
const packageJsonPath = join6(targetRoot, "package.json");
|
|
5755
|
+
const packageJson = {
|
|
5756
|
+
name: "agdi-upstream-mirror",
|
|
5757
|
+
private: true,
|
|
5758
|
+
type: "module",
|
|
5759
|
+
description: "Mirrored upstream Agdi feature/runtime surface for Agdi-dev"
|
|
5760
|
+
};
|
|
5761
|
+
await fsExtra.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
|
5762
|
+
}
|
|
5763
|
+
async function ensureMirrorNodeModules(sourceRepo, targetRoot) {
|
|
5764
|
+
const sourceNodeModules = join6(sourceRepo, "node_modules");
|
|
5765
|
+
const targetNodeModules = join6(targetRoot, "node_modules");
|
|
5766
|
+
if (!await fsExtra.pathExists(sourceNodeModules)) {
|
|
5767
|
+
return "missing";
|
|
5768
|
+
}
|
|
5769
|
+
try {
|
|
5770
|
+
if (await fsExtra.pathExists(targetNodeModules)) {
|
|
5771
|
+
const stat = await fsExtra.lstat(targetNodeModules);
|
|
5772
|
+
if (stat.isSymbolicLink()) {
|
|
5773
|
+
const existing = await fsExtra.realpath(targetNodeModules);
|
|
5774
|
+
const expected = await fsExtra.realpath(sourceNodeModules);
|
|
5775
|
+
if (existing === expected) {
|
|
5776
|
+
return "linked";
|
|
5777
|
+
}
|
|
5778
|
+
}
|
|
5779
|
+
await fsExtra.remove(targetNodeModules);
|
|
5780
|
+
}
|
|
5781
|
+
await fsExtra.ensureSymlink(sourceNodeModules, targetNodeModules, "junction");
|
|
5782
|
+
return "linked";
|
|
5783
|
+
} catch {
|
|
5784
|
+
return "failed";
|
|
5785
|
+
}
|
|
5786
|
+
}
|
|
5694
5787
|
async function listSkills(targetRoot) {
|
|
5695
5788
|
const skillsRoot = join6(targetRoot, "skills");
|
|
5696
5789
|
if (!await fsExtra.pathExists(skillsRoot)) {
|
|
@@ -5771,12 +5864,14 @@ async function runFeaturesCommand(options) {
|
|
|
5771
5864
|
const sourceRepo = resolve2(cwd, options.from ?? "../Agdi");
|
|
5772
5865
|
const targetRoot = resolve2(cwd, options.to ?? "./upstream/agdi");
|
|
5773
5866
|
console.log("");
|
|
5774
|
-
console.log(chalk16.cyan.bold("Feature Packs"));
|
|
5867
|
+
console.log(chalk16.cyan.bold(options.all ? "Feature Mirror" : "Feature Packs"));
|
|
5775
5868
|
console.log(chalk16.gray(` Source: ${sourceRepo}`));
|
|
5776
5869
|
console.log(chalk16.gray(` Target: ${targetRoot}`));
|
|
5777
5870
|
console.log("");
|
|
5778
5871
|
if (options.sync) {
|
|
5779
|
-
const spinner = ora6(
|
|
5872
|
+
const spinner = ora6(
|
|
5873
|
+
options.all ? "Syncing full upstream Agdi mirror..." : "Syncing feature packs from Agdi..."
|
|
5874
|
+
).start();
|
|
5780
5875
|
if (!await fsExtra.pathExists(sourceRepo)) {
|
|
5781
5876
|
spinner.fail("Source Agdi repository not found");
|
|
5782
5877
|
console.log(chalk16.red(`Expected source path: ${sourceRepo}`));
|
|
@@ -5784,8 +5879,24 @@ async function runFeaturesCommand(options) {
|
|
|
5784
5879
|
}
|
|
5785
5880
|
try {
|
|
5786
5881
|
await fsExtra.ensureDir(targetRoot);
|
|
5787
|
-
|
|
5882
|
+
let nodeModulesStatus = null;
|
|
5883
|
+
if (options.all) {
|
|
5884
|
+
await copyAllTargetPaths(sourceRepo, targetRoot);
|
|
5885
|
+
await writeMirrorPackageJson(targetRoot);
|
|
5886
|
+
nodeModulesStatus = await ensureMirrorNodeModules(sourceRepo, targetRoot);
|
|
5887
|
+
} else {
|
|
5888
|
+
await copyTargetPaths(sourceRepo, targetRoot);
|
|
5889
|
+
}
|
|
5788
5890
|
spinner.succeed("Sync completed");
|
|
5891
|
+
if (options.all && nodeModulesStatus !== null) {
|
|
5892
|
+
if (nodeModulesStatus === "linked") {
|
|
5893
|
+
console.log(chalk16.gray(" Mirror node_modules: linked to source repo"));
|
|
5894
|
+
} else if (nodeModulesStatus === "missing") {
|
|
5895
|
+
console.log(chalk16.yellow(" Mirror node_modules: source node_modules missing"));
|
|
5896
|
+
} else {
|
|
5897
|
+
console.log(chalk16.yellow(" Mirror node_modules: failed to link (proxy commands may fail)"));
|
|
5898
|
+
}
|
|
5899
|
+
}
|
|
5789
5900
|
} catch (error) {
|
|
5790
5901
|
spinner.fail("Sync failed");
|
|
5791
5902
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -5807,6 +5918,14 @@ async function runFeaturesCommand(options) {
|
|
|
5807
5918
|
console.log(chalk16.gray(` Pairing TS files: ${pairingTs}`));
|
|
5808
5919
|
console.log(chalk16.gray(` Channel policy TS files: ${channelPolicyTs}`));
|
|
5809
5920
|
console.log("");
|
|
5921
|
+
if (options.all) {
|
|
5922
|
+
const hasRuntimeEntry = await fsExtra.pathExists(join6(targetRoot, "agdi.mjs"));
|
|
5923
|
+
const hasRuntimeDist = await fsExtra.pathExists(join6(targetRoot, "dist/entry.js"));
|
|
5924
|
+
console.log(chalk16.white.bold("Mirror runtime:"));
|
|
5925
|
+
console.log(chalk16.gray(` agdi.mjs present: ${hasRuntimeEntry ? "yes" : "no"}`));
|
|
5926
|
+
console.log(chalk16.gray(` dist/entry.js present: ${hasRuntimeDist ? "yes" : "no"}`));
|
|
5927
|
+
console.log("");
|
|
5928
|
+
}
|
|
5810
5929
|
if (extensions.length > 0) {
|
|
5811
5930
|
console.log(chalk16.white.bold("Top extensions:"));
|
|
5812
5931
|
console.log(chalk16.gray(` ${extensions.slice(0, 16).join(", ")}`));
|
|
@@ -6463,18 +6582,588 @@ async function runChannelsDoctorCommand() {
|
|
|
6463
6582
|
console.log("");
|
|
6464
6583
|
}
|
|
6465
6584
|
|
|
6466
|
-
// src/
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6585
|
+
// src/commands/gateway.ts
|
|
6586
|
+
import net from "net";
|
|
6587
|
+
import chalk18 from "chalk";
|
|
6588
|
+
function resolveGatewayTarget(options) {
|
|
6589
|
+
const host = options.host?.trim() || process.env.AGDI_GATEWAY_HOST || "127.0.0.1";
|
|
6590
|
+
const rawPort = options.port ?? process.env.AGDI_GATEWAY_PORT ?? "18789";
|
|
6591
|
+
const parsed = Number.parseInt(String(rawPort), 10);
|
|
6592
|
+
const port = Number.isFinite(parsed) && parsed > 0 ? parsed : 18789;
|
|
6593
|
+
return { host, port };
|
|
6594
|
+
}
|
|
6595
|
+
async function checkPortOpen(target) {
|
|
6596
|
+
return new Promise((resolve3) => {
|
|
6597
|
+
const socket = net.createConnection({ host: target.host, port: target.port });
|
|
6598
|
+
let settled = false;
|
|
6599
|
+
const done = (value) => {
|
|
6600
|
+
if (settled) {
|
|
6601
|
+
return;
|
|
6602
|
+
}
|
|
6603
|
+
settled = true;
|
|
6604
|
+
socket.destroy();
|
|
6605
|
+
resolve3(value);
|
|
6606
|
+
};
|
|
6607
|
+
socket.setTimeout(2e3);
|
|
6608
|
+
socket.once("connect", () => done(true));
|
|
6609
|
+
socket.once("timeout", () => done(false));
|
|
6610
|
+
socket.once("error", () => done(false));
|
|
6611
|
+
});
|
|
6612
|
+
}
|
|
6613
|
+
async function fetchGatewayHealth(target) {
|
|
6614
|
+
const url = `http://${target.host}:${target.port}/health`;
|
|
6615
|
+
try {
|
|
6616
|
+
const response = await fetch(url, {
|
|
6617
|
+
method: "GET",
|
|
6618
|
+
headers: { Accept: "application/json" }
|
|
6619
|
+
});
|
|
6620
|
+
const body = await response.text();
|
|
6621
|
+
return { ok: response.ok, status: response.status, body };
|
|
6622
|
+
} catch {
|
|
6623
|
+
return { ok: false };
|
|
6624
|
+
}
|
|
6625
|
+
}
|
|
6626
|
+
async function runGatewayStatusCommand(options) {
|
|
6627
|
+
const target = resolveGatewayTarget(options);
|
|
6628
|
+
const open = await checkPortOpen(target);
|
|
6629
|
+
const health = open ? await fetchGatewayHealth(target) : { ok: false };
|
|
6630
|
+
console.log("");
|
|
6631
|
+
console.log(chalk18.cyan.bold("Gateway Status (native Agdi-dev)"));
|
|
6632
|
+
console.log(chalk18.gray(` Target: ws://${target.host}:${target.port}`));
|
|
6633
|
+
console.log(chalk18.gray(` Port open: ${open ? "yes" : "no"}`));
|
|
6634
|
+
if (health.status !== void 0) {
|
|
6635
|
+
console.log(chalk18.gray(` Health HTTP: ${health.status}`));
|
|
6636
|
+
} else {
|
|
6637
|
+
console.log(chalk18.gray(" Health HTTP: unreachable"));
|
|
6638
|
+
}
|
|
6639
|
+
if (health.body && health.body.trim().length > 0) {
|
|
6640
|
+
const trimmed = health.body.length > 240 ? `${health.body.slice(0, 240)}...` : health.body;
|
|
6641
|
+
console.log(chalk18.gray(` Health body: ${trimmed}`));
|
|
6642
|
+
}
|
|
6643
|
+
console.log("");
|
|
6644
|
+
}
|
|
6645
|
+
async function runGatewayHealthCommand(options) {
|
|
6646
|
+
const target = resolveGatewayTarget(options);
|
|
6647
|
+
const health = await fetchGatewayHealth(target);
|
|
6648
|
+
if (!health.ok) {
|
|
6649
|
+
console.log("");
|
|
6650
|
+
console.log(chalk18.red("Gateway health check failed."));
|
|
6651
|
+
console.log(chalk18.gray(` Target: http://${target.host}:${target.port}/health`));
|
|
6652
|
+
if (health.status !== void 0) {
|
|
6653
|
+
console.log(chalk18.gray(` Status: ${health.status}`));
|
|
6654
|
+
}
|
|
6655
|
+
console.log("");
|
|
6656
|
+
process.exitCode = 1;
|
|
6657
|
+
return;
|
|
6658
|
+
}
|
|
6659
|
+
console.log("");
|
|
6660
|
+
console.log(chalk18.green.bold("Gateway healthy"));
|
|
6661
|
+
console.log(chalk18.gray(` Target: http://${target.host}:${target.port}/health`));
|
|
6662
|
+
console.log(chalk18.gray(` Status: ${health.status}`));
|
|
6663
|
+
if (health.body && health.body.trim().length > 0) {
|
|
6664
|
+
const trimmed = health.body.length > 240 ? `${health.body.slice(0, 240)}...` : health.body;
|
|
6665
|
+
console.log(chalk18.gray(` Body: ${trimmed}`));
|
|
6666
|
+
}
|
|
6667
|
+
console.log("");
|
|
6668
|
+
}
|
|
6669
|
+
|
|
6670
|
+
// src/commands/upstream-proxy.ts
|
|
6671
|
+
import { spawn as spawn2 } from "child_process";
|
|
6672
|
+
import path14 from "path";
|
|
6673
|
+
import fs13 from "fs";
|
|
6674
|
+
import chalk19 from "chalk";
|
|
6675
|
+
var DEFAULT_UPSTREAM_CANDIDATES = (cwd) => {
|
|
6676
|
+
const envRepo = process.env.AGDI_UPSTREAM_REPO?.trim();
|
|
6677
|
+
const envBin = process.env.AGDI_UPSTREAM_BIN?.trim();
|
|
6678
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
6679
|
+
if (envBin) {
|
|
6680
|
+
candidates.add(path14.resolve(cwd, envBin));
|
|
6681
|
+
}
|
|
6682
|
+
if (envRepo) {
|
|
6683
|
+
candidates.add(path14.resolve(cwd, envRepo, "agdi.mjs"));
|
|
6684
|
+
}
|
|
6685
|
+
candidates.add(path14.resolve(cwd, "upstream/agdi/agdi.mjs"));
|
|
6686
|
+
candidates.add(path14.resolve(cwd, "../upstream/agdi/agdi.mjs"));
|
|
6687
|
+
candidates.add(path14.resolve(cwd, "../../upstream/agdi/agdi.mjs"));
|
|
6688
|
+
candidates.add(path14.resolve(cwd, "../../../upstream/agdi/agdi.mjs"));
|
|
6689
|
+
candidates.add(path14.resolve(cwd, "../Agdi/agdi.mjs"));
|
|
6690
|
+
candidates.add(path14.resolve(cwd, "Agdi/agdi.mjs"));
|
|
6691
|
+
candidates.add(path14.resolve(cwd, "../../Agdi/agdi.mjs"));
|
|
6692
|
+
candidates.add(path14.resolve(cwd, "../../../Agdi/agdi.mjs"));
|
|
6693
|
+
candidates.add(path14.resolve(cwd, "../../../../Agdi/agdi.mjs"));
|
|
6694
|
+
return [...candidates];
|
|
6695
|
+
};
|
|
6696
|
+
function resolveUpstreamBin(cwd = process.cwd()) {
|
|
6697
|
+
for (const candidate of DEFAULT_UPSTREAM_CANDIDATES(cwd)) {
|
|
6698
|
+
if (fs13.existsSync(candidate)) {
|
|
6699
|
+
return candidate;
|
|
6700
|
+
}
|
|
6701
|
+
}
|
|
6702
|
+
return null;
|
|
6703
|
+
}
|
|
6704
|
+
function extractForwardedArgs(invokedNames) {
|
|
6705
|
+
const raw = process.argv.slice(2);
|
|
6706
|
+
const index = raw.findIndex((token) => invokedNames.includes(token));
|
|
6707
|
+
if (index < 0) {
|
|
6708
|
+
return {
|
|
6709
|
+
invokedName: invokedNames[0],
|
|
6710
|
+
forwarded: []
|
|
6711
|
+
};
|
|
6712
|
+
}
|
|
6713
|
+
return {
|
|
6714
|
+
invokedName: raw[index],
|
|
6715
|
+
forwarded: raw.slice(index + 1)
|
|
6716
|
+
};
|
|
6717
|
+
}
|
|
6718
|
+
async function runUpstreamProxy(spec) {
|
|
6719
|
+
const upstreamBin = resolveUpstreamBin(process.cwd());
|
|
6720
|
+
if (!upstreamBin) {
|
|
6721
|
+
console.log("");
|
|
6722
|
+
console.log(chalk19.red("Upstream Agdi CLI not found."));
|
|
6723
|
+
console.log(chalk19.gray("Expected one of:"));
|
|
6724
|
+
for (const candidate of DEFAULT_UPSTREAM_CANDIDATES(process.cwd())) {
|
|
6725
|
+
console.log(chalk19.gray(` - ${candidate}`));
|
|
6726
|
+
}
|
|
6727
|
+
console.log(chalk19.gray("Set AGDI_UPSTREAM_REPO or AGDI_UPSTREAM_BIN to override."));
|
|
6728
|
+
console.log("");
|
|
6729
|
+
process.exitCode = 1;
|
|
6730
|
+
return;
|
|
6731
|
+
}
|
|
6732
|
+
const invocationNames = [spec.name, ...spec.aliases ?? []];
|
|
6733
|
+
const { invokedName, forwarded } = extractForwardedArgs(invocationNames);
|
|
6734
|
+
await new Promise((resolve3) => {
|
|
6735
|
+
const child = spawn2(process.execPath, [upstreamBin, invokedName, ...forwarded], {
|
|
6736
|
+
stdio: "inherit",
|
|
6737
|
+
env: process.env
|
|
6738
|
+
});
|
|
6739
|
+
child.on("error", (error) => {
|
|
6740
|
+
console.log(chalk19.red(`Failed to run upstream command: ${error.message}`));
|
|
6741
|
+
process.exitCode = 1;
|
|
6742
|
+
resolve3();
|
|
6743
|
+
});
|
|
6744
|
+
child.on("exit", (code, signal) => {
|
|
6745
|
+
if (typeof code === "number") {
|
|
6746
|
+
process.exitCode = code;
|
|
6747
|
+
} else if (signal) {
|
|
6748
|
+
console.log(chalk19.red(`Upstream command terminated by signal: ${signal}`));
|
|
6749
|
+
process.exitCode = 1;
|
|
6750
|
+
}
|
|
6751
|
+
resolve3();
|
|
6752
|
+
});
|
|
6753
|
+
});
|
|
6754
|
+
}
|
|
6755
|
+
var UPSTREAM_PROXY_COMMANDS = [
|
|
6756
|
+
{ name: "setup", description: "Upstream setup helpers" },
|
|
6757
|
+
{ name: "onboard", description: "Upstream onboarding helpers" },
|
|
6758
|
+
{ name: "configure", description: "Upstream interactive configuration wizard" },
|
|
6759
|
+
{ name: "dashboard", description: "Open the upstream control dashboard" },
|
|
6760
|
+
{ name: "reset", description: "Reset upstream local state/config" },
|
|
6761
|
+
{ name: "uninstall", description: "Uninstall upstream local service/data" },
|
|
6762
|
+
{ name: "message", description: "Upstream message operations (send/read/manage)" },
|
|
6763
|
+
{ name: "memory", description: "Upstream memory commands" },
|
|
6764
|
+
{ name: "agent", aliases: ["agents"], description: "Upstream agent management commands" },
|
|
6765
|
+
{ name: "status", description: "Upstream gateway status" },
|
|
6766
|
+
{ name: "health", description: "Upstream health checks" },
|
|
6767
|
+
{ name: "sessions", description: "Upstream sessions management" },
|
|
6768
|
+
{ name: "browser", description: "Upstream browser tooling" },
|
|
6769
|
+
{ name: "acp", description: "Upstream Agent Control Protocol tooling" },
|
|
6770
|
+
{ name: "gateway", description: "Upstream gateway control" },
|
|
6771
|
+
{ name: "daemon", description: "Upstream gateway service (legacy alias)" },
|
|
6772
|
+
{ name: "logs", description: "Upstream gateway logs" },
|
|
6773
|
+
{ name: "system", description: "Upstream system events and presence" },
|
|
6774
|
+
{ name: "models", description: "Upstream model configuration" },
|
|
6775
|
+
{ name: "approvals", description: "Upstream exec approvals workflow" },
|
|
6776
|
+
{ name: "nodes", description: "Upstream node commands" },
|
|
6777
|
+
{ name: "devices", description: "Upstream device pairing + token management" },
|
|
6778
|
+
{ name: "node", description: "Upstream node control" },
|
|
6779
|
+
{ name: "sandbox", description: "Upstream sandbox tooling" },
|
|
6780
|
+
{ name: "tui", description: "Upstream terminal UI" },
|
|
6781
|
+
{ name: "cron", description: "Upstream cron scheduler" },
|
|
6782
|
+
{ name: "dns", description: "Upstream DNS helpers" },
|
|
6783
|
+
{ name: "docs", description: "Upstream docs helpers" },
|
|
6784
|
+
{ name: "hooks", description: "Upstream hooks tooling" },
|
|
6785
|
+
{ name: "webhooks", description: "Upstream webhook helpers" },
|
|
6786
|
+
{ name: "pairing", description: "Upstream pairing helpers" },
|
|
6787
|
+
{ name: "plugins", description: "Upstream plugin management" },
|
|
6788
|
+
{ name: "directory", description: "Upstream directory commands" },
|
|
6789
|
+
{ name: "security", description: "Upstream security helpers" },
|
|
6790
|
+
{ name: "skills", description: "Upstream skills management" },
|
|
6791
|
+
{ name: "update", description: "Upstream CLI update helpers" },
|
|
6792
|
+
{ name: "completion", description: "Generate upstream shell completion script" },
|
|
6793
|
+
{ name: "autonomous", description: "Upstream autonomous browser agent" }
|
|
6794
|
+
];
|
|
6795
|
+
|
|
6796
|
+
// src/cli/banner.ts
|
|
6797
|
+
import { execSync } from "child_process";
|
|
6798
|
+
|
|
6799
|
+
// src/cli/ansi.ts
|
|
6800
|
+
var ANSI_SGR_PATTERN = /\u001b\[[0-9;]*m/g;
|
|
6801
|
+
var OSC8_PATTERN = /\u001b]8;;.*?(?:\u001b\\|\u0007)|\u001b]8;;(?:\u001b\\|\u0007)/g;
|
|
6802
|
+
function stripAnsi(input6) {
|
|
6803
|
+
return input6.replace(OSC8_PATTERN, "").replace(ANSI_SGR_PATTERN, "");
|
|
6804
|
+
}
|
|
6805
|
+
function visibleWidth(input6) {
|
|
6806
|
+
return Array.from(stripAnsi(input6)).length;
|
|
6807
|
+
}
|
|
6808
|
+
|
|
6809
|
+
// src/cli/theme.ts
|
|
6810
|
+
import chalk20, { Chalk } from "chalk";
|
|
6811
|
+
var LOBSTER_PALETTE = {
|
|
6812
|
+
accent: "#00d5ff",
|
|
6813
|
+
accentBright: "#38bdf8",
|
|
6814
|
+
accentDim: "#0ea5e9",
|
|
6815
|
+
info: "#22d3ee",
|
|
6816
|
+
success: "#2fbf71",
|
|
6817
|
+
warn: "#ffb020",
|
|
6818
|
+
error: "#e23d2d",
|
|
6819
|
+
muted: "#64748b"
|
|
6820
|
+
};
|
|
6821
|
+
var hasForceColor = typeof process.env.FORCE_COLOR === "string" && process.env.FORCE_COLOR.trim().length > 0 && process.env.FORCE_COLOR.trim() !== "0";
|
|
6822
|
+
var hasNoColorArg = process.argv.includes("--no-color");
|
|
6823
|
+
var disableColor = (process.env.NO_COLOR || hasNoColorArg) && !hasForceColor;
|
|
6824
|
+
var baseChalk = disableColor ? new Chalk({ level: 0 }) : chalk20;
|
|
6825
|
+
var hex = (value) => baseChalk.hex(value);
|
|
6826
|
+
var theme = {
|
|
6827
|
+
accent: hex(LOBSTER_PALETTE.accent),
|
|
6828
|
+
accentBright: hex(LOBSTER_PALETTE.accentBright),
|
|
6829
|
+
accentDim: hex(LOBSTER_PALETTE.accentDim),
|
|
6830
|
+
info: hex(LOBSTER_PALETTE.info),
|
|
6831
|
+
success: hex(LOBSTER_PALETTE.success),
|
|
6832
|
+
warn: hex(LOBSTER_PALETTE.warn),
|
|
6833
|
+
error: hex(LOBSTER_PALETTE.error),
|
|
6834
|
+
muted: hex(LOBSTER_PALETTE.muted),
|
|
6835
|
+
heading: baseChalk.bold.hex(LOBSTER_PALETTE.accent),
|
|
6836
|
+
command: hex(LOBSTER_PALETTE.accentBright),
|
|
6837
|
+
option: hex(LOBSTER_PALETTE.warn)
|
|
6838
|
+
};
|
|
6839
|
+
var isRich = () => Boolean(baseChalk.level > 0);
|
|
6840
|
+
|
|
6841
|
+
// src/cli/tagline.ts
|
|
6842
|
+
var DEFAULT_TAGLINE = "All your chats, one AGDI.";
|
|
6843
|
+
var HOLIDAY_TAGLINES = {
|
|
6844
|
+
newYear: "New Year: new configs, cleaner diffs, fewer port conflicts.",
|
|
6845
|
+
christmas: "Christmas: ship joy, rollback safely, keep secrets out of logs.",
|
|
6846
|
+
eid: "Eid: queues cleared, tasks done, good vibes merged to main.",
|
|
6847
|
+
diwali: "Diwali: let logs sparkle and bugs fade away.",
|
|
6848
|
+
easter: "Easter: found your missing env var in record time.",
|
|
6849
|
+
hanukkah: "Hanukkah: eight nights, steady retries, stable gateway.",
|
|
6850
|
+
halloween: "Halloween: haunted dependencies detected, caution advised.",
|
|
6851
|
+
thanksgiving: "Thanksgiving: grateful for healthy ports and clean deploys.",
|
|
6852
|
+
valentines: "Valentines: roses are typed, pipelines are green."
|
|
6853
|
+
};
|
|
6854
|
+
var TAGLINES = [
|
|
6855
|
+
"Automation with claws: less toil, more shipping.",
|
|
6856
|
+
"One CLI for chat ops, coding workflows, and controlled chaos.",
|
|
6857
|
+
"Your terminal just got better at boring work.",
|
|
6858
|
+
"From prompt to action without tab-sprawl.",
|
|
6859
|
+
"Less clicking, more shipping.",
|
|
6860
|
+
"Fast commands, clear logs, fewer regrets.",
|
|
6861
|
+
"Write less glue code. Keep moving.",
|
|
6862
|
+
"If it repeats, automate it.",
|
|
6863
|
+
"Smarter defaults for real-world terminal work.",
|
|
6864
|
+
"Build, run, and route messages from one place.",
|
|
6865
|
+
"Your scripts, your infra, your control.",
|
|
6866
|
+
"CLI-first workflows for teams that ship.",
|
|
6867
|
+
"Secure-by-default habits, practical-by-default behavior.",
|
|
6868
|
+
"Task in, outcome out.",
|
|
6869
|
+
HOLIDAY_TAGLINES.newYear,
|
|
6870
|
+
HOLIDAY_TAGLINES.christmas,
|
|
6871
|
+
HOLIDAY_TAGLINES.eid,
|
|
6872
|
+
HOLIDAY_TAGLINES.diwali,
|
|
6873
|
+
HOLIDAY_TAGLINES.easter,
|
|
6874
|
+
HOLIDAY_TAGLINES.hanukkah,
|
|
6875
|
+
HOLIDAY_TAGLINES.halloween,
|
|
6876
|
+
HOLIDAY_TAGLINES.thanksgiving,
|
|
6877
|
+
HOLIDAY_TAGLINES.valentines
|
|
6878
|
+
];
|
|
6879
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
6880
|
+
function utcParts(date) {
|
|
6881
|
+
return {
|
|
6882
|
+
year: date.getUTCFullYear(),
|
|
6883
|
+
month: date.getUTCMonth(),
|
|
6884
|
+
day: date.getUTCDate()
|
|
6885
|
+
};
|
|
6886
|
+
}
|
|
6887
|
+
var onMonthDay = (month, day) => (date) => {
|
|
6888
|
+
const parts = utcParts(date);
|
|
6889
|
+
return parts.month === month && parts.day === day;
|
|
6890
|
+
};
|
|
6891
|
+
var onSpecificDates = (dates, durationDays = 1) => (date) => {
|
|
6892
|
+
const parts = utcParts(date);
|
|
6893
|
+
return dates.some(([year, month, day]) => {
|
|
6894
|
+
if (parts.year !== year) {
|
|
6895
|
+
return false;
|
|
6896
|
+
}
|
|
6897
|
+
const start = Date.UTC(year, month, day);
|
|
6898
|
+
const current = Date.UTC(parts.year, parts.month, parts.day);
|
|
6899
|
+
return current >= start && current < start + durationDays * DAY_MS;
|
|
6900
|
+
});
|
|
6901
|
+
};
|
|
6902
|
+
var inYearWindow = (windows) => (date) => {
|
|
6903
|
+
const parts = utcParts(date);
|
|
6904
|
+
const window = windows.find((entry) => entry.year === parts.year);
|
|
6905
|
+
if (!window) {
|
|
6906
|
+
return false;
|
|
6907
|
+
}
|
|
6908
|
+
const start = Date.UTC(window.year, window.month, window.day);
|
|
6909
|
+
const current = Date.UTC(parts.year, parts.month, parts.day);
|
|
6910
|
+
return current >= start && current < start + window.duration * DAY_MS;
|
|
6911
|
+
};
|
|
6912
|
+
var isFourthThursdayOfNovember = (date) => {
|
|
6913
|
+
const parts = utcParts(date);
|
|
6914
|
+
if (parts.month !== 10) {
|
|
6915
|
+
return false;
|
|
6916
|
+
}
|
|
6917
|
+
const firstDay = new Date(Date.UTC(parts.year, 10, 1)).getUTCDay();
|
|
6918
|
+
const offsetToThursday = (4 - firstDay + 7) % 7;
|
|
6919
|
+
const fourthThursday = 1 + offsetToThursday + 21;
|
|
6920
|
+
return parts.day === fourthThursday;
|
|
6921
|
+
};
|
|
6922
|
+
var HOLIDAY_RULES = /* @__PURE__ */ new Map([
|
|
6923
|
+
[HOLIDAY_TAGLINES.newYear, onMonthDay(0, 1)],
|
|
6924
|
+
[HOLIDAY_TAGLINES.christmas, onMonthDay(11, 25)],
|
|
6925
|
+
[HOLIDAY_TAGLINES.valentines, onMonthDay(1, 14)],
|
|
6926
|
+
[HOLIDAY_TAGLINES.halloween, onMonthDay(9, 31)],
|
|
6927
|
+
[HOLIDAY_TAGLINES.thanksgiving, isFourthThursdayOfNovember],
|
|
6928
|
+
[
|
|
6929
|
+
HOLIDAY_TAGLINES.eid,
|
|
6930
|
+
onSpecificDates(
|
|
6931
|
+
[
|
|
6932
|
+
[2025, 2, 30],
|
|
6933
|
+
[2025, 2, 31],
|
|
6934
|
+
[2026, 2, 20],
|
|
6935
|
+
[2027, 2, 10]
|
|
6936
|
+
],
|
|
6937
|
+
1
|
|
6938
|
+
)
|
|
6939
|
+
],
|
|
6940
|
+
[
|
|
6941
|
+
HOLIDAY_TAGLINES.diwali,
|
|
6942
|
+
onSpecificDates(
|
|
6943
|
+
[
|
|
6944
|
+
[2025, 9, 20],
|
|
6945
|
+
[2026, 10, 8],
|
|
6946
|
+
[2027, 9, 28]
|
|
6947
|
+
],
|
|
6948
|
+
1
|
|
6949
|
+
)
|
|
6950
|
+
],
|
|
6951
|
+
[
|
|
6952
|
+
HOLIDAY_TAGLINES.easter,
|
|
6953
|
+
onSpecificDates(
|
|
6954
|
+
[
|
|
6955
|
+
[2025, 3, 20],
|
|
6956
|
+
[2026, 3, 5],
|
|
6957
|
+
[2027, 2, 28]
|
|
6958
|
+
],
|
|
6959
|
+
1
|
|
6960
|
+
)
|
|
6961
|
+
],
|
|
6962
|
+
[
|
|
6963
|
+
HOLIDAY_TAGLINES.hanukkah,
|
|
6964
|
+
inYearWindow([
|
|
6965
|
+
{ year: 2025, month: 11, day: 15, duration: 8 },
|
|
6966
|
+
{ year: 2026, month: 11, day: 5, duration: 8 },
|
|
6967
|
+
{ year: 2027, month: 11, day: 25, duration: 8 }
|
|
6968
|
+
])
|
|
6969
|
+
]
|
|
6970
|
+
]);
|
|
6971
|
+
function isTaglineActive(tagline, date) {
|
|
6972
|
+
const rule = HOLIDAY_RULES.get(tagline);
|
|
6973
|
+
if (!rule) {
|
|
6974
|
+
return true;
|
|
6975
|
+
}
|
|
6976
|
+
return rule(date);
|
|
6977
|
+
}
|
|
6978
|
+
function activeTaglines(options = {}) {
|
|
6979
|
+
if (TAGLINES.length === 0) {
|
|
6980
|
+
return [DEFAULT_TAGLINE];
|
|
6981
|
+
}
|
|
6982
|
+
const today = options.now ? options.now() : /* @__PURE__ */ new Date();
|
|
6983
|
+
const filtered = TAGLINES.filter((tagline) => isTaglineActive(tagline, today));
|
|
6984
|
+
return filtered.length > 0 ? filtered : TAGLINES;
|
|
6985
|
+
}
|
|
6986
|
+
function pickTagline(options = {}) {
|
|
6987
|
+
const env = options.env ?? process.env;
|
|
6988
|
+
const override = env?.AGDI_TAGLINE_INDEX;
|
|
6989
|
+
if (override !== void 0) {
|
|
6990
|
+
const parsed = Number.parseInt(override, 10);
|
|
6991
|
+
if (!Number.isNaN(parsed) && parsed >= 0) {
|
|
6992
|
+
const pool2 = TAGLINES.length > 0 ? TAGLINES : [DEFAULT_TAGLINE];
|
|
6993
|
+
return pool2[parsed % pool2.length];
|
|
6994
|
+
}
|
|
6995
|
+
}
|
|
6996
|
+
const pool = activeTaglines(options);
|
|
6997
|
+
const rand = options.random ?? Math.random;
|
|
6998
|
+
const index = Math.floor(rand() * pool.length) % pool.length;
|
|
6999
|
+
return pool[index];
|
|
7000
|
+
}
|
|
7001
|
+
|
|
7002
|
+
// src/cli/banner.ts
|
|
7003
|
+
var bannerEmitted = false;
|
|
7004
|
+
var cachedCommit;
|
|
7005
|
+
var hasJsonFlag = (argv) => argv.some((arg) => arg === "--json" || arg.startsWith("--json="));
|
|
7006
|
+
var hasVersionFlag = (argv) => argv.some((arg) => arg === "--version" || arg === "-V");
|
|
7007
|
+
function resolveCommitHash() {
|
|
7008
|
+
if (cachedCommit !== void 0) {
|
|
7009
|
+
return cachedCommit;
|
|
7010
|
+
}
|
|
7011
|
+
const envCommit = process.env.AGDI_COMMIT || process.env.VERCEL_GIT_COMMIT_SHA || process.env.GITHUB_SHA || process.env.npm_package_gitHead;
|
|
7012
|
+
if (envCommit && envCommit.trim().length > 0) {
|
|
7013
|
+
cachedCommit = envCommit.trim().slice(0, 8);
|
|
7014
|
+
return cachedCommit;
|
|
7015
|
+
}
|
|
7016
|
+
try {
|
|
7017
|
+
const out = execSync("git rev-parse --short HEAD", {
|
|
7018
|
+
encoding: "utf8",
|
|
7019
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
7020
|
+
}).trim();
|
|
7021
|
+
cachedCommit = out.length > 0 ? out : null;
|
|
7022
|
+
return cachedCommit;
|
|
7023
|
+
} catch {
|
|
7024
|
+
cachedCommit = null;
|
|
7025
|
+
return cachedCommit;
|
|
7026
|
+
}
|
|
7027
|
+
}
|
|
7028
|
+
function formatCliBannerLine(version, options = {}) {
|
|
7029
|
+
const commit = options.commit ?? resolveCommitHash();
|
|
7030
|
+
const commitLabel = commit ?? "unknown";
|
|
7031
|
+
const tagline = pickTagline(options);
|
|
7032
|
+
const rich = options.richTty ?? isRich();
|
|
7033
|
+
const title = "AGDI";
|
|
7034
|
+
const prefix = "* ";
|
|
7035
|
+
const columns = options.columns ?? process.stdout.columns ?? 120;
|
|
7036
|
+
const plainFullLine = `${title} ${version} (${commitLabel}) - ${tagline}`;
|
|
7037
|
+
const fitsOnOneLine = visibleWidth(plainFullLine) <= columns;
|
|
7038
|
+
if (rich) {
|
|
7039
|
+
if (fitsOnOneLine) {
|
|
7040
|
+
return `${theme.heading(title)} ${theme.info(version)} ${theme.muted(
|
|
7041
|
+
`(${commitLabel})`
|
|
7042
|
+
)} ${theme.muted("-")} ${theme.accentDim(tagline)}`;
|
|
7043
|
+
}
|
|
7044
|
+
const line12 = `${theme.heading(title)} ${theme.info(version)} ${theme.muted(`(${commitLabel})`)}`;
|
|
7045
|
+
const line22 = `${" ".repeat(prefix.length)}${theme.accentDim(tagline)}`;
|
|
7046
|
+
return `${line12}
|
|
7047
|
+
${line22}`;
|
|
7048
|
+
}
|
|
7049
|
+
if (fitsOnOneLine) {
|
|
7050
|
+
return plainFullLine;
|
|
7051
|
+
}
|
|
7052
|
+
const line1 = `${title} ${version} (${commitLabel})`;
|
|
7053
|
+
const line2 = `${" ".repeat(prefix.length)}${tagline}`;
|
|
7054
|
+
return `${line1}
|
|
7055
|
+
${line2}`;
|
|
7056
|
+
}
|
|
7057
|
+
function emitCliBanner(version, options = {}) {
|
|
7058
|
+
if (bannerEmitted) {
|
|
7059
|
+
return;
|
|
7060
|
+
}
|
|
7061
|
+
const argv = options.argv ?? process.argv;
|
|
7062
|
+
if (!process.stdout.isTTY) {
|
|
7063
|
+
return;
|
|
7064
|
+
}
|
|
7065
|
+
if (hasJsonFlag(argv)) {
|
|
7066
|
+
return;
|
|
7067
|
+
}
|
|
7068
|
+
if (hasVersionFlag(argv)) {
|
|
7069
|
+
return;
|
|
7070
|
+
}
|
|
7071
|
+
const line = formatCliBannerLine(version, options);
|
|
7072
|
+
process.stdout.write(`
|
|
7073
|
+
${line}
|
|
7074
|
+
|
|
7075
|
+
`);
|
|
7076
|
+
bannerEmitted = true;
|
|
7077
|
+
}
|
|
7078
|
+
function hasEmittedCliBanner() {
|
|
7079
|
+
return bannerEmitted;
|
|
7080
|
+
}
|
|
7081
|
+
|
|
7082
|
+
// src/cli/links.ts
|
|
7083
|
+
var DOCS_ROOT = "https://docs.agdi.ai";
|
|
7084
|
+
function formatTerminalLink(label, url, opts) {
|
|
7085
|
+
const esc = "\x1B";
|
|
7086
|
+
const safeLabel = label.replaceAll(esc, "");
|
|
7087
|
+
const safeUrl = url.replaceAll(esc, "");
|
|
7088
|
+
const allow = opts?.force === true ? true : opts?.force === false ? false : Boolean(process.stdout.isTTY);
|
|
7089
|
+
if (!allow) {
|
|
7090
|
+
return opts?.fallback ?? `${safeLabel} (${safeUrl})`;
|
|
7091
|
+
}
|
|
7092
|
+
return `\x1B]8;;${safeUrl}\x07${safeLabel}\x1B]8;;\x07`;
|
|
7093
|
+
}
|
|
7094
|
+
function formatDocsLink(path15, label) {
|
|
7095
|
+
const trimmed = path15.trim();
|
|
7096
|
+
const url = trimmed.startsWith("http") ? trimmed : `${DOCS_ROOT}${trimmed.startsWith("/") ? trimmed : `/${trimmed}`}`;
|
|
7097
|
+
return formatTerminalLink(label ?? url, url, { fallback: url });
|
|
7098
|
+
}
|
|
7099
|
+
|
|
7100
|
+
// src/cli/help.ts
|
|
7101
|
+
var EXAMPLES = [
|
|
7102
|
+
["agdi wizard", "Run the interactive setup flow."],
|
|
7103
|
+
['agdi build "crm dashboard" --output ./my-app', "Generate an app from a prompt."],
|
|
7104
|
+
['agdi squad "build a booking app" --deploy', "Run autonomous multi-agent delivery."],
|
|
7105
|
+
["agdi channels list", "List synced channel runtimes and status."],
|
|
7106
|
+
[
|
|
7107
|
+
'agdi channels send --channel telegram --message "Hi" --to @team-room',
|
|
7108
|
+
"Send outbound message via a channel runtime."
|
|
7109
|
+
]
|
|
7110
|
+
];
|
|
7111
|
+
function hasVersionFlag2(argv) {
|
|
7112
|
+
return argv.some((arg) => arg === "-V" || arg === "--version");
|
|
7113
|
+
}
|
|
7114
|
+
function configureCliDesign(program2, programVersion) {
|
|
7115
|
+
program2.configureHelp({
|
|
7116
|
+
sortSubcommands: true,
|
|
7117
|
+
sortOptions: true,
|
|
7118
|
+
optionTerm: (option) => theme.option(option.flags),
|
|
7119
|
+
subcommandTerm: (cmd) => theme.command(cmd.name())
|
|
7120
|
+
});
|
|
7121
|
+
program2.configureOutput({
|
|
7122
|
+
writeOut: (str) => {
|
|
7123
|
+
const colored = str.replace(/^Usage:/gm, theme.heading("Usage:")).replace(/^Options:/gm, theme.heading("Options:")).replace(/^Commands:/gm, theme.heading("Commands:"));
|
|
7124
|
+
process.stdout.write(colored);
|
|
7125
|
+
},
|
|
7126
|
+
writeErr: (str) => process.stderr.write(str),
|
|
7127
|
+
outputError: (str, write) => write(theme.error(str))
|
|
7128
|
+
});
|
|
7129
|
+
if (hasVersionFlag2(process.argv)) {
|
|
7130
|
+
console.log(programVersion);
|
|
7131
|
+
process.exit(0);
|
|
7132
|
+
}
|
|
7133
|
+
program2.addHelpText("beforeAll", () => {
|
|
7134
|
+
if (hasEmittedCliBanner()) {
|
|
7135
|
+
return "";
|
|
7136
|
+
}
|
|
7137
|
+
const line = formatCliBannerLine(programVersion, { richTty: isRich() });
|
|
7138
|
+
return `
|
|
7139
|
+
${line}
|
|
7140
|
+
`;
|
|
7141
|
+
});
|
|
7142
|
+
const formattedExamples = EXAMPLES.map(
|
|
7143
|
+
([command, description]) => ` ${theme.command(command)}
|
|
7144
|
+
${theme.muted(description)}`
|
|
7145
|
+
).join("\n");
|
|
7146
|
+
program2.addHelpText("afterAll", ({ command }) => {
|
|
7147
|
+
if (command !== program2) {
|
|
7148
|
+
return "";
|
|
7149
|
+
}
|
|
7150
|
+
const docs = formatDocsLink("/cli", "docs.agdi.ai/cli");
|
|
7151
|
+
return `
|
|
7152
|
+
${theme.heading("Examples:")}
|
|
7153
|
+
${formattedExamples}
|
|
7154
|
+
|
|
7155
|
+
${theme.muted("Docs:")} ${docs}
|
|
6474
7156
|
`;
|
|
7157
|
+
});
|
|
7158
|
+
}
|
|
7159
|
+
|
|
7160
|
+
// src/index.ts
|
|
7161
|
+
var PROGRAM_VERSION = "3.3.8";
|
|
6475
7162
|
var program = new Command();
|
|
6476
|
-
program.name("agdi").description(
|
|
7163
|
+
program.name("agdi").description("").version(PROGRAM_VERSION).option("-y, --yes", "Auto-approve all prompts (headless/CI mode)").option("-m, --minimal", "Generate only the requested file(s), not a full app").option("-d, --dry-run", "Show what would be created without writing files").option("--saas", "Generate a production SaaS blueprint (Next.js + Prisma + Postgres + Stripe)").option("--no-color", "Disable ANSI colors", false);
|
|
7164
|
+
configureCliDesign(program, PROGRAM_VERSION);
|
|
6477
7165
|
program.hook("preAction", (thisCommand) => {
|
|
7166
|
+
emitCliBanner(PROGRAM_VERSION, { argv: process.argv });
|
|
6478
7167
|
const opts = thisCommand.opts();
|
|
6479
7168
|
if (opts.yes) {
|
|
6480
7169
|
ui.setFlags({ yes: true, headless: true });
|
|
@@ -6489,20 +7178,12 @@ program.hook("preAction", (thisCommand) => {
|
|
|
6489
7178
|
ui.setFlags({ saas: true });
|
|
6490
7179
|
}
|
|
6491
7180
|
});
|
|
6492
|
-
program.addHelpText("beforeAll", () => {
|
|
6493
|
-
return BANNER + "\n" + chalk18.gray(" The Autonomous AI Employee") + "\n" + chalk18.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
6494
|
-
});
|
|
6495
|
-
program.addHelpText("afterAll", () => {
|
|
6496
|
-
return "\n" + chalk18.gray("Links:") + `
|
|
6497
|
-
${chalk18.cyan("Discord:")} https://discord.gg/pPkZ93Yb
|
|
6498
|
-
`;
|
|
6499
|
-
});
|
|
6500
7181
|
program.action(async () => {
|
|
6501
7182
|
try {
|
|
6502
7183
|
await runWizard();
|
|
6503
7184
|
} catch (error) {
|
|
6504
7185
|
if (error.name === "ExitPromptError") {
|
|
6505
|
-
console.log(
|
|
7186
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Goodbye!\n"));
|
|
6506
7187
|
try {
|
|
6507
7188
|
ui.safeExit(0);
|
|
6508
7189
|
} catch {
|
|
@@ -6524,7 +7205,7 @@ program.command("auth").description("Configure API keys").option("--status", "Sh
|
|
|
6524
7205
|
}
|
|
6525
7206
|
} catch (error) {
|
|
6526
7207
|
if (error.name === "ExitPromptError") {
|
|
6527
|
-
console.log(
|
|
7208
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6528
7209
|
try {
|
|
6529
7210
|
ui.safeExit(0);
|
|
6530
7211
|
} catch {
|
|
@@ -6542,7 +7223,7 @@ program.command("model").alias("models").description("Change AI model").action(a
|
|
|
6542
7223
|
await selectModel();
|
|
6543
7224
|
} catch (error) {
|
|
6544
7225
|
if (error.name === "ExitPromptError") {
|
|
6545
|
-
console.log(
|
|
7226
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6546
7227
|
try {
|
|
6547
7228
|
ui.safeExit(0);
|
|
6548
7229
|
} catch {
|
|
@@ -6563,7 +7244,7 @@ program.command("chat").description("Start a chat session").action(async () => {
|
|
|
6563
7244
|
await startChat();
|
|
6564
7245
|
} catch (error) {
|
|
6565
7246
|
if (error.name === "ExitPromptError") {
|
|
6566
|
-
console.log(
|
|
7247
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Goodbye!\n"));
|
|
6567
7248
|
try {
|
|
6568
7249
|
ui.safeExit(0);
|
|
6569
7250
|
} catch {
|
|
@@ -6581,7 +7262,7 @@ program.command("run [directory]").description("Run a generated project").action
|
|
|
6581
7262
|
await runProject(directory);
|
|
6582
7263
|
} catch (error) {
|
|
6583
7264
|
if (error.name === "ExitPromptError") {
|
|
6584
|
-
console.log(
|
|
7265
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6585
7266
|
try {
|
|
6586
7267
|
ui.safeExit(0);
|
|
6587
7268
|
} catch {
|
|
@@ -6604,7 +7285,7 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
|
|
|
6604
7285
|
}
|
|
6605
7286
|
const activeConfig = getActiveProvider();
|
|
6606
7287
|
if (!activeConfig) {
|
|
6607
|
-
console.log(
|
|
7288
|
+
console.log(chalk21.red("\u274C No API key configured. Run: agdi auth"));
|
|
6608
7289
|
return;
|
|
6609
7290
|
}
|
|
6610
7291
|
const spinner = ora7("Generating application...").start();
|
|
@@ -6616,52 +7297,52 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
|
|
|
6616
7297
|
const pm = new ProjectManager();
|
|
6617
7298
|
pm.create(options.output.replace("./", ""), prompt);
|
|
6618
7299
|
const { plan, files } = await generateApp(prompt, llm, (step, file) => {
|
|
6619
|
-
spinner.text = file ? `${step} ${
|
|
7300
|
+
spinner.text = file ? `${step} ${chalk21.gray(file)}` : step;
|
|
6620
7301
|
});
|
|
6621
7302
|
pm.updateFiles(files);
|
|
6622
7303
|
pm.updateDependencies(plan.dependencies);
|
|
6623
7304
|
if (options.dryRun || ui.flags.dryRun) {
|
|
6624
7305
|
spinner.stop();
|
|
6625
|
-
console.log(
|
|
6626
|
-
console.log(
|
|
7306
|
+
console.log(chalk21.cyan.bold("\n\u{1F6A7} DRY RUN SUMMARY\n"));
|
|
7307
|
+
console.log(chalk21.gray(`Project: ${plan.name}
|
|
6627
7308
|
`));
|
|
6628
|
-
console.log(
|
|
6629
|
-
files.forEach((f) => console.log(
|
|
6630
|
-
console.log(
|
|
6631
|
-
console.log(
|
|
6632
|
-
console.log(
|
|
7309
|
+
console.log(chalk21.cyan("Files to be created:"));
|
|
7310
|
+
files.forEach((f) => console.log(chalk21.gray(` \u{1F4C4} ${f.path}`)));
|
|
7311
|
+
console.log(chalk21.cyan("\nDependencies:"));
|
|
7312
|
+
console.log(chalk21.gray(` \u{1F4E6} ${plan.dependencies.join(", ")}`));
|
|
7313
|
+
console.log(chalk21.green("\n\u2713 Dry run complete. No files written.\n"));
|
|
6633
7314
|
return;
|
|
6634
7315
|
}
|
|
6635
7316
|
await writeProject(pm.get(), options.output);
|
|
6636
|
-
spinner.succeed(
|
|
6637
|
-
console.log(
|
|
6638
|
-
\u{1F4C1} Created ${files.length} files in ${
|
|
7317
|
+
spinner.succeed(chalk21.green("App generated!"));
|
|
7318
|
+
console.log(chalk21.gray(`
|
|
7319
|
+
\u{1F4C1} Created ${files.length} files in ${chalk21.cyan(options.output)}`));
|
|
6639
7320
|
if (ui.flags.saas || options.saas) {
|
|
6640
|
-
console.log(
|
|
6641
|
-
console.log(
|
|
6642
|
-
console.log(
|
|
6643
|
-
console.log(
|
|
6644
|
-
console.log(
|
|
6645
|
-
console.log(
|
|
6646
|
-
console.log(
|
|
7321
|
+
console.log(chalk21.cyan("\nSaaS Quick Start:"));
|
|
7322
|
+
console.log(chalk21.gray(` 1) cd ${options.output}`));
|
|
7323
|
+
console.log(chalk21.gray(" 2) npm install"));
|
|
7324
|
+
console.log(chalk21.gray(" 3) cp .env.example .env"));
|
|
7325
|
+
console.log(chalk21.gray(" 4) npx prisma generate"));
|
|
7326
|
+
console.log(chalk21.gray(" 5) npx prisma db push"));
|
|
7327
|
+
console.log(chalk21.gray(" 6) npm run dev\n"));
|
|
6647
7328
|
} else {
|
|
6648
|
-
console.log(
|
|
7329
|
+
console.log(chalk21.gray("\nNext: cd " + options.output + " && npm install && npm run dev\n"));
|
|
6649
7330
|
}
|
|
6650
7331
|
} catch (error) {
|
|
6651
7332
|
spinner.fail("Generation failed");
|
|
6652
7333
|
const msg = error instanceof Error ? error.message : String(error);
|
|
6653
7334
|
if (msg.includes("429") || msg.includes("quota")) {
|
|
6654
|
-
console.log(
|
|
7335
|
+
console.log(chalk21.yellow("\n\u26A0\uFE0F Quota exceeded. Run: agdi model\n"));
|
|
6655
7336
|
} else if (msg.includes("401") || msg.includes("403")) {
|
|
6656
|
-
console.log(
|
|
7337
|
+
console.log(chalk21.red("\n\u{1F511} Invalid API key. Run: agdi auth\n"));
|
|
6657
7338
|
} else {
|
|
6658
|
-
console.error(
|
|
7339
|
+
console.error(chalk21.red("\n" + msg + "\n"));
|
|
6659
7340
|
}
|
|
6660
7341
|
ui.safeExit(1);
|
|
6661
7342
|
}
|
|
6662
7343
|
} catch (error) {
|
|
6663
7344
|
if (error.name === "ExitPromptError") {
|
|
6664
|
-
console.log(
|
|
7345
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6665
7346
|
try {
|
|
6666
7347
|
ui.safeExit(0);
|
|
6667
7348
|
} catch {
|
|
@@ -6677,11 +7358,11 @@ program.command("build <prompt>").alias("b").description("Generate an app from a
|
|
|
6677
7358
|
program.command("config").description("Show configuration").action(async () => {
|
|
6678
7359
|
const config = loadConfig();
|
|
6679
7360
|
const active = getActiveProvider();
|
|
6680
|
-
console.log(
|
|
6681
|
-
console.log(
|
|
6682
|
-
console.log(
|
|
6683
|
-
console.log(
|
|
6684
|
-
console.log(
|
|
7361
|
+
console.log(chalk21.cyan.bold("\n\u2699\uFE0F Configuration\n"));
|
|
7362
|
+
console.log(chalk21.gray(" Provider: ") + chalk21.cyan(config.defaultProvider || "not set"));
|
|
7363
|
+
console.log(chalk21.gray(" Model: ") + chalk21.cyan(config.defaultModel || "not set"));
|
|
7364
|
+
console.log(chalk21.gray(" Config: ") + chalk21.gray("~/.agdi/config.json"));
|
|
7365
|
+
console.log(chalk21.cyan.bold("\n\u{1F510} API Keys\n"));
|
|
6685
7366
|
const keys = [
|
|
6686
7367
|
["Gemini", config.geminiApiKey],
|
|
6687
7368
|
["OpenRouter", config.openrouterApiKey],
|
|
@@ -6690,13 +7371,13 @@ program.command("config").description("Show configuration").action(async () => {
|
|
|
6690
7371
|
["DeepSeek", config.deepseekApiKey]
|
|
6691
7372
|
];
|
|
6692
7373
|
for (const [name, key] of keys) {
|
|
6693
|
-
const status = key ?
|
|
7374
|
+
const status = key ? chalk21.green("\u2713") : chalk21.gray("\u2717");
|
|
6694
7375
|
console.log(` ${status} ${name}`);
|
|
6695
7376
|
}
|
|
6696
|
-
console.log(
|
|
7377
|
+
console.log(chalk21.cyan.bold("\n\u{1F4CA} Telemetry\n"));
|
|
6697
7378
|
const telemetryEnabled = config.telemetry?.enabled ?? false;
|
|
6698
|
-
console.log(` ${telemetryEnabled ?
|
|
6699
|
-
console.log(
|
|
7379
|
+
console.log(` ${telemetryEnabled ? chalk21.green("\u2713 Enabled") : chalk21.gray("\u2717 Disabled")}`);
|
|
7380
|
+
console.log(chalk21.gray(" Change with: agdi config telemetry --enable | --disable"));
|
|
6700
7381
|
console.log("");
|
|
6701
7382
|
console.log("");
|
|
6702
7383
|
});
|
|
@@ -6704,68 +7385,68 @@ program.command("config:telemetry").alias("telemetry").description("Manage telem
|
|
|
6704
7385
|
const { isTelemetryEnabled, setTelemetryConsent, getTelemetryConfig } = await import("./config-K2XM6D4Z.js");
|
|
6705
7386
|
const { generateSampleEvent, generateSanitizationDemo } = await import("./telemetry-service-76YPOPDM.js");
|
|
6706
7387
|
if (options.dryRun || options.test) {
|
|
6707
|
-
console.log(
|
|
6708
|
-
console.log(
|
|
6709
|
-
console.log(
|
|
6710
|
-
console.log(
|
|
7388
|
+
console.log(chalk21.cyan.bold("\n\u{1F50D} TELEMETRY TRANSPARENCY MODE\n"));
|
|
7389
|
+
console.log(chalk21.gray("This is exactly what Agdi sends. Notice there is"));
|
|
7390
|
+
console.log(chalk21.green.bold("NO source code, file paths, or API keys.\n"));
|
|
7391
|
+
console.log(chalk21.white.bold('\u{1F4CA} Sample "Build Failed" Event:\n'));
|
|
6711
7392
|
const sample = generateSampleEvent();
|
|
6712
|
-
console.log(
|
|
6713
|
-
console.log(
|
|
6714
|
-
console.log(
|
|
6715
|
-
console.log(
|
|
7393
|
+
console.log(chalk21.gray(JSON.stringify(sample, null, 2)));
|
|
7394
|
+
console.log(chalk21.white.bold("\n\u{1F6E1}\uFE0F Sanitization Demo:\n"));
|
|
7395
|
+
console.log(chalk21.gray("Even if sensitive data accidentally enters an error message,"));
|
|
7396
|
+
console.log(chalk21.gray("our sanitization layer strips it before transmission:\n"));
|
|
6716
7397
|
const demo = generateSanitizationDemo();
|
|
6717
|
-
console.log(
|
|
6718
|
-
console.log(
|
|
7398
|
+
console.log(chalk21.red.bold("BEFORE sanitization (never sent):"));
|
|
7399
|
+
console.log(chalk21.gray(JSON.stringify({
|
|
6719
7400
|
errorCode: demo.before.errorCode,
|
|
6720
7401
|
feedback: demo.before.feedback
|
|
6721
7402
|
}, null, 2)));
|
|
6722
|
-
console.log(
|
|
6723
|
-
console.log(
|
|
7403
|
+
console.log(chalk21.green.bold("\nAFTER sanitization (what we actually send):"));
|
|
7404
|
+
console.log(chalk21.gray(JSON.stringify({
|
|
6724
7405
|
errorCode: demo.after.errorCode,
|
|
6725
7406
|
feedback: demo.after.feedback
|
|
6726
7407
|
}, null, 2)));
|
|
6727
|
-
console.log(
|
|
6728
|
-
console.log(
|
|
7408
|
+
console.log(chalk21.cyan("\n\u2705 Your code and secrets are NEVER transmitted."));
|
|
7409
|
+
console.log(chalk21.gray(" Learn more: https://agdi-dev.vercel.app/privacy\n"));
|
|
6729
7410
|
return;
|
|
6730
7411
|
}
|
|
6731
7412
|
if (options.enable) {
|
|
6732
7413
|
setTelemetryConsent(true);
|
|
6733
|
-
console.log(
|
|
6734
|
-
console.log(
|
|
6735
|
-
console.log(
|
|
6736
|
-
console.log(
|
|
7414
|
+
console.log(chalk21.green("\n\u2705 Telemetry enabled"));
|
|
7415
|
+
console.log(chalk21.gray(" We collect: success/fail, error types, model used"));
|
|
7416
|
+
console.log(chalk21.gray(" We NEVER collect: source code, API keys, file paths"));
|
|
7417
|
+
console.log(chalk21.gray(" Verify anytime: agdi config telemetry --dry-run\n"));
|
|
6737
7418
|
} else if (options.disable) {
|
|
6738
7419
|
setTelemetryConsent(false);
|
|
6739
|
-
console.log(
|
|
6740
|
-
console.log(
|
|
7420
|
+
console.log(chalk21.yellow("\n\u{1F4CA} Telemetry disabled"));
|
|
7421
|
+
console.log(chalk21.gray(" You can re-enable anytime with: agdi config telemetry --enable\n"));
|
|
6741
7422
|
} else {
|
|
6742
7423
|
const config = getTelemetryConfig();
|
|
6743
|
-
console.log(
|
|
6744
|
-
console.log(
|
|
6745
|
-
console.log(
|
|
7424
|
+
console.log(chalk21.cyan.bold("\n\u{1F4CA} Telemetry Status\n"));
|
|
7425
|
+
console.log(chalk21.gray(" Enabled: ") + (config.enabled ? chalk21.green("Yes") : chalk21.gray("No")));
|
|
7426
|
+
console.log(chalk21.gray(" Consent: ") + (config.consentAsked ? chalk21.green("Asked") : chalk21.gray("Not asked")));
|
|
6746
7427
|
if (config.anonymousId) {
|
|
6747
|
-
console.log(
|
|
7428
|
+
console.log(chalk21.gray(" ID: ") + chalk21.gray(config.anonymousId.slice(0, 8) + "..."));
|
|
6748
7429
|
}
|
|
6749
7430
|
console.log("");
|
|
6750
|
-
console.log(
|
|
6751
|
-
console.log(
|
|
6752
|
-
console.log(
|
|
7431
|
+
console.log(chalk21.gray(" Enable: agdi config telemetry --enable"));
|
|
7432
|
+
console.log(chalk21.gray(" Disable: agdi config telemetry --disable"));
|
|
7433
|
+
console.log(chalk21.gray(" Verify: agdi config telemetry --dry-run\n"));
|
|
6753
7434
|
}
|
|
6754
7435
|
});
|
|
6755
7436
|
program.command("doctor").alias("doc").description("Run self-diagnosis checks").action(async () => {
|
|
6756
7437
|
try {
|
|
6757
7438
|
await runDoctor();
|
|
6758
7439
|
} catch (error) {
|
|
6759
|
-
console.error(
|
|
7440
|
+
console.error(chalk21.red("Diagnostic failed: " + error));
|
|
6760
7441
|
ui.safeExit(1);
|
|
6761
7442
|
}
|
|
6762
7443
|
});
|
|
6763
|
-
program.command("features").description("List or sync upstream Agdi feature packs into this repo").option("--sync", "Copy feature packs from Agdi into ./upstream/agdi").option("--from <path>", "Path to Agdi source repo (default: ../Agdi)").option("--to <path>", "Destination path (default: ./upstream/agdi)").action(async (options) => {
|
|
7444
|
+
program.command("features").description("List or sync upstream Agdi feature packs into this repo").option("--sync", "Copy feature packs from Agdi into ./upstream/agdi").option("--all", "Mirror full upstream Agdi runtime/features into ./upstream/agdi").option("--from <path>", "Path to Agdi source repo (default: ../Agdi)").option("--to <path>", "Destination path (default: ./upstream/agdi)").action(async (options) => {
|
|
6764
7445
|
try {
|
|
6765
7446
|
await runFeaturesCommand(options);
|
|
6766
7447
|
} catch (error) {
|
|
6767
7448
|
if (error.name === "ExitPromptError") {
|
|
6768
|
-
console.log(
|
|
7449
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6769
7450
|
try {
|
|
6770
7451
|
ui.safeExit(0);
|
|
6771
7452
|
} catch {
|
|
@@ -6784,7 +7465,7 @@ channelsCommand.command("list").description("List discovered channel extensions
|
|
|
6784
7465
|
await runChannelsListCommand();
|
|
6785
7466
|
} catch (error) {
|
|
6786
7467
|
if (error.name === "ExitPromptError") {
|
|
6787
|
-
console.log(
|
|
7468
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6788
7469
|
try {
|
|
6789
7470
|
ui.safeExit(0);
|
|
6790
7471
|
} catch {
|
|
@@ -6802,7 +7483,7 @@ channelsCommand.command("send").description("Send a message through a supported
|
|
|
6802
7483
|
await runChannelsSendCommand(options);
|
|
6803
7484
|
} catch (error) {
|
|
6804
7485
|
const message = error instanceof Error ? error.message : String(error);
|
|
6805
|
-
console.log(
|
|
7486
|
+
console.log(chalk21.red(`
|
|
6806
7487
|
${message}
|
|
6807
7488
|
`));
|
|
6808
7489
|
try {
|
|
@@ -6816,7 +7497,7 @@ channelsCommand.command("doctor").description("Validate tokens/webhooks/session
|
|
|
6816
7497
|
await runChannelsDoctorCommand();
|
|
6817
7498
|
} catch (error) {
|
|
6818
7499
|
const message = error instanceof Error ? error.message : String(error);
|
|
6819
|
-
console.log(
|
|
7500
|
+
console.log(chalk21.red(`
|
|
6820
7501
|
${message}
|
|
6821
7502
|
`));
|
|
6822
7503
|
try {
|
|
@@ -6825,6 +7506,36 @@ ${message}
|
|
|
6825
7506
|
}
|
|
6826
7507
|
}
|
|
6827
7508
|
});
|
|
7509
|
+
var gatewayCommand = program.command("gateway").description("Native gateway control for Agdi-dev");
|
|
7510
|
+
gatewayCommand.command("status").description("Check gateway reachability and health endpoint").option("--host <host>", "Gateway host (default: 127.0.0.1)").option("--port <port>", "Gateway port (default: 18789)").action(async (options) => {
|
|
7511
|
+
await runGatewayStatusCommand(options);
|
|
7512
|
+
});
|
|
7513
|
+
gatewayCommand.command("health").description("Fetch /health from the gateway endpoint").option("--host <host>", "Gateway host (default: 127.0.0.1)").option("--port <port>", "Gateway port (default: 18789)").action(async (options) => {
|
|
7514
|
+
await runGatewayHealthCommand(options);
|
|
7515
|
+
});
|
|
7516
|
+
function registerUpstreamProxyCommand(spec) {
|
|
7517
|
+
const existingNames = /* @__PURE__ */ new Set();
|
|
7518
|
+
for (const cmd of program.commands) {
|
|
7519
|
+
existingNames.add(cmd.name());
|
|
7520
|
+
const aliases = cmd._aliases ?? [];
|
|
7521
|
+
for (const alias of aliases) {
|
|
7522
|
+
existingNames.add(alias);
|
|
7523
|
+
}
|
|
7524
|
+
}
|
|
7525
|
+
const requestedNames = [spec.name, ...spec.aliases ?? []];
|
|
7526
|
+
if (requestedNames.some((name) => existingNames.has(name))) {
|
|
7527
|
+
return;
|
|
7528
|
+
}
|
|
7529
|
+
const command = program.command(`${spec.name} [args...]`).description(`${spec.description} ${chalk21.gray("(proxied to upstream Agdi)")}`).helpOption(false).allowUnknownOption(true).allowExcessArguments(true).action(async () => {
|
|
7530
|
+
await runUpstreamProxy(spec);
|
|
7531
|
+
});
|
|
7532
|
+
for (const alias of spec.aliases ?? []) {
|
|
7533
|
+
command.alias(alias);
|
|
7534
|
+
}
|
|
7535
|
+
}
|
|
7536
|
+
for (const spec of UPSTREAM_PROXY_COMMANDS) {
|
|
7537
|
+
registerUpstreamProxyCommand(spec);
|
|
7538
|
+
}
|
|
6828
7539
|
program.command("squad [prompt]").alias("s").description("\u{1F9B8} Autonomous multi-agent app builder").option("-d, --deploy", "Auto-deploy to Vercel after build").option("-o, --output <dir>", "Output directory", "./").option("-v, --verbose", "Show detailed agent logs", true).action(async (prompt, options) => {
|
|
6829
7540
|
try {
|
|
6830
7541
|
if (needsOnboarding()) {
|
|
@@ -6832,7 +7543,7 @@ program.command("squad [prompt]").alias("s").description("\u{1F9B8} Autonomous m
|
|
|
6832
7543
|
}
|
|
6833
7544
|
const activeConfig = getActiveProvider();
|
|
6834
7545
|
if (!activeConfig) {
|
|
6835
|
-
console.log(
|
|
7546
|
+
console.log(chalk21.red("\u274C No API key configured. Run: agdi auth"));
|
|
6836
7547
|
return;
|
|
6837
7548
|
}
|
|
6838
7549
|
const llm = createLLMProvider(activeConfig.provider, {
|
|
@@ -6846,7 +7557,7 @@ program.command("squad [prompt]").alias("s").description("\u{1F9B8} Autonomous m
|
|
|
6846
7557
|
});
|
|
6847
7558
|
} catch (error) {
|
|
6848
7559
|
if (error.name === "ExitPromptError") {
|
|
6849
|
-
console.log(
|
|
7560
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6850
7561
|
try {
|
|
6851
7562
|
ui.safeExit(0);
|
|
6852
7563
|
} catch {
|
|
@@ -6874,7 +7585,7 @@ program.command("replay <runId>").description("\u{1F501} Replay a previous squad
|
|
|
6874
7585
|
}
|
|
6875
7586
|
const activeConfig = getActiveProvider();
|
|
6876
7587
|
if (!activeConfig) {
|
|
6877
|
-
console.log(
|
|
7588
|
+
console.log(chalk21.red("\u274C No API key configured. Run: agdi auth"));
|
|
6878
7589
|
return;
|
|
6879
7590
|
}
|
|
6880
7591
|
const llm = createLLMProvider(activeConfig.provider, {
|
|
@@ -6888,7 +7599,7 @@ program.command("replay <runId>").description("\u{1F501} Replay a previous squad
|
|
|
6888
7599
|
});
|
|
6889
7600
|
} catch (error) {
|
|
6890
7601
|
if (error.name === "ExitPromptError") {
|
|
6891
|
-
console.log(
|
|
7602
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6892
7603
|
try {
|
|
6893
7604
|
ui.safeExit(0);
|
|
6894
7605
|
} catch {
|
|
@@ -6906,7 +7617,7 @@ program.command("import <url>").alias("i").description("\u{1F4E6} Import a GitHu
|
|
|
6906
7617
|
await runImportCommand(url, options.output);
|
|
6907
7618
|
} catch (error) {
|
|
6908
7619
|
if (error.name === "ExitPromptError") {
|
|
6909
|
-
console.log(
|
|
7620
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6910
7621
|
try {
|
|
6911
7622
|
ui.safeExit(0);
|
|
6912
7623
|
} catch {
|
|
@@ -6920,7 +7631,7 @@ program.command("wizard").alias("w").description("\u{1F9D9} Start the ClawBot Se
|
|
|
6920
7631
|
try {
|
|
6921
7632
|
await runWizard();
|
|
6922
7633
|
} catch (error) {
|
|
6923
|
-
console.log(
|
|
7634
|
+
console.log(chalk21.gray("\n\n\u{1F44B} Cancelled.\n"));
|
|
6924
7635
|
try {
|
|
6925
7636
|
ui.safeExit(0);
|
|
6926
7637
|
} catch {
|