@innominatum/agentforge-cli 1.0.1 → 1.0.7
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/.github/workflows/publish.yml +36 -0
- package/README.md +28 -7
- package/dist/index.js +56 -28
- package/package.json +5 -2
- package/src/index.ts +64 -27
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Publish Package to npmjs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
# Alternatively, you can uncomment the following to publish whenever you push to main
|
|
7
|
+
# push:
|
|
8
|
+
# branches:
|
|
9
|
+
# - main
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build-and-publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
env:
|
|
15
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
id-token: write # Required for NPM Trusted Publishing (OIDC)
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout code
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Setup Node.js
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: '20.x'
|
|
27
|
+
registry-url: 'https://registry.npmjs.org'
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: npm ci
|
|
31
|
+
|
|
32
|
+
- name: Build TypeScript code
|
|
33
|
+
run: npm run build
|
|
34
|
+
|
|
35
|
+
- name: Publish to NPM
|
|
36
|
+
run: npm publish --access public --provenance
|
package/README.md
CHANGED
|
@@ -8,6 +8,14 @@ A powerful command-line interface to scaffold, manage, build, and deploy AI Agen
|
|
|
8
8
|
|
|
9
9
|
## Installation & Local Development
|
|
10
10
|
|
|
11
|
+
### Global Installation (Recommended)
|
|
12
|
+
You can install the AgentForge CLI globally directly from NPM:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g @innominatum/agentforge-cli
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Local Development
|
|
11
19
|
Since you are modifying or maintaining the CLI source code, you should install and use it globally on your local machine using NPM's symlink feature:
|
|
12
20
|
|
|
13
21
|
1. Clone this repository and navigate to its folder.
|
|
@@ -63,10 +71,23 @@ If you add a new command or change how the CLI works:
|
|
|
63
71
|
|
|
64
72
|
## NPM Publishing (Maintainers)
|
|
65
73
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
### Manual Publishing
|
|
75
|
+
When this CLI is ready for a new release:
|
|
76
|
+
1. Update the `version` in `package.json` (e.g., from `"1.0.1"` to `"1.0.2"`).
|
|
77
|
+
2. Run `npm run build` to ensure the `dist/` directory is fully updated.
|
|
78
|
+
3. Login to your npm account using `npm login`.
|
|
79
|
+
4. Publish the package using `npm publish --access public` (you will be prompted for your 2FA security key).
|
|
80
|
+
|
|
81
|
+
### Automated Publishing (Trusted Publishing / OIDC)
|
|
82
|
+
To fully automate your CI/CD pipeline securely without using any hardcoded NPM tokens or bypassing 2FA, NPM provides "Trusted Publishing" with GitHub Actions:
|
|
83
|
+
|
|
84
|
+
1. Go to the NPM website and navigate to the `@innominatum/agentforge-cli` package.
|
|
85
|
+
2. Go to **Settings** > **Publishing Access**.
|
|
86
|
+
3. Under **Trusted Publishers**, click **Add Publisher** > **GitHub Actions**.
|
|
87
|
+
4. Fill in the repository details:
|
|
88
|
+
- **GitHub Organization/User:** `Innominatum-pt`
|
|
89
|
+
- **GitHub Repository:** `agentforge-cli`
|
|
90
|
+
- **Workflow file (optional):** `publish.yml`
|
|
91
|
+
5. Click **Add Publisher**.
|
|
92
|
+
|
|
93
|
+
Once configured, the `.github/workflows/publish.yml` workflow provided in this repository will automatically securely authenticate via OIDC and publish your package whenever you create a new GitHub Release.
|
package/dist/index.js
CHANGED
|
@@ -285,6 +285,19 @@ async function getConfig() {
|
|
|
285
285
|
}
|
|
286
286
|
return config;
|
|
287
287
|
}
|
|
288
|
+
async function resolveAgentId(slug, config) {
|
|
289
|
+
try {
|
|
290
|
+
const listResponse = await axios_1.default.get(`${config.goclaw.api_url}/v1/agents`, {
|
|
291
|
+
headers: { Authorization: `Bearer ${config.goclaw.token}`, "X-GoClaw-User-Id": config.goclaw.username || "system" }
|
|
292
|
+
});
|
|
293
|
+
const agents = listResponse.data.agents || [];
|
|
294
|
+
const agent = agents.find((a) => a.agent_key === slug);
|
|
295
|
+
return agent ? agent.id : null;
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
288
301
|
const deployCmd = program
|
|
289
302
|
.command("deploy")
|
|
290
303
|
.description("Faz o deploy de entidades para a plataforma GoClaw");
|
|
@@ -336,34 +349,61 @@ deployCmd
|
|
|
336
349
|
}
|
|
337
350
|
}
|
|
338
351
|
});
|
|
339
|
-
async function deployContextFiles(slug, config) {
|
|
352
|
+
async function deployContextFiles(slug, config, resolvedId) {
|
|
353
|
+
const agentId = resolvedId || (await resolveAgentId(slug, config)) || slug;
|
|
340
354
|
const basePath = getWorkspaceRoot();
|
|
341
355
|
const agentPath = path_1.default.join(basePath, "agents", slug);
|
|
342
356
|
if (!(await fs_extra_1.default.pathExists(agentPath))) {
|
|
343
357
|
throw new Error(`Agente não encontrado em agents/${slug}`);
|
|
344
358
|
}
|
|
345
359
|
const files = await fs_extra_1.default.readdir(agentPath);
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
360
|
+
// Identificar ficheiros de contexto e de memória
|
|
361
|
+
const memoryFileNames = ['MEMORY.md', 'memory.md'];
|
|
362
|
+
const memoryDirName = 'memory';
|
|
363
|
+
const contextFiles = files.filter(f => (f.endsWith('.md') || f.endsWith('.txt') || f.endsWith('.py')) &&
|
|
364
|
+
f !== 'README.md' &&
|
|
365
|
+
f !== 'agent.json' &&
|
|
366
|
+
!memoryFileNames.includes(f));
|
|
367
|
+
const hasMemoryDir = await fs_extra_1.default.pathExists(path_1.default.join(agentPath, memoryDirName));
|
|
368
|
+
const memoryFilesFound = files.filter(f => memoryFileNames.includes(f));
|
|
369
|
+
const hasMemory = hasMemoryDir || memoryFilesFound.length > 0;
|
|
370
|
+
if (contextFiles.length === 0 && !hasMemory) {
|
|
371
|
+
console.log(`Nenhum ficheiro de contexto ou memória encontrado para "${slug}".`);
|
|
349
372
|
return;
|
|
350
373
|
}
|
|
351
374
|
const tempExportDir = path_1.default.join(basePath, `temp_export_${slug}`);
|
|
352
375
|
const tempContextDir = path_1.default.join(tempExportDir, "context_files");
|
|
376
|
+
const tempMemoryDir = path_1.default.join(tempExportDir, "memory");
|
|
353
377
|
const tarPath = path_1.default.join(basePath, `temp_export_${slug}.tar.gz`);
|
|
354
378
|
try {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
379
|
+
const sections = [];
|
|
380
|
+
if (contextFiles.length > 0) {
|
|
381
|
+
sections.push("context_files");
|
|
382
|
+
await fs_extra_1.default.ensureDir(tempContextDir);
|
|
383
|
+
for (const file of contextFiles) {
|
|
384
|
+
await fs_extra_1.default.copy(path_1.default.join(agentPath, file), path_1.default.join(tempContextDir, file));
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
if (hasMemory) {
|
|
388
|
+
sections.push("memory");
|
|
389
|
+
await fs_extra_1.default.ensureDir(tempMemoryDir);
|
|
390
|
+
// Copiar ficheiros de memória explícitos para a pasta memory no arquivo
|
|
391
|
+
for (const file of memoryFilesFound) {
|
|
392
|
+
await fs_extra_1.default.copy(path_1.default.join(agentPath, file), path_1.default.join(tempMemoryDir, file));
|
|
393
|
+
}
|
|
394
|
+
// Copiar conteúdo da pasta memory se existir
|
|
395
|
+
if (hasMemoryDir) {
|
|
396
|
+
await fs_extra_1.default.copy(path_1.default.join(agentPath, memoryDirName), tempMemoryDir);
|
|
397
|
+
}
|
|
358
398
|
}
|
|
359
399
|
await tar.c({
|
|
360
400
|
gzip: true,
|
|
361
401
|
file: tarPath,
|
|
362
402
|
cwd: tempExportDir
|
|
363
|
-
},
|
|
403
|
+
}, sections);
|
|
364
404
|
const form = new form_data_1.default();
|
|
365
405
|
form.append("file", fs_extra_1.default.createReadStream(tarPath));
|
|
366
|
-
const url = `${config.goclaw.api_url}/v1/agents/${
|
|
406
|
+
const url = `${config.goclaw.api_url}/v1/agents/${agentId}/import?include=${sections.join(",")}`;
|
|
367
407
|
await axios_1.default.post(url, form, {
|
|
368
408
|
headers: {
|
|
369
409
|
...form.getHeaders(),
|
|
@@ -371,7 +411,7 @@ async function deployContextFiles(slug, config) {
|
|
|
371
411
|
"X-GoClaw-User-Id": config.goclaw.username || "system"
|
|
372
412
|
}
|
|
373
413
|
});
|
|
374
|
-
console.log(`✅ Upload cirúrgico de ${contextFiles.length}
|
|
414
|
+
console.log(`✅ Upload cirúrgico de ${contextFiles.length} ficheiros de contexto e ${hasMemory ? 'dados de memória' : 'sem memória'} concluído com sucesso!`);
|
|
375
415
|
}
|
|
376
416
|
finally {
|
|
377
417
|
if (await fs_extra_1.default.pathExists(tempExportDir))
|
|
@@ -417,20 +457,8 @@ deployCmd
|
|
|
417
457
|
const agentConfig = await fs_extra_1.default.readJson(agentJsonPath);
|
|
418
458
|
console.log(`🚀 Atualizando configuração do agente "${slug}"...`);
|
|
419
459
|
try {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
await axios_1.default.get(`${config.goclaw.api_url}/v1/agents/${slug}`, {
|
|
423
|
-
headers: { Authorization: `Bearer ${config.goclaw.token}`, "X-GoClaw-User-Id": config.goclaw.username || "system" }
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
catch (e) {
|
|
427
|
-
if (e.response && e.response.status === 404) {
|
|
428
|
-
exists = false;
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
throw e;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
460
|
+
const agentId = await resolveAgentId(slug, config);
|
|
461
|
+
const exists = agentId !== null;
|
|
434
462
|
if (!exists) {
|
|
435
463
|
await axios_1.default.post(`${config.goclaw.api_url}/v1/agents`, agentConfig, {
|
|
436
464
|
headers: { Authorization: `Bearer ${config.goclaw.token}`, "X-GoClaw-User-Id": config.goclaw.username || "system" }
|
|
@@ -438,13 +466,13 @@ deployCmd
|
|
|
438
466
|
console.log("✅ Agente criado com sucesso.");
|
|
439
467
|
}
|
|
440
468
|
else {
|
|
441
|
-
await axios_1.default.put(`${config.goclaw.api_url}/v1/agents/${
|
|
469
|
+
await axios_1.default.put(`${config.goclaw.api_url}/v1/agents/${agentId}`, agentConfig, {
|
|
442
470
|
headers: { Authorization: `Bearer ${config.goclaw.token}`, "X-GoClaw-User-Id": config.goclaw.username || "system" }
|
|
443
471
|
});
|
|
444
472
|
console.log("✅ Configurações do agente atualizadas.");
|
|
445
473
|
}
|
|
446
474
|
console.log(`🚀 Sincronizando arquivos de contexto...`);
|
|
447
|
-
await deployContextFiles(slug, config);
|
|
475
|
+
await deployContextFiles(slug, config, agentId);
|
|
448
476
|
console.log("✅ Deploy completo concluído!");
|
|
449
477
|
}
|
|
450
478
|
catch (error) {
|
|
@@ -560,7 +588,7 @@ pullCmd
|
|
|
560
588
|
for (const agent of agents) {
|
|
561
589
|
const slug = agent.agent_key;
|
|
562
590
|
console.log(`📦 Baixando agente: ${slug}...`);
|
|
563
|
-
const url = `${config.goclaw.api_url}/v1/agents/${agent.id}/export`;
|
|
591
|
+
const url = `${config.goclaw.api_url}/v1/agents/${agent.id}/export?sections=config,context_files,memory`;
|
|
564
592
|
const response = await axios_1.default.get(url, {
|
|
565
593
|
headers: { Authorization: `Bearer ${config.goclaw.token}`, "X-GoClaw-User-Id": config.goclaw.username || "system" },
|
|
566
594
|
responseType: "stream"
|
|
@@ -580,7 +608,7 @@ pullCmd
|
|
|
580
608
|
cwd: agentPath,
|
|
581
609
|
strip: 0,
|
|
582
610
|
filter: (path) => {
|
|
583
|
-
return path === 'agent.json' || path.startsWith('context_files/');
|
|
611
|
+
return path === 'agent.json' || path.startsWith('context_files/') || path.startsWith('memory/') || path === 'MEMORY.md' || path === 'memory.md';
|
|
584
612
|
}
|
|
585
613
|
});
|
|
586
614
|
const contextDir = path_1.default.join(agentPath, "context_files");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@innominatum/agentforge-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "A powerful command-line interface to scaffold, manage, build, and deploy AI Agents and Skills for the GoClaw platform.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
"type": "git",
|
|
17
17
|
"url": "git+https://github.com/Innominatum-pt/agentforge-cli.git"
|
|
18
18
|
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
19
22
|
"keywords": [
|
|
20
23
|
"ai",
|
|
21
24
|
"agents",
|
|
@@ -49,4 +52,4 @@
|
|
|
49
52
|
"tsx": "^4.21.0",
|
|
50
53
|
"typescript": "^6.0.3"
|
|
51
54
|
}
|
|
52
|
-
}
|
|
55
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -297,6 +297,19 @@ async function getConfig() {
|
|
|
297
297
|
return config;
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
+
async function resolveAgentId(slug: string, config: any): Promise<string | null> {
|
|
301
|
+
try {
|
|
302
|
+
const listResponse = await axios.get(`${config.goclaw.api_url}/v1/agents`, {
|
|
303
|
+
headers: { Authorization: `Bearer ${config.goclaw.token}`, "X-GoClaw-User-Id": config.goclaw.username || "system" }
|
|
304
|
+
});
|
|
305
|
+
const agents = listResponse.data.agents || [];
|
|
306
|
+
const agent = agents.find((a: any) => a.agent_key === slug);
|
|
307
|
+
return agent ? agent.id : null;
|
|
308
|
+
} catch (error) {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
300
313
|
const deployCmd = program
|
|
301
314
|
.command("deploy")
|
|
302
315
|
.description("Faz o deploy de entidades para a plataforma GoClaw");
|
|
@@ -354,7 +367,8 @@ deployCmd
|
|
|
354
367
|
}
|
|
355
368
|
});
|
|
356
369
|
|
|
357
|
-
async function deployContextFiles(slug: string, config: any) {
|
|
370
|
+
async function deployContextFiles(slug: string, config: any, resolvedId?: string | null) {
|
|
371
|
+
const agentId = resolvedId || (await resolveAgentId(slug, config)) || slug;
|
|
358
372
|
const basePath = getWorkspaceRoot();
|
|
359
373
|
const agentPath = path.join(basePath, "agents", slug);
|
|
360
374
|
if (!(await fs.pathExists(agentPath))) {
|
|
@@ -362,33 +376,66 @@ async function deployContextFiles(slug: string, config: any) {
|
|
|
362
376
|
}
|
|
363
377
|
|
|
364
378
|
const files = await fs.readdir(agentPath);
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
379
|
+
|
|
380
|
+
// Identificar ficheiros de contexto e de memória
|
|
381
|
+
const memoryFileNames = ['MEMORY.md', 'memory.md'];
|
|
382
|
+
const memoryDirName = 'memory';
|
|
383
|
+
|
|
384
|
+
const contextFiles = files.filter(f =>
|
|
385
|
+
(f.endsWith('.md') || f.endsWith('.txt') || f.endsWith('.py')) &&
|
|
386
|
+
f !== 'README.md' &&
|
|
387
|
+
f !== 'agent.json' &&
|
|
388
|
+
!memoryFileNames.includes(f)
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
const hasMemoryDir = await fs.pathExists(path.join(agentPath, memoryDirName));
|
|
392
|
+
const memoryFilesFound = files.filter(f => memoryFileNames.includes(f));
|
|
393
|
+
const hasMemory = hasMemoryDir || memoryFilesFound.length > 0;
|
|
394
|
+
|
|
395
|
+
if (contextFiles.length === 0 && !hasMemory) {
|
|
396
|
+
console.log(`Nenhum ficheiro de contexto ou memória encontrado para "${slug}".`);
|
|
369
397
|
return;
|
|
370
398
|
}
|
|
371
399
|
|
|
372
400
|
const tempExportDir = path.join(basePath, `temp_export_${slug}`);
|
|
373
401
|
const tempContextDir = path.join(tempExportDir, "context_files");
|
|
402
|
+
const tempMemoryDir = path.join(tempExportDir, "memory");
|
|
374
403
|
const tarPath = path.join(basePath, `temp_export_${slug}.tar.gz`);
|
|
375
404
|
|
|
376
405
|
try {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
406
|
+
const sections: string[] = [];
|
|
407
|
+
|
|
408
|
+
if (contextFiles.length > 0) {
|
|
409
|
+
sections.push("context_files");
|
|
410
|
+
await fs.ensureDir(tempContextDir);
|
|
411
|
+
for (const file of contextFiles) {
|
|
412
|
+
await fs.copy(path.join(agentPath, file), path.join(tempContextDir, file));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (hasMemory) {
|
|
417
|
+
sections.push("memory");
|
|
418
|
+
await fs.ensureDir(tempMemoryDir);
|
|
419
|
+
// Copiar ficheiros de memória explícitos para a pasta memory no arquivo
|
|
420
|
+
for (const file of memoryFilesFound) {
|
|
421
|
+
await fs.copy(path.join(agentPath, file), path.join(tempMemoryDir, file));
|
|
422
|
+
}
|
|
423
|
+
// Copiar conteúdo da pasta memory se existir
|
|
424
|
+
if (hasMemoryDir) {
|
|
425
|
+
await fs.copy(path.join(agentPath, memoryDirName), tempMemoryDir);
|
|
426
|
+
}
|
|
380
427
|
}
|
|
381
428
|
|
|
382
429
|
await tar.c({
|
|
383
430
|
gzip: true,
|
|
384
431
|
file: tarPath,
|
|
385
432
|
cwd: tempExportDir
|
|
386
|
-
},
|
|
433
|
+
}, sections);
|
|
387
434
|
|
|
388
435
|
const form = new FormData();
|
|
389
436
|
form.append("file", fs.createReadStream(tarPath));
|
|
390
437
|
|
|
391
|
-
const url = `${config.goclaw.api_url}/v1/agents/${
|
|
438
|
+
const url = `${config.goclaw.api_url}/v1/agents/${agentId}/import?include=${sections.join(",")}`;
|
|
392
439
|
await axios.post(url, form, {
|
|
393
440
|
headers: {
|
|
394
441
|
...form.getHeaders(),
|
|
@@ -397,7 +444,7 @@ async function deployContextFiles(slug: string, config: any) {
|
|
|
397
444
|
}
|
|
398
445
|
});
|
|
399
446
|
|
|
400
|
-
console.log(`✅ Upload cirúrgico de ${contextFiles.length}
|
|
447
|
+
console.log(`✅ Upload cirúrgico de ${contextFiles.length} ficheiros de contexto e ${hasMemory ? 'dados de memória' : 'sem memória'} concluído com sucesso!`);
|
|
401
448
|
} finally {
|
|
402
449
|
if (await fs.pathExists(tempExportDir)) await fs.remove(tempExportDir);
|
|
403
450
|
if (await fs.pathExists(tarPath)) await fs.remove(tarPath);
|
|
@@ -446,18 +493,8 @@ deployCmd
|
|
|
446
493
|
console.log(`🚀 Atualizando configuração do agente "${slug}"...`);
|
|
447
494
|
|
|
448
495
|
try {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
await axios.get(`${config.goclaw.api_url}/v1/agents/${slug}`, {
|
|
452
|
-
headers: { Authorization: `Bearer ${config.goclaw.token}`, "X-GoClaw-User-Id": config.goclaw.username || "system" }
|
|
453
|
-
});
|
|
454
|
-
} catch (e: any) {
|
|
455
|
-
if (e.response && e.response.status === 404) {
|
|
456
|
-
exists = false;
|
|
457
|
-
} else {
|
|
458
|
-
throw e;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
496
|
+
const agentId = await resolveAgentId(slug, config);
|
|
497
|
+
const exists = agentId !== null;
|
|
461
498
|
|
|
462
499
|
if (!exists) {
|
|
463
500
|
await axios.post(`${config.goclaw.api_url}/v1/agents`, agentConfig, {
|
|
@@ -465,14 +502,14 @@ deployCmd
|
|
|
465
502
|
});
|
|
466
503
|
console.log("✅ Agente criado com sucesso.");
|
|
467
504
|
} else {
|
|
468
|
-
await axios.put(`${config.goclaw.api_url}/v1/agents/${
|
|
505
|
+
await axios.put(`${config.goclaw.api_url}/v1/agents/${agentId}`, agentConfig, {
|
|
469
506
|
headers: { Authorization: `Bearer ${config.goclaw.token}`, "X-GoClaw-User-Id": config.goclaw.username || "system" }
|
|
470
507
|
});
|
|
471
508
|
console.log("✅ Configurações do agente atualizadas.");
|
|
472
509
|
}
|
|
473
510
|
|
|
474
511
|
console.log(`🚀 Sincronizando arquivos de contexto...`);
|
|
475
|
-
await deployContextFiles(slug, config);
|
|
512
|
+
await deployContextFiles(slug, config, agentId);
|
|
476
513
|
|
|
477
514
|
console.log("✅ Deploy completo concluído!");
|
|
478
515
|
} catch (error: any) {
|
|
@@ -603,7 +640,7 @@ pullCmd
|
|
|
603
640
|
const slug = agent.agent_key;
|
|
604
641
|
console.log(`📦 Baixando agente: ${slug}...`);
|
|
605
642
|
|
|
606
|
-
const url = `${config.goclaw.api_url}/v1/agents/${agent.id}/export`;
|
|
643
|
+
const url = `${config.goclaw.api_url}/v1/agents/${agent.id}/export?sections=config,context_files,memory`;
|
|
607
644
|
const response = await axios.get(url, {
|
|
608
645
|
headers: { Authorization: `Bearer ${config.goclaw.token}`, "X-GoClaw-User-Id": config.goclaw.username || "system" },
|
|
609
646
|
responseType: "stream"
|
|
@@ -628,7 +665,7 @@ pullCmd
|
|
|
628
665
|
cwd: agentPath,
|
|
629
666
|
strip: 0,
|
|
630
667
|
filter: (path) => {
|
|
631
|
-
return path === 'agent.json' || path.startsWith('context_files/');
|
|
668
|
+
return path === 'agent.json' || path.startsWith('context_files/') || path.startsWith('memory/') || path === 'MEMORY.md' || path === 'memory.md';
|
|
632
669
|
}
|
|
633
670
|
});
|
|
634
671
|
|