@agi_inc/cli 0.5.8 → 0.5.10
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.mjs +641 -82
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/index.tsx
|
|
2
2
|
import React10 from "react";
|
|
3
3
|
import { render } from "ink";
|
|
4
|
-
import { isBinaryAvailable } from "@agi_inc/agi-js";
|
|
4
|
+
import { isBinaryAvailable as isBinaryAvailable2 } from "@agi_inc/agi-js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import yargs from "yargs";
|
|
@@ -288,7 +288,7 @@ async function parseArgs() {
|
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
// src/app/App.tsx
|
|
291
|
-
import React9, { useEffect as
|
|
291
|
+
import React9, { useEffect as useEffect5, useState as useState7, useCallback as useCallback3, useMemo as useMemo2, useRef as useRef3 } from "react";
|
|
292
292
|
import { Box as Box8, Text as Text9, useApp } from "ink";
|
|
293
293
|
|
|
294
294
|
// src/hooks/useAgent.ts
|
|
@@ -674,8 +674,332 @@ import { Text as Text6, Box as Box5, useInput as useInput4 } from "ink";
|
|
|
674
674
|
import TextInput2 from "ink-text-input";
|
|
675
675
|
|
|
676
676
|
// src/commands/slash.ts
|
|
677
|
-
import { readFileSync as
|
|
678
|
-
import { basename } from "path";
|
|
677
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
678
|
+
import { basename as basename2 } from "path";
|
|
679
|
+
import os4 from "os";
|
|
680
|
+
import { isBinaryAvailable } from "@agi_inc/agi-js";
|
|
681
|
+
|
|
682
|
+
// src/history.ts
|
|
683
|
+
import fs2 from "fs";
|
|
684
|
+
import path2 from "path";
|
|
685
|
+
import os2 from "os";
|
|
686
|
+
var HISTORY_DIR = path2.join(os2.homedir(), ".agi");
|
|
687
|
+
var HISTORY_FILE = path2.join(HISTORY_DIR, "history.json");
|
|
688
|
+
var MAX_ENTRIES = 200;
|
|
689
|
+
function ensureDir() {
|
|
690
|
+
if (!fs2.existsSync(HISTORY_DIR)) {
|
|
691
|
+
fs2.mkdirSync(HISTORY_DIR, { recursive: true, mode: 448 });
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
function loadHistory() {
|
|
695
|
+
try {
|
|
696
|
+
const raw = fs2.readFileSync(HISTORY_FILE, "utf-8");
|
|
697
|
+
const data = JSON.parse(raw);
|
|
698
|
+
if (Array.isArray(data)) return data;
|
|
699
|
+
} catch {
|
|
700
|
+
}
|
|
701
|
+
return [];
|
|
702
|
+
}
|
|
703
|
+
function appendHistory(entry) {
|
|
704
|
+
ensureDir();
|
|
705
|
+
const history = loadHistory();
|
|
706
|
+
history.push(entry);
|
|
707
|
+
const trimmed = history.slice(-MAX_ENTRIES);
|
|
708
|
+
fs2.writeFileSync(HISTORY_FILE, JSON.stringify(trimmed, null, 2) + "\n", {
|
|
709
|
+
mode: 384
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
function clearHistory() {
|
|
713
|
+
try {
|
|
714
|
+
fs2.unlinkSync(HISTORY_FILE);
|
|
715
|
+
} catch {
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
function formatHistory(entries, limit = 20) {
|
|
719
|
+
if (entries.length === 0) return " No history yet.";
|
|
720
|
+
const recent = entries.slice(-limit).reverse();
|
|
721
|
+
const lines = ["", " Recent sessions:", ""];
|
|
722
|
+
for (const entry of recent) {
|
|
723
|
+
const date = new Date(entry.timestamp);
|
|
724
|
+
const timeStr = date.toLocaleDateString("en-US", {
|
|
725
|
+
month: "short",
|
|
726
|
+
day: "numeric"
|
|
727
|
+
}) + " " + date.toLocaleTimeString("en-US", {
|
|
728
|
+
hour: "2-digit",
|
|
729
|
+
minute: "2-digit",
|
|
730
|
+
hour12: false
|
|
731
|
+
});
|
|
732
|
+
const status = entry.success === true ? "\u25CF" : entry.success === false ? "\u2715" : "\u25CB";
|
|
733
|
+
const duration = entry.durationMs ? ` (${Math.round(entry.durationMs / 1e3)}s)` : "";
|
|
734
|
+
const goal = entry.goal.length > 55 ? entry.goal.slice(0, 55) + "\u2026" : entry.goal;
|
|
735
|
+
lines.push(` ${status} ${timeStr} ${goal}${duration}`);
|
|
736
|
+
}
|
|
737
|
+
lines.push("");
|
|
738
|
+
if (entries.length > limit) {
|
|
739
|
+
lines.push(` Showing ${limit} of ${entries.length} entries`);
|
|
740
|
+
lines.push("");
|
|
741
|
+
}
|
|
742
|
+
return lines.join("\n");
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// src/project.ts
|
|
746
|
+
import { readFileSync as readFileSync2, existsSync, readdirSync } from "fs";
|
|
747
|
+
import { join as join2, basename } from "path";
|
|
748
|
+
|
|
749
|
+
// src/skills.ts
|
|
750
|
+
import fs3 from "fs";
|
|
751
|
+
import path3 from "path";
|
|
752
|
+
import os3 from "os";
|
|
753
|
+
function parseFrontmatter(content) {
|
|
754
|
+
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
755
|
+
if (!match) return { meta: {}, body: content.trim() };
|
|
756
|
+
const meta = {};
|
|
757
|
+
for (const line of match[1].split("\n")) {
|
|
758
|
+
const colonIdx = line.indexOf(":");
|
|
759
|
+
if (colonIdx > 0) {
|
|
760
|
+
const key = line.slice(0, colonIdx).trim();
|
|
761
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
762
|
+
meta[key] = value;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
return { meta, body: match[2].trim() };
|
|
766
|
+
}
|
|
767
|
+
var NAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
768
|
+
function isValidSkillName(name) {
|
|
769
|
+
if (name.length > 64) return false;
|
|
770
|
+
if (!NAME_RE.test(name)) return false;
|
|
771
|
+
if (name.includes("--")) return false;
|
|
772
|
+
return true;
|
|
773
|
+
}
|
|
774
|
+
function discoverSkillsInDir(skillsDir, scope) {
|
|
775
|
+
const skills = [];
|
|
776
|
+
if (!fs3.existsSync(skillsDir)) return skills;
|
|
777
|
+
let entries;
|
|
778
|
+
try {
|
|
779
|
+
entries = fs3.readdirSync(skillsDir);
|
|
780
|
+
} catch {
|
|
781
|
+
return skills;
|
|
782
|
+
}
|
|
783
|
+
for (const entry of entries) {
|
|
784
|
+
const skillDir = path3.join(skillsDir, entry);
|
|
785
|
+
const skillFile = path3.join(skillDir, "SKILL.md");
|
|
786
|
+
try {
|
|
787
|
+
if (!fs3.statSync(skillDir).isDirectory()) continue;
|
|
788
|
+
if (!fs3.existsSync(skillFile)) continue;
|
|
789
|
+
} catch {
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
if (!isValidSkillName(entry)) continue;
|
|
793
|
+
try {
|
|
794
|
+
const content = fs3.readFileSync(skillFile, "utf-8");
|
|
795
|
+
const { meta } = parseFrontmatter(content);
|
|
796
|
+
const name = meta["name"] || entry;
|
|
797
|
+
if (name !== entry) continue;
|
|
798
|
+
const description = meta["description"] || "";
|
|
799
|
+
if (!description) continue;
|
|
800
|
+
skills.push({
|
|
801
|
+
name,
|
|
802
|
+
description,
|
|
803
|
+
path: skillFile,
|
|
804
|
+
root: skillDir,
|
|
805
|
+
scope,
|
|
806
|
+
license: meta["license"],
|
|
807
|
+
compatibility: meta["compatibility"],
|
|
808
|
+
userInvocable: meta["user-invocable"] !== "false",
|
|
809
|
+
argumentHint: meta["argument-hint"],
|
|
810
|
+
metadata: Object.keys(meta).length > 0 ? meta : void 0
|
|
811
|
+
});
|
|
812
|
+
} catch {
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
return skills;
|
|
816
|
+
}
|
|
817
|
+
function discoverSkills(cwd = process.cwd()) {
|
|
818
|
+
const personalDir = path3.join(os3.homedir(), ".agi", "skills");
|
|
819
|
+
const projectDir = path3.join(cwd, ".agi", "skills");
|
|
820
|
+
const personal = discoverSkillsInDir(personalDir, "personal");
|
|
821
|
+
const project = discoverSkillsInDir(projectDir, "project");
|
|
822
|
+
const byName = /* @__PURE__ */ new Map();
|
|
823
|
+
for (const skill of personal) byName.set(skill.name, skill);
|
|
824
|
+
for (const skill of project) byName.set(skill.name, skill);
|
|
825
|
+
return Array.from(byName.values());
|
|
826
|
+
}
|
|
827
|
+
function loadSkill(skill) {
|
|
828
|
+
const content = fs3.readFileSync(skill.path, "utf-8");
|
|
829
|
+
const { body } = parseFrontmatter(content);
|
|
830
|
+
return { ...skill, body };
|
|
831
|
+
}
|
|
832
|
+
function generateSkillsPrompt(skills) {
|
|
833
|
+
if (skills.length === 0) return "";
|
|
834
|
+
const lines = ["<available_skills>"];
|
|
835
|
+
for (const skill of skills) {
|
|
836
|
+
lines.push(" <skill>");
|
|
837
|
+
lines.push(` <name>${skill.name}</name>`);
|
|
838
|
+
lines.push(` <description>${skill.description}</description>`);
|
|
839
|
+
lines.push(` <location>${skill.path}</location>`);
|
|
840
|
+
lines.push(" </skill>");
|
|
841
|
+
}
|
|
842
|
+
lines.push("</available_skills>");
|
|
843
|
+
return lines.join("\n");
|
|
844
|
+
}
|
|
845
|
+
function formatSkillsList(skills) {
|
|
846
|
+
if (skills.length === 0) return " No skills found.";
|
|
847
|
+
const lines = ["", " Available skills:", ""];
|
|
848
|
+
for (const skill of skills) {
|
|
849
|
+
const scope = skill.scope === "personal" ? "~" : ".";
|
|
850
|
+
const hint = skill.argumentHint ? ` ${skill.argumentHint}` : "";
|
|
851
|
+
lines.push(` ${scope} /${skill.name}${hint}`);
|
|
852
|
+
lines.push(` ${skill.description}`);
|
|
853
|
+
}
|
|
854
|
+
lines.push("");
|
|
855
|
+
return lines.join("\n");
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// src/project.ts
|
|
859
|
+
import { mkdirSync, writeFileSync } from "fs";
|
|
860
|
+
var INSTRUCTION_FILES = ["AGI.md", ".agi/AGI.md", ".agi/instructions.md"];
|
|
861
|
+
function loadRules(cwd) {
|
|
862
|
+
const rulesDir = join2(cwd, ".agi", "rules");
|
|
863
|
+
if (!existsSync(rulesDir)) return [];
|
|
864
|
+
const rules = [];
|
|
865
|
+
try {
|
|
866
|
+
const files = readdirSync(rulesDir).filter((f) => f.endsWith(".md")).sort();
|
|
867
|
+
for (const file of files) {
|
|
868
|
+
const filePath = join2(rulesDir, file);
|
|
869
|
+
try {
|
|
870
|
+
const raw = readFileSync2(filePath, "utf-8");
|
|
871
|
+
const name = basename(file, ".md");
|
|
872
|
+
let content = raw.trim();
|
|
873
|
+
let paths;
|
|
874
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
875
|
+
if (fmMatch) {
|
|
876
|
+
const meta = fmMatch[1];
|
|
877
|
+
content = fmMatch[2].trim();
|
|
878
|
+
const pathsMatch = meta.match(/^paths:\s*(.+)$/m);
|
|
879
|
+
if (pathsMatch) {
|
|
880
|
+
paths = pathsMatch[1].split(",").map((p) => p.trim()).filter(Boolean);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
if (content) {
|
|
884
|
+
rules.push({ name, path: filePath, content, paths });
|
|
885
|
+
}
|
|
886
|
+
} catch {
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
} catch {
|
|
890
|
+
}
|
|
891
|
+
return rules;
|
|
892
|
+
}
|
|
893
|
+
function loadProjectConfig(cwd = process.cwd()) {
|
|
894
|
+
let instructions = null;
|
|
895
|
+
let instructionsPath = null;
|
|
896
|
+
for (const relPath of INSTRUCTION_FILES) {
|
|
897
|
+
const fullPath = join2(cwd, relPath);
|
|
898
|
+
if (existsSync(fullPath)) {
|
|
899
|
+
try {
|
|
900
|
+
instructions = readFileSync2(fullPath, "utf-8").trim();
|
|
901
|
+
instructionsPath = fullPath;
|
|
902
|
+
break;
|
|
903
|
+
} catch {
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
const agiDir = join2(cwd, ".agi");
|
|
908
|
+
const agiDirExists = existsSync(agiDir);
|
|
909
|
+
const commandFiles = [];
|
|
910
|
+
const commandsDir = join2(cwd, ".agi", "commands");
|
|
911
|
+
if (existsSync(commandsDir)) {
|
|
912
|
+
try {
|
|
913
|
+
const files = readdirSync(commandsDir);
|
|
914
|
+
for (const file of files) {
|
|
915
|
+
if (file.endsWith(".md")) {
|
|
916
|
+
commandFiles.push(join2(commandsDir, file));
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
} catch {
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
const rules = loadRules(cwd);
|
|
923
|
+
const skills = discoverSkills(cwd);
|
|
924
|
+
return {
|
|
925
|
+
instructions,
|
|
926
|
+
instructionsPath,
|
|
927
|
+
agiDir: agiDirExists ? agiDir : null,
|
|
928
|
+
commandFiles,
|
|
929
|
+
rules,
|
|
930
|
+
skills
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
function withProjectInstructions(goal, config) {
|
|
934
|
+
const sections = [];
|
|
935
|
+
if (config.instructions) {
|
|
936
|
+
sections.push(
|
|
937
|
+
"--- Project Instructions (from " + (config.instructionsPath ?? "AGI.md") + ") ---",
|
|
938
|
+
config.instructions,
|
|
939
|
+
"--- End Project Instructions ---"
|
|
940
|
+
);
|
|
941
|
+
}
|
|
942
|
+
if (config.rules.length > 0) {
|
|
943
|
+
sections.push("--- Project Rules ---");
|
|
944
|
+
for (const rule of config.rules) {
|
|
945
|
+
sections.push(`[${rule.name}]`);
|
|
946
|
+
sections.push(rule.content);
|
|
947
|
+
sections.push("");
|
|
948
|
+
}
|
|
949
|
+
sections.push("--- End Project Rules ---");
|
|
950
|
+
}
|
|
951
|
+
if (config.skills.length > 0) {
|
|
952
|
+
sections.push(generateSkillsPrompt(config.skills));
|
|
953
|
+
}
|
|
954
|
+
if (sections.length === 0) return goal;
|
|
955
|
+
sections.push("", "Task: " + goal);
|
|
956
|
+
return sections.join("\n");
|
|
957
|
+
}
|
|
958
|
+
function initProject(cwd = process.cwd()) {
|
|
959
|
+
const created = [];
|
|
960
|
+
const agiMd = join2(cwd, "AGI.md");
|
|
961
|
+
if (!existsSync(agiMd)) {
|
|
962
|
+
writeFileSync(
|
|
963
|
+
agiMd,
|
|
964
|
+
[
|
|
965
|
+
"# Project Instructions",
|
|
966
|
+
"",
|
|
967
|
+
"<!-- Add project-specific instructions for the AGI agent here. -->",
|
|
968
|
+
"<!-- These instructions are loaded automatically when you run `agi`. -->",
|
|
969
|
+
""
|
|
970
|
+
].join("\n")
|
|
971
|
+
);
|
|
972
|
+
created.push("AGI.md");
|
|
973
|
+
}
|
|
974
|
+
const dirs = [
|
|
975
|
+
".agi",
|
|
976
|
+
".agi/commands",
|
|
977
|
+
".agi/rules",
|
|
978
|
+
".agi/skills"
|
|
979
|
+
];
|
|
980
|
+
for (const dir of dirs) {
|
|
981
|
+
const fullPath = join2(cwd, dir);
|
|
982
|
+
if (!existsSync(fullPath)) {
|
|
983
|
+
mkdirSync(fullPath, { recursive: true });
|
|
984
|
+
created.push(dir + "/");
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
const gitignore = join2(cwd, ".agi", ".gitignore");
|
|
988
|
+
if (!existsSync(gitignore)) {
|
|
989
|
+
writeFileSync(
|
|
990
|
+
gitignore,
|
|
991
|
+
[
|
|
992
|
+
"# Local files that should not be committed",
|
|
993
|
+
"local.md",
|
|
994
|
+
""
|
|
995
|
+
].join("\n")
|
|
996
|
+
);
|
|
997
|
+
created.push(".agi/.gitignore");
|
|
998
|
+
}
|
|
999
|
+
return created;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// src/commands/slash.ts
|
|
679
1003
|
var VALID_MODELS = ["claude-sonnet", "claude-opus"];
|
|
680
1004
|
var builtinCommands = [
|
|
681
1005
|
{
|
|
@@ -689,8 +1013,9 @@ var builtinCommands = [
|
|
|
689
1013
|
" Available commands:",
|
|
690
1014
|
""
|
|
691
1015
|
];
|
|
692
|
-
const builtins = all.filter((c) => !c.isUserDefined);
|
|
1016
|
+
const builtins = all.filter((c) => !c.isUserDefined && !c.isSkill);
|
|
693
1017
|
const userDefined = all.filter((c) => c.isUserDefined);
|
|
1018
|
+
const skills = all.filter((c) => c.isSkill);
|
|
694
1019
|
for (const cmd of builtins) {
|
|
695
1020
|
const aliases = cmd.aliases?.length ? ` (${cmd.aliases.map((a) => "/" + a).join(", ")})` : "";
|
|
696
1021
|
const usage = cmd.usage ? ` ${cmd.usage}` : "";
|
|
@@ -707,6 +1032,65 @@ var builtinCommands = [
|
|
|
707
1032
|
lines.push(` ${cmd.description}`);
|
|
708
1033
|
}
|
|
709
1034
|
}
|
|
1035
|
+
if (skills.length > 0) {
|
|
1036
|
+
lines.push("");
|
|
1037
|
+
lines.push(" Skills (.agi/skills/):");
|
|
1038
|
+
lines.push("");
|
|
1039
|
+
for (const cmd of skills) {
|
|
1040
|
+
const usage = cmd.usage ? ` ${cmd.usage}` : "";
|
|
1041
|
+
lines.push(` /${cmd.name}${usage}`);
|
|
1042
|
+
lines.push(` ${cmd.description}`);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
lines.push("");
|
|
1046
|
+
return lines.join("\n");
|
|
1047
|
+
}
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
name: "history",
|
|
1051
|
+
aliases: ["hist"],
|
|
1052
|
+
description: "Show session history",
|
|
1053
|
+
usage: "[clear]",
|
|
1054
|
+
execute: (args) => {
|
|
1055
|
+
if (args.trim().toLowerCase() === "clear") {
|
|
1056
|
+
clearHistory();
|
|
1057
|
+
return " History cleared.";
|
|
1058
|
+
}
|
|
1059
|
+
const entries = loadHistory();
|
|
1060
|
+
return formatHistory(entries);
|
|
1061
|
+
}
|
|
1062
|
+
},
|
|
1063
|
+
{
|
|
1064
|
+
name: "status",
|
|
1065
|
+
aliases: ["info"],
|
|
1066
|
+
description: "Show environment and session info",
|
|
1067
|
+
execute: (_args, ctx) => {
|
|
1068
|
+
const lines = ["", " Environment:", ""];
|
|
1069
|
+
lines.push(` Version ${ctx.version || "unknown"}`);
|
|
1070
|
+
lines.push(` Model ${ctx.model}`);
|
|
1071
|
+
lines.push(` Working dir ${process.cwd().replace(os4.homedir(), "~")}`);
|
|
1072
|
+
lines.push(` Node.js ${process.version}`);
|
|
1073
|
+
lines.push(` Platform ${process.platform} ${process.arch}`);
|
|
1074
|
+
lines.push(` Driver ${isBinaryAvailable() ? "\u2714 available" : "\u2718 not found"}`);
|
|
1075
|
+
lines.push(` API key ${process.env.AGI_API_KEY ? "\u2714 set" : process.env.ANTHROPIC_API_KEY ? "\u2714 set (ANTHROPIC_API_KEY)" : "\u2718 not set"}`);
|
|
1076
|
+
lines.push("");
|
|
1077
|
+
lines.push(" Session:");
|
|
1078
|
+
lines.push("");
|
|
1079
|
+
lines.push(` Verbose ${ctx.verbose ? "on" : "off"}`);
|
|
1080
|
+
lines.push(` Auto-confirm ${ctx.noConfirm ? "on" : "off"}`);
|
|
1081
|
+
lines.push(` Compact mode ${ctx.compact ? "on" : "off"}`);
|
|
1082
|
+
if (ctx.projectConfig) {
|
|
1083
|
+
lines.push("");
|
|
1084
|
+
lines.push(" Project:");
|
|
1085
|
+
lines.push("");
|
|
1086
|
+
lines.push(` Instructions ${ctx.projectConfig.instructionsPath?.replace(process.cwd(), ".") || "none"}`);
|
|
1087
|
+
lines.push(` Rules ${ctx.projectConfig.rules.length} loaded`);
|
|
1088
|
+
lines.push(` Commands ${ctx.projectConfig.commandFiles.length} custom`);
|
|
1089
|
+
lines.push(` Skills ${ctx.projectConfig.skills.length} discovered`);
|
|
1090
|
+
}
|
|
1091
|
+
const history = loadHistory();
|
|
1092
|
+
lines.push("");
|
|
1093
|
+
lines.push(` History ${history.length} past sessions`);
|
|
710
1094
|
lines.push("");
|
|
711
1095
|
return lines.join("\n");
|
|
712
1096
|
}
|
|
@@ -737,6 +1121,14 @@ var builtinCommands = [
|
|
|
737
1121
|
return ` Verbose output ${!ctx.verbose ? "on" : "off"}`;
|
|
738
1122
|
}
|
|
739
1123
|
},
|
|
1124
|
+
{
|
|
1125
|
+
name: "compact",
|
|
1126
|
+
description: "Toggle compact output mode",
|
|
1127
|
+
execute: (_args, ctx) => {
|
|
1128
|
+
ctx.setCompact(!ctx.compact);
|
|
1129
|
+
return ` Compact mode ${!ctx.compact ? "on" : "off"}`;
|
|
1130
|
+
}
|
|
1131
|
+
},
|
|
740
1132
|
{
|
|
741
1133
|
name: "confirm",
|
|
742
1134
|
description: "Toggle auto-confirm mode",
|
|
@@ -745,6 +1137,80 @@ var builtinCommands = [
|
|
|
745
1137
|
return ` Auto-confirm ${!ctx.noConfirm ? "on" : "off"}`;
|
|
746
1138
|
}
|
|
747
1139
|
},
|
|
1140
|
+
{
|
|
1141
|
+
name: "init",
|
|
1142
|
+
description: "Initialize AGI.md and .agi/ project structure",
|
|
1143
|
+
execute: () => {
|
|
1144
|
+
const created = initProject();
|
|
1145
|
+
if (created.length === 0) {
|
|
1146
|
+
return " Project already initialized \u2014 AGI.md and .agi/ exist.";
|
|
1147
|
+
}
|
|
1148
|
+
const lines = ["", " Initialized project:", ""];
|
|
1149
|
+
for (const item of created) {
|
|
1150
|
+
lines.push(` \u2714 Created ${item}`);
|
|
1151
|
+
}
|
|
1152
|
+
lines.push("");
|
|
1153
|
+
lines.push(" Edit AGI.md to add project instructions for the agent.");
|
|
1154
|
+
lines.push(" Add custom commands in .agi/commands/*.md");
|
|
1155
|
+
lines.push(" Add rules in .agi/rules/*.md");
|
|
1156
|
+
lines.push(" Add skills in .agi/skills/<name>/SKILL.md");
|
|
1157
|
+
lines.push("");
|
|
1158
|
+
return lines.join("\n");
|
|
1159
|
+
}
|
|
1160
|
+
},
|
|
1161
|
+
{
|
|
1162
|
+
name: "doctor",
|
|
1163
|
+
aliases: ["check"],
|
|
1164
|
+
description: "Check system health and configuration",
|
|
1165
|
+
execute: (_args, ctx) => {
|
|
1166
|
+
const checks = [];
|
|
1167
|
+
const hasKey = !!(process.env.AGI_API_KEY || process.env.ANTHROPIC_API_KEY);
|
|
1168
|
+
checks.push({
|
|
1169
|
+
label: "API key",
|
|
1170
|
+
ok: hasKey,
|
|
1171
|
+
detail: hasKey ? "configured" : "missing \u2014 run `agi login` or set AGI_API_KEY"
|
|
1172
|
+
});
|
|
1173
|
+
const hasDriver = isBinaryAvailable();
|
|
1174
|
+
checks.push({
|
|
1175
|
+
label: "Driver binary",
|
|
1176
|
+
ok: hasDriver,
|
|
1177
|
+
detail: hasDriver ? "found" : "not found \u2014 reinstall @agi_inc/cli"
|
|
1178
|
+
});
|
|
1179
|
+
const nodeVer = process.versions.node;
|
|
1180
|
+
const [major] = nodeVer.split(".").map(Number);
|
|
1181
|
+
checks.push({
|
|
1182
|
+
label: "Node.js",
|
|
1183
|
+
ok: major >= 18,
|
|
1184
|
+
detail: `v${nodeVer}${major < 18 ? " \u2014 v18+ required" : ""}`
|
|
1185
|
+
});
|
|
1186
|
+
if (ctx.projectConfig) {
|
|
1187
|
+
checks.push({
|
|
1188
|
+
label: "Project instructions",
|
|
1189
|
+
ok: !!ctx.projectConfig.instructions,
|
|
1190
|
+
detail: ctx.projectConfig.instructionsPath?.replace(process.cwd(), ".") || "none \u2014 run /init"
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
const lines = ["", " System health:", ""];
|
|
1194
|
+
for (const check of checks) {
|
|
1195
|
+
const icon = check.ok ? "\u2714" : "\u2718";
|
|
1196
|
+
const color = check.ok ? "" : "";
|
|
1197
|
+
lines.push(` ${icon} ${check.label.padEnd(22)} ${check.detail}`);
|
|
1198
|
+
}
|
|
1199
|
+
const allOk = checks.every((c) => c.ok);
|
|
1200
|
+
lines.push("");
|
|
1201
|
+
lines.push(allOk ? " All checks passed." : " Some checks failed \u2014 see above.");
|
|
1202
|
+
lines.push("");
|
|
1203
|
+
return lines.join("\n");
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1206
|
+
{
|
|
1207
|
+
name: "skills",
|
|
1208
|
+
description: "List discovered skills",
|
|
1209
|
+
execute: (_args, ctx) => {
|
|
1210
|
+
if (!ctx.projectConfig) return " No project config loaded.";
|
|
1211
|
+
return formatSkillsList(ctx.projectConfig.skills);
|
|
1212
|
+
}
|
|
1213
|
+
},
|
|
748
1214
|
{
|
|
749
1215
|
name: "clear",
|
|
750
1216
|
aliases: ["c"],
|
|
@@ -764,7 +1230,7 @@ var builtinCommands = [
|
|
|
764
1230
|
}
|
|
765
1231
|
}
|
|
766
1232
|
];
|
|
767
|
-
function
|
|
1233
|
+
function parseFrontmatter2(content) {
|
|
768
1234
|
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
769
1235
|
if (!match) return { meta: {}, body: content.trim() };
|
|
770
1236
|
const meta = {};
|
|
@@ -782,9 +1248,9 @@ function loadUserCommands(commandFiles) {
|
|
|
782
1248
|
const userCommands = [];
|
|
783
1249
|
for (const filePath of commandFiles) {
|
|
784
1250
|
try {
|
|
785
|
-
const content =
|
|
786
|
-
const { meta, body } =
|
|
787
|
-
const name =
|
|
1251
|
+
const content = readFileSync3(filePath, "utf-8");
|
|
1252
|
+
const { meta, body } = parseFrontmatter2(content);
|
|
1253
|
+
const name = basename2(filePath, ".md");
|
|
788
1254
|
const description = meta["description"] || body.split("\n")[0].slice(0, 60);
|
|
789
1255
|
const usage = meta["argument-hint"];
|
|
790
1256
|
userCommands.push({
|
|
@@ -810,6 +1276,26 @@ function loadUserCommands(commandFiles) {
|
|
|
810
1276
|
}
|
|
811
1277
|
return userCommands;
|
|
812
1278
|
}
|
|
1279
|
+
function loadSkillCommands(skills) {
|
|
1280
|
+
return skills.filter((s) => s.userInvocable).map((skill) => ({
|
|
1281
|
+
name: skill.name,
|
|
1282
|
+
description: skill.description,
|
|
1283
|
+
usage: skill.argumentHint,
|
|
1284
|
+
isSkill: true,
|
|
1285
|
+
execute: (args, ctx) => {
|
|
1286
|
+
if (!ctx.runGoal) return ` Error: cannot run skill commands in this context`;
|
|
1287
|
+
const loaded = loadSkill(skill);
|
|
1288
|
+
let prompt = loaded.body;
|
|
1289
|
+
prompt = prompt.replace(/\$ARGUMENTS/g, args);
|
|
1290
|
+
const argParts = args.split(/\s+/).filter(Boolean);
|
|
1291
|
+
for (let i = 0; i < argParts.length; i++) {
|
|
1292
|
+
prompt = prompt.replace(new RegExp(`\\$${i + 1}`, "g"), argParts[i]);
|
|
1293
|
+
}
|
|
1294
|
+
ctx.runGoal(prompt);
|
|
1295
|
+
return null;
|
|
1296
|
+
}
|
|
1297
|
+
}));
|
|
1298
|
+
}
|
|
813
1299
|
var allCommands = [...builtinCommands];
|
|
814
1300
|
var commandMap = /* @__PURE__ */ new Map();
|
|
815
1301
|
function rebuildMap() {
|
|
@@ -929,89 +1415,139 @@ var Spinner = ({ text }) => {
|
|
|
929
1415
|
};
|
|
930
1416
|
|
|
931
1417
|
// src/components/Logo.tsx
|
|
932
|
-
import React8 from "react";
|
|
1418
|
+
import React8, { useState as useState6, useEffect as useEffect4, useMemo } from "react";
|
|
933
1419
|
import { Text as Text8, Box as Box7 } from "ink";
|
|
934
|
-
var
|
|
935
|
-
|
|
936
|
-
"\u2588
|
|
937
|
-
"
|
|
1420
|
+
var BLOCK_CHARS = " \u2591\u2592\u2593\u2588";
|
|
1421
|
+
var BASE_LOGO = [
|
|
1422
|
+
" \u2588\u2588\u2588\u2588\u2591 \u2588\u2588\u2588\u2588 ",
|
|
1423
|
+
" \u2588\u2588\u2592 \u2588\u2588\u2588 \u2591\u2588\u2588 \u2588\u2588\u2588 ",
|
|
1424
|
+
" \u2588\u2588\u2588 \u2591\u2588\u2588\u2588 \u2588\u2588\u2588 ",
|
|
1425
|
+
" \u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2592\u2588\u2588 ",
|
|
1426
|
+
" \u2588\u2588\u2588\u2588 \u2591\u2588\u2588\u2588\u2588 "
|
|
938
1427
|
];
|
|
939
|
-
var
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
var
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1428
|
+
var BASE_GRID = BASE_LOGO.map(
|
|
1429
|
+
(line) => [...line].map((ch) => {
|
|
1430
|
+
const idx = BLOCK_CHARS.indexOf(ch);
|
|
1431
|
+
return idx >= 0 ? idx : 0;
|
|
1432
|
+
})
|
|
1433
|
+
);
|
|
1434
|
+
var MASK = BASE_GRID.map((row) => row.map((v) => v > 0));
|
|
1435
|
+
var WIDTH = BASE_GRID[0].length;
|
|
1436
|
+
var MOODS = {
|
|
1437
|
+
idle: {
|
|
1438
|
+
speed: 0.3,
|
|
1439
|
+
amplitude: 1.2,
|
|
1440
|
+
shimmer: 0.3,
|
|
1441
|
+
breathe: 0.5,
|
|
1442
|
+
breatheSpeed: 0.15,
|
|
1443
|
+
colors: ["#005566", "#008899", "#00aacc", "#00ccee", "#66eeff"]
|
|
1444
|
+
},
|
|
1445
|
+
thinking: {
|
|
1446
|
+
speed: 1.5,
|
|
1447
|
+
amplitude: 1.8,
|
|
1448
|
+
shimmer: 0.6,
|
|
1449
|
+
breathe: 0.3,
|
|
1450
|
+
breatheSpeed: 0.4,
|
|
1451
|
+
colors: ["#665500", "#998800", "#ccaa00", "#eedd00", "#ffff44"]
|
|
1452
|
+
},
|
|
1453
|
+
active: {
|
|
1454
|
+
speed: 0.8,
|
|
1455
|
+
amplitude: 1,
|
|
1456
|
+
shimmer: 0.2,
|
|
1457
|
+
breathe: 0.4,
|
|
1458
|
+
breatheSpeed: 0.25,
|
|
1459
|
+
colors: ["#004400", "#007700", "#00aa00", "#00dd00", "#44ff66"]
|
|
1460
|
+
},
|
|
1461
|
+
success: {
|
|
1462
|
+
speed: 0.2,
|
|
1463
|
+
amplitude: 0.6,
|
|
1464
|
+
shimmer: 0.1,
|
|
1465
|
+
breathe: 0.6,
|
|
1466
|
+
breatheSpeed: 0.1,
|
|
1467
|
+
colors: ["#005500", "#008800", "#00bb00", "#00ee00", "#66ff88"]
|
|
1468
|
+
},
|
|
1469
|
+
error: {
|
|
1470
|
+
speed: 2.5,
|
|
1471
|
+
amplitude: 2,
|
|
1472
|
+
shimmer: 0.8,
|
|
1473
|
+
breathe: 0.2,
|
|
1474
|
+
breatheSpeed: 0.6,
|
|
1475
|
+
colors: ["#660000", "#990000", "#cc0000", "#ff2200", "#ff6644"]
|
|
976
1476
|
}
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1477
|
+
};
|
|
1478
|
+
function computeFrame(time, cfg) {
|
|
1479
|
+
const breathe = Math.sin(time * cfg.breatheSpeed * Math.PI * 2) * cfg.breathe;
|
|
1480
|
+
return BASE_GRID.map(
|
|
1481
|
+
(row, r) => row.map((base, c) => {
|
|
1482
|
+
if (!MASK[r][c]) return { char: " ", color: "" };
|
|
1483
|
+
const phase = c / WIDTH + r * 0.08 - time * cfg.speed;
|
|
1484
|
+
const wave = Math.sin(phase * Math.PI * 2) * cfg.amplitude;
|
|
1485
|
+
const shimmer = Math.sin(c * 7.3 + r * 13.1 + time * 5.7) * cfg.shimmer;
|
|
1486
|
+
const raw = base + wave + shimmer + breathe;
|
|
1487
|
+
const intensity = Math.max(1, Math.min(4, Math.round(raw)));
|
|
1488
|
+
return {
|
|
1489
|
+
char: BLOCK_CHARS[intensity],
|
|
1490
|
+
color: cfg.colors[intensity]
|
|
1491
|
+
};
|
|
1492
|
+
})
|
|
1493
|
+
);
|
|
993
1494
|
}
|
|
1495
|
+
var Logo = ({
|
|
1496
|
+
version,
|
|
1497
|
+
model,
|
|
1498
|
+
cwd,
|
|
1499
|
+
mood = "idle"
|
|
1500
|
+
}) => {
|
|
1501
|
+
const [time, setTime] = useState6(() => Date.now() / 1e3);
|
|
1502
|
+
const cfg = MOODS[mood];
|
|
1503
|
+
useEffect4(() => {
|
|
1504
|
+
const id = setInterval(() => setTime(Date.now() / 1e3), 67);
|
|
1505
|
+
return () => clearInterval(id);
|
|
1506
|
+
}, []);
|
|
1507
|
+
const cells = useMemo(() => computeFrame(time, cfg), [time, cfg]);
|
|
1508
|
+
const shortCwd = cwd ? cwd.replace(process.env.HOME || "", "~") : void 0;
|
|
1509
|
+
const info = [
|
|
1510
|
+
null,
|
|
1511
|
+
// top padding row
|
|
1512
|
+
/* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Text8, { color: "cyan", bold: true }, "AGI"), /* @__PURE__ */ React8.createElement(Text8, { dimColor: true }, " v", version)),
|
|
1513
|
+
/* @__PURE__ */ React8.createElement(Text8, null, model),
|
|
1514
|
+
shortCwd ? /* @__PURE__ */ React8.createElement(Text8, { dimColor: true }, shortCwd) : null,
|
|
1515
|
+
null
|
|
1516
|
+
// bottom padding row
|
|
1517
|
+
];
|
|
1518
|
+
return /* @__PURE__ */ React8.createElement(Box7, { flexDirection: "column" }, cells.map((row, r) => /* @__PURE__ */ React8.createElement(Box7, { key: r }, /* @__PURE__ */ React8.createElement(Text8, null, row.map(
|
|
1519
|
+
(cell, c) => cell.char === " " ? /* @__PURE__ */ React8.createElement(Text8, { key: c }, " ") : /* @__PURE__ */ React8.createElement(Text8, { key: c, color: cell.color }, cell.char)
|
|
1520
|
+
)), info[r] != null && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Text8, null, " "), info[r]))));
|
|
1521
|
+
};
|
|
994
1522
|
|
|
995
1523
|
// src/app/App.tsx
|
|
996
1524
|
import { createRequire } from "module";
|
|
997
1525
|
var require2 = createRequire(import.meta.url);
|
|
998
|
-
var { version: CLI_VERSION } = require2("
|
|
1526
|
+
var { version: CLI_VERSION } = require2("../package.json");
|
|
999
1527
|
var App = ({ args }) => {
|
|
1000
1528
|
const { exit } = useApp();
|
|
1001
|
-
const [phase, setPhase] =
|
|
1002
|
-
const [currentGoal, setCurrentGoal] =
|
|
1003
|
-
const projectConfig =
|
|
1529
|
+
const [phase, setPhase] = useState7(args.goal ? "executing" : "input");
|
|
1530
|
+
const [currentGoal, setCurrentGoal] = useState7(args.goal ?? "");
|
|
1531
|
+
const projectConfig = useMemo2(() => {
|
|
1004
1532
|
const config = loadProjectConfig();
|
|
1533
|
+
const cmds = [];
|
|
1005
1534
|
if (config.commandFiles.length > 0) {
|
|
1006
|
-
|
|
1007
|
-
|
|
1535
|
+
cmds.push(...loadUserCommands(config.commandFiles));
|
|
1536
|
+
}
|
|
1537
|
+
if (config.skills.length > 0) {
|
|
1538
|
+
cmds.push(...loadSkillCommands(config.skills));
|
|
1539
|
+
}
|
|
1540
|
+
if (cmds.length > 0) {
|
|
1541
|
+
registerCommands(cmds);
|
|
1008
1542
|
}
|
|
1009
1543
|
return config;
|
|
1010
1544
|
}, []);
|
|
1011
|
-
const [model, setModel] =
|
|
1012
|
-
const [verbose, setVerbose] =
|
|
1013
|
-
const [noConfirm, setNoConfirm] =
|
|
1014
|
-
const [
|
|
1545
|
+
const [model, setModel] = useState7(args.model);
|
|
1546
|
+
const [verbose, setVerbose] = useState7(args.verbose);
|
|
1547
|
+
const [noConfirm, setNoConfirm] = useState7(args.noConfirm);
|
|
1548
|
+
const [compact, setCompact] = useState7(false);
|
|
1549
|
+
const [commandMessage, setCommandMessage] = useState7(null);
|
|
1550
|
+
const taskStartTime = useRef3(null);
|
|
1015
1551
|
const {
|
|
1016
1552
|
state,
|
|
1017
1553
|
step,
|
|
@@ -1029,12 +1565,24 @@ var App = ({ args }) => {
|
|
|
1029
1565
|
model,
|
|
1030
1566
|
verbose,
|
|
1031
1567
|
noConfirm,
|
|
1032
|
-
onFinished: () => {
|
|
1568
|
+
onFinished: (result) => {
|
|
1569
|
+
if (currentGoal) {
|
|
1570
|
+
const entry = {
|
|
1571
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1572
|
+
goal: currentGoal,
|
|
1573
|
+
model,
|
|
1574
|
+
durationMs: taskStartTime.current ? Date.now() - taskStartTime.current : void 0,
|
|
1575
|
+
success: result?.success
|
|
1576
|
+
};
|
|
1577
|
+
appendHistory(entry);
|
|
1578
|
+
taskStartTime.current = null;
|
|
1579
|
+
}
|
|
1033
1580
|
setPhase("input");
|
|
1034
1581
|
}
|
|
1035
1582
|
});
|
|
1036
|
-
|
|
1583
|
+
useEffect5(() => {
|
|
1037
1584
|
if (phase === "executing" && currentGoal) {
|
|
1585
|
+
taskStartTime.current = Date.now();
|
|
1038
1586
|
start(withProjectInstructions(currentGoal, projectConfig));
|
|
1039
1587
|
}
|
|
1040
1588
|
}, [phase, currentGoal, start, projectConfig]);
|
|
@@ -1047,12 +1595,16 @@ var App = ({ args }) => {
|
|
|
1047
1595
|
model,
|
|
1048
1596
|
verbose,
|
|
1049
1597
|
noConfirm,
|
|
1598
|
+
compact,
|
|
1050
1599
|
setModel,
|
|
1051
1600
|
setVerbose,
|
|
1052
1601
|
setNoConfirm,
|
|
1602
|
+
setCompact,
|
|
1053
1603
|
clearEvents,
|
|
1054
1604
|
quit: () => exit(),
|
|
1055
|
-
runGoal
|
|
1605
|
+
runGoal,
|
|
1606
|
+
projectConfig,
|
|
1607
|
+
version: CLI_VERSION
|
|
1056
1608
|
};
|
|
1057
1609
|
const handleSubmitGoal = useCallback3(
|
|
1058
1610
|
(input) => {
|
|
@@ -1084,7 +1636,14 @@ var App = ({ args }) => {
|
|
|
1084
1636
|
disabled: phase === "input" || !!pendingConfirm || !!pendingQuestion
|
|
1085
1637
|
});
|
|
1086
1638
|
const isTerminal = state === "finished" || state === "stopped" || state === "error";
|
|
1087
|
-
|
|
1639
|
+
const logoMood = (() => {
|
|
1640
|
+
if (phase === "input") return "idle";
|
|
1641
|
+
if (state === "error") return "error";
|
|
1642
|
+
if (state === "finished") return "success";
|
|
1643
|
+
if (state === "paused") return "thinking";
|
|
1644
|
+
return "active";
|
|
1645
|
+
})();
|
|
1646
|
+
return /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column" }, phase === "input" && events.length === 0 && /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Logo, { version: CLI_VERSION, model, cwd: process.cwd(), mood: logoMood }), projectConfig.instructions && /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1, marginLeft: 1 }, /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, "\u25B8 loaded "), /* @__PURE__ */ React9.createElement(Text9, { color: "green" }, projectConfig.instructionsPath)), projectConfig.rules.length > 0 && /* @__PURE__ */ React9.createElement(Box8, { marginLeft: 1 }, /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, "\u25B8 "), /* @__PURE__ */ React9.createElement(Text9, { color: "green" }, projectConfig.rules.length), /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, " rule(s) from .agi/rules/")), projectConfig.commandFiles.length > 0 && /* @__PURE__ */ React9.createElement(Box8, { marginLeft: 1 }, /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, "\u25B8 "), /* @__PURE__ */ React9.createElement(Text9, { color: "green" }, projectConfig.commandFiles.length), /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, " custom command(s) from .agi/commands/")), projectConfig.skills.length > 0 && /* @__PURE__ */ React9.createElement(Box8, { marginLeft: 1 }, /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, "\u25B8 "), /* @__PURE__ */ React9.createElement(Text9, { color: "green" }, projectConfig.skills.length), /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, " skill(s) from .agi/skills/"))), phase === "executing" && /* @__PURE__ */ React9.createElement(StatusBar, { state, step, goal: currentGoal }), /* @__PURE__ */ React9.createElement(Box8, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React9.createElement(EventDisplay, { events, maxEvents: compact ? 6 : 12 }), phase === "executing" && state === "running" && /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, " \u2503 "), /* @__PURE__ */ React9.createElement(Spinner, null)), phase === "executing" && state === "paused" && /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, " \u2503 "), /* @__PURE__ */ React9.createElement(Text9, { color: "yellow", bold: true }, "\u25AE\u25AE"), /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, " paused \u2014 space to resume"))), pendingConfirm && /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(ConfirmDialog, { reason: pendingConfirm, onConfirm: respondConfirm })), pendingQuestion && /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(QuestionDialog, { question: pendingQuestion, onAnswer: respondAnswer })), commandMessage && phase === "input" && /* @__PURE__ */ React9.createElement(Box8, null, /* @__PURE__ */ React9.createElement(Text9, { color: "gray" }, commandMessage)), phase === "input" && /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(PromptInput, { onSubmit: handleSubmitGoal })), phase === "executing" && !isTerminal && !pendingConfirm && !pendingQuestion && /* @__PURE__ */ React9.createElement(Box8, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, " space pause \xB7 q stop \xB7 ^c quit")));
|
|
1088
1647
|
};
|
|
1089
1648
|
|
|
1090
1649
|
// src/index.tsx
|
|
@@ -1107,7 +1666,7 @@ async function main() {
|
|
|
1107
1666
|
if (!process.env.AGI_API_KEY && !process.env.ANTHROPIC_API_KEY) {
|
|
1108
1667
|
process.env.AGI_API_KEY = apiKey;
|
|
1109
1668
|
}
|
|
1110
|
-
if (!
|
|
1669
|
+
if (!isBinaryAvailable2()) {
|
|
1111
1670
|
console.error("Error: AGI driver binary not found");
|
|
1112
1671
|
console.error("");
|
|
1113
1672
|
console.error("The driver binary is required for local agent execution.");
|