@neat.is/core 0.10.6 → 0.10.7-dev.20261011
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-MW2XYLCS.js → chunk-6K22WGO7.js} +49 -1
- package/dist/{chunk-MW2XYLCS.js.map → chunk-6K22WGO7.js.map} +1 -1
- package/dist/chunk-AEMLUMHC.js +42 -0
- package/dist/chunk-AEMLUMHC.js.map +1 -0
- package/dist/{chunk-OKM4N7GH.js → chunk-S5S2FYCQ.js} +26 -5
- package/dist/chunk-S5S2FYCQ.js.map +1 -0
- package/dist/cli.cjs +137 -10
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +3 -2
- package/dist/cli.d.ts +3 -2
- package/dist/cli.js +53 -12
- package/dist/cli.js.map +1 -1
- package/dist/incidents-render.cjs +66 -0
- package/dist/incidents-render.cjs.map +1 -0
- package/dist/incidents-render.d.cts +5 -0
- package/dist/incidents-render.d.ts +5 -0
- package/dist/incidents-render.js +8 -0
- package/dist/incidents-render.js.map +1 -0
- package/dist/index.cjs +72 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +78 -6
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +8 -5
- package/dist/neatd.js.map +1 -1
- package/dist/server.cjs +48 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +7 -2
- package/dist/chunk-OKM4N7GH.js.map +0 -1
package/dist/cli.d.cts
CHANGED
|
@@ -83,7 +83,7 @@ declare class ProjectResolutionError extends Error {
|
|
|
83
83
|
}
|
|
84
84
|
declare function isLoopbackEndpoint(endpoint: string): boolean;
|
|
85
85
|
declare function resolveProjectForVerb(client: HttpClient, parsed: ParsedArgs, cwdProject?: string): Promise<string | undefined>;
|
|
86
|
-
type ClientTargetSource = 'profile' | 'env' | 'active' | 'daemon-record' | 'default';
|
|
86
|
+
type ClientTargetSource = 'profile' | 'env' | 'active' | 'daemon-record' | 'sole-daemon' | 'default';
|
|
87
87
|
interface ClientTarget {
|
|
88
88
|
endpoint: string;
|
|
89
89
|
authToken?: string;
|
|
@@ -96,6 +96,7 @@ declare function resolveClientTarget(opts?: {
|
|
|
96
96
|
project?: string;
|
|
97
97
|
profile?: string;
|
|
98
98
|
}): Promise<ClientTarget>;
|
|
99
|
+
declare function loopbackResolutionHint(): Promise<string | undefined>;
|
|
99
100
|
declare function projectForCwd(cwd?: string): Promise<string | undefined>;
|
|
100
101
|
declare function cwdProjectApplies(source: ClientTargetSource): boolean;
|
|
101
102
|
declare function resolveDaemonUrl(project?: string, profile?: string): Promise<string>;
|
|
@@ -103,4 +104,4 @@ declare function runQueryVerb(cmd: string, parsed: ParsedArgs): Promise<number>;
|
|
|
103
104
|
declare function runMonitorVerb(parsed: ParsedArgs): Promise<number>;
|
|
104
105
|
declare function reportFatal(err: unknown, log?: (line: unknown) => void): number;
|
|
105
106
|
|
|
106
|
-
export { CLAUDE_SKILL_CONFIG, type ClientTarget, type ClientTargetSource, type InitOptions, type InitResult, ProjectResolutionError, QUERY_VERBS, type SkillOptions, UnknownProfileError, commandPrefix, cwdProjectApplies, isLoopbackEndpoint, isNpxInvocation, main, parseArgs, printBanner, projectForCwd, readPackageVersion, reportFatal, resolveClientTarget, resolveDaemonUrl, resolveProjectForVerb, runInit, runMonitorVerb, runQueryVerb, runSkill, usage };
|
|
107
|
+
export { CLAUDE_SKILL_CONFIG, type ClientTarget, type ClientTargetSource, type InitOptions, type InitResult, ProjectResolutionError, QUERY_VERBS, type SkillOptions, UnknownProfileError, commandPrefix, cwdProjectApplies, isLoopbackEndpoint, isNpxInvocation, loopbackResolutionHint, main, parseArgs, printBanner, projectForCwd, readPackageVersion, reportFatal, resolveClientTarget, resolveDaemonUrl, resolveProjectForVerb, runInit, runMonitorVerb, runQueryVerb, runSkill, usage };
|
package/dist/cli.d.ts
CHANGED
|
@@ -83,7 +83,7 @@ declare class ProjectResolutionError extends Error {
|
|
|
83
83
|
}
|
|
84
84
|
declare function isLoopbackEndpoint(endpoint: string): boolean;
|
|
85
85
|
declare function resolveProjectForVerb(client: HttpClient, parsed: ParsedArgs, cwdProject?: string): Promise<string | undefined>;
|
|
86
|
-
type ClientTargetSource = 'profile' | 'env' | 'active' | 'daemon-record' | 'default';
|
|
86
|
+
type ClientTargetSource = 'profile' | 'env' | 'active' | 'daemon-record' | 'sole-daemon' | 'default';
|
|
87
87
|
interface ClientTarget {
|
|
88
88
|
endpoint: string;
|
|
89
89
|
authToken?: string;
|
|
@@ -96,6 +96,7 @@ declare function resolveClientTarget(opts?: {
|
|
|
96
96
|
project?: string;
|
|
97
97
|
profile?: string;
|
|
98
98
|
}): Promise<ClientTarget>;
|
|
99
|
+
declare function loopbackResolutionHint(): Promise<string | undefined>;
|
|
99
100
|
declare function projectForCwd(cwd?: string): Promise<string | undefined>;
|
|
100
101
|
declare function cwdProjectApplies(source: ClientTargetSource): boolean;
|
|
101
102
|
declare function resolveDaemonUrl(project?: string, profile?: string): Promise<string>;
|
|
@@ -103,4 +104,4 @@ declare function runQueryVerb(cmd: string, parsed: ParsedArgs): Promise<number>;
|
|
|
103
104
|
declare function runMonitorVerb(parsed: ParsedArgs): Promise<number>;
|
|
104
105
|
declare function reportFatal(err: unknown, log?: (line: unknown) => void): number;
|
|
105
106
|
|
|
106
|
-
export { CLAUDE_SKILL_CONFIG, type ClientTarget, type ClientTargetSource, type InitOptions, type InitResult, ProjectResolutionError, QUERY_VERBS, type SkillOptions, UnknownProfileError, commandPrefix, cwdProjectApplies, isLoopbackEndpoint, isNpxInvocation, main, parseArgs, printBanner, projectForCwd, readPackageVersion, reportFatal, resolveClientTarget, resolveDaemonUrl, resolveProjectForVerb, runInit, runMonitorVerb, runQueryVerb, runSkill, usage };
|
|
107
|
+
export { CLAUDE_SKILL_CONFIG, type ClientTarget, type ClientTargetSource, type InitOptions, type InitResult, ProjectResolutionError, QUERY_VERBS, type SkillOptions, UnknownProfileError, commandPrefix, cwdProjectApplies, isLoopbackEndpoint, isNpxInvocation, loopbackResolutionHint, main, parseArgs, printBanner, projectForCwd, readPackageVersion, reportFatal, resolveClientTarget, resolveDaemonUrl, resolveProjectForVerb, runInit, runMonitorVerb, runQueryVerb, runSkill, usage };
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
deployHintLines
|
|
4
|
+
} from "./chunk-AEMLUMHC.js";
|
|
2
5
|
import {
|
|
3
6
|
clearDaemonRecord,
|
|
4
7
|
portFromListenAddress,
|
|
@@ -8,7 +11,7 @@ import {
|
|
|
8
11
|
resolveNeatVersion,
|
|
9
12
|
startK8sSubstratePolling,
|
|
10
13
|
writeDaemonRecord
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-S5S2FYCQ.js";
|
|
12
15
|
import {
|
|
13
16
|
buildSearchIndex,
|
|
14
17
|
searchProviderFromEnv
|
|
@@ -68,11 +71,12 @@ import {
|
|
|
68
71
|
startStalenessLoop,
|
|
69
72
|
upsertConnectorEntry,
|
|
70
73
|
validateConnectorEntry
|
|
71
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-6K22WGO7.js";
|
|
72
75
|
import {
|
|
73
76
|
ProjectNameCollisionError,
|
|
74
77
|
RegistryError,
|
|
75
78
|
addProject,
|
|
79
|
+
discoverDaemons,
|
|
76
80
|
findDaemonByProject,
|
|
77
81
|
findProjectByPath,
|
|
78
82
|
getProject,
|
|
@@ -5065,7 +5069,7 @@ async function connectorAdd(args, deps) {
|
|
|
5065
5069
|
}
|
|
5066
5070
|
const { replaced } = await upsertConnectorEntry(entry2, deps.home);
|
|
5067
5071
|
const verb = replaced ? "updated" : "added";
|
|
5068
|
-
const where = project ? `project "${project}"` : "
|
|
5072
|
+
const where = project ? `project "${project}"` : "every project (no --project set)";
|
|
5069
5073
|
deps.out(`${verb} connector "${id}" (${provider}) for ${where}.`);
|
|
5070
5074
|
if (push) {
|
|
5071
5075
|
deps.out("The drain is live \u2014 traces arrive at the daemon's OTLP receiver. No poll or restart needed.");
|
|
@@ -5128,7 +5132,7 @@ async function connectorList(deps, filterProject, json = false) {
|
|
|
5128
5132
|
}
|
|
5129
5133
|
deps.out("id provider project credential");
|
|
5130
5134
|
for (const e of entries) {
|
|
5131
|
-
const project = e.project ?? "(
|
|
5135
|
+
const project = e.project ?? "(every project)";
|
|
5132
5136
|
const credential = describeCredential(e.credential, deps.env).map((c) => {
|
|
5133
5137
|
const status = c.status ? ` (${c.status})` : c.kind === "plaintext" ? " (plaintext)" : "";
|
|
5134
5138
|
return c.field ? `${c.field}=${c.display}${status}` : `${c.display}${status}`;
|
|
@@ -6391,6 +6395,8 @@ async function runIncidents(client, input) {
|
|
|
6391
6395
|
const blockLines = [];
|
|
6392
6396
|
for (const ev of ordered) {
|
|
6393
6397
|
blockLines.push(` ${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`);
|
|
6398
|
+
if (ev.exceptionType) blockLines.push(` exception: ${ev.exceptionType}`);
|
|
6399
|
+
for (const l of deployHintLines(ev)) blockLines.push(` ${l}`);
|
|
6394
6400
|
blockLines.push(` trace=${ev.traceId} span=${ev.spanId}`);
|
|
6395
6401
|
}
|
|
6396
6402
|
const target = input.nodeId ?? "the project";
|
|
@@ -7242,7 +7248,7 @@ import path15 from "path";
|
|
|
7242
7248
|
import readline4 from "readline/promises";
|
|
7243
7249
|
|
|
7244
7250
|
// src/agent-directive.generated.ts
|
|
7245
|
-
var AGENT_DIRECTIVE = '##
|
|
7251
|
+
var AGENT_DIRECTIVE = '## Let NEAT investigate before you search files\n\nThis project has NEAT. It does the investigation for this system so you can\nspend your effort on the code: what exists, what actually ran, where a failure\nbegan, and what a change will reach. It answers from a live graph that fuses\ncode, data and infrastructure declarations with runtime traffic, incidents and\nsupported provider telemetry. The graph is deterministic: you supply the\nreasoning about the fix; NEAT resolves named nodes and traverses recorded\nevidence rather than asking an LLM to infer architecture from file names.\n\nEvery claim carries provenance and confidence. `EXTRACTED` comes from recognized\nsource or configuration, `OBSERVED` from spans or supported provider signals,\n`INFERRED` from a bridged relationship, and `STALE` marks an observed edge that\nwent quiet. Missing runtime evidence does not prove a path never runs.\n\n**For questions about this system\'s behavior, structure, data dependencies,\nfailures, or change impact, call the MCP `ask` tool (`mcp__neat__ask`) before\nRead/Grep/Glob/Bash.** You do not need an exact node id. `ask` resolves names\nand routes to the relevant graph traversal, returning provenance-tagged facts.\nWhen MCP is unavailable, use the same door through the CLI:\n\n```\nnpx neat.is ask "why is checkout failing?"\nnpx neat.is ask "what breaks if I change the orders table?"\nnpx neat.is ask "what does the payments service depend on at runtime?"\n```\n\nFor a failure, call `get_incident_card` on the failing service, file or symbol\n(if you don\'t know which, `ask` what is failing first). The card is the\ninvestigation already done: the incident, its likely cause chain, blast radius,\nthe governing policies and divergence, in one work order. Use `expand` one hop\nat a time and `relate` to test whether the suspected cause and symptom share a\nsignal. Check provenance and confidence before acting.\n\nBefore a change, use `get_blast_radius` and `check_policies` to see dependents\nand advisory architectural rules. Use `get_divergences` to compare declared\nintent with observed behavior, `get_graph_diff` to compare a saved snapshot\nwith the live graph, and `get_recent_stale_edges` when traffic goes quiet.\n`get_dependencies` maps a node\'s outgoing graph; `get_observed_dependencies`\nshows only seen runtime/provider calls. `semantic_search` finds node labels,\nnot arbitrary source text.\n\nRead source when the graph does not model what you need: comments, arbitrary\nstring literals, config details, unsupported syntax, or a repository that has\nnot been extracted or connected. If a graph answer is empty, check the daemon\nwith `npx neat.is list` or restart it with `npx neat.is up`; wire MCP with\n`npx neat.is skill --apply`.\n';
|
|
7246
7252
|
|
|
7247
7253
|
// src/welcome.ts
|
|
7248
7254
|
var WORDMARK = [
|
|
@@ -7257,10 +7263,13 @@ function renderAgentSetupPrompt(project, restPort) {
|
|
|
7257
7263
|
const endpoint = restPort === void 0 ? "The daemon endpoint is unavailable; run `npx neat.is up` to start it." : `The local daemon is serving it at http://127.0.0.1:${restPort}.`;
|
|
7258
7264
|
return `NEAT is set up for project "${project}". ${endpoint}
|
|
7259
7265
|
|
|
7260
|
-
NEAT
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
what a
|
|
7266
|
+
NEAT does the investigation for this system, so you can spend your effort on the
|
|
7267
|
+
code. When something fails, call get_incident_card on the failing service, file
|
|
7268
|
+
or symbol: one work order with where the failure is, the cause chain (provenance
|
|
7269
|
+
on every hop), what a fix reaches, the policies that govern the code, and where
|
|
7270
|
+
code and runtime disagree. For anything else about how the system works, ask.
|
|
7271
|
+
NEAT answers from a live graph that fuses the code with what actually ran; a
|
|
7272
|
+
path it hasn't seen run is not proof the path never runs.
|
|
7264
7273
|
|
|
7265
7274
|
1. Wire NEAT's MCP server into this agent session:
|
|
7266
7275
|
npx neat.is skill --apply
|
|
@@ -7271,8 +7280,10 @@ what a change could affect. Missing observations do not prove a path never runs.
|
|
|
7271
7280
|
If the daemon is unreachable, run \`npx neat.is up\`.
|
|
7272
7281
|
|
|
7273
7282
|
${AGENT_DIRECTIVE}
|
|
7274
|
-
|
|
7275
|
-
neat-
|
|
7283
|
+
Runtime evidence arrives once the app runs with NEAT attached: for Node, load
|
|
7284
|
+
.env.neat first (\`set -a; . ./.env.neat; set +a\`); for Python, start under
|
|
7285
|
+
\`opentelemetry-instrument\`. Daemon log: neat-out/daemon.log. Reopen this
|
|
7286
|
+
door with \`npx neat.is welcome\`.`;
|
|
7276
7287
|
}
|
|
7277
7288
|
function printHeader(out) {
|
|
7278
7289
|
for (const line of WORDMARK) out(line);
|
|
@@ -10041,10 +10052,15 @@ async function main() {
|
|
|
10041
10052
|
return;
|
|
10042
10053
|
}
|
|
10043
10054
|
if (cmd === "sync") {
|
|
10055
|
+
const syncTarget = await resolveClientTarget({
|
|
10056
|
+
...parsed.project ? { project: parsed.project } : {},
|
|
10057
|
+
...parsed.profile ? { profile: parsed.profile } : {}
|
|
10058
|
+
});
|
|
10044
10059
|
const result = await runSync({
|
|
10045
10060
|
...parsed.project ? { project: parsed.project } : {},
|
|
10046
10061
|
...parsed.to ? { to: parsed.to } : {},
|
|
10047
10062
|
...parsed.token ? { token: parsed.token } : {},
|
|
10063
|
+
daemonUrl: syncTarget.endpoint,
|
|
10048
10064
|
dryRun: parsed.dryRun,
|
|
10049
10065
|
noInstrument: parsed.noInstrument,
|
|
10050
10066
|
sourceEdit: parsed.sourceEdit,
|
|
@@ -10203,9 +10219,28 @@ async function resolveClientTarget(opts = {}) {
|
|
|
10203
10219
|
if (daemon) {
|
|
10204
10220
|
return { endpoint: `http://localhost:${daemon.record.ports.rest}`, source: "daemon-record" };
|
|
10205
10221
|
}
|
|
10222
|
+
} else {
|
|
10223
|
+
const live = (await discoverDaemons()).filter((d) => d.live);
|
|
10224
|
+
if (live.length === 1) {
|
|
10225
|
+
return {
|
|
10226
|
+
endpoint: `http://localhost:${live[0].record.ports.rest}`,
|
|
10227
|
+
source: "sole-daemon"
|
|
10228
|
+
};
|
|
10229
|
+
}
|
|
10206
10230
|
}
|
|
10207
10231
|
return { endpoint: "http://localhost:8080", source: "default" };
|
|
10208
10232
|
}
|
|
10233
|
+
async function loopbackResolutionHint() {
|
|
10234
|
+
const live = (await discoverDaemons()).filter((d) => d.live);
|
|
10235
|
+
if (live.length === 0) {
|
|
10236
|
+
return "No NEAT daemon is running. Start one with `npx neat.is` in your project (or `neat up`), then re-run \u2014 or set NEAT_API_URL to a daemon.";
|
|
10237
|
+
}
|
|
10238
|
+
if (live.length > 1) {
|
|
10239
|
+
const list = live.map((d) => ` ${d.record.project} \u2192 http://localhost:${d.record.ports.rest}`).join("\n");
|
|
10240
|
+
return "This directory is not a registered NEAT project and several daemons are running, so NEAT cannot pick one. Run from the project directory, pass --project <name>, or set NEAT_API_URL:\n" + list;
|
|
10241
|
+
}
|
|
10242
|
+
return void 0;
|
|
10243
|
+
}
|
|
10209
10244
|
async function projectForCwd(cwd = process.cwd()) {
|
|
10210
10245
|
try {
|
|
10211
10246
|
return (await findProjectByPath(cwd))?.name;
|
|
@@ -10214,7 +10249,7 @@ async function projectForCwd(cwd = process.cwd()) {
|
|
|
10214
10249
|
}
|
|
10215
10250
|
}
|
|
10216
10251
|
function cwdProjectApplies(source) {
|
|
10217
|
-
return source === "daemon-record" || source === "default";
|
|
10252
|
+
return source === "daemon-record" || source === "sole-daemon" || source === "default";
|
|
10218
10253
|
}
|
|
10219
10254
|
async function resolveDaemonUrl(project, profile) {
|
|
10220
10255
|
return (await resolveClientTarget({ project, profile })).endpoint;
|
|
@@ -10236,6 +10271,11 @@ async function runQueryVerb(cmd, parsed) {
|
|
|
10236
10271
|
}
|
|
10237
10272
|
throw err;
|
|
10238
10273
|
}
|
|
10274
|
+
if (target.source === "default" && !requestedProject && !cwdProject) {
|
|
10275
|
+
const hint = await loopbackResolutionHint();
|
|
10276
|
+
if (hint) process.stderr.write(`${hint}
|
|
10277
|
+
`);
|
|
10278
|
+
}
|
|
10239
10279
|
const client = createHttpClient(target.endpoint, target.authToken);
|
|
10240
10280
|
const positional = parsed.positional;
|
|
10241
10281
|
let makeWork;
|
|
@@ -10482,6 +10522,7 @@ export {
|
|
|
10482
10522
|
cwdProjectApplies,
|
|
10483
10523
|
isLoopbackEndpoint,
|
|
10484
10524
|
isNpxInvocation,
|
|
10525
|
+
loopbackResolutionHint,
|
|
10485
10526
|
main,
|
|
10486
10527
|
parseArgs,
|
|
10487
10528
|
printBanner,
|