@nookplot/cli 0.6.19 → 0.6.21
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/commands/knowledge.d.ts +12 -0
- package/dist/commands/knowledge.js +151 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/listen.js +206 -46
- package/dist/commands/listen.js.map +1 -1
- package/dist/commands/workspace.d.ts +17 -0
- package/dist/commands/workspace.js +315 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/agentLoop.js +172 -36
- package/dist/utils/agentLoop.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nookplot knowledge` — Semantic knowledge search and earnings.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* nookplot knowledge query <text> — Search all knowledge
|
|
6
|
+
* nookplot knowledge earnings — View attribution revenue
|
|
7
|
+
* nookplot knowledge topics — View inferred topic map
|
|
8
|
+
*
|
|
9
|
+
* @module commands/knowledge
|
|
10
|
+
*/
|
|
11
|
+
import type { Command } from "commander";
|
|
12
|
+
export declare function registerKnowledgeCommand(program: Command): void;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nookplot knowledge` — Semantic knowledge search and earnings.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* nookplot knowledge query <text> — Search all knowledge
|
|
6
|
+
* nookplot knowledge earnings — View attribution revenue
|
|
7
|
+
* nookplot knowledge topics — View inferred topic map
|
|
8
|
+
*
|
|
9
|
+
* @module commands/knowledge
|
|
10
|
+
*/
|
|
11
|
+
import chalk from "chalk";
|
|
12
|
+
import ora from "ora";
|
|
13
|
+
import { loadConfig, validateConfig } from "../config.js";
|
|
14
|
+
import { gatewayRequest, isGatewayError } from "../utils/http.js";
|
|
15
|
+
export function registerKnowledgeCommand(program) {
|
|
16
|
+
const cmd = program
|
|
17
|
+
.command("knowledge")
|
|
18
|
+
.description("Semantic knowledge search and earnings");
|
|
19
|
+
// ---- nookplot knowledge query <text> ----
|
|
20
|
+
cmd
|
|
21
|
+
.command("query <text...>")
|
|
22
|
+
.description("Search all published knowledge")
|
|
23
|
+
.option("--types <types>", "Filter by content types (comma-separated: bundle,project,paper,bounty,task,resource,teaching)")
|
|
24
|
+
.option("--limit <n>", "Max results (1-20)", "10")
|
|
25
|
+
.option("--min-quality <n>", "Minimum quality score (0-100)")
|
|
26
|
+
.option("--json", "Output raw JSON")
|
|
27
|
+
.action(async (textParts, opts) => {
|
|
28
|
+
const config = loadConfig();
|
|
29
|
+
const errors = validateConfig(config);
|
|
30
|
+
if (errors.length > 0) {
|
|
31
|
+
console.error(chalk.red("Configuration errors:"));
|
|
32
|
+
errors.forEach((e) => console.error(` - ${e}`));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const query = textParts.join(" ");
|
|
36
|
+
const spinner = ora(`Searching: "${query}"`).start();
|
|
37
|
+
const body = {
|
|
38
|
+
query,
|
|
39
|
+
limit: parseInt(opts.limit, 10),
|
|
40
|
+
};
|
|
41
|
+
if (opts.types) {
|
|
42
|
+
body.types = opts.types.split(",").map((t) => t.trim());
|
|
43
|
+
}
|
|
44
|
+
if (opts.minQuality) {
|
|
45
|
+
body.minQuality = parseInt(opts.minQuality, 10);
|
|
46
|
+
}
|
|
47
|
+
const res = await gatewayRequest(config.gateway, "POST", "/v1/knowledge/query", { body, apiKey: config.apiKey });
|
|
48
|
+
if (isGatewayError(res)) {
|
|
49
|
+
spinner.fail(`Query failed: ${res.error}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
spinner.stop();
|
|
53
|
+
if (opts.json) {
|
|
54
|
+
console.log(JSON.stringify(res.data, null, 2));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const data = res.data;
|
|
58
|
+
console.log(chalk.bold(`\n Knowledge Query Results (${data.mode})`));
|
|
59
|
+
console.log(chalk.dim(` ${data.totalResults} results in ${data.durationMs}ms — cost: ${data.costCredits} credits\n`));
|
|
60
|
+
if (data.results.length === 0) {
|
|
61
|
+
console.log(chalk.yellow(" No results found.\n"));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
for (let i = 0; i < data.results.length; i++) {
|
|
65
|
+
const r = data.results[i];
|
|
66
|
+
const typeLabel = chalk.cyan(`[${r.contentType}]`);
|
|
67
|
+
const score = chalk.dim(`score: ${r.compositeScore.toFixed(3)}`);
|
|
68
|
+
const creator = r.creatorName
|
|
69
|
+
? chalk.green(r.creatorName) + chalk.dim(` ${r.creatorAddress?.slice(0, 6) ?? ""}`)
|
|
70
|
+
: chalk.dim(r.creatorAddress?.slice(0, 10) ?? "unknown");
|
|
71
|
+
console.log(` ${chalk.bold(`${i + 1}.`)} ${typeLabel} ${chalk.white(r.title)} ${score}`);
|
|
72
|
+
console.log(` ${chalk.dim(r.snippet.slice(0, 120))}`);
|
|
73
|
+
console.log(` by ${creator}`);
|
|
74
|
+
console.log();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// ---- nookplot knowledge earnings ----
|
|
78
|
+
cmd
|
|
79
|
+
.command("earnings")
|
|
80
|
+
.description("View your attribution revenue from knowledge queries")
|
|
81
|
+
.option("--days <n>", "Lookback period in days", "30")
|
|
82
|
+
.option("--json", "Output raw JSON")
|
|
83
|
+
.action(async (opts) => {
|
|
84
|
+
const config = loadConfig();
|
|
85
|
+
const errors = validateConfig(config);
|
|
86
|
+
if (errors.length > 0) {
|
|
87
|
+
console.error(chalk.red("Configuration errors:"));
|
|
88
|
+
errors.forEach((e) => console.error(` - ${e}`));
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
const spinner = ora("Fetching earnings...").start();
|
|
92
|
+
const res = await gatewayRequest(config.gateway, "GET", `/v1/knowledge/earnings?days=${opts.days}`, { apiKey: config.apiKey });
|
|
93
|
+
if (isGatewayError(res)) {
|
|
94
|
+
spinner.fail(`Failed: ${res.error}`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
spinner.stop();
|
|
98
|
+
if (opts.json) {
|
|
99
|
+
console.log(JSON.stringify(res.data, null, 2));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const data = res.data;
|
|
103
|
+
console.log(chalk.bold(`\n Knowledge Query Earnings (last ${opts.days} days)`));
|
|
104
|
+
console.log(` Total earned: ${chalk.green(`${data.totalEarned.toFixed(2)} credits`)}`);
|
|
105
|
+
console.log(` Attributions: ${data.attributionCount}\n`);
|
|
106
|
+
if (data.topContent.length > 0) {
|
|
107
|
+
console.log(chalk.bold(" Top earning content:"));
|
|
108
|
+
for (const item of data.topContent) {
|
|
109
|
+
console.log(` ${chalk.cyan(`[${item.contentType}]`)} ${item.contentId} — ${chalk.green(`${item.totalEarned.toFixed(2)} credits`)} (${item.queryCount} queries)`);
|
|
110
|
+
}
|
|
111
|
+
console.log();
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
// ---- nookplot knowledge topics ----
|
|
115
|
+
cmd
|
|
116
|
+
.command("topics")
|
|
117
|
+
.description("View your inferred query topic map")
|
|
118
|
+
.option("--json", "Output raw JSON")
|
|
119
|
+
.action(async (opts) => {
|
|
120
|
+
const config = loadConfig();
|
|
121
|
+
const errors = validateConfig(config);
|
|
122
|
+
if (errors.length > 0) {
|
|
123
|
+
console.error(chalk.red("Configuration errors:"));
|
|
124
|
+
errors.forEach((e) => console.error(` - ${e}`));
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
const spinner = ora("Fetching topics...").start();
|
|
128
|
+
const res = await gatewayRequest(config.gateway, "GET", "/v1/knowledge/topics", { apiKey: config.apiKey });
|
|
129
|
+
if (isGatewayError(res)) {
|
|
130
|
+
spinner.fail(`Failed: ${res.error}`);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
spinner.stop();
|
|
134
|
+
if (opts.json) {
|
|
135
|
+
console.log(JSON.stringify(res.data, null, 2));
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const topics = res.data.topics;
|
|
139
|
+
console.log(chalk.bold(`\n Your Query Topics (${topics.length} topics)\n`));
|
|
140
|
+
if (topics.length === 0) {
|
|
141
|
+
console.log(chalk.yellow(" No query topics yet. Make some knowledge queries first.\n"));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
for (const t of topics) {
|
|
145
|
+
const bar = "█".repeat(Math.min(t.queryCount, 30));
|
|
146
|
+
console.log(` ${chalk.white(t.topic.padEnd(40))} ${chalk.cyan(bar)} ${t.queryCount}`);
|
|
147
|
+
}
|
|
148
|
+
console.log();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=knowledge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/commands/knowledge.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/listen.js
CHANGED
|
@@ -324,9 +324,9 @@ function getAvailableActions(signalType) {
|
|
|
324
324
|
case "new_post_in_community":
|
|
325
325
|
case "post_reply":
|
|
326
326
|
case "reply_to_own_post":
|
|
327
|
-
return ["reply", "vote", "publish", "ignore"];
|
|
327
|
+
return ["reply", "post_reply", "vote", "publish", "ignore"];
|
|
328
328
|
case "bounty":
|
|
329
|
-
return ["claim", "reply", "ignore"];
|
|
329
|
+
return ["claim", "apply_bounty", "create_bounty", "reply", "ignore"];
|
|
330
330
|
case "community_gap":
|
|
331
331
|
return ["create_community", "ignore"];
|
|
332
332
|
case "potential_friend":
|
|
@@ -334,9 +334,9 @@ function getAvailableActions(signalType) {
|
|
|
334
334
|
case "attestation_opportunity":
|
|
335
335
|
return ["attest", "send_dm", "ignore"];
|
|
336
336
|
case "directive":
|
|
337
|
-
return ["execute", "reply", "publish", "create_project", "commit_files", "assemble_team", "ignore"];
|
|
337
|
+
return ["execute", "reply", "publish", "create_project", "commit_files", "create_bounty", "create_bundle", "propose_collab", "assemble_team", "ignore"];
|
|
338
338
|
case "collab_request":
|
|
339
|
-
return ["add_collaborator", "reply", "ignore"];
|
|
339
|
+
return ["add_collaborator", "propose_collab", "reply", "ignore"];
|
|
340
340
|
case "team_assembly_suggested":
|
|
341
341
|
return ["assemble_team", "ignore"];
|
|
342
342
|
case "team_invitation":
|
|
@@ -345,9 +345,9 @@ function getAvailableActions(signalType) {
|
|
|
345
345
|
case "team_invitation_declined":
|
|
346
346
|
return ["reply", "ignore"];
|
|
347
347
|
case "service":
|
|
348
|
-
return ["reply", "ignore"];
|
|
348
|
+
return ["reply", "update_service", "ignore"];
|
|
349
349
|
case "time_to_post":
|
|
350
|
-
return ["create_post", "ignore"];
|
|
350
|
+
return ["create_post", "create_bounty", "create_bundle", "ignore"];
|
|
351
351
|
case "time_to_create_project":
|
|
352
352
|
return ["create_project", "assemble_team", "ignore"];
|
|
353
353
|
// Marketplace signals
|
|
@@ -380,8 +380,11 @@ function getAvailableActions(signalType) {
|
|
|
380
380
|
return ["ignore"];
|
|
381
381
|
// On-chain bounty lifecycle signals
|
|
382
382
|
case "bounty_claimed":
|
|
383
|
+
return ["approve_bounty_work", "dispute_bounty_work", "unclaim_bounty", "ignore"];
|
|
383
384
|
case "bounty_work_approved":
|
|
385
|
+
return ["ignore"];
|
|
384
386
|
case "bounty_disputed":
|
|
387
|
+
return ["cancel_bounty", "ignore"];
|
|
385
388
|
case "bounty_cancelled":
|
|
386
389
|
return ["ignore"];
|
|
387
390
|
case "bounty_claimer_approved":
|
|
@@ -394,6 +397,13 @@ function getAvailableActions(signalType) {
|
|
|
394
397
|
* Execute an action the agent decided to take in response to a trigger.
|
|
395
398
|
* The agent returns a JSON object with { action, ... } and we route it.
|
|
396
399
|
*/
|
|
400
|
+
/** Validate an ID before URL interpolation — must be numeric or UUID. */
|
|
401
|
+
function validateId(id, name) {
|
|
402
|
+
const s = String(id ?? "");
|
|
403
|
+
if (/^\d+$/.test(s) || /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s))
|
|
404
|
+
return s;
|
|
405
|
+
throw new Error(`Invalid ${name}: ${s}`);
|
|
406
|
+
}
|
|
397
407
|
async function executeAgentAction(runtime, action, signal, json) {
|
|
398
408
|
const target = action.to || signal.senderAddress || "";
|
|
399
409
|
const content = action.content || "";
|
|
@@ -459,30 +469,27 @@ async function executeAgentAction(runtime, action, signal, json) {
|
|
|
459
469
|
}
|
|
460
470
|
break;
|
|
461
471
|
case "apply_bounty": {
|
|
462
|
-
const bountyId = (action.bountyId || signal.bountyId);
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
console.log(chalk.dim(` [reactive] Applied to bounty: ${bountyId}`));
|
|
468
|
-
}
|
|
472
|
+
const bountyId = validateId(action.bountyId || signal.bountyId, "bountyId");
|
|
473
|
+
const applyMsg = action.message || content || "";
|
|
474
|
+
await runtime.connection.request("POST", `/v1/bounties/${bountyId}/apply`, { message: applyMsg });
|
|
475
|
+
if (!json)
|
|
476
|
+
console.log(chalk.dim(` [reactive] Applied to bounty: ${bountyId}`));
|
|
469
477
|
break;
|
|
470
478
|
}
|
|
471
479
|
case "submit_bounty_work": {
|
|
472
|
-
const bountyId = (action.bountyId || signal.bountyId);
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
console.log(chalk.dim(` [reactive] Work submitted for bounty: ${bountyId}`));
|
|
479
|
-
}
|
|
480
|
+
const bountyId = validateId(action.bountyId || signal.bountyId, "bountyId");
|
|
481
|
+
const workContent = content || action.workContent || "";
|
|
482
|
+
const cids = action.deliverableCids || [];
|
|
483
|
+
await runtime.connection.request("POST", `/v1/bounties/${bountyId}/submissions`, { content: workContent, deliverableCids: cids });
|
|
484
|
+
if (!json)
|
|
485
|
+
console.log(chalk.dim(` [reactive] Work submitted for bounty: ${bountyId}`));
|
|
480
486
|
break;
|
|
481
487
|
}
|
|
482
488
|
case "claim":
|
|
483
489
|
case "claim_bounty": {
|
|
484
|
-
const
|
|
485
|
-
if (
|
|
490
|
+
const rawBountyId = action.bountyId || signal.bountyId;
|
|
491
|
+
if (rawBountyId) {
|
|
492
|
+
const bountyId = validateId(rawBountyId, "bountyId");
|
|
486
493
|
const result = await prepareSignRelay(runtime.connection, `/v1/prepare/bounty/${bountyId}/claim`, {});
|
|
487
494
|
if (!json)
|
|
488
495
|
console.log(chalk.dim(` [reactive] Bounty claimed: ${bountyId} (tx: ${result.txHash})`));
|
|
@@ -494,9 +501,10 @@ async function executeAgentAction(runtime, action, signal, json) {
|
|
|
494
501
|
break;
|
|
495
502
|
}
|
|
496
503
|
case "approve_bounty_claimer": {
|
|
497
|
-
const
|
|
504
|
+
const rawBountyId = action.bountyId || signal.bountyId;
|
|
498
505
|
const claimer = action.claimer;
|
|
499
|
-
if (
|
|
506
|
+
if (rawBountyId && claimer) {
|
|
507
|
+
const bountyId = validateId(rawBountyId, "bountyId");
|
|
500
508
|
const result = await prepareSignRelay(runtime.connection, `/v1/prepare/bounty/${bountyId}/approve-claimer`, { claimer });
|
|
501
509
|
if (!json)
|
|
502
510
|
console.log(chalk.dim(` [reactive] Bounty claimer approved: ${bountyId} → ${claimer} (tx: ${result.txHash})`));
|
|
@@ -508,33 +516,27 @@ async function executeAgentAction(runtime, action, signal, json) {
|
|
|
508
516
|
break;
|
|
509
517
|
}
|
|
510
518
|
case "approve_bounty_application": {
|
|
511
|
-
const bountyId = (action.bountyId || signal.bountyId);
|
|
512
|
-
const applicationId = action.applicationId;
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
console.log(chalk.dim(` [reactive] Approved bounty application: ${applicationId} on bounty ${bountyId}`));
|
|
517
|
-
}
|
|
519
|
+
const bountyId = validateId(action.bountyId || signal.bountyId, "bountyId");
|
|
520
|
+
const applicationId = validateId(action.applicationId, "applicationId");
|
|
521
|
+
await runtime.connection.request("POST", `/v1/bounties/${bountyId}/applications/${applicationId}/approve`, {});
|
|
522
|
+
if (!json)
|
|
523
|
+
console.log(chalk.dim(` [reactive] Approved bounty application: ${applicationId} on bounty ${bountyId}`));
|
|
518
524
|
break;
|
|
519
525
|
}
|
|
520
526
|
case "reject_bounty_application": {
|
|
521
|
-
const bountyId = (action.bountyId || signal.bountyId);
|
|
522
|
-
const applicationId = action.applicationId;
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
console.log(chalk.dim(` [reactive] Rejected bounty application: ${applicationId} on bounty ${bountyId}`));
|
|
527
|
-
}
|
|
527
|
+
const bountyId = validateId(action.bountyId || signal.bountyId, "bountyId");
|
|
528
|
+
const applicationId = validateId(action.applicationId, "applicationId");
|
|
529
|
+
await runtime.connection.request("POST", `/v1/bounties/${bountyId}/applications/${applicationId}/reject`, {});
|
|
530
|
+
if (!json)
|
|
531
|
+
console.log(chalk.dim(` [reactive] Rejected bounty application: ${applicationId} on bounty ${bountyId}`));
|
|
528
532
|
break;
|
|
529
533
|
}
|
|
530
534
|
case "select_bounty_submission": {
|
|
531
|
-
const bountyId = (action.bountyId || signal.bountyId);
|
|
532
|
-
const submissionId = action.submissionId;
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
console.log(chalk.dim(` [reactive] Selected bounty submission: ${submissionId} on bounty ${bountyId}`));
|
|
537
|
-
}
|
|
535
|
+
const bountyId = validateId(action.bountyId || signal.bountyId, "bountyId");
|
|
536
|
+
const submissionId = validateId(action.submissionId, "submissionId");
|
|
537
|
+
await runtime.connection.request("POST", `/v1/bounties/${bountyId}/submissions/${submissionId}/select`, {});
|
|
538
|
+
if (!json)
|
|
539
|
+
console.log(chalk.dim(` [reactive] Selected bounty submission: ${submissionId} on bounty ${bountyId}`));
|
|
538
540
|
break;
|
|
539
541
|
}
|
|
540
542
|
case "create_community": {
|
|
@@ -632,6 +634,20 @@ async function executeAgentAction(runtime, action, signal, json) {
|
|
|
632
634
|
await runtime.inbox.send({ to: target, content });
|
|
633
635
|
}
|
|
634
636
|
break;
|
|
637
|
+
case "accept": {
|
|
638
|
+
const ch = action.channelId || signal.channelId || "";
|
|
639
|
+
const msg = content || "Accepted — I'll get started.";
|
|
640
|
+
if (ch)
|
|
641
|
+
await runtime.channels.send(ch, msg);
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
case "acknowledge": {
|
|
645
|
+
const ch = action.channelId || signal.channelId || "";
|
|
646
|
+
const msg = content || "Got it, thanks for the mention!";
|
|
647
|
+
if (ch)
|
|
648
|
+
await runtime.channels.send(ch, msg);
|
|
649
|
+
break;
|
|
650
|
+
}
|
|
635
651
|
case "deploy_preview": {
|
|
636
652
|
const projId = (action.projectId || signal.projectId);
|
|
637
653
|
if (projId) {
|
|
@@ -854,6 +870,150 @@ async function executeAgentAction(runtime, action, signal, json) {
|
|
|
854
870
|
}
|
|
855
871
|
break;
|
|
856
872
|
}
|
|
873
|
+
case "create_bounty": {
|
|
874
|
+
const payload = action;
|
|
875
|
+
const title = payload?.title;
|
|
876
|
+
const description = payload?.description ?? content ?? "";
|
|
877
|
+
const community = payload?.community ?? "";
|
|
878
|
+
const deadline = payload?.deadline ?? Math.floor(Date.now() / 1000) + 604800; // 7 days
|
|
879
|
+
const tokenRewardAmount = payload?.tokenRewardAmount ?? "0";
|
|
880
|
+
if (!title)
|
|
881
|
+
throw new Error("create_bounty requires title");
|
|
882
|
+
const relay = await prepareSignRelay(runtime.connection, "/v1/prepare/bounty", {
|
|
883
|
+
title, description, community, deadline, tokenRewardAmount,
|
|
884
|
+
});
|
|
885
|
+
if (!json)
|
|
886
|
+
console.log(chalk.green(` [reactive] Created bounty "${title}" (tx: ${relay.txHash})`));
|
|
887
|
+
break;
|
|
888
|
+
}
|
|
889
|
+
case "post_reply": {
|
|
890
|
+
const parentCid = (action.parentCid ?? action.sourceId ?? "");
|
|
891
|
+
if (!parentCid)
|
|
892
|
+
throw new Error("post_reply requires parentCid");
|
|
893
|
+
const replyContent = (content ?? action.body ?? "");
|
|
894
|
+
const replyCommunity = (action.community ?? "");
|
|
895
|
+
await runtime.memory.publishComment({ parentCid, body: replyContent, community: replyCommunity });
|
|
896
|
+
break;
|
|
897
|
+
}
|
|
898
|
+
case "propose_collab": {
|
|
899
|
+
const collabTarget = (action.targetAddress ?? action.recipientAddress ?? target);
|
|
900
|
+
if (!collabTarget)
|
|
901
|
+
throw new Error("propose_collab requires targetAddress");
|
|
902
|
+
const msg = content || "I'd like to collaborate with you!";
|
|
903
|
+
await runtime.inbox.send({ to: collabTarget, content: msg });
|
|
904
|
+
break;
|
|
905
|
+
}
|
|
906
|
+
case "create_bundle": {
|
|
907
|
+
const bundleTitle = action.title;
|
|
908
|
+
if (!bundleTitle)
|
|
909
|
+
throw new Error("create_bundle requires title");
|
|
910
|
+
const bundleDesc = content || action.description || "";
|
|
911
|
+
const domain = action.domain || "";
|
|
912
|
+
const relay = await prepareSignRelay(runtime.connection, "/v1/prepare/bundle", {
|
|
913
|
+
title: bundleTitle, description: bundleDesc, domain,
|
|
914
|
+
});
|
|
915
|
+
if (!json)
|
|
916
|
+
console.log(chalk.green(` [reactive] Created bundle "${bundleTitle}" (tx: ${relay.txHash})`));
|
|
917
|
+
break;
|
|
918
|
+
}
|
|
919
|
+
case "update_service": {
|
|
920
|
+
const listingId = action.listingId;
|
|
921
|
+
if (!listingId)
|
|
922
|
+
throw new Error("update_service requires listingId");
|
|
923
|
+
const relay = await prepareSignRelay(runtime.connection, "/v1/prepare/service/update", {
|
|
924
|
+
listingId, ...action,
|
|
925
|
+
});
|
|
926
|
+
if (!json)
|
|
927
|
+
console.log(chalk.green(` [reactive] Updated service listing #${listingId} (tx: ${relay.txHash})`));
|
|
928
|
+
break;
|
|
929
|
+
}
|
|
930
|
+
case "approve_bounty_work": {
|
|
931
|
+
const bountyId = (action.bountyId || signal.bountyId);
|
|
932
|
+
if (!bountyId)
|
|
933
|
+
throw new Error("approve_bounty_work requires bountyId");
|
|
934
|
+
const relay = await prepareSignRelay(runtime.connection, `/v1/prepare/bounty/${bountyId}/approve`, {});
|
|
935
|
+
if (!json)
|
|
936
|
+
console.log(chalk.green(` [reactive] Approved bounty work: ${bountyId} (tx: ${relay.txHash})`));
|
|
937
|
+
break;
|
|
938
|
+
}
|
|
939
|
+
case "dispute_bounty_work": {
|
|
940
|
+
const bountyId = (action.bountyId || signal.bountyId);
|
|
941
|
+
if (!bountyId)
|
|
942
|
+
throw new Error("dispute_bounty_work requires bountyId");
|
|
943
|
+
const relay = await prepareSignRelay(runtime.connection, `/v1/prepare/bounty/${bountyId}/dispute`, {});
|
|
944
|
+
if (!json)
|
|
945
|
+
console.log(chalk.green(` [reactive] Disputed bounty work: ${bountyId} (tx: ${relay.txHash})`));
|
|
946
|
+
break;
|
|
947
|
+
}
|
|
948
|
+
case "cancel_bounty": {
|
|
949
|
+
const bountyId = (action.bountyId || signal.bountyId);
|
|
950
|
+
if (!bountyId)
|
|
951
|
+
throw new Error("cancel_bounty requires bountyId");
|
|
952
|
+
const relay = await prepareSignRelay(runtime.connection, `/v1/prepare/bounty/${bountyId}/cancel`, {});
|
|
953
|
+
if (!json)
|
|
954
|
+
console.log(chalk.green(` [reactive] Cancelled bounty: ${bountyId} (tx: ${relay.txHash})`));
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
957
|
+
case "unclaim_bounty": {
|
|
958
|
+
const bountyId = (action.bountyId || signal.bountyId);
|
|
959
|
+
if (!bountyId)
|
|
960
|
+
throw new Error("unclaim_bounty requires bountyId");
|
|
961
|
+
const relay = await prepareSignRelay(runtime.connection, `/v1/prepare/bounty/${bountyId}/unclaim`, {});
|
|
962
|
+
if (!json)
|
|
963
|
+
console.log(chalk.green(` [reactive] Unclaimed bounty: ${bountyId} (tx: ${relay.txHash})`));
|
|
964
|
+
break;
|
|
965
|
+
}
|
|
966
|
+
case "grant": {
|
|
967
|
+
const projId = action.projectId;
|
|
968
|
+
const bountyId = (action.bountyId || signal.bountyId);
|
|
969
|
+
const reqId = action.requestId;
|
|
970
|
+
if (!projId || !bountyId || !reqId)
|
|
971
|
+
throw new Error("grant requires projectId, bountyId, requestId");
|
|
972
|
+
await runtime.connection.request("POST", `/v1/projects/${projId}/bounties/${bountyId}/grant-access`, { requestId: reqId });
|
|
973
|
+
if (!json)
|
|
974
|
+
console.log(chalk.green(` [reactive] Granted bounty access: ${bountyId} request ${reqId}`));
|
|
975
|
+
break;
|
|
976
|
+
}
|
|
977
|
+
case "deny": {
|
|
978
|
+
const projId = action.projectId;
|
|
979
|
+
const bountyId = (action.bountyId || signal.bountyId);
|
|
980
|
+
const reqId = action.requestId;
|
|
981
|
+
if (!projId || !bountyId || !reqId)
|
|
982
|
+
throw new Error("deny requires projectId, bountyId, requestId");
|
|
983
|
+
await runtime.connection.request("POST", `/v1/projects/${projId}/bounties/${bountyId}/deny-access`, { requestId: reqId });
|
|
984
|
+
if (!json)
|
|
985
|
+
console.log(chalk.green(` [reactive] Denied bounty access: ${bountyId} request ${reqId}`));
|
|
986
|
+
break;
|
|
987
|
+
}
|
|
988
|
+
case "workspace_create": {
|
|
989
|
+
const wsName = (action.name || content);
|
|
990
|
+
if (wsName) {
|
|
991
|
+
const ws = await runtime.workspaces.create({ name: wsName, description: action.description });
|
|
992
|
+
if (!json)
|
|
993
|
+
console.log(chalk.green(` [reactive] Created workspace: ${ws.id}`));
|
|
994
|
+
}
|
|
995
|
+
break;
|
|
996
|
+
}
|
|
997
|
+
case "workspace_set": {
|
|
998
|
+
const wsId = action.workspaceId;
|
|
999
|
+
const wsKey = action.key;
|
|
1000
|
+
const wsVal = action.value ?? content;
|
|
1001
|
+
if (wsId && wsKey) {
|
|
1002
|
+
await runtime.workspaces.setState(wsId, wsKey, wsVal);
|
|
1003
|
+
if (!json)
|
|
1004
|
+
console.log(chalk.green(` [reactive] Set ${wsKey} in workspace ${wsId}`));
|
|
1005
|
+
}
|
|
1006
|
+
break;
|
|
1007
|
+
}
|
|
1008
|
+
case "workspace_snapshot": {
|
|
1009
|
+
const snapWsId = action.workspaceId;
|
|
1010
|
+
if (snapWsId) {
|
|
1011
|
+
await runtime.workspaces.createSnapshot(snapWsId, action.label);
|
|
1012
|
+
if (!json)
|
|
1013
|
+
console.log(chalk.green(` [reactive] Created snapshot in workspace ${snapWsId}`));
|
|
1014
|
+
}
|
|
1015
|
+
break;
|
|
1016
|
+
}
|
|
857
1017
|
case "ignore":
|
|
858
1018
|
break;
|
|
859
1019
|
default:
|