sentinelayer-cli 0.4.5 → 0.8.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/README.md +16 -18
- package/package.json +7 -6
- package/src/agents/jules/config/definition.js +13 -62
- package/src/agents/jules/config/system-prompt.js +8 -1
- package/src/agents/jules/fix-cycle.js +12 -372
- package/src/agents/jules/loop.js +116 -26
- package/src/agents/jules/pulse.js +10 -327
- package/src/agents/jules/stream.js +13 -12
- package/src/agents/jules/swarm/orchestrator.js +3 -3
- package/src/agents/jules/swarm/sub-agent.js +6 -3
- package/src/agents/jules/tools/aidenid-email.js +189 -0
- package/src/agents/jules/tools/auth-audit.js +1187 -45
- package/src/agents/jules/tools/dispatch.js +25 -12
- package/src/agents/jules/tools/file-edit.js +2 -180
- package/src/agents/jules/tools/file-read.js +2 -100
- package/src/agents/jules/tools/glob.js +2 -168
- package/src/agents/jules/tools/grep.js +2 -228
- package/src/agents/jules/tools/path-guards.js +2 -161
- package/src/agents/jules/tools/runtime-audit.js +6 -2
- package/src/agents/jules/tools/shell.js +2 -383
- package/src/agents/persona-visuals.js +64 -0
- package/src/agents/shared-tools/dispatch-core.js +320 -0
- package/src/agents/shared-tools/file-edit.js +180 -0
- package/src/agents/shared-tools/file-read.js +100 -0
- package/src/agents/shared-tools/glob.js +168 -0
- package/src/agents/shared-tools/grep.js +228 -0
- package/src/agents/shared-tools/index.js +46 -0
- package/src/agents/shared-tools/path-guards.js +161 -0
- package/src/agents/shared-tools/shell.js +383 -0
- package/src/ai/aidenid.js +56 -7
- package/src/ai/client.js +45 -0
- package/src/ai/proxy.js +137 -0
- package/src/auth/gate.js +290 -16
- package/src/auth/http.js +450 -39
- package/src/auth/service.js +262 -47
- package/src/auth/session-store.js +475 -21
- package/src/cli.js +5 -0
- package/src/commands/audit.js +13 -8
- package/src/commands/auth.js +53 -9
- package/src/commands/omargate.js +10 -2
- package/src/commands/scan.js +10 -4
- package/src/commands/session.js +590 -0
- package/src/commands/spec.js +62 -0
- package/src/commands/watch.js +3 -2
- package/src/daemon/assignment-ledger.js +196 -0
- package/src/daemon/error-worker.js +599 -16
- package/src/daemon/fix-cycle.js +384 -0
- package/src/daemon/ingest-refresh.js +10 -9
- package/src/daemon/jira-lifecycle.js +135 -0
- package/src/daemon/pulse.js +327 -0
- package/src/daemon/scope-engine.js +1068 -0
- package/src/events/schema.js +190 -0
- package/src/interactive/index.js +18 -16
- package/src/legacy-cli.js +606 -37
- package/src/prompt/generator.js +19 -1
- package/src/review/ai-review.js +11 -1
- package/src/review/local-review.js +75 -19
- package/src/review/omargate-interactive.js +68 -0
- package/src/review/omargate-orchestrator.js +404 -0
- package/src/review/persona-prompts.js +296 -0
- package/src/review/scan-modes.js +48 -0
- package/src/scan/generator.js +1 -1
- package/src/session/agent-registry.js +352 -0
- package/src/session/daemon.js +801 -0
- package/src/session/paths.js +33 -0
- package/src/session/runtime-bridge.js +739 -0
- package/src/session/store.js +388 -0
- package/src/session/stream.js +325 -0
- package/src/spec/generator.js +100 -0
- package/src/telemetry/session-tracker.js +148 -32
- package/src/telemetry/sync.js +6 -2
- package/src/ui/command-hints.js +13 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
const AGENT_EVENT_STREAM = "sl_event";
|
|
2
|
+
const LEGACY_AGENT_ID = "legacy-emitter";
|
|
3
|
+
|
|
4
|
+
function isPlainObject(value) {
|
|
5
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function normalizeNonEmptyString(value) {
|
|
9
|
+
const normalized = String(value || "").trim();
|
|
10
|
+
return normalized || "";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function normalizeOptionalString(value) {
|
|
14
|
+
const normalized = normalizeNonEmptyString(value);
|
|
15
|
+
return normalized || undefined;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function normalizeTimestamp(value, fallbackTimestamp) {
|
|
19
|
+
const rawValue = normalizeNonEmptyString(value);
|
|
20
|
+
const fallback = normalizeNonEmptyString(fallbackTimestamp) || new Date().toISOString();
|
|
21
|
+
if (!rawValue) {
|
|
22
|
+
return fallback;
|
|
23
|
+
}
|
|
24
|
+
const epoch = Date.parse(rawValue);
|
|
25
|
+
if (!Number.isFinite(epoch)) {
|
|
26
|
+
return fallback;
|
|
27
|
+
}
|
|
28
|
+
return new Date(epoch).toISOString();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function stripUndefinedEntries(record) {
|
|
32
|
+
const cleaned = {};
|
|
33
|
+
for (const [key, value] of Object.entries(record || {})) {
|
|
34
|
+
if (value !== undefined) {
|
|
35
|
+
cleaned[key] = value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return cleaned;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function normalizeAgentShape(input = {}) {
|
|
42
|
+
const fromAgentObject = isPlainObject(input.agent) ? { ...input.agent } : {};
|
|
43
|
+
const fromLegacyString = typeof input.agent === "string" ? input.agent : "";
|
|
44
|
+
const candidateId =
|
|
45
|
+
normalizeNonEmptyString(input.agentId) ||
|
|
46
|
+
normalizeNonEmptyString(fromLegacyString) ||
|
|
47
|
+
normalizeNonEmptyString(fromAgentObject.id);
|
|
48
|
+
if (!candidateId) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const normalized = {
|
|
52
|
+
...fromAgentObject,
|
|
53
|
+
id: candidateId,
|
|
54
|
+
model: normalizeOptionalString(input.agentModel) || normalizeOptionalString(fromAgentObject.model),
|
|
55
|
+
};
|
|
56
|
+
return stripUndefinedEntries(normalized);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function resolveLegacyPayload(evt) {
|
|
60
|
+
if (isPlainObject(evt.payload)) {
|
|
61
|
+
return { ...evt.payload };
|
|
62
|
+
}
|
|
63
|
+
if (isPlainObject(evt.data)) {
|
|
64
|
+
return { ...evt.data };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const synthesized = {};
|
|
68
|
+
for (const key of ["alert", "target", "message", "details", "reason", "error"]) {
|
|
69
|
+
if (evt[key] !== undefined) {
|
|
70
|
+
synthesized[key] = evt[key];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return Object.keys(synthesized).length > 0 ? synthesized : null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function createAgentEvent({
|
|
77
|
+
event,
|
|
78
|
+
agentId,
|
|
79
|
+
agentModel,
|
|
80
|
+
payload,
|
|
81
|
+
sessionId,
|
|
82
|
+
usage,
|
|
83
|
+
runId,
|
|
84
|
+
workItemId,
|
|
85
|
+
requestId,
|
|
86
|
+
agent,
|
|
87
|
+
ts,
|
|
88
|
+
timestamp,
|
|
89
|
+
} = {}) {
|
|
90
|
+
const normalizedEvent = normalizeNonEmptyString(event);
|
|
91
|
+
const normalizedAgent = normalizeAgentShape({
|
|
92
|
+
agentId,
|
|
93
|
+
agentModel,
|
|
94
|
+
agent,
|
|
95
|
+
});
|
|
96
|
+
const normalizedPayload = isPlainObject(payload) ? { ...payload } : null;
|
|
97
|
+
if (!normalizedEvent || !normalizedAgent?.id || !normalizedPayload) {
|
|
98
|
+
throw new Error("createAgentEvent requires event, agentId, and payload");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const canonicalTs = normalizeTimestamp(ts || timestamp);
|
|
102
|
+
return stripUndefinedEntries({
|
|
103
|
+
stream: AGENT_EVENT_STREAM,
|
|
104
|
+
event: normalizedEvent,
|
|
105
|
+
agent: normalizedAgent,
|
|
106
|
+
payload: normalizedPayload,
|
|
107
|
+
usage: isPlainObject(usage) ? { ...usage } : undefined,
|
|
108
|
+
sessionId: normalizeOptionalString(sessionId),
|
|
109
|
+
runId: normalizeOptionalString(runId),
|
|
110
|
+
workItemId: normalizeOptionalString(workItemId),
|
|
111
|
+
requestId: normalizeOptionalString(requestId),
|
|
112
|
+
ts: canonicalTs,
|
|
113
|
+
// Keep legacy timestamp key for existing consumers while PR0 migrates envelope usage.
|
|
114
|
+
timestamp: canonicalTs,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function normalizeAgentEvent(evt, { allowLegacy = true } = {}) {
|
|
119
|
+
if (!isPlainObject(evt)) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const stream = normalizeOptionalString(evt.stream);
|
|
124
|
+
if (stream && stream !== AGENT_EVENT_STREAM) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
if (!stream && !allowLegacy) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const normalizedEvent = normalizeNonEmptyString(evt.event || (allowLegacy ? evt.type : ""));
|
|
132
|
+
if (!normalizedEvent) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const payload = resolveLegacyPayload(evt);
|
|
137
|
+
if (!payload) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const normalizedAgent =
|
|
142
|
+
normalizeAgentShape({
|
|
143
|
+
agentId: evt.agentId,
|
|
144
|
+
agentModel: evt.agentModel,
|
|
145
|
+
agent: evt.agent,
|
|
146
|
+
}) ||
|
|
147
|
+
(allowLegacy && !stream
|
|
148
|
+
? normalizeAgentShape({
|
|
149
|
+
agentId:
|
|
150
|
+
normalizeNonEmptyString(evt.sourceAgentId) ||
|
|
151
|
+
normalizeNonEmptyString(evt.source) ||
|
|
152
|
+
LEGACY_AGENT_ID,
|
|
153
|
+
})
|
|
154
|
+
: null);
|
|
155
|
+
if (!normalizedAgent) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const rawTimestamp = evt.ts || evt.timestamp || evt.time || evt.at || "";
|
|
160
|
+
if (!rawTimestamp && !allowLegacy) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
const fallbackTimestamp = allowLegacy ? new Date().toISOString() : undefined;
|
|
164
|
+
const normalizedTs = normalizeTimestamp(rawTimestamp, fallbackTimestamp);
|
|
165
|
+
if (!normalizedTs) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
return createAgentEvent({
|
|
171
|
+
event: normalizedEvent,
|
|
172
|
+
agent: normalizedAgent,
|
|
173
|
+
payload,
|
|
174
|
+
usage: evt.usage,
|
|
175
|
+
sessionId: evt.sessionId,
|
|
176
|
+
runId: evt.runId,
|
|
177
|
+
workItemId: evt.workItemId,
|
|
178
|
+
requestId: evt.requestId,
|
|
179
|
+
ts: normalizedTs,
|
|
180
|
+
});
|
|
181
|
+
} catch {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function validateAgentEvent(evt, options = {}) {
|
|
187
|
+
return Boolean(normalizeAgentEvent(evt, options));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export { AGENT_EVENT_STREAM };
|
package/src/interactive/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import pc from "picocolors";
|
|
|
2
2
|
import { selectRepo } from "./workspace.js";
|
|
3
3
|
import { autoIngestWithProgress } from "./auto-ingest.js";
|
|
4
4
|
import { showActionMenu } from "./action-menu.js";
|
|
5
|
+
import { preferredCliCommand } from "../ui/command-hints.js";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Interactive CLI mode — the "sl" experience with no args.
|
|
@@ -28,7 +29,7 @@ export async function runInteractiveMode(options = {}) {
|
|
|
28
29
|
// Step 1: Repo selection
|
|
29
30
|
const repo = await selectRepo();
|
|
30
31
|
if (!repo) {
|
|
31
|
-
console.error(pc.yellow(
|
|
32
|
+
console.error(pc.yellow(`No repository selected. Run ${preferredCliCommand()} --help for available commands.`));
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -59,36 +60,37 @@ export async function runInteractiveMode(options = {}) {
|
|
|
59
60
|
* Build the equivalent CLI command string for a menu choice.
|
|
60
61
|
*/
|
|
61
62
|
function buildEquivalentCommand(choice, repo) {
|
|
63
|
+
const cli = preferredCliCommand();
|
|
62
64
|
const pathFlag = " --path " + repo.path;
|
|
63
65
|
|
|
64
66
|
switch (choice.action) {
|
|
65
67
|
case "audit":
|
|
66
|
-
if (choice.subAction === "deep") return
|
|
67
|
-
return
|
|
68
|
+
if (choice.subAction === "deep") return `${cli} audit${pathFlag} --json`;
|
|
69
|
+
return `${cli} audit ${choice.subAction}${pathFlag} --stream`;
|
|
68
70
|
case "review":
|
|
69
|
-
if (choice.subAction === "diff") return
|
|
70
|
-
if (choice.subAction === "staged") return
|
|
71
|
-
return
|
|
71
|
+
if (choice.subAction === "diff") return `${cli} review scan --mode diff${pathFlag} --json`;
|
|
72
|
+
if (choice.subAction === "staged") return `${cli} review scan --mode staged${pathFlag} --json`;
|
|
73
|
+
return `${cli} review scan --mode full${pathFlag} --json`;
|
|
72
74
|
case "feature":
|
|
73
|
-
return
|
|
75
|
+
return `${cli} spec generate --description "${(choice.input || "").slice(0, 50)}..."${pathFlag}`;
|
|
74
76
|
case "create":
|
|
75
|
-
return
|
|
77
|
+
return `${cli} init`;
|
|
76
78
|
case "cost":
|
|
77
|
-
return
|
|
79
|
+
return `${cli} cost show${pathFlag} --json`;
|
|
78
80
|
case "telemetry":
|
|
79
|
-
return
|
|
81
|
+
return `${cli} telemetry show${pathFlag} --json`;
|
|
80
82
|
case "config":
|
|
81
|
-
return
|
|
83
|
+
return `${cli} config list --json`;
|
|
82
84
|
case "auth-status":
|
|
83
|
-
return
|
|
85
|
+
return `${cli} auth status --json`;
|
|
84
86
|
case "plugins":
|
|
85
|
-
return
|
|
87
|
+
return `${cli} plugin list --json`;
|
|
86
88
|
case "watch":
|
|
87
|
-
return
|
|
89
|
+
return `${cli} watch history${pathFlag} --json`;
|
|
88
90
|
case "ai":
|
|
89
|
-
return
|
|
91
|
+
return `${cli} ai provision-email --json`;
|
|
90
92
|
case "daemon":
|
|
91
|
-
return
|
|
93
|
+
return `${cli} daemon budget status${pathFlag} --json`;
|
|
92
94
|
default:
|
|
93
95
|
return null;
|
|
94
96
|
}
|