@astra-cli/cli 1.2.0 → 1.2.2
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/astra.js +96 -8
- package/package.json +1 -1
package/dist/astra.js
CHANGED
|
@@ -139,6 +139,9 @@ function pluginManifestPath(pluginName) {
|
|
|
139
139
|
function pluginSkillPath(pluginName) {
|
|
140
140
|
return path.join(pluginDir(pluginName), "skill.md");
|
|
141
141
|
}
|
|
142
|
+
function pluginMapPath(pluginName) {
|
|
143
|
+
return path.join(pluginDir(pluginName), "plugin-map.json");
|
|
144
|
+
}
|
|
142
145
|
function ensureDir(dirPath) {
|
|
143
146
|
if (!fs.existsSync(dirPath)) {
|
|
144
147
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
@@ -967,12 +970,15 @@ var FETCH_TIMEOUT_MS = 3e4;
|
|
|
967
970
|
var FETCH_TIMEOUT_RETRY_MS = 15e3;
|
|
968
971
|
async function apiCall(method, path7, body, agentName, retryOpts) {
|
|
969
972
|
const config = loadConfig();
|
|
970
|
-
const baseUrl = config?.apiBase ?? "https://agents.astranova.live";
|
|
971
973
|
const headers = {
|
|
972
974
|
"Content-Type": "application/json"
|
|
973
975
|
};
|
|
976
|
+
let baseUrl = config?.apiBase ?? "https://agents.astranova.live";
|
|
974
977
|
if (agentName) {
|
|
975
978
|
const creds = loadCredentials(agentName);
|
|
979
|
+
if (creds?.api_base) {
|
|
980
|
+
baseUrl = creds.api_base;
|
|
981
|
+
}
|
|
976
982
|
if (creds?.api_key) {
|
|
977
983
|
headers["Authorization"] = `Bearer ${creds.api_key}`;
|
|
978
984
|
}
|
|
@@ -4192,10 +4198,48 @@ function writeFileSecure2(filePath, data) {
|
|
|
4192
4198
|
fs10.writeFileSync(tmpPath, data, { encoding: "utf-8", mode: 384 });
|
|
4193
4199
|
fs10.renameSync(tmpPath, filePath);
|
|
4194
4200
|
}
|
|
4195
|
-
function
|
|
4201
|
+
function buildPluginMap(pluginName, manifest, sections) {
|
|
4202
|
+
const map = { version: 1, pluginName };
|
|
4203
|
+
const statusSection = sections["STATUS"];
|
|
4204
|
+
if (statusSection) {
|
|
4205
|
+
const poll = typeof statusSection.poll === "string" ? statusSection.poll.trim() : null;
|
|
4206
|
+
const rawFields = Array.isArray(statusSection.fields) ? statusSection.fields : [];
|
|
4207
|
+
const fields = rawFields.flatMap((raw) => {
|
|
4208
|
+
const parts = raw.split("|").map((s) => s.trim());
|
|
4209
|
+
if (parts.length === 3) return [{ path: parts[0], label: parts[1], color: parts[2] }];
|
|
4210
|
+
return [];
|
|
4211
|
+
});
|
|
4212
|
+
const pollAllowed = poll && manifest.allowedPaths.some((ap) => poll.startsWith(ap));
|
|
4213
|
+
if (poll && pollAllowed && fields.length > 0) {
|
|
4214
|
+
map.status = { poll, fields };
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
const cmdSection = sections["COMMANDS"];
|
|
4218
|
+
if (cmdSection) {
|
|
4219
|
+
const rawCmds = Array.isArray(cmdSection.commands) ? cmdSection.commands : [];
|
|
4220
|
+
map.commands = rawCmds.flatMap((raw) => {
|
|
4221
|
+
const match = raw.match(/^(\S+)\s{2,}(.+)$/);
|
|
4222
|
+
if (match) return [{ command: match[1], description: match[2].trim() }];
|
|
4223
|
+
return [];
|
|
4224
|
+
});
|
|
4225
|
+
}
|
|
4226
|
+
return map;
|
|
4227
|
+
}
|
|
4228
|
+
function loadPluginMap(pluginName) {
|
|
4229
|
+
const p = pluginMapPath(pluginName);
|
|
4230
|
+
if (!fs10.existsSync(p)) return null;
|
|
4231
|
+
try {
|
|
4232
|
+
return JSON.parse(fs10.readFileSync(p, "utf-8"));
|
|
4233
|
+
} catch {
|
|
4234
|
+
return null;
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4237
|
+
function savePluginToDisk(manifest, skillMdContent, sections) {
|
|
4196
4238
|
ensureDir(pluginDir(manifest.name));
|
|
4197
4239
|
writeFileSecure2(pluginManifestPath(manifest.name), JSON.stringify(manifest, null, 2));
|
|
4198
4240
|
writeFileSecure2(pluginSkillPath(manifest.name), skillMdContent);
|
|
4241
|
+
const pluginMap = buildPluginMap(manifest.name, manifest, sections);
|
|
4242
|
+
writeFileSecure2(pluginMapPath(manifest.name), JSON.stringify(pluginMap, null, 2));
|
|
4199
4243
|
}
|
|
4200
4244
|
async function addPlugin(manifestUrl) {
|
|
4201
4245
|
clack5.intro(" astra add ");
|
|
@@ -4286,7 +4330,7 @@ async function addPlugin(manifestUrl) {
|
|
|
4286
4330
|
}
|
|
4287
4331
|
const manifestWithSkillUrl = { ...manifest, skillUrl: urlResult.url.toString() };
|
|
4288
4332
|
try {
|
|
4289
|
-
savePluginToDisk(manifestWithSkillUrl, skillMdContent);
|
|
4333
|
+
savePluginToDisk(manifestWithSkillUrl, skillMdContent, sections);
|
|
4290
4334
|
} catch (err) {
|
|
4291
4335
|
clack5.log.error(
|
|
4292
4336
|
`Failed to save plugin: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -4384,11 +4428,29 @@ var StatusBar = React.memo(function StatusBar2({
|
|
|
4384
4428
|
journeyStage,
|
|
4385
4429
|
autopilotMode = "off",
|
|
4386
4430
|
autopilotIntervalMs = 3e5,
|
|
4387
|
-
onEpochChange
|
|
4431
|
+
onEpochChange,
|
|
4432
|
+
pluginMap
|
|
4388
4433
|
}) {
|
|
4389
4434
|
const [data, setData] = useState({ market: null, portfolio: null });
|
|
4390
4435
|
const mounted = useRef(true);
|
|
4391
4436
|
const canFetchData = isAstraNova && journeyStage !== "fresh" && journeyStage !== "pending";
|
|
4437
|
+
const [pluginData, setPluginData] = useState(null);
|
|
4438
|
+
const mountedPlugin = useRef(true);
|
|
4439
|
+
useEffect(() => {
|
|
4440
|
+
if (isAstraNova || !pluginMap?.status) return;
|
|
4441
|
+
mountedPlugin.current = true;
|
|
4442
|
+
const fetchPlugin = async () => {
|
|
4443
|
+
const result = await apiCall("GET", pluginMap.status.poll, void 0, agentName);
|
|
4444
|
+
if (!result.ok || !mountedPlugin.current) return;
|
|
4445
|
+
setPluginData(result.data);
|
|
4446
|
+
};
|
|
4447
|
+
void fetchPlugin();
|
|
4448
|
+
const interval = setInterval(() => void fetchPlugin(), POLL_INTERVAL_MS);
|
|
4449
|
+
return () => {
|
|
4450
|
+
mountedPlugin.current = false;
|
|
4451
|
+
clearInterval(interval);
|
|
4452
|
+
};
|
|
4453
|
+
}, [isAstraNova, pluginMap, agentName]);
|
|
4392
4454
|
const poll = useCallback(async () => {
|
|
4393
4455
|
const [marketRes, portfolioRes] = await Promise.all([
|
|
4394
4456
|
fetchMarket(agentName),
|
|
@@ -4420,6 +4482,22 @@ var StatusBar = React.memo(function StatusBar2({
|
|
|
4420
4482
|
/* @__PURE__ */ jsx(Text, { bold: true, color: "#00ff00", children: pluginName }),
|
|
4421
4483
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \u2502 " }),
|
|
4422
4484
|
/* @__PURE__ */ jsx(Text, { color: "#ff8800", children: agentName }),
|
|
4485
|
+
!isAstraNova && pluginData && pluginMap?.status?.fields.map((field) => {
|
|
4486
|
+
const value = getNestedValue(pluginData, field.path);
|
|
4487
|
+
if (value == null) return null;
|
|
4488
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
4489
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \u2502 " }),
|
|
4490
|
+
/* @__PURE__ */ jsxs(Text, { color: field.color, children: [
|
|
4491
|
+
field.label,
|
|
4492
|
+
": ",
|
|
4493
|
+
String(value)
|
|
4494
|
+
] })
|
|
4495
|
+
] }, field.path);
|
|
4496
|
+
}),
|
|
4497
|
+
!isAstraNova && !pluginData && pluginMap?.status && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4498
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \u2502 " }),
|
|
4499
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "loading..." })
|
|
4500
|
+
] }),
|
|
4423
4501
|
canFetchData && market && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4424
4502
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \u2502 " }),
|
|
4425
4503
|
/* @__PURE__ */ jsx(Text, { color: "#ffff00", children: "$NOVA " }),
|
|
@@ -4500,6 +4578,12 @@ function moodColor(mood) {
|
|
|
4500
4578
|
return "white";
|
|
4501
4579
|
}
|
|
4502
4580
|
}
|
|
4581
|
+
function getNestedValue(obj, path7) {
|
|
4582
|
+
return path7.split(".").reduce(
|
|
4583
|
+
(cur, key) => cur && typeof cur === "object" ? cur[key] : void 0,
|
|
4584
|
+
obj
|
|
4585
|
+
);
|
|
4586
|
+
}
|
|
4503
4587
|
async function fetchMarket(agentName) {
|
|
4504
4588
|
const result = await apiCall("GET", "/api/v1/market/state", void 0, agentName);
|
|
4505
4589
|
if (!result.ok) return null;
|
|
@@ -4888,7 +4972,8 @@ function App({
|
|
|
4888
4972
|
initialChatMessages,
|
|
4889
4973
|
initialAutopilotConfig,
|
|
4890
4974
|
initialPendingTrades = 0,
|
|
4891
|
-
debug
|
|
4975
|
+
debug,
|
|
4976
|
+
pluginMap
|
|
4892
4977
|
}) {
|
|
4893
4978
|
const { exit } = useApp();
|
|
4894
4979
|
const manifest = getActiveManifest();
|
|
@@ -5414,14 +5499,15 @@ ${stack}
|
|
|
5414
5499
|
journeyStage: profile.journeyStage ?? "full",
|
|
5415
5500
|
autopilotMode,
|
|
5416
5501
|
autopilotIntervalMs,
|
|
5417
|
-
onEpochChange: handleEpochChange
|
|
5502
|
+
onEpochChange: handleEpochChange,
|
|
5503
|
+
pluginMap
|
|
5418
5504
|
}
|
|
5419
5505
|
) }),
|
|
5420
5506
|
/* @__PURE__ */ jsx7(Box7, { flexShrink: 0, width: "100%", paddingX: 2, marginTop: 1, justifyContent: "space-between", children: hasJourneyStages ? /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
5421
5507
|
/* @__PURE__ */ jsx7(Text8, { dimColor: true, children: "/help \xB7 /portfolio \xB7 /market \xB7 /strategy \xB7 /exit" }),
|
|
5422
5508
|
/* @__PURE__ */ jsx7(Text8, { dimColor: true, children: "/auto on\xB7off\xB7set \xB7 Ctrl+C quit" })
|
|
5423
5509
|
] }) : /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
5424
|
-
/* @__PURE__ */ jsx7(Text8, { dimColor: true, children: "
|
|
5510
|
+
/* @__PURE__ */ jsx7(Text8, { dimColor: true, children: (pluginMap?.commands?.map((c) => c.command).join(" \xB7 ") ?? "/help") + " \xB7 /exit" }),
|
|
5425
5511
|
/* @__PURE__ */ jsx7(Text8, { dimColor: true, children: manifest.name })
|
|
5426
5512
|
] }) })
|
|
5427
5513
|
] });
|
|
@@ -5491,6 +5577,7 @@ async function main() {
|
|
|
5491
5577
|
manifest = ASTRANOVA_MANIFEST;
|
|
5492
5578
|
}
|
|
5493
5579
|
setActiveManifest(manifest);
|
|
5580
|
+
const pluginMap = activePluginName === "astranova" ? null : loadPluginMap(activePluginName);
|
|
5494
5581
|
if (isDaemonMode) {
|
|
5495
5582
|
await runDaemon();
|
|
5496
5583
|
return;
|
|
@@ -5637,7 +5724,8 @@ async function main() {
|
|
|
5637
5724
|
initialChatMessages,
|
|
5638
5725
|
initialAutopilotConfig,
|
|
5639
5726
|
initialPendingTrades,
|
|
5640
|
-
debug
|
|
5727
|
+
debug,
|
|
5728
|
+
pluginMap
|
|
5641
5729
|
})
|
|
5642
5730
|
);
|
|
5643
5731
|
await waitUntilExit();
|