@neat.is/core 0.9.18 → 0.9.19
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/{chunk-MGQSR6QZ.js → chunk-NTVHVZYC.js} +191 -29
- package/dist/chunk-NTVHVZYC.js.map +1 -0
- package/dist/cli.cjs +1133 -1013
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +158 -47
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +259 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/neatd.cjs +271 -108
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +1 -1
- package/package.json +3 -2
- package/dist/chunk-MGQSR6QZ.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
resolveNeatVersion,
|
|
9
9
|
startK8sSubstratePolling,
|
|
10
10
|
writeDaemonRecord
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-NTVHVZYC.js";
|
|
12
12
|
import {
|
|
13
13
|
buildSearchIndex
|
|
14
14
|
} from "./chunk-BC53SCT7.js";
|
|
@@ -99,6 +99,107 @@ import { promises as fs16 } from "fs";
|
|
|
99
99
|
import path from "path";
|
|
100
100
|
import { readFileSync } from "fs";
|
|
101
101
|
import { fileURLToPath } from "url";
|
|
102
|
+
|
|
103
|
+
// src/style.ts
|
|
104
|
+
import { Provenance } from "@neat.is/types";
|
|
105
|
+
var RESET = "\x1B[0m";
|
|
106
|
+
function computeEnabled(env = process.env) {
|
|
107
|
+
if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0" && env.FORCE_COLOR !== "") {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (env.NO_COLOR !== void 0) return false;
|
|
111
|
+
if (env.TERM === "dumb") return false;
|
|
112
|
+
return Boolean(process.stdout && process.stdout.isTTY);
|
|
113
|
+
}
|
|
114
|
+
var enabled = computeEnabled();
|
|
115
|
+
function wrap(open, s) {
|
|
116
|
+
return enabled ? `${open}${s}${RESET}` : s;
|
|
117
|
+
}
|
|
118
|
+
var bold = (s) => wrap("\x1B[1m", s);
|
|
119
|
+
var dim = (s) => wrap("\x1B[2m", s);
|
|
120
|
+
var OBSERVED_GREEN = "\x1B[38;2;95;207;158m";
|
|
121
|
+
var STALE_AMBER = "\x1B[38;2;214;164;92m";
|
|
122
|
+
var ERROR_RED = "\x1B[38;2;224;108;108m";
|
|
123
|
+
var INFERRED_CYAN = "\x1B[38;2;122;162;247m";
|
|
124
|
+
var green = (s) => wrap(OBSERVED_GREEN, s);
|
|
125
|
+
var amber = (s) => wrap(STALE_AMBER, s);
|
|
126
|
+
var red = (s) => wrap(ERROR_RED, s);
|
|
127
|
+
var cyan = (s) => wrap(INFERRED_CYAN, s);
|
|
128
|
+
var accent = green;
|
|
129
|
+
var ok = green;
|
|
130
|
+
var warn = amber;
|
|
131
|
+
var error = red;
|
|
132
|
+
var sym = {
|
|
133
|
+
ok: "\u2713",
|
|
134
|
+
fail: "\u2717",
|
|
135
|
+
warn: "\u26A0",
|
|
136
|
+
bullet: "\u2022",
|
|
137
|
+
arrow: "\u2192",
|
|
138
|
+
stale: "\u22EF",
|
|
139
|
+
add: "+",
|
|
140
|
+
dot: "\u25CF",
|
|
141
|
+
chevron: "\u25B8"
|
|
142
|
+
};
|
|
143
|
+
function heading(label) {
|
|
144
|
+
return bold(label);
|
|
145
|
+
}
|
|
146
|
+
function provenanceToken(token) {
|
|
147
|
+
switch (token.trim().toUpperCase()) {
|
|
148
|
+
case Provenance.OBSERVED:
|
|
149
|
+
return green(token);
|
|
150
|
+
case Provenance.STALE:
|
|
151
|
+
return amber(token);
|
|
152
|
+
case Provenance.INFERRED:
|
|
153
|
+
return cyan(token);
|
|
154
|
+
case Provenance.EXTRACTED:
|
|
155
|
+
return dim(token);
|
|
156
|
+
default:
|
|
157
|
+
return token;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function provenance(value) {
|
|
161
|
+
return value.split(",").map((part, i) => i === 0 ? provenanceToken(part) : " " + provenanceToken(part.replace(/^\s+/, ""))).join(",");
|
|
162
|
+
}
|
|
163
|
+
var ANSI = /\x1b\[[0-9;]*m/g;
|
|
164
|
+
function visibleWidth(s) {
|
|
165
|
+
return s.replace(ANSI, "").length;
|
|
166
|
+
}
|
|
167
|
+
function table(rows, gap = 2) {
|
|
168
|
+
if (rows.length === 0) return [];
|
|
169
|
+
const cols = Math.max(...rows.map((r) => r.length));
|
|
170
|
+
const widths = [];
|
|
171
|
+
for (let c = 0; c < cols - 1; c++) {
|
|
172
|
+
widths[c] = Math.max(...rows.map((r) => r[c] ? visibleWidth(r[c]) : 0));
|
|
173
|
+
}
|
|
174
|
+
const pad = " ".repeat(gap);
|
|
175
|
+
return rows.map(
|
|
176
|
+
(r) => r.map((cell, c) => {
|
|
177
|
+
if (c === r.length - 1) return cell;
|
|
178
|
+
const extra = widths[c] - visibleWidth(cell);
|
|
179
|
+
return cell + " ".repeat(Math.max(0, extra));
|
|
180
|
+
}).join(pad)
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
function styleBlock(block) {
|
|
184
|
+
return block.split("\n").map((line) => {
|
|
185
|
+
let out = line.replace(/\b(OBSERVED|STALE|INFERRED|EXTRACTED)\b/g, (m) => provenanceToken(m));
|
|
186
|
+
out = out.replace(/^(\s*)•/, (_all, indent2) => `${indent2}${dim(sym.bullet)}`);
|
|
187
|
+
return out;
|
|
188
|
+
}).join("\n");
|
|
189
|
+
}
|
|
190
|
+
function footer(confidence, provenanceValue) {
|
|
191
|
+
const prov = provenanceValue === "n/a" ? dim(provenanceValue) : provenance(provenanceValue);
|
|
192
|
+
return `${dim("confidence:")} ${confidence} ${dim("\xB7")} ${dim("provenance:")} ${prov}`;
|
|
193
|
+
}
|
|
194
|
+
function wordmark(version) {
|
|
195
|
+
const mark = `${accent(sym.chevron)} ${bold("neat")}`;
|
|
196
|
+
const expansion = dim("Network Environment Architecture Tools");
|
|
197
|
+
const meta = dim(`neat.is \xB7 v${version} \xB7 Apache 2.0`);
|
|
198
|
+
return `${mark} ${expansion}
|
|
199
|
+
${meta}`;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/banner.ts
|
|
102
203
|
function readPackageVersion() {
|
|
103
204
|
const here = typeof __dirname !== "undefined" ? __dirname : path.dirname(fileURLToPath(import.meta.url));
|
|
104
205
|
const candidates = [
|
|
@@ -118,15 +219,8 @@ function readPackageVersion() {
|
|
|
118
219
|
return "unknown";
|
|
119
220
|
}
|
|
120
221
|
function printBanner() {
|
|
121
|
-
console.log("\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557");
|
|
122
|
-
console.log("\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D");
|
|
123
|
-
console.log("\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 ");
|
|
124
|
-
console.log("\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 ");
|
|
125
|
-
console.log("\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 ");
|
|
126
|
-
console.log("\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ");
|
|
127
222
|
console.log("");
|
|
128
|
-
console.log(
|
|
129
|
-
console.log(` neat.is \xB7 v${readPackageVersion()} \xB7 Apache 2.0`);
|
|
223
|
+
console.log(wordmark(readPackageVersion()));
|
|
130
224
|
console.log("");
|
|
131
225
|
}
|
|
132
226
|
function isNpxInvocation() {
|
|
@@ -177,7 +271,7 @@ ${NEAT_OUT_LINE}
|
|
|
177
271
|
}
|
|
178
272
|
|
|
179
273
|
// src/summary.ts
|
|
180
|
-
import { NodeType, Provenance } from "@neat.is/types";
|
|
274
|
+
import { NodeType, Provenance as Provenance2 } from "@neat.is/types";
|
|
181
275
|
function renderOtelEnvBlock() {
|
|
182
276
|
return [
|
|
183
277
|
"for prod OTel routing, set these in your deploy platform's env:",
|
|
@@ -193,7 +287,7 @@ function findIncompatServices(nodes) {
|
|
|
193
287
|
function servicesWithoutObserved(nodes, edges) {
|
|
194
288
|
const seen = /* @__PURE__ */ new Set();
|
|
195
289
|
for (const e of edges) {
|
|
196
|
-
if (e.provenance ===
|
|
290
|
+
if (e.provenance === Provenance2.OBSERVED) {
|
|
197
291
|
seen.add(e.source);
|
|
198
292
|
seen.add(e.target);
|
|
199
293
|
}
|
|
@@ -213,7 +307,7 @@ function renderValueForwardSummary(input) {
|
|
|
213
307
|
const edges = [];
|
|
214
308
|
graph.forEachEdge((_id, attrs) => edges.push(attrs));
|
|
215
309
|
const lines = [];
|
|
216
|
-
lines.push("
|
|
310
|
+
lines.push(heading("neat \xB7 findings"));
|
|
217
311
|
lines.push("");
|
|
218
312
|
const incompatServices = findIncompatServices(nodes);
|
|
219
313
|
const totalIncompats = incompatServices.reduce(
|
|
@@ -3965,8 +4059,8 @@ var PROBE_INTERVAL_MS = 500;
|
|
|
3965
4059
|
async function fetchDaemonHealth(restPort) {
|
|
3966
4060
|
return new Promise((resolve) => {
|
|
3967
4061
|
const req = http.get(`http://127.0.0.1:${restPort}/health`, (res) => {
|
|
3968
|
-
const
|
|
3969
|
-
if (!
|
|
4062
|
+
const ok2 = res.statusCode !== void 0 && res.statusCode >= 200 && res.statusCode < 300;
|
|
4063
|
+
if (!ok2) {
|
|
3970
4064
|
res.resume();
|
|
3971
4065
|
resolve(null);
|
|
3972
4066
|
return;
|
|
@@ -5377,7 +5471,7 @@ import { promises as fs11 } from "fs";
|
|
|
5377
5471
|
import path12 from "path";
|
|
5378
5472
|
|
|
5379
5473
|
// src/cli-client.ts
|
|
5380
|
-
import { Provenance as
|
|
5474
|
+
import { Provenance as Provenance3 } from "@neat.is/types";
|
|
5381
5475
|
var HttpError = class extends Error {
|
|
5382
5476
|
constructor(status, message, responseBody = "") {
|
|
5383
5477
|
super(message);
|
|
@@ -5519,7 +5613,7 @@ async function runBlastRadius(client, input) {
|
|
|
5519
5613
|
}
|
|
5520
5614
|
}
|
|
5521
5615
|
function formatBlastEntry(n) {
|
|
5522
|
-
const tag = n.edgeProvenance ===
|
|
5616
|
+
const tag = n.edgeProvenance === Provenance3.STALE ? " [STALE \u2014 last seen too long ago]" : "";
|
|
5523
5617
|
return ` \u2022 ${n.nodeId} (distance ${n.distance}, ${n.edgeProvenance})${tag}`;
|
|
5524
5618
|
}
|
|
5525
5619
|
async function runDependencies(client, input) {
|
|
@@ -5576,7 +5670,7 @@ async function runObservedDependencies(client, input) {
|
|
|
5576
5670
|
if (result.observed) {
|
|
5577
5671
|
return {
|
|
5578
5672
|
summary: `${input.nodeId} makes no outbound runtime calls, but OTel has observed it receiving traffic on ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 it's a pure receiver.`,
|
|
5579
|
-
provenance:
|
|
5673
|
+
provenance: Provenance3.OBSERVED
|
|
5580
5674
|
};
|
|
5581
5675
|
}
|
|
5582
5676
|
const note = result.hasExtractedOutbound ? " Static (EXTRACTED) dependencies exist but no runtime traffic has been seen \u2014 is OTel running?" : "";
|
|
@@ -5586,7 +5680,7 @@ async function runObservedDependencies(client, input) {
|
|
|
5586
5680
|
return {
|
|
5587
5681
|
summary: `${input.nodeId} has ${result.dependencies.length} runtime dependenc${result.dependencies.length === 1 ? "y" : "ies"} confirmed by OTel.`,
|
|
5588
5682
|
block: blockLines.join("\n"),
|
|
5589
|
-
provenance:
|
|
5683
|
+
provenance: Provenance3.OBSERVED
|
|
5590
5684
|
};
|
|
5591
5685
|
} catch (err) {
|
|
5592
5686
|
if (err instanceof HttpError && err.status === 404) {
|
|
@@ -5640,7 +5734,7 @@ async function runIncidents(client, input) {
|
|
|
5640
5734
|
return {
|
|
5641
5735
|
summary: `${target} has ${body.total} recorded incident${body.total === 1 ? "" : "s"}; showing the ${ordered.length} most recent.`,
|
|
5642
5736
|
block: blockLines.join("\n"),
|
|
5643
|
-
provenance:
|
|
5737
|
+
provenance: Provenance3.OBSERVED
|
|
5644
5738
|
};
|
|
5645
5739
|
} catch (err) {
|
|
5646
5740
|
if (err instanceof HttpError && err.status === 404) {
|
|
@@ -5749,7 +5843,7 @@ async function runStaleEdges(client, input) {
|
|
|
5749
5843
|
return {
|
|
5750
5844
|
summary: `${events.length} stale-edge transition${events.length === 1 ? "" : "s"} recorded${input.edgeType ? ` for ${input.edgeType}` : ""}.`,
|
|
5751
5845
|
block: blockLines.join("\n"),
|
|
5752
|
-
provenance:
|
|
5846
|
+
provenance: Provenance3.STALE
|
|
5753
5847
|
};
|
|
5754
5848
|
}
|
|
5755
5849
|
async function runPolicies(client, input) {
|
|
@@ -5910,14 +6004,14 @@ async function runAsk(client, input) {
|
|
|
5910
6004
|
...result.provenance.length > 0 ? { provenance: result.provenance } : {}
|
|
5911
6005
|
};
|
|
5912
6006
|
}
|
|
5913
|
-
function formatFooter(confidence,
|
|
6007
|
+
function formatFooter(confidence, provenance2) {
|
|
5914
6008
|
const c = confidence === void 0 ? "n/a" : confidence.toFixed(2);
|
|
5915
|
-
const p =
|
|
5916
|
-
return
|
|
6009
|
+
const p = provenance2 === void 0 ? "n/a" : Array.isArray(provenance2) ? [...new Set(provenance2)].join(", ") : provenance2;
|
|
6010
|
+
return footer(c, p);
|
|
5917
6011
|
}
|
|
5918
6012
|
function formatHuman(result) {
|
|
5919
6013
|
const sections = [result.summary.trim()];
|
|
5920
|
-
if (result.block && result.block.trim().length > 0) sections.push(result.block.trimEnd());
|
|
6014
|
+
if (result.block && result.block.trim().length > 0) sections.push(styleBlock(result.block.trimEnd()));
|
|
5921
6015
|
sections.push(formatFooter(result.confidence, result.provenance));
|
|
5922
6016
|
return sections.join("\n\n");
|
|
5923
6017
|
}
|
|
@@ -5977,10 +6071,10 @@ var NODE_FLOOR = 20;
|
|
|
5977
6071
|
var HEALTH_TIMEOUT_MS = 3e3;
|
|
5978
6072
|
function checkNode(nodeVersion) {
|
|
5979
6073
|
const major = Number.parseInt(nodeVersion.split(".")[0] ?? "", 10);
|
|
5980
|
-
const
|
|
5981
|
-
return
|
|
6074
|
+
const ok2 = Number.isFinite(major) && major >= NODE_FLOOR;
|
|
6075
|
+
return ok2 ? { name: "node", ok: ok2, detail: `v${nodeVersion} (>= ${NODE_FLOOR} required)` } : {
|
|
5982
6076
|
name: "node",
|
|
5983
|
-
ok,
|
|
6077
|
+
ok: ok2,
|
|
5984
6078
|
detail: `v${nodeVersion} \u2014 NEAT needs Node ${NODE_FLOOR} or newer`,
|
|
5985
6079
|
fix: `install Node ${NODE_FLOOR}.x (e.g. \`nvm install ${NODE_FLOOR}\`) and re-run`
|
|
5986
6080
|
};
|
|
@@ -6072,16 +6166,16 @@ async function runDoctorChecks(deps = {}) {
|
|
|
6072
6166
|
}
|
|
6073
6167
|
var NAME_COL = "project".length;
|
|
6074
6168
|
function renderHuman(checks, out) {
|
|
6075
|
-
out("neat doctor \u2014 checking this project's setup");
|
|
6169
|
+
out(heading("neat doctor") + dim(" \u2014 checking this project's setup"));
|
|
6076
6170
|
out("");
|
|
6077
6171
|
for (const c of checks) {
|
|
6078
|
-
const mark = c.ok ?
|
|
6079
|
-
out(` ${mark} ${c.name.padEnd(NAME_COL)} ${c.detail}`);
|
|
6080
|
-
if (!c.ok && c.fix) out(` ${" ".repeat(NAME_COL + 3)}fix: ${c.fix}`);
|
|
6172
|
+
const mark = c.ok ? ok(sym.ok) : error(sym.fail);
|
|
6173
|
+
out(` ${mark} ${dim(c.name.padEnd(NAME_COL))} ${c.detail}`);
|
|
6174
|
+
if (!c.ok && c.fix) out(` ${" ".repeat(NAME_COL + 3)}${dim("fix:")} ${warn(c.fix)}`);
|
|
6081
6175
|
}
|
|
6082
6176
|
out("");
|
|
6083
6177
|
const failed = checks.filter((c) => !c.ok).length;
|
|
6084
|
-
out(failed === 0 ? "all good." : `${failed} check${failed === 1 ? "" : "s"} failed.`);
|
|
6178
|
+
out(failed === 0 ? ok("all good.") : warn(`${failed} check${failed === 1 ? "" : "s"} failed.`));
|
|
6085
6179
|
}
|
|
6086
6180
|
async function runDoctorCommand(argv, deps = {}) {
|
|
6087
6181
|
const out = deps.out ?? ((line) => console.log(line));
|
|
@@ -7438,7 +7532,7 @@ async function runEditorCommand(clientId, args, projectDir = process.cwd()) {
|
|
|
7438
7532
|
}
|
|
7439
7533
|
|
|
7440
7534
|
// src/monitor.ts
|
|
7441
|
-
import { EdgeType, parseEdgeId, Provenance as
|
|
7535
|
+
import { EdgeType, parseEdgeId, Provenance as Provenance4 } from "@neat.is/types";
|
|
7442
7536
|
var OBSERVED_DEP_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
7443
7537
|
EdgeType.CALLS,
|
|
7444
7538
|
EdgeType.CONNECTS_TO,
|
|
@@ -7600,7 +7694,7 @@ var MonitorEmitter = class {
|
|
|
7600
7694
|
// ignores non-OBSERVED edges and non-dependency edge types (structural
|
|
7601
7695
|
// ownership), so only real runtime dependencies reach stdout.
|
|
7602
7696
|
emitObservedEdge(edge) {
|
|
7603
|
-
if (edge.provenance !==
|
|
7697
|
+
if (edge.provenance !== Provenance4.OBSERVED) return false;
|
|
7604
7698
|
if (!OBSERVED_DEP_EDGE_TYPES.has(edge.type)) return false;
|
|
7605
7699
|
const key = `edge|${edge.id}`;
|
|
7606
7700
|
if (this.seen.has(key)) return false;
|
|
@@ -7781,7 +7875,7 @@ async function runMonitor(opts) {
|
|
|
7781
7875
|
case "edge-added": {
|
|
7782
7876
|
const payload = safeParse(frame.data);
|
|
7783
7877
|
const edge = payload?.edge;
|
|
7784
|
-
if (edge && edge.provenance ===
|
|
7878
|
+
if (edge && edge.provenance === Provenance4.OBSERVED) {
|
|
7785
7879
|
emitter.emitObservedEdge(edge);
|
|
7786
7880
|
divergences.schedule();
|
|
7787
7881
|
}
|
|
@@ -7928,7 +8022,7 @@ function emitResult(result, json) {
|
|
|
7928
8022
|
} else {
|
|
7929
8023
|
console.log("skipped instrumentation (--no-instrument)");
|
|
7930
8024
|
}
|
|
7931
|
-
for (const
|
|
8025
|
+
for (const warn2 of result.warnings) console.error(warn2);
|
|
7932
8026
|
}
|
|
7933
8027
|
async function runSync(opts) {
|
|
7934
8028
|
const entry2 = await resolveProjectEntry(opts);
|
|
@@ -8064,7 +8158,7 @@ function usage5() {
|
|
|
8064
8158
|
console.log(`The run stays in your terminal \u2014 query the graph over MCP or the CLI. For a visual`);
|
|
8065
8159
|
console.log(`dashboard, log in to hosted NEAT; \`--open\` launches the local preview one by choice.`);
|
|
8066
8160
|
console.log("");
|
|
8067
|
-
console.log("lifecycle commands:");
|
|
8161
|
+
console.log(heading("lifecycle commands:"));
|
|
8068
8162
|
console.log(" welcome Open the first-run menu: log in to a hosted NEAT, or set up");
|
|
8069
8163
|
console.log(" self-hosted (print an agent-setup prompt, then build the graph");
|
|
8070
8164
|
console.log(" for the current directory).");
|
|
@@ -8206,7 +8300,7 @@ function usage5() {
|
|
|
8206
8300
|
console.log(" logout Clear the active hosted profile (back to your local daemon);");
|
|
8207
8301
|
console.log(" --name <name> removes that profile entirely.");
|
|
8208
8302
|
console.log("");
|
|
8209
|
-
console.log("query commands (mirror the MCP tools, ADR-050):");
|
|
8303
|
+
console.log(heading("query commands (mirror the MCP tools, ADR-050):"));
|
|
8210
8304
|
console.log(" ask <question> Plain-language door: resolves the question to");
|
|
8211
8305
|
console.log(" nodes and routes it to the right traversal, with");
|
|
8212
8306
|
console.log(" a compact provenance-tagged answer. Reach here first.");
|
|
@@ -8391,19 +8485,36 @@ function printVersion() {
|
|
|
8391
8485
|
process.stdout.write(`${readPackageVersion()}
|
|
8392
8486
|
`);
|
|
8393
8487
|
}
|
|
8394
|
-
function
|
|
8488
|
+
function styleState(state) {
|
|
8489
|
+
switch (state) {
|
|
8490
|
+
case "running":
|
|
8491
|
+
case "active":
|
|
8492
|
+
return ok(state);
|
|
8493
|
+
case "paused":
|
|
8494
|
+
return warn(state);
|
|
8495
|
+
case "broken":
|
|
8496
|
+
return error(state);
|
|
8497
|
+
case "stopped":
|
|
8498
|
+
case "registered":
|
|
8499
|
+
return dim(state);
|
|
8500
|
+
default:
|
|
8501
|
+
return state;
|
|
8502
|
+
}
|
|
8503
|
+
}
|
|
8504
|
+
function machineProjectCells(r) {
|
|
8395
8505
|
if (r.ports) {
|
|
8396
|
-
const
|
|
8397
|
-
|
|
8506
|
+
const ports = dim(`rest=${r.ports.rest} otlp=${r.ports.otlp} web=${r.ports.web}`);
|
|
8507
|
+
const where = r.pid !== void 0 ? `${r.projectPath} ${dim(`pid=${r.pid}`)}` : r.projectPath;
|
|
8508
|
+
return [r.project, styleState(r.state), ports, where];
|
|
8398
8509
|
}
|
|
8399
|
-
const status = r.registryStatus ?
|
|
8400
|
-
return
|
|
8510
|
+
const status = r.registryStatus ? `${dim("(")}${styleState(r.registryStatus)}${dim(")")}` : "";
|
|
8511
|
+
return [r.project, styleState(r.state), status, r.projectPath];
|
|
8401
8512
|
}
|
|
8402
8513
|
function printDiscoveryReport(opts, services) {
|
|
8403
8514
|
const languages = [...new Set(services.map((s) => s.node.language))].sort();
|
|
8404
8515
|
const mode = opts.dryRun ? "dry-run" : opts.apply ? "apply" : "patch-only";
|
|
8405
8516
|
printBanner();
|
|
8406
|
-
console.log("
|
|
8517
|
+
console.log(heading("neat init \xB7 discovery"));
|
|
8407
8518
|
console.log(`scan path: ${opts.scanPath}`);
|
|
8408
8519
|
console.log(`project: ${opts.project}`);
|
|
8409
8520
|
console.log(`mode: ${mode}`);
|
|
@@ -8809,9 +8920,9 @@ async function main() {
|
|
|
8809
8920
|
console.log("no daemons running and no projects registered. run `neat init <path>` to register one.");
|
|
8810
8921
|
return;
|
|
8811
8922
|
}
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8923
|
+
const header = ["project", "state", "ports", "path"].map((h) => dim(h));
|
|
8924
|
+
const body = rows.map(machineProjectCells);
|
|
8925
|
+
for (const line of table([header, ...body])) console.log(line);
|
|
8815
8926
|
return;
|
|
8816
8927
|
}
|
|
8817
8928
|
if (cmd === "pause") {
|