agentsmesh 0.12.0 → 0.14.0
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/CHANGELOG.md +18 -0
- package/README.md +20 -4
- package/dist/canonical.js +89 -36
- package/dist/canonical.js.map +1 -1
- package/dist/cli.js +152 -126
- package/dist/engine.js +111 -58
- package/dist/engine.js.map +1 -1
- package/dist/index.js +111 -58
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 16a7f0d: Self-serve MCP server. `agentsmesh mcp` boots a stdio MCP server exposing 41 tools and 16 resources for canonical config introspection, CRUD on rules/commands/agents/skills, settings management (config/mcp-servers/permissions/hooks/ignore), capability matrix queries, and orchestration verbs (generate/lint/check/diff/import/convert). Auto-registered in `.agentsmesh/mcp.json` on `init` and `import`. See the MCP server reference page.
|
|
8
|
+
|
|
9
|
+
## 0.13.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- f68ab67: feat(cli): add convert command for direct tool-to-tool migration
|
|
14
|
+
|
|
15
|
+
Adds `agentsmesh convert --from <source> --to <target>` for direct tool-to-tool conversion without going through canonical setup. Internally chains the existing import and generate pipelines via a temporary directory, producing destination tool files from source tool files in a single command. Supports `--dry-run` and `--json` flags.
|
|
16
|
+
|
|
17
|
+
- c8d58c0: feat(cli): add structured JSON output mode
|
|
18
|
+
|
|
19
|
+
Adds `--json` support across CLI commands so automation and CI can consume stable machine-readable command results. JSON mode returns structured success/error envelopes while keeping the existing human-readable output as the default.
|
|
20
|
+
|
|
3
21
|
## 0.12.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -85,7 +85,7 @@ Prefer a local install? `npm install -D agentsmesh` (also `pnpm add -D` / `yarn
|
|
|
85
85
|
If your repo already has `.cursor/`, `.claude/`, `.github/copilot-instructions.md`, or other native files, you don't have to delete them. The recommended flow imports them into `.agentsmesh/` first, lets you preview the projection, and only then trusts `generate`.
|
|
86
86
|
|
|
87
87
|
```bash
|
|
88
|
-
npx agentsmesh import --from cursor # or claude-code, copilot, codex-cli, gemini-cli, windsurf, ...
|
|
88
|
+
npx agentsmesh import --from cursor # or claude-code, copilot, codex-cli, gemini-cli, windsurf, amp, zed, warp, ...
|
|
89
89
|
npx agentsmesh diff # patch-style preview of what generate would change
|
|
90
90
|
npx agentsmesh generate # write native configs (back) from canonical
|
|
91
91
|
npx agentsmesh check # add to CI to detect drift
|
|
@@ -121,7 +121,7 @@ On macOS/Linux you can also run `tree .agentsmesh` if you have `tree` installed.
|
|
|
121
121
|
|
|
122
122
|
## Supported AI coding tools
|
|
123
123
|
|
|
124
|
-
AgentsMesh currently generates native config for every major AI coding assistant — Claude Code, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Continue, Cline, Kiro, Codex CLI, Junie, Roo Code, Antigravity — plus plugin targets you can ship as standalone npm packages. Each tool's native vs. embedded support per feature is tracked in the [supported tools matrix](https://samplexbro.github.io/agentsmesh/reference/supported-tools/). The full matrix table is also embedded [further down this README](#supported-tools--feature-matrix).
|
|
124
|
+
AgentsMesh currently generates native config for every major AI coding assistant — Claude Code, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Continue, Cline, Kiro, Codex CLI, Junie, Roo Code, Antigravity, Amp, Zed, Warp — plus plugin targets you can ship as standalone npm packages. Each tool's native vs. embedded support per feature is tracked in the [supported tools matrix](https://samplexbro.github.io/agentsmesh/reference/supported-tools/). The full matrix table is also embedded [further down this README](#supported-tools--feature-matrix).
|
|
125
125
|
|
|
126
126
|
---
|
|
127
127
|
|
|
@@ -133,6 +133,7 @@ AgentsMesh currently generates native config for every major AI coding assistant
|
|
|
133
133
|
- **Team-safe collaboration** — `agentsmesh check` is a CI drift gate against `.agentsmesh/.lock`, `agentsmesh diff` previews changes, `agentsmesh merge` rebuilds the lock after three-way Git conflicts, and `lock_features` + per-feature `strategy` prevent accidental overrides.
|
|
134
134
|
- **Global mode** — `~/.agentsmesh/` syncs personal AI config to `~/.claude/`, `~/.cursor/`, `~/.codex/`, `~/.windsurf/`, and other user-level folders. Every CLI command accepts `--global`.
|
|
135
135
|
- **Extensible** — community packs (`agentsmesh install ...`), remote `extends`, runtime plugins (`agentsmesh plugin add`), schema-validated config files, and a typed programmatic API for scripts, IDE extensions, and CI.
|
|
136
|
+
- **Self-serve MCP server** — `agentsmesh mcp` exposes canonical configuration as an MCP tool so AI agents can introspect rules, commands, agents, and skills, and trigger `generate` — all within the conversation. Seeded automatically by `agentsmesh init`.
|
|
136
137
|
|
|
137
138
|
---
|
|
138
139
|
|
|
@@ -147,7 +148,7 @@ The reason `AGENTS.md` alone is not enough: most AI coding assistants expose con
|
|
|
147
148
|
- **GitHub Copilot** has `.github/copilot-instructions.md`, `.github/instructions/*.instructions.md`, agents, prompts, and (partial) hooks.
|
|
148
149
|
- **Gemini CLI** has `GEMINI.md`, `.gemini/settings.json` (MCP + hooks), `.gemini/commands/*.toml`, and agents.
|
|
149
150
|
- **Codex CLI** has `AGENTS.md` plus `.codex/config.toml`, `.codex/agents/*.toml`, and `.codex/rules/`.
|
|
150
|
-
- **Windsurf**, **Continue**, **Cline**, **Kiro**, **Junie**, **Roo Code**, **Antigravity** each have their own native rules, workflows, MCP servers, skills, and ignore files.
|
|
151
|
+
- **Windsurf**, **Continue**, **Cline**, **Kiro**, **Junie**, **Roo Code**, **Antigravity**, **Amp**, **Zed**, **Warp** each have their own native rules, workflows, MCP servers, skills, and ignore files.
|
|
151
152
|
|
|
152
153
|
AgentsMesh canonicalizes all of these — rules, commands, agents, skills, MCP servers, hooks, ignore patterns, permissions — so you don't pick one tool's surface as the lowest common denominator. When a tool has no native slot for a feature, AgentsMesh embeds it with round-trip metadata instead of dropping it.
|
|
153
154
|
|
|
@@ -183,6 +184,7 @@ Detailed contracts: [Canonical Config](https://samplexbro.github.io/agentsmesh/c
|
|
|
183
184
|
agentsmesh init [--global] [--yes]
|
|
184
185
|
agentsmesh generate [--global] [--targets <csv>] [--check] [--dry-run] [--force] [--refresh-cache]
|
|
185
186
|
agentsmesh import --from <target> [--global]
|
|
187
|
+
agentsmesh convert --from <target> --to <target> [--global] [--dry-run]
|
|
186
188
|
agentsmesh diff [--global] [--targets <csv>]
|
|
187
189
|
agentsmesh lint [--global] [--targets <csv>]
|
|
188
190
|
agentsmesh watch [--global] [--targets <csv>]
|
|
@@ -196,6 +198,20 @@ agentsmesh target scaffold <id> [--name <displayName>] [--force]
|
|
|
196
198
|
|
|
197
199
|
`agentsmesh --help` prints the same surface; `agentsmesh <cmd> --help` is also supported.
|
|
198
200
|
|
|
201
|
+
### Machine-readable output
|
|
202
|
+
|
|
203
|
+
All commands support `--json` for CI pipelines and scripting:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
agentsmesh lint --json
|
|
207
|
+
# {"success":true,"command":"lint","data":{"diagnostics":[],"summary":{"errors":0,"warnings":0}}}
|
|
208
|
+
|
|
209
|
+
agentsmesh generate --check --json
|
|
210
|
+
# {"success":false,"command":"generate","error":"Command 'generate' failed","data":{"scope":"project","mode":"check","files":[...],...}}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Every command emits a single JSON envelope to stdout: `{ success, command, data?, error? }`. Human output is fully suppressed. Exit codes are preserved. `--json` is not supported with `watch`.
|
|
214
|
+
|
|
199
215
|
### Global mode (personal AI assistant config)
|
|
200
216
|
|
|
201
217
|
`.agentsmesh/` at the project level is for teams. `~/.agentsmesh/` at the home level is for personal setup across every repo you touch:
|
|
@@ -375,7 +391,7 @@ See the [full feature matrix docs](https://samplexbro.github.io/agentsmesh/refer
|
|
|
375
391
|
|
|
376
392
|
- **[Getting Started](https://samplexbro.github.io/agentsmesh/getting-started/installation/)** — installation, quick start
|
|
377
393
|
- **[Canonical Config](https://samplexbro.github.io/agentsmesh/canonical-config/)** — rules, commands, agents, skills, MCP, hooks, ignore, permissions
|
|
378
|
-
- **[CLI Reference](https://samplexbro.github.io/agentsmesh/cli/)** — `init`, `generate`, `import`, `install`, `diff`, `lint`, `watch`, `check`, `merge`, `matrix`, `plugin`, `target`
|
|
394
|
+
- **[CLI Reference](https://samplexbro.github.io/agentsmesh/cli/)** — `init`, `generate`, `import`, `convert`, `install`, `diff`, `lint`, `watch`, `check`, `merge`, `matrix`, `plugin`, `target`
|
|
379
395
|
- **[Configuration](https://samplexbro.github.io/agentsmesh/configuration/agentsmesh-yaml/)** — `agentsmesh.yaml`, local overrides, extends, collaboration, conversions
|
|
380
396
|
- **[Guides](https://samplexbro.github.io/agentsmesh/guides/existing-project/)** — adopting in existing projects · multi-tool teams · sharing config · CI drift detection · community packs · **building plugins**
|
|
381
397
|
- **[Reference](https://samplexbro.github.io/agentsmesh/reference/generation-pipeline/)** — supported tools matrix · generation pipeline · managed embedding
|
package/dist/canonical.js
CHANGED
|
@@ -1166,12 +1166,12 @@ async function readExistingServers(path) {
|
|
|
1166
1166
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
1167
1167
|
const raw = parsed.mcpServers;
|
|
1168
1168
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
1169
|
-
const
|
|
1169
|
+
const out2 = {};
|
|
1170
1170
|
for (const [name, value] of Object.entries(raw)) {
|
|
1171
1171
|
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
1172
|
-
|
|
1172
|
+
out2[name] = value;
|
|
1173
1173
|
}
|
|
1174
|
-
return
|
|
1174
|
+
return out2;
|
|
1175
1175
|
}
|
|
1176
1176
|
var init_mcp_merge = __esm({
|
|
1177
1177
|
"src/targets/import/mcp-merge.ts"() {
|
|
@@ -1454,13 +1454,13 @@ function parseMcpJson(content) {
|
|
|
1454
1454
|
if (!parsed || typeof parsed !== "object") return {};
|
|
1455
1455
|
const raw = parsed.mcpServers;
|
|
1456
1456
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
1457
|
-
const
|
|
1457
|
+
const out2 = {};
|
|
1458
1458
|
for (const [name, value] of Object.entries(raw)) {
|
|
1459
1459
|
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
1460
1460
|
const server = value;
|
|
1461
1461
|
const description = typeof server.description === "string" ? server.description : void 0;
|
|
1462
1462
|
if (typeof server.command === "string") {
|
|
1463
|
-
|
|
1463
|
+
out2[name] = {
|
|
1464
1464
|
type: typeof server.type === "string" ? server.type : "stdio",
|
|
1465
1465
|
command: server.command,
|
|
1466
1466
|
args: toStringArray5(server.args),
|
|
@@ -1470,7 +1470,7 @@ function parseMcpJson(content) {
|
|
|
1470
1470
|
continue;
|
|
1471
1471
|
}
|
|
1472
1472
|
if (typeof server.url === "string") {
|
|
1473
|
-
|
|
1473
|
+
out2[name] = {
|
|
1474
1474
|
type: typeof server.type === "string" ? server.type : "http",
|
|
1475
1475
|
url: server.url,
|
|
1476
1476
|
headers: toStringRecord(server.headers),
|
|
@@ -1479,7 +1479,7 @@ function parseMcpJson(content) {
|
|
|
1479
1479
|
};
|
|
1480
1480
|
}
|
|
1481
1481
|
}
|
|
1482
|
-
return
|
|
1482
|
+
return out2;
|
|
1483
1483
|
}
|
|
1484
1484
|
async function runMcpJson(spec, sources, projectRoot, fromTool) {
|
|
1485
1485
|
if (!spec.canonicalFilename) {
|
|
@@ -9549,18 +9549,18 @@ function generateRules11(canonical) {
|
|
|
9549
9549
|
return outputs;
|
|
9550
9550
|
}
|
|
9551
9551
|
function toJunieMcpServer(server) {
|
|
9552
|
-
const
|
|
9553
|
-
if (server.description)
|
|
9554
|
-
if (server.type !== "stdio")
|
|
9552
|
+
const out2 = {};
|
|
9553
|
+
if (server.description) out2.description = server.description;
|
|
9554
|
+
if (server.type !== "stdio") out2.type = server.type;
|
|
9555
9555
|
if (isStdioMcpServer(server)) {
|
|
9556
|
-
|
|
9557
|
-
|
|
9556
|
+
out2.command = server.command;
|
|
9557
|
+
out2.args = server.args;
|
|
9558
9558
|
} else {
|
|
9559
|
-
|
|
9560
|
-
if (Object.keys(server.headers).length > 0)
|
|
9559
|
+
out2.url = server.url;
|
|
9560
|
+
if (Object.keys(server.headers).length > 0) out2.headers = server.headers;
|
|
9561
9561
|
}
|
|
9562
|
-
if (Object.keys(server.env).length > 0)
|
|
9563
|
-
return
|
|
9562
|
+
if (Object.keys(server.env).length > 0) out2.env = server.env;
|
|
9563
|
+
return out2;
|
|
9564
9564
|
}
|
|
9565
9565
|
function generateMcp7(canonical) {
|
|
9566
9566
|
if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
|
|
@@ -11029,11 +11029,11 @@ var init_generator17 = __esm({
|
|
|
11029
11029
|
});
|
|
11030
11030
|
function toStringRecord2(value) {
|
|
11031
11031
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
11032
|
-
const
|
|
11032
|
+
const out2 = {};
|
|
11033
11033
|
for (const [k, v] of Object.entries(value)) {
|
|
11034
|
-
if (typeof v === "string")
|
|
11034
|
+
if (typeof v === "string") out2[k] = v;
|
|
11035
11035
|
}
|
|
11036
|
-
return
|
|
11036
|
+
return out2;
|
|
11037
11037
|
}
|
|
11038
11038
|
function parseOpenCodeMcp(content) {
|
|
11039
11039
|
let parsed;
|
|
@@ -11045,12 +11045,12 @@ function parseOpenCodeMcp(content) {
|
|
|
11045
11045
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
11046
11046
|
const raw = parsed.mcp;
|
|
11047
11047
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
11048
|
-
const
|
|
11048
|
+
const out2 = {};
|
|
11049
11049
|
for (const [name, value] of Object.entries(raw)) {
|
|
11050
11050
|
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
11051
11051
|
const entry = value;
|
|
11052
11052
|
if (typeof entry.url === "string") {
|
|
11053
|
-
|
|
11053
|
+
out2[name] = {
|
|
11054
11054
|
type: "url",
|
|
11055
11055
|
url: entry.url,
|
|
11056
11056
|
headers: toStringRecord2(entry.headers),
|
|
@@ -11064,7 +11064,7 @@ function parseOpenCodeMcp(content) {
|
|
|
11064
11064
|
const command = cmdArr[0];
|
|
11065
11065
|
if (command === void 0) continue;
|
|
11066
11066
|
const args = cmdArr.slice(1);
|
|
11067
|
-
|
|
11067
|
+
out2[name] = {
|
|
11068
11068
|
type: "stdio",
|
|
11069
11069
|
command,
|
|
11070
11070
|
args,
|
|
@@ -11073,7 +11073,7 @@ function parseOpenCodeMcp(content) {
|
|
|
11073
11073
|
};
|
|
11074
11074
|
}
|
|
11075
11075
|
}
|
|
11076
|
-
return
|
|
11076
|
+
return out2;
|
|
11077
11077
|
}
|
|
11078
11078
|
async function importMcp4(projectRoot, scope, results) {
|
|
11079
11079
|
const configFile = scope === "global" ? OPENCODE_GLOBAL_CONFIG_FILE : OPENCODE_CONFIG_FILE;
|
|
@@ -13495,12 +13495,12 @@ function topLevelDotfilePrefixes(descriptor19) {
|
|
|
13495
13495
|
...layouts.flatMap((l) => l.managedOutputs?.dirs ?? []),
|
|
13496
13496
|
...layouts.flatMap((l) => l.managedOutputs?.files ?? [])
|
|
13497
13497
|
];
|
|
13498
|
-
const
|
|
13498
|
+
const out2 = /* @__PURE__ */ new Set();
|
|
13499
13499
|
for (const candidate of candidates) {
|
|
13500
13500
|
const top = candidate.split("/")[0];
|
|
13501
|
-
if (top && top.startsWith(".") && top.length > 1)
|
|
13501
|
+
if (top && top.startsWith(".") && top.length > 1) out2.add(`${top}/`);
|
|
13502
13502
|
}
|
|
13503
|
-
return
|
|
13503
|
+
return out2;
|
|
13504
13504
|
}
|
|
13505
13505
|
function buildDefaultRootRelativePrefixes() {
|
|
13506
13506
|
const set = /* @__PURE__ */ new Set([".agentsmesh/"]);
|
|
@@ -15076,12 +15076,60 @@ function parseServer(raw) {
|
|
|
15076
15076
|
env
|
|
15077
15077
|
};
|
|
15078
15078
|
}
|
|
15079
|
+
function stripJsonComments(text) {
|
|
15080
|
+
let result = "";
|
|
15081
|
+
let i = 0;
|
|
15082
|
+
const len = text.length;
|
|
15083
|
+
while (i < len) {
|
|
15084
|
+
const ch = text[i];
|
|
15085
|
+
if (ch === '"') {
|
|
15086
|
+
result += ch;
|
|
15087
|
+
i++;
|
|
15088
|
+
while (i < len) {
|
|
15089
|
+
const sc = text[i];
|
|
15090
|
+
result += sc;
|
|
15091
|
+
if (sc === "\\") {
|
|
15092
|
+
i++;
|
|
15093
|
+
if (i < len) {
|
|
15094
|
+
result += text[i];
|
|
15095
|
+
}
|
|
15096
|
+
} else if (sc === '"') {
|
|
15097
|
+
break;
|
|
15098
|
+
}
|
|
15099
|
+
i++;
|
|
15100
|
+
}
|
|
15101
|
+
i++;
|
|
15102
|
+
continue;
|
|
15103
|
+
}
|
|
15104
|
+
if (ch === "/" && text[i + 1] === "*") {
|
|
15105
|
+
i += 2;
|
|
15106
|
+
while (i < len) {
|
|
15107
|
+
if (text[i] === "*" && text[i + 1] === "/") {
|
|
15108
|
+
i += 2;
|
|
15109
|
+
break;
|
|
15110
|
+
}
|
|
15111
|
+
i++;
|
|
15112
|
+
}
|
|
15113
|
+
continue;
|
|
15114
|
+
}
|
|
15115
|
+
if (ch === "/" && text[i + 1] === "/") {
|
|
15116
|
+
i += 2;
|
|
15117
|
+
while (i < len && text[i] !== "\n") {
|
|
15118
|
+
i++;
|
|
15119
|
+
}
|
|
15120
|
+
continue;
|
|
15121
|
+
}
|
|
15122
|
+
result += ch;
|
|
15123
|
+
i++;
|
|
15124
|
+
}
|
|
15125
|
+
return result;
|
|
15126
|
+
}
|
|
15079
15127
|
async function parseMcp(mcpPath) {
|
|
15080
15128
|
const content = await readFileSafe(mcpPath);
|
|
15081
15129
|
if (!content) return null;
|
|
15082
15130
|
let parsed;
|
|
15083
15131
|
try {
|
|
15084
|
-
parsed = JSON.parse(content);
|
|
15132
|
+
parsed = JSON.parse(stripJsonComments(content));
|
|
15085
15133
|
} catch {
|
|
15086
15134
|
return null;
|
|
15087
15135
|
}
|
|
@@ -15283,14 +15331,14 @@ function mergeHooks(base, overlay) {
|
|
|
15283
15331
|
}
|
|
15284
15332
|
function mergeIgnore(base, overlay) {
|
|
15285
15333
|
const seen = new Set(base);
|
|
15286
|
-
const
|
|
15334
|
+
const out2 = [...base];
|
|
15287
15335
|
for (const p of overlay) {
|
|
15288
15336
|
if (!seen.has(p)) {
|
|
15289
15337
|
seen.add(p);
|
|
15290
|
-
|
|
15338
|
+
out2.push(p);
|
|
15291
15339
|
}
|
|
15292
15340
|
}
|
|
15293
|
-
return
|
|
15341
|
+
return out2;
|
|
15294
15342
|
}
|
|
15295
15343
|
|
|
15296
15344
|
// src/config/resolve/native-format-detector.ts
|
|
@@ -15398,6 +15446,11 @@ var C = {
|
|
|
15398
15446
|
cyan: "\x1B[36m",
|
|
15399
15447
|
reset: "\x1B[0m"
|
|
15400
15448
|
};
|
|
15449
|
+
function out(text) {
|
|
15450
|
+
{
|
|
15451
|
+
process.stdout.write(text);
|
|
15452
|
+
}
|
|
15453
|
+
}
|
|
15401
15454
|
function noColor() {
|
|
15402
15455
|
return process.env.NO_COLOR !== void 0 && process.env.NO_COLOR !== "";
|
|
15403
15456
|
}
|
|
@@ -15410,7 +15463,7 @@ function pad(str, width) {
|
|
|
15410
15463
|
}
|
|
15411
15464
|
var logger = {
|
|
15412
15465
|
info(msg) {
|
|
15413
|
-
|
|
15466
|
+
out(c(C.cyan, msg) + "\n");
|
|
15414
15467
|
},
|
|
15415
15468
|
warn(msg) {
|
|
15416
15469
|
process.stderr.write(c(C.yellow, "\u26A0 ") + msg + "\n");
|
|
@@ -15419,11 +15472,11 @@ var logger = {
|
|
|
15419
15472
|
process.stderr.write(c(C.red, "\u2717 ") + msg + "\n");
|
|
15420
15473
|
},
|
|
15421
15474
|
success(msg) {
|
|
15422
|
-
|
|
15475
|
+
out(c(C.green, "\u2713 ") + msg + "\n");
|
|
15423
15476
|
},
|
|
15424
15477
|
debug(msg) {
|
|
15425
15478
|
if (process.env.AGENTSMESH_DEBUG === "1") {
|
|
15426
|
-
|
|
15479
|
+
out(c(C.cyan, "[debug] ") + msg + "\n");
|
|
15427
15480
|
}
|
|
15428
15481
|
},
|
|
15429
15482
|
table(rows) {
|
|
@@ -15439,13 +15492,13 @@ var logger = {
|
|
|
15439
15492
|
widths[j] = max;
|
|
15440
15493
|
}
|
|
15441
15494
|
const border = "+" + widths.map((w) => "-".repeat(w + 2)).join("+") + "+";
|
|
15442
|
-
|
|
15495
|
+
out(border + "\n");
|
|
15443
15496
|
for (let i = 0; i < rows.length; i++) {
|
|
15444
15497
|
const row = rows[i];
|
|
15445
15498
|
const line = "| " + row.map((cell, j) => pad(cell, widths[j])).join(" | ") + " |";
|
|
15446
|
-
|
|
15499
|
+
out(line + "\n");
|
|
15447
15500
|
}
|
|
15448
|
-
|
|
15501
|
+
out(border + "\n");
|
|
15449
15502
|
}
|
|
15450
15503
|
};
|
|
15451
15504
|
|