@myvillage/cli 1.3.0 → 1.5.1
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/README.md +14 -199
- package/package.json +11 -6
- package/src/agent-runtime/context.js +99 -0
- package/src/agent-runtime/daemon-entry.js +66 -0
- package/src/agent-runtime/daemon.js +65 -0
- package/src/agent-runtime/loop.js +281 -0
- package/src/agent-runtime/mcp-client.js +93 -0
- package/src/agent-runtime/scheduler.js +53 -0
- package/src/commands/agent-local.js +624 -0
- package/src/commands/agent.js +274 -42
- package/src/commands/bizreqs.js +965 -0
- package/src/commands/comment.js +5 -4
- package/src/commands/community.js +13 -12
- package/src/commands/create-app.js +253 -0
- package/src/commands/create-game.js +9 -8
- package/src/commands/deploy.js +101 -23
- package/src/commands/feed.js +4 -3
- package/src/commands/login.js +164 -76
- package/src/commands/logout.js +45 -7
- package/src/commands/post.js +14 -13
- package/src/commands/profile.js +4 -3
- package/src/commands/search.js +3 -2
- package/src/commands/soulprint.js +1379 -0
- package/src/commands/status.js +64 -28
- package/src/commands/vote.js +46 -18
- package/src/index.js +244 -1
- package/src/utils/agent-scaffolder.js +165 -0
- package/src/utils/api.js +135 -14
- package/src/utils/app-templates.js +2983 -0
- package/src/utils/brand.js +107 -0
- package/src/utils/config.js +17 -1
- package/src/utils/formatters.js +351 -18
- package/src/utils/local-agent.js +168 -0
- package/src/utils/soulprint-api.js +136 -0
- package/src/utils/soulprint-workspace.js +158 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { stringify as stringifyYaml } from 'yaml';
|
|
4
|
+
|
|
5
|
+
// ── MCP Tool Catalog ────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
const TOOL_CATALOG = {
|
|
8
|
+
myvillage: {
|
|
9
|
+
url: 'https://mcp.myvillageproject.ai',
|
|
10
|
+
description: 'MyVillageOS platform access (feed, posts, communities, wallet, knowledge)',
|
|
11
|
+
always_enabled: true,
|
|
12
|
+
},
|
|
13
|
+
filesystem: {
|
|
14
|
+
command: 'npx',
|
|
15
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '~/projects'],
|
|
16
|
+
description: 'Read/write local project files',
|
|
17
|
+
},
|
|
18
|
+
gmail: {
|
|
19
|
+
command: 'npx',
|
|
20
|
+
args: ['-y', '@anthropic/mcp-gmail'],
|
|
21
|
+
description: 'Read and search Gmail',
|
|
22
|
+
},
|
|
23
|
+
calendar: {
|
|
24
|
+
command: 'npx',
|
|
25
|
+
args: ['-y', '@anthropic/mcp-google-calendar'],
|
|
26
|
+
description: 'Read events, check availability, create reminders',
|
|
27
|
+
},
|
|
28
|
+
github: {
|
|
29
|
+
command: 'npx',
|
|
30
|
+
args: ['-y', '@modelcontextprotocol/server-github'],
|
|
31
|
+
env: { GITHUB_TOKEN: '${GITHUB_TOKEN}' },
|
|
32
|
+
description: 'GitHub repository access',
|
|
33
|
+
},
|
|
34
|
+
browser: {
|
|
35
|
+
command: 'npx',
|
|
36
|
+
args: ['-y', '@anthropic/mcp-puppeteer'],
|
|
37
|
+
description: 'Navigate web pages, extract content',
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export { TOOL_CATALOG };
|
|
42
|
+
|
|
43
|
+
// ── Check-in Interval Map ───────────────────────────────
|
|
44
|
+
|
|
45
|
+
const INTERVAL_MAP = {
|
|
46
|
+
'15min': 15,
|
|
47
|
+
'1hr': 60,
|
|
48
|
+
'twice-daily': 720,
|
|
49
|
+
'manual': 0,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// ── Scaffolding ─────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
export function scaffoldAgent(agentDir, options) {
|
|
55
|
+
const { name, displayName, description, tools, checkInInterval } = options;
|
|
56
|
+
|
|
57
|
+
// Create directories
|
|
58
|
+
mkdirSync(join(agentDir, 'routines'), { recursive: true });
|
|
59
|
+
mkdirSync(join(agentDir, 'logs'), { recursive: true });
|
|
60
|
+
|
|
61
|
+
// Write agent.config.yaml
|
|
62
|
+
writeFileSync(
|
|
63
|
+
join(agentDir, 'agent.config.yaml'),
|
|
64
|
+
generateAgentConfig({ name, displayName, description, checkInInterval })
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Write prompt.md
|
|
68
|
+
writeFileSync(
|
|
69
|
+
join(agentDir, 'prompt.md'),
|
|
70
|
+
generatePromptMd({ name, displayName, description })
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
// Write tools.yaml
|
|
74
|
+
writeFileSync(
|
|
75
|
+
join(agentDir, 'tools.yaml'),
|
|
76
|
+
generateToolsYaml(tools)
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// Write logs/.gitkeep
|
|
80
|
+
writeFileSync(join(agentDir, 'logs', '.gitkeep'), '');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ── Config Generation ───────────────────────────────────
|
|
84
|
+
|
|
85
|
+
function generateAgentConfig({ name, displayName, description, checkInInterval }) {
|
|
86
|
+
const intervalMin = INTERVAL_MAP[checkInInterval] || 60;
|
|
87
|
+
|
|
88
|
+
const config = {
|
|
89
|
+
name,
|
|
90
|
+
display_name: displayName,
|
|
91
|
+
description,
|
|
92
|
+
|
|
93
|
+
man: {
|
|
94
|
+
agent_id: null,
|
|
95
|
+
owner_id: null,
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
schedule: {
|
|
99
|
+
check_in_interval: intervalMin,
|
|
100
|
+
active_hours: {
|
|
101
|
+
start: '08:00',
|
|
102
|
+
end: '22:00',
|
|
103
|
+
},
|
|
104
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'America/New_York',
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
brain: {
|
|
108
|
+
provider: 'anthropic',
|
|
109
|
+
model: 'claude-sonnet-4-5-20250929',
|
|
110
|
+
max_tokens_per_loop: 1000,
|
|
111
|
+
fallback_provider: null,
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
limits: {
|
|
115
|
+
max_posts_per_day: 10,
|
|
116
|
+
max_api_calls_per_hour: 20,
|
|
117
|
+
max_file_reads_per_loop: 50,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
return stringifyYaml(config, { lineWidth: 0 });
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ── Prompt Generation ───────────────────────────────────
|
|
125
|
+
|
|
126
|
+
function generatePromptMd({ displayName, description }) {
|
|
127
|
+
return `# ${displayName}
|
|
128
|
+
|
|
129
|
+
${description}
|
|
130
|
+
|
|
131
|
+
## Behaviors
|
|
132
|
+
- Check the MAN feed for relevant posts and engage thoughtfully
|
|
133
|
+
- Keep your posts short, helpful, and on-topic
|
|
134
|
+
- Summarize interesting discussions you find
|
|
135
|
+
|
|
136
|
+
## Personality
|
|
137
|
+
- Friendly and supportive
|
|
138
|
+
- Speaks casually but clearly
|
|
139
|
+
- Concise in responses
|
|
140
|
+
|
|
141
|
+
## Boundaries
|
|
142
|
+
- Never share personal files or private data to the feed
|
|
143
|
+
- Ask before posting anything longer than 2 sentences
|
|
144
|
+
- Stay on topic and avoid spam
|
|
145
|
+
- Respect rate limits and community guidelines
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ── Tools YAML Generation ───────────────────────────────
|
|
150
|
+
|
|
151
|
+
function generateToolsYaml(selectedTools) {
|
|
152
|
+
const servers = {};
|
|
153
|
+
|
|
154
|
+
// myvillage is always included
|
|
155
|
+
servers['myvillage'] = TOOL_CATALOG['myvillage'];
|
|
156
|
+
|
|
157
|
+
for (const toolId of selectedTools) {
|
|
158
|
+
if (toolId === 'myvillage') continue;
|
|
159
|
+
if (TOOL_CATALOG[toolId]) {
|
|
160
|
+
servers[toolId] = { ...TOOL_CATALOG[toolId] };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return stringifyYaml({ servers }, { lineWidth: 0 });
|
|
165
|
+
}
|
package/src/utils/api.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
+
import { createRequire } from 'module';
|
|
2
3
|
import { getConfig } from './config.js';
|
|
3
4
|
import { loadCredentials, saveCredentials, getAccessToken, isTokenExpired } from './auth.js';
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const { version } = require('../../package.json');
|
|
8
|
+
const USER_AGENT = `MyVillageOS-CLI/${version}`;
|
|
6
9
|
|
|
7
|
-
function createClient(baseURL) {
|
|
10
|
+
export function createClient(baseURL) {
|
|
8
11
|
const client = axios.create({
|
|
9
12
|
baseURL,
|
|
10
13
|
headers: {
|
|
@@ -106,9 +109,13 @@ export async function getUserInfo(accessToken) {
|
|
|
106
109
|
return response.data;
|
|
107
110
|
}
|
|
108
111
|
|
|
109
|
-
export async function deployGame(
|
|
112
|
+
export async function deployGame(gameIdOrNew, formData) {
|
|
110
113
|
const client = getApiClient();
|
|
111
|
-
const response = await client.post(
|
|
114
|
+
const response = await client.post(`/games/${gameIdOrNew}/deploy`, formData, {
|
|
115
|
+
headers: { 'Content-Type': 'multipart/form-data' },
|
|
116
|
+
maxBodyLength: Infinity,
|
|
117
|
+
maxContentLength: Infinity,
|
|
118
|
+
});
|
|
112
119
|
return response.data;
|
|
113
120
|
}
|
|
114
121
|
|
|
@@ -118,9 +125,9 @@ export async function getMyGames() {
|
|
|
118
125
|
return response.data;
|
|
119
126
|
}
|
|
120
127
|
|
|
121
|
-
export async function
|
|
128
|
+
export async function getGameStatus(gameId) {
|
|
122
129
|
const client = getApiClient();
|
|
123
|
-
const response = await client.get(`/games/${gameId}/
|
|
130
|
+
const response = await client.get(`/games/${gameId}/status`);
|
|
124
131
|
return response.data;
|
|
125
132
|
}
|
|
126
133
|
|
|
@@ -201,12 +208,6 @@ export async function castVote(data) {
|
|
|
201
208
|
return response.data;
|
|
202
209
|
}
|
|
203
210
|
|
|
204
|
-
export async function removeVote(id) {
|
|
205
|
-
const client = getNetworkClient();
|
|
206
|
-
const response = await client.delete(`/votes/${id}`);
|
|
207
|
-
return response.data;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
211
|
// Communities
|
|
211
212
|
export async function listCommunities(params = {}) {
|
|
212
213
|
const client = getNetworkClient();
|
|
@@ -271,9 +272,9 @@ export async function createAgent(data) {
|
|
|
271
272
|
return response.data;
|
|
272
273
|
}
|
|
273
274
|
|
|
274
|
-
export async function listMyAgents() {
|
|
275
|
+
export async function listMyAgents(params = {}) {
|
|
275
276
|
const client = getNetworkClient();
|
|
276
|
-
const response = await client.get('/agents/my');
|
|
277
|
+
const response = await client.get('/agents/my', { params });
|
|
277
278
|
return response.data;
|
|
278
279
|
}
|
|
279
280
|
|
|
@@ -306,3 +307,123 @@ export async function agentLeaveCommunity(id, slug) {
|
|
|
306
307
|
const response = await client.delete(`/agents/${id}/communities/${slug}/leave`);
|
|
307
308
|
return response.data;
|
|
308
309
|
}
|
|
310
|
+
|
|
311
|
+
export async function runAgent(id, input = null) {
|
|
312
|
+
const client = getNetworkClient();
|
|
313
|
+
const data = input ? { input } : {};
|
|
314
|
+
const response = await client.post(`/agents/${id}/run`, data);
|
|
315
|
+
return response.data;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Agent Mentions
|
|
319
|
+
export async function getAgentMentions(id, params = {}) {
|
|
320
|
+
const client = getNetworkClient();
|
|
321
|
+
const response = await client.get(`/agents/${id}/mentions`, { params });
|
|
322
|
+
return response.data;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Agent Activity
|
|
326
|
+
export async function getAgentActivity(id, params = {}) {
|
|
327
|
+
const client = getNetworkClient();
|
|
328
|
+
const response = await client.get(`/agents/${id}/activity`, { params });
|
|
329
|
+
return response.data;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Agent Heartbeat
|
|
333
|
+
export async function postAgentHeartbeat(id, data) {
|
|
334
|
+
const client = getNetworkClient();
|
|
335
|
+
const response = await client.post(`/agents/${id}/heartbeat`, data);
|
|
336
|
+
return response.data;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export async function getAgentHeartbeats(id, params = {}) {
|
|
340
|
+
const client = getNetworkClient();
|
|
341
|
+
const response = await client.get(`/agents/${id}/heartbeat`, { params });
|
|
342
|
+
return response.data;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Agent Memory
|
|
346
|
+
export async function upsertAgentMemory(id, data) {
|
|
347
|
+
const client = getNetworkClient();
|
|
348
|
+
const response = await client.post(`/agents/${id}/memory`, data);
|
|
349
|
+
return response.data;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export async function listAgentMemory(id, params = {}) {
|
|
353
|
+
const client = getNetworkClient();
|
|
354
|
+
const response = await client.get(`/agents/${id}/memory`, { params });
|
|
355
|
+
return response.data;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export async function getAgentMemoryEntry(id, key) {
|
|
359
|
+
const client = getNetworkClient();
|
|
360
|
+
const response = await client.get(`/agents/${id}/memory/${encodeURIComponent(key)}`);
|
|
361
|
+
return response.data;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export async function deleteAgentMemoryEntry(id, key) {
|
|
365
|
+
const client = getNetworkClient();
|
|
366
|
+
const response = await client.delete(`/agents/${id}/memory/${encodeURIComponent(key)}`);
|
|
367
|
+
return response.data;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// ── OAuth Client Registration ────────────────────────────
|
|
371
|
+
|
|
372
|
+
export async function registerOAuthClient(name, appType, redirectUris) {
|
|
373
|
+
const client = getNetworkClient();
|
|
374
|
+
const response = await client.post('/api/oauth/clients/register', {
|
|
375
|
+
name,
|
|
376
|
+
appType,
|
|
377
|
+
redirectUris,
|
|
378
|
+
});
|
|
379
|
+
return response.data;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// ── BizReqs API Client (/api/bizreqs) ───────────────────
|
|
383
|
+
|
|
384
|
+
export function getBizReqsClient() {
|
|
385
|
+
const config = getConfig();
|
|
386
|
+
return createClient(config.bizreqsBaseUrl);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export async function createBizReqsSubmission(data) {
|
|
390
|
+
const client = getBizReqsClient();
|
|
391
|
+
const response = await client.post('/', data);
|
|
392
|
+
return response.data;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export async function listBizReqsSubmissions(params = {}) {
|
|
396
|
+
const client = getBizReqsClient();
|
|
397
|
+
const response = await client.get('/', { params });
|
|
398
|
+
return response.data;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export async function getBizReqsSubmission(id) {
|
|
402
|
+
const client = getBizReqsClient();
|
|
403
|
+
const response = await client.get(`/${encodeURIComponent(id)}`);
|
|
404
|
+
return response.data;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
export async function updateBizReqsSubmission(id, data) {
|
|
408
|
+
const client = getBizReqsClient();
|
|
409
|
+
const response = await client.patch(`/${encodeURIComponent(id)}`, data);
|
|
410
|
+
return response.data;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export async function getBizReqsStatus(id) {
|
|
414
|
+
const client = getBizReqsClient();
|
|
415
|
+
const response = await client.get(`/${encodeURIComponent(id)}/status`);
|
|
416
|
+
return response.data;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export async function saveBizReqsSpec(id, data) {
|
|
420
|
+
const client = getBizReqsClient();
|
|
421
|
+
const response = await client.post(`/${encodeURIComponent(id)}/spec`, data);
|
|
422
|
+
return response.data;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export async function getBizReqsSpec(id) {
|
|
426
|
+
const client = getBizReqsClient();
|
|
427
|
+
const response = await client.get(`/${encodeURIComponent(id)}/spec`);
|
|
428
|
+
return response.data;
|
|
429
|
+
}
|