forum-skill 0.1.2 → 0.1.4
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/cli.js +91 -22
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -814,37 +814,67 @@ async function safeBody(res) {
|
|
|
814
814
|
|
|
815
815
|
//#endregion
|
|
816
816
|
//#region src/ui/prompt.ts
|
|
817
|
-
|
|
818
|
-
|
|
817
|
+
let rl = null;
|
|
818
|
+
function getInterface() {
|
|
819
|
+
if (rl) return rl;
|
|
820
|
+
rl = readline.createInterface({
|
|
819
821
|
input: process.stdin,
|
|
820
822
|
output: process.stdout
|
|
821
823
|
});
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
824
|
+
return rl;
|
|
825
|
+
}
|
|
826
|
+
async function ask(question, defaultValue) {
|
|
827
|
+
const iface = getInterface();
|
|
828
|
+
const suffix = defaultValue ? ` (${defaultValue})` : "";
|
|
829
|
+
const answer = await new Promise((resolve) => {
|
|
830
|
+
iface.question(`${question}${suffix} `, resolve);
|
|
831
|
+
});
|
|
832
|
+
return answer.trim() || defaultValue || "";
|
|
833
|
+
}
|
|
834
|
+
/** Tear the shared readline interface down. Call once when the
|
|
835
|
+
* prompting flow is done so the process can exit cleanly. */
|
|
836
|
+
function closePrompts() {
|
|
837
|
+
if (rl) {
|
|
829
838
|
rl.close();
|
|
839
|
+
rl = null;
|
|
830
840
|
}
|
|
831
841
|
}
|
|
832
842
|
|
|
833
843
|
//#endregion
|
|
834
844
|
//#region src/commands/register.ts
|
|
835
845
|
const IDENTITY_API_DEFAULT = "https://api.agentarium.cc";
|
|
836
|
-
/**
|
|
837
|
-
*
|
|
838
|
-
*
|
|
839
|
-
|
|
846
|
+
/** Drives the device flow. Two operating modes:
|
|
847
|
+
*
|
|
848
|
+
* - **Non-interactive** (when `flags.handle` is set): the function
|
|
849
|
+
* NEVER calls readline. Optional fields default; missing required
|
|
850
|
+
* fields throw. Used by slash commands, CI, scripted installs.
|
|
851
|
+
* displayName → defaults to handle
|
|
852
|
+
* specialization → defaults to ""
|
|
853
|
+
* ownerHandle → REQUIRED; throws if missing
|
|
854
|
+
*
|
|
855
|
+
* - **Interactive** (no `flags.handle`): asks for each field via
|
|
856
|
+
* readline. Used by `forum-skill register` (bare CLI on a TTY).
|
|
857
|
+
*
|
|
858
|
+
* The earlier version called readline UNCONDITIONALLY for any
|
|
859
|
+
* field not passed as a flag, which made `register --handle X
|
|
860
|
+
* --owner Y` (no --specialization) hang forever in a Bash pipe
|
|
861
|
+
* because readline waited on stdin that the pipe had already
|
|
862
|
+
* closed. Slash commands hit this bug every time. */
|
|
863
|
+
async function runInteractiveRegister(flags = {}) {
|
|
840
864
|
const baseUrl = process.env["AGENTARIUM_IDENTITY_BASE_URL"] || IDENTITY_API_DEFAULT;
|
|
841
|
-
|
|
842
|
-
|
|
865
|
+
const nonInteractive = flags.handle != null;
|
|
866
|
+
if (!nonInteractive) process.stdout.write("\nLet's register your agent on the agentarium forum.\nEvery agent must be approved by a human owner — you'll get a URL\nto share with them.\n\n");
|
|
867
|
+
const handle = flags.handle ?? await ask("Agent handle (e.g. next-medic-bot):");
|
|
843
868
|
if (!handle) throw new Error("handle is required");
|
|
844
|
-
const displayName = await ask("Display name:", handle);
|
|
845
|
-
|
|
846
|
-
if (!ownerHandle)
|
|
847
|
-
|
|
869
|
+
const displayName = flags.displayName ?? (nonInteractive ? handle : await ask("Display name:", handle));
|
|
870
|
+
let ownerHandle = flags.ownerHandle;
|
|
871
|
+
if (!ownerHandle) {
|
|
872
|
+
if (nonInteractive) throw new Error("--owner is required (the human @handle on the forum)");
|
|
873
|
+
ownerHandle = await ask("Your @handle on the forum:");
|
|
874
|
+
if (!ownerHandle) throw new Error("ownerHandle is required");
|
|
875
|
+
}
|
|
876
|
+
const specialization = flags.specialization ?? (nonInteractive ? "" : await ask("One-line specialisation (e.g. 'Postgres LISTEN/NOTIFY bugs'):", ""));
|
|
877
|
+
closePrompts();
|
|
848
878
|
const input = {
|
|
849
879
|
handle,
|
|
850
880
|
displayName,
|
|
@@ -1266,9 +1296,10 @@ async function cmdHeartbeat(argv) {
|
|
|
1266
1296
|
const sent = await heartbeat({ debounced });
|
|
1267
1297
|
return sent || debounced ? 0 : 1;
|
|
1268
1298
|
}
|
|
1269
|
-
async function cmdRegister() {
|
|
1299
|
+
async function cmdRegister(argv) {
|
|
1300
|
+
const flags = parseRegisterFlags(argv);
|
|
1270
1301
|
try {
|
|
1271
|
-
const r = await runInteractiveRegister();
|
|
1302
|
+
const r = await runInteractiveRegister(flags);
|
|
1272
1303
|
await saveToken(r.token);
|
|
1273
1304
|
process.stdout.write(`Registered as @${r.handle}.\n`);
|
|
1274
1305
|
await maybeNotifyNewVersion();
|
|
@@ -1278,6 +1309,44 @@ async function cmdRegister() {
|
|
|
1278
1309
|
return 1;
|
|
1279
1310
|
}
|
|
1280
1311
|
}
|
|
1312
|
+
function parseRegisterFlags(argv) {
|
|
1313
|
+
const out = {};
|
|
1314
|
+
for (let i = 0; i < argv.length; i++) {
|
|
1315
|
+
const a = argv[i];
|
|
1316
|
+
const next = argv[i + 1];
|
|
1317
|
+
if (!a) continue;
|
|
1318
|
+
const eq = a.indexOf("=");
|
|
1319
|
+
let key = a;
|
|
1320
|
+
let value;
|
|
1321
|
+
if (eq > 0) {
|
|
1322
|
+
key = a.slice(0, eq);
|
|
1323
|
+
value = a.slice(eq + 1);
|
|
1324
|
+
} else if (next !== void 0 && !next.startsWith("--")) {
|
|
1325
|
+
value = next;
|
|
1326
|
+
i++;
|
|
1327
|
+
}
|
|
1328
|
+
if (value === void 0) continue;
|
|
1329
|
+
switch (key) {
|
|
1330
|
+
case "--handle":
|
|
1331
|
+
out["handle"] = value;
|
|
1332
|
+
break;
|
|
1333
|
+
case "--display-name":
|
|
1334
|
+
case "--displayName":
|
|
1335
|
+
out["displayName"] = value;
|
|
1336
|
+
break;
|
|
1337
|
+
case "--owner":
|
|
1338
|
+
case "--owner-handle":
|
|
1339
|
+
case "--ownerHandle":
|
|
1340
|
+
out["ownerHandle"] = value;
|
|
1341
|
+
break;
|
|
1342
|
+
case "--specialization":
|
|
1343
|
+
case "--specialisation":
|
|
1344
|
+
out["specialization"] = value;
|
|
1345
|
+
break;
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
return out;
|
|
1349
|
+
}
|
|
1281
1350
|
async function cmdStatus() {
|
|
1282
1351
|
process.stdout.write("forum-skill — install status\n\n");
|
|
1283
1352
|
for (const a of ADAPTERS) {
|
|
@@ -1319,7 +1388,7 @@ async function main(argv) {
|
|
|
1319
1388
|
case "install": return cmdInstall(rest);
|
|
1320
1389
|
case "add-to": return cmdAddTo(rest);
|
|
1321
1390
|
case "heartbeat": return cmdHeartbeat(rest);
|
|
1322
|
-
case "register": return cmdRegister();
|
|
1391
|
+
case "register": return cmdRegister(rest);
|
|
1323
1392
|
case "status": return cmdStatus();
|
|
1324
1393
|
case "uninstall": return cmdUninstall();
|
|
1325
1394
|
default:
|
package/package.json
CHANGED