sentinelayer-cli 0.1.2 → 0.4.4
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 +998 -996
- package/bin/create-sentinelayer.js +5 -5
- package/bin/sentinelayer-cli.js +4 -4
- package/bin/sl.js +5 -5
- package/package.json +63 -54
- package/src/agents/jules/config/definition.js +209 -209
- package/src/agents/jules/config/system-prompt.js +175 -175
- package/src/agents/jules/error-intake.js +51 -51
- package/src/agents/jules/fix-cycle.js +377 -377
- package/src/agents/jules/loop.js +367 -367
- package/src/agents/jules/pulse.js +327 -319
- package/src/agents/jules/stream.js +186 -186
- package/src/agents/jules/swarm/file-scanner.js +74 -74
- package/src/agents/jules/swarm/index.js +11 -11
- package/src/agents/jules/swarm/orchestrator.js +362 -362
- package/src/agents/jules/swarm/pattern-hunter.js +123 -123
- package/src/agents/jules/swarm/sub-agent.js +308 -308
- package/src/agents/jules/tools/auth-audit.js +557 -222
- package/src/agents/jules/tools/dispatch.js +327 -327
- package/src/agents/jules/tools/file-edit.js +180 -180
- package/src/agents/jules/tools/file-read.js +100 -100
- package/src/agents/jules/tools/frontend-analyze.js +570 -570
- package/src/agents/jules/tools/glob.js +168 -168
- package/src/agents/jules/tools/grep.js +228 -228
- package/src/agents/jules/tools/index.js +29 -29
- package/src/agents/jules/tools/path-guards.js +161 -161
- package/src/agents/jules/tools/runtime-audit.js +503 -493
- package/src/agents/jules/tools/shell.js +383 -383
- package/src/agents/jules/tools/url-policy.js +100 -0
- package/src/ai/aidenid.js +972 -945
- package/src/ai/client.js +508 -508
- package/src/ai/domain-target-store.js +268 -268
- package/src/ai/identity-store.js +270 -270
- package/src/ai/site-store.js +145 -145
- package/src/audit/agents/architecture.js +180 -180
- package/src/audit/agents/compliance.js +179 -179
- package/src/audit/agents/documentation.js +165 -165
- package/src/audit/agents/performance.js +145 -145
- package/src/audit/agents/security.js +215 -215
- package/src/audit/agents/testing.js +172 -172
- package/src/audit/orchestrator.js +557 -557
- package/src/audit/package.js +204 -204
- package/src/audit/registry.js +284 -284
- package/src/audit/replay.js +103 -103
- package/src/auth/gate.js +45 -11
- package/src/auth/http.js +270 -113
- package/src/auth/service.js +891 -848
- package/src/auth/session-store.js +359 -345
- package/src/cli.js +252 -252
- package/src/commands/ai/identity-lifecycle.js +1338 -1337
- package/src/commands/ai/provision-governance.js +1272 -1246
- package/src/commands/ai/shared.js +147 -147
- package/src/commands/ai.js +11 -11
- package/src/commands/apply.js +12 -12
- package/src/commands/audit.js +1166 -1166
- package/src/commands/auth.js +375 -366
- package/src/commands/chat.js +191 -191
- package/src/commands/config.js +184 -184
- package/src/commands/cost.js +311 -311
- package/src/commands/daemon/core.js +850 -850
- package/src/commands/daemon/extended.js +1048 -1048
- package/src/commands/daemon/shared.js +213 -213
- package/src/commands/daemon.js +11 -11
- package/src/commands/guide.js +174 -174
- package/src/commands/ingest.js +58 -58
- package/src/commands/init.js +55 -55
- package/src/commands/legacy-args.js +10 -10
- package/src/commands/mcp.js +461 -404
- package/src/commands/omargate.js +15 -15
- package/src/commands/persona.js +20 -20
- package/src/commands/plugin.js +260 -260
- package/src/commands/policy.js +132 -132
- package/src/commands/prompt.js +238 -238
- package/src/commands/review.js +704 -704
- package/src/commands/scan.js +866 -788
- package/src/commands/spec.js +716 -716
- package/src/commands/swarm.js +651 -651
- package/src/commands/telemetry.js +202 -202
- package/src/commands/watch.js +510 -510
- package/src/config/agent-dictionary.js +182 -182
- package/src/config/io.js +56 -56
- package/src/config/paths.js +18 -18
- package/src/config/schema.js +55 -55
- package/src/config/service.js +184 -184
- package/src/cost/budget.js +235 -235
- package/src/cost/history.js +188 -188
- package/src/cost/tracker.js +171 -171
- package/src/daemon/artifact-lineage.js +534 -534
- package/src/daemon/assignment-ledger.js +770 -770
- package/src/daemon/ast-parser-layer.js +258 -258
- package/src/daemon/budget-governor.js +633 -633
- package/src/daemon/callgraph-overlay.js +646 -646
- package/src/daemon/error-worker.js +626 -626
- package/src/daemon/hybrid-mapper.js +929 -929
- package/src/daemon/jira-lifecycle.js +632 -632
- package/src/daemon/operator-control.js +657 -657
- package/src/daemon/reliability-lane.js +471 -471
- package/src/daemon/watchdog.js +971 -971
- package/src/guide/generator.js +316 -316
- package/src/ingest/engine.js +918 -918
- package/src/legacy-cli.js +2592 -2435
- package/src/mcp/registry.js +695 -695
- package/src/memory/blackboard.js +301 -301
- package/src/memory/retrieval.js +581 -581
- package/src/plugin/manifest.js +553 -553
- package/src/policy/packs.js +144 -144
- package/src/prompt/generator.js +118 -106
- package/src/review/ai-review.js +669 -669
- package/src/review/local-review.js +1295 -1284
- package/src/review/replay.js +235 -235
- package/src/review/report.js +664 -664
- package/src/review/spec-binding.js +487 -487
- package/src/scaffold/generator.js +67 -0
- package/src/scaffold/templates.js +150 -0
- package/src/scan/generator.js +418 -351
- package/src/scan/gh-secrets.js +107 -0
- package/src/spec/generator.js +519 -519
- package/src/spec/regenerate.js +237 -237
- package/src/spec/templates.js +91 -91
- package/src/swarm/dashboard.js +247 -247
- package/src/swarm/factory.js +363 -363
- package/src/swarm/pentest.js +934 -934
- package/src/swarm/registry.js +419 -419
- package/src/swarm/report.js +158 -158
- package/src/swarm/runtime.js +576 -576
- package/src/swarm/scenario-dsl.js +272 -272
- package/src/telemetry/ledger.js +302 -302
- package/src/telemetry/sync.js +107 -61
- package/src/ui/markdown.js +220 -220
package/src/commands/config.js
CHANGED
|
@@ -1,184 +1,184 @@
|
|
|
1
|
-
import { spawnSync } from "node:child_process";
|
|
2
|
-
import process from "node:process";
|
|
3
|
-
|
|
4
|
-
import pc from "picocolors";
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
ensureEditableConfigPath,
|
|
8
|
-
findConfigSource,
|
|
9
|
-
getLayer,
|
|
10
|
-
listConfigKeys,
|
|
11
|
-
loadConfig,
|
|
12
|
-
setConfigValue,
|
|
13
|
-
} from "../config/service.js";
|
|
14
|
-
|
|
15
|
-
const SCOPES = "global|project|env|resolved";
|
|
16
|
-
|
|
17
|
-
function shouldEmitJson(options, command) {
|
|
18
|
-
const local = Boolean(options && options.json);
|
|
19
|
-
const globalFromCommand =
|
|
20
|
-
command && command.optsWithGlobals ? Boolean(command.optsWithGlobals().json) : false;
|
|
21
|
-
return local || globalFromCommand;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function displayValue(value) {
|
|
25
|
-
if (value === undefined) {
|
|
26
|
-
return "";
|
|
27
|
-
}
|
|
28
|
-
if (typeof value === "string") {
|
|
29
|
-
return value;
|
|
30
|
-
}
|
|
31
|
-
return JSON.stringify(value);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function assertKnownKey(key) {
|
|
35
|
-
const normalized = String(key || "").trim();
|
|
36
|
-
if (!listConfigKeys().includes(normalized)) {
|
|
37
|
-
throw new Error(`Unknown key '${normalized}'. Allowed keys: ${listConfigKeys().join(", ")}`);
|
|
38
|
-
}
|
|
39
|
-
return normalized;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function registerConfigCommand(program) {
|
|
43
|
-
const config = program
|
|
44
|
-
.command("config")
|
|
45
|
-
.description("Manage layered Sentinelayer CLI configuration");
|
|
46
|
-
|
|
47
|
-
config
|
|
48
|
-
.command("list")
|
|
49
|
-
.description("List configuration values")
|
|
50
|
-
.option("--scope <scope>", `Config scope (${SCOPES})`, "resolved")
|
|
51
|
-
.option("--path <path>", "Project root for project scope resolution")
|
|
52
|
-
.option("--json", "Emit machine-readable output")
|
|
53
|
-
.action(async (options, command) => {
|
|
54
|
-
const payload = await loadConfig({ cwd: options.path });
|
|
55
|
-
const scope = String(options.scope || "resolved");
|
|
56
|
-
const layer = getLayer(payload, scope);
|
|
57
|
-
const emitJson = shouldEmitJson(options, command);
|
|
58
|
-
|
|
59
|
-
if (emitJson) {
|
|
60
|
-
console.log(
|
|
61
|
-
JSON.stringify(
|
|
62
|
-
{
|
|
63
|
-
scope,
|
|
64
|
-
config: layer,
|
|
65
|
-
paths: payload.paths,
|
|
66
|
-
},
|
|
67
|
-
null,
|
|
68
|
-
2
|
|
69
|
-
)
|
|
70
|
-
);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const entries = Object.entries(layer).sort(([left], [right]) => left.localeCompare(right));
|
|
75
|
-
console.log(pc.bold(`Config scope: ${scope}`));
|
|
76
|
-
if (!entries.length) {
|
|
77
|
-
console.log(pc.gray("(empty)"));
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
for (const [key, value] of entries) {
|
|
81
|
-
console.log(`${key}: ${displayValue(value)}`);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
config
|
|
86
|
-
.command("get <key>")
|
|
87
|
-
.description("Read a single configuration value")
|
|
88
|
-
.option("--scope <scope>", `Config scope (${SCOPES})`, "resolved")
|
|
89
|
-
.option("--path <path>", "Project root for project scope resolution")
|
|
90
|
-
.option("--json", "Emit machine-readable output")
|
|
91
|
-
.action(async (key, options, command) => {
|
|
92
|
-
const normalizedKey = assertKnownKey(key);
|
|
93
|
-
const payload = await loadConfig({ cwd: options.path });
|
|
94
|
-
const scope = String(options.scope || "resolved");
|
|
95
|
-
const layer = getLayer(payload, scope);
|
|
96
|
-
const value = layer[normalizedKey];
|
|
97
|
-
const source = findConfigSource(payload, normalizedKey);
|
|
98
|
-
const emitJson = shouldEmitJson(options, command);
|
|
99
|
-
|
|
100
|
-
if (emitJson) {
|
|
101
|
-
console.log(
|
|
102
|
-
JSON.stringify(
|
|
103
|
-
{
|
|
104
|
-
key: normalizedKey,
|
|
105
|
-
scope,
|
|
106
|
-
value,
|
|
107
|
-
source,
|
|
108
|
-
},
|
|
109
|
-
null,
|
|
110
|
-
2
|
|
111
|
-
)
|
|
112
|
-
);
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (value === undefined) {
|
|
117
|
-
console.log(pc.yellow(`No value set for '${normalizedKey}' in scope '${scope}'.`));
|
|
118
|
-
process.exitCode = 1;
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
console.log(displayValue(value));
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
config
|
|
126
|
-
.command("set <key> <value>")
|
|
127
|
-
.description("Set a configuration value in global or project scope")
|
|
128
|
-
.option("--scope <scope>", "Write scope (global|project)", "project")
|
|
129
|
-
.option("--path <path>", "Project root for project scope resolution")
|
|
130
|
-
.option("--json", "Emit machine-readable output")
|
|
131
|
-
.action(async (key, value, options, command) => {
|
|
132
|
-
const result = await setConfigValue({
|
|
133
|
-
key: assertKnownKey(key),
|
|
134
|
-
value,
|
|
135
|
-
scope: options.scope,
|
|
136
|
-
cwd: options.path,
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
if (shouldEmitJson(options, command)) {
|
|
140
|
-
console.log(JSON.stringify(result, null, 2));
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
console.log(pc.green(`Updated ${result.key} in ${result.scope} config.`));
|
|
145
|
-
console.log(pc.gray(`Path: ${result.path}`));
|
|
146
|
-
console.log(`${result.key}: ${displayValue(result.value)}`);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
config
|
|
150
|
-
.command("edit")
|
|
151
|
-
.description("Open config file for editing (uses $EDITOR or $VISUAL)")
|
|
152
|
-
.option("--scope <scope>", "Edit scope (global|project)", "project")
|
|
153
|
-
.option("--path <path>", "Project root for project scope resolution")
|
|
154
|
-
.option("--json", "Emit machine-readable output")
|
|
155
|
-
.action(async (options, command) => {
|
|
156
|
-
const target = await ensureEditableConfigPath({
|
|
157
|
-
scope: options.scope,
|
|
158
|
-
cwd: options.path,
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
if (shouldEmitJson(options, command)) {
|
|
162
|
-
console.log(JSON.stringify(target, null, 2));
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const editor = String(process.env.EDITOR || process.env.VISUAL || "").trim();
|
|
167
|
-
if (!editor) {
|
|
168
|
-
console.log(pc.yellow(`No editor configured. Set $EDITOR or open manually:`));
|
|
169
|
-
console.log(target.path);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const result = spawnSync(editor, [target.path], {
|
|
174
|
-
stdio: "inherit",
|
|
175
|
-
shell: true,
|
|
176
|
-
});
|
|
177
|
-
if (result.error) {
|
|
178
|
-
throw result.error;
|
|
179
|
-
}
|
|
180
|
-
if (typeof result.status === "number" && result.status !== 0) {
|
|
181
|
-
throw new Error(`Editor exited with status ${result.status}.`);
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
}
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ensureEditableConfigPath,
|
|
8
|
+
findConfigSource,
|
|
9
|
+
getLayer,
|
|
10
|
+
listConfigKeys,
|
|
11
|
+
loadConfig,
|
|
12
|
+
setConfigValue,
|
|
13
|
+
} from "../config/service.js";
|
|
14
|
+
|
|
15
|
+
const SCOPES = "global|project|env|resolved";
|
|
16
|
+
|
|
17
|
+
function shouldEmitJson(options, command) {
|
|
18
|
+
const local = Boolean(options && options.json);
|
|
19
|
+
const globalFromCommand =
|
|
20
|
+
command && command.optsWithGlobals ? Boolean(command.optsWithGlobals().json) : false;
|
|
21
|
+
return local || globalFromCommand;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function displayValue(value) {
|
|
25
|
+
if (value === undefined) {
|
|
26
|
+
return "";
|
|
27
|
+
}
|
|
28
|
+
if (typeof value === "string") {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
return JSON.stringify(value);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function assertKnownKey(key) {
|
|
35
|
+
const normalized = String(key || "").trim();
|
|
36
|
+
if (!listConfigKeys().includes(normalized)) {
|
|
37
|
+
throw new Error(`Unknown key '${normalized}'. Allowed keys: ${listConfigKeys().join(", ")}`);
|
|
38
|
+
}
|
|
39
|
+
return normalized;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function registerConfigCommand(program) {
|
|
43
|
+
const config = program
|
|
44
|
+
.command("config")
|
|
45
|
+
.description("Manage layered Sentinelayer CLI configuration");
|
|
46
|
+
|
|
47
|
+
config
|
|
48
|
+
.command("list")
|
|
49
|
+
.description("List configuration values")
|
|
50
|
+
.option("--scope <scope>", `Config scope (${SCOPES})`, "resolved")
|
|
51
|
+
.option("--path <path>", "Project root for project scope resolution")
|
|
52
|
+
.option("--json", "Emit machine-readable output")
|
|
53
|
+
.action(async (options, command) => {
|
|
54
|
+
const payload = await loadConfig({ cwd: options.path });
|
|
55
|
+
const scope = String(options.scope || "resolved");
|
|
56
|
+
const layer = getLayer(payload, scope);
|
|
57
|
+
const emitJson = shouldEmitJson(options, command);
|
|
58
|
+
|
|
59
|
+
if (emitJson) {
|
|
60
|
+
console.log(
|
|
61
|
+
JSON.stringify(
|
|
62
|
+
{
|
|
63
|
+
scope,
|
|
64
|
+
config: layer,
|
|
65
|
+
paths: payload.paths,
|
|
66
|
+
},
|
|
67
|
+
null,
|
|
68
|
+
2
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const entries = Object.entries(layer).sort(([left], [right]) => left.localeCompare(right));
|
|
75
|
+
console.log(pc.bold(`Config scope: ${scope}`));
|
|
76
|
+
if (!entries.length) {
|
|
77
|
+
console.log(pc.gray("(empty)"));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
for (const [key, value] of entries) {
|
|
81
|
+
console.log(`${key}: ${displayValue(value)}`);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
config
|
|
86
|
+
.command("get <key>")
|
|
87
|
+
.description("Read a single configuration value")
|
|
88
|
+
.option("--scope <scope>", `Config scope (${SCOPES})`, "resolved")
|
|
89
|
+
.option("--path <path>", "Project root for project scope resolution")
|
|
90
|
+
.option("--json", "Emit machine-readable output")
|
|
91
|
+
.action(async (key, options, command) => {
|
|
92
|
+
const normalizedKey = assertKnownKey(key);
|
|
93
|
+
const payload = await loadConfig({ cwd: options.path });
|
|
94
|
+
const scope = String(options.scope || "resolved");
|
|
95
|
+
const layer = getLayer(payload, scope);
|
|
96
|
+
const value = layer[normalizedKey];
|
|
97
|
+
const source = findConfigSource(payload, normalizedKey);
|
|
98
|
+
const emitJson = shouldEmitJson(options, command);
|
|
99
|
+
|
|
100
|
+
if (emitJson) {
|
|
101
|
+
console.log(
|
|
102
|
+
JSON.stringify(
|
|
103
|
+
{
|
|
104
|
+
key: normalizedKey,
|
|
105
|
+
scope,
|
|
106
|
+
value,
|
|
107
|
+
source,
|
|
108
|
+
},
|
|
109
|
+
null,
|
|
110
|
+
2
|
|
111
|
+
)
|
|
112
|
+
);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (value === undefined) {
|
|
117
|
+
console.log(pc.yellow(`No value set for '${normalizedKey}' in scope '${scope}'.`));
|
|
118
|
+
process.exitCode = 1;
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
console.log(displayValue(value));
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
config
|
|
126
|
+
.command("set <key> <value>")
|
|
127
|
+
.description("Set a configuration value in global or project scope")
|
|
128
|
+
.option("--scope <scope>", "Write scope (global|project)", "project")
|
|
129
|
+
.option("--path <path>", "Project root for project scope resolution")
|
|
130
|
+
.option("--json", "Emit machine-readable output")
|
|
131
|
+
.action(async (key, value, options, command) => {
|
|
132
|
+
const result = await setConfigValue({
|
|
133
|
+
key: assertKnownKey(key),
|
|
134
|
+
value,
|
|
135
|
+
scope: options.scope,
|
|
136
|
+
cwd: options.path,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (shouldEmitJson(options, command)) {
|
|
140
|
+
console.log(JSON.stringify(result, null, 2));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
console.log(pc.green(`Updated ${result.key} in ${result.scope} config.`));
|
|
145
|
+
console.log(pc.gray(`Path: ${result.path}`));
|
|
146
|
+
console.log(`${result.key}: ${displayValue(result.value)}`);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
config
|
|
150
|
+
.command("edit")
|
|
151
|
+
.description("Open config file for editing (uses $EDITOR or $VISUAL)")
|
|
152
|
+
.option("--scope <scope>", "Edit scope (global|project)", "project")
|
|
153
|
+
.option("--path <path>", "Project root for project scope resolution")
|
|
154
|
+
.option("--json", "Emit machine-readable output")
|
|
155
|
+
.action(async (options, command) => {
|
|
156
|
+
const target = await ensureEditableConfigPath({
|
|
157
|
+
scope: options.scope,
|
|
158
|
+
cwd: options.path,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
if (shouldEmitJson(options, command)) {
|
|
162
|
+
console.log(JSON.stringify(target, null, 2));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const editor = String(process.env.EDITOR || process.env.VISUAL || "").trim();
|
|
167
|
+
if (!editor) {
|
|
168
|
+
console.log(pc.yellow(`No editor configured. Set $EDITOR or open manually:`));
|
|
169
|
+
console.log(target.path);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const result = spawnSync(editor, [target.path], {
|
|
174
|
+
stdio: "inherit",
|
|
175
|
+
shell: true,
|
|
176
|
+
});
|
|
177
|
+
if (result.error) {
|
|
178
|
+
throw result.error;
|
|
179
|
+
}
|
|
180
|
+
if (typeof result.status === "number" && result.status !== 0) {
|
|
181
|
+
throw new Error(`Editor exited with status ${result.status}.`);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|