@m1a0rz/agent-identity 0.1.2
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-cn.md +223 -0
- package/README.md +223 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +306 -0
- package/dist/src/actions/identity-actions.d.ts +142 -0
- package/dist/src/actions/identity-actions.d.ts.map +1 -0
- package/dist/src/actions/identity-actions.js +429 -0
- package/dist/src/commands/identity-commands.d.ts +33 -0
- package/dist/src/commands/identity-commands.d.ts.map +1 -0
- package/dist/src/commands/identity-commands.js +572 -0
- package/dist/src/hooks/after-tool-call.d.ts +22 -0
- package/dist/src/hooks/after-tool-call.d.ts.map +1 -0
- package/dist/src/hooks/after-tool-call.js +35 -0
- package/dist/src/hooks/before-agent-start.d.ts +30 -0
- package/dist/src/hooks/before-agent-start.d.ts.map +1 -0
- package/dist/src/hooks/before-agent-start.js +93 -0
- package/dist/src/hooks/before-tool-call.d.ts +38 -0
- package/dist/src/hooks/before-tool-call.d.ts.map +1 -0
- package/dist/src/hooks/before-tool-call.js +138 -0
- package/dist/src/risk/classify-risk.d.ts +24 -0
- package/dist/src/risk/classify-risk.d.ts.map +1 -0
- package/dist/src/risk/classify-risk.js +61 -0
- package/dist/src/risk/diagnose-risk.d.ts +21 -0
- package/dist/src/risk/diagnose-risk.d.ts.map +1 -0
- package/dist/src/risk/diagnose-risk.js +37 -0
- package/dist/src/risk/llm-risk-check.d.ts +27 -0
- package/dist/src/risk/llm-risk-check.d.ts.map +1 -0
- package/dist/src/risk/llm-risk-check.js +274 -0
- package/dist/src/risk/low-risk-tools.d.ts +5 -0
- package/dist/src/risk/low-risk-tools.d.ts.map +1 -0
- package/dist/src/risk/low-risk-tools.js +29 -0
- package/dist/src/routes/oidc-login.d.ts +51 -0
- package/dist/src/routes/oidc-login.d.ts.map +1 -0
- package/dist/src/routes/oidc-login.js +153 -0
- package/dist/src/services/identity-client.d.ts +366 -0
- package/dist/src/services/identity-client.d.ts.map +1 -0
- package/dist/src/services/identity-client.js +578 -0
- package/dist/src/services/identity-credentials.d.ts +28 -0
- package/dist/src/services/identity-credentials.d.ts.map +1 -0
- package/dist/src/services/identity-credentials.js +170 -0
- package/dist/src/services/identity-service.d.ts +33 -0
- package/dist/src/services/identity-service.d.ts.map +1 -0
- package/dist/src/services/identity-service.js +53 -0
- package/dist/src/services/oidc-client.d.ts +57 -0
- package/dist/src/services/oidc-client.d.ts.map +1 -0
- package/dist/src/services/oidc-client.js +127 -0
- package/dist/src/services/send-notification-feishu.d.ts +27 -0
- package/dist/src/services/send-notification-feishu.d.ts.map +1 -0
- package/dist/src/services/send-notification-feishu.js +148 -0
- package/dist/src/services/session-refresh.d.ts +16 -0
- package/dist/src/services/session-refresh.d.ts.map +1 -0
- package/dist/src/services/session-refresh.js +38 -0
- package/dist/src/store/credential-env-bindings.d.ts +16 -0
- package/dist/src/store/credential-env-bindings.d.ts.map +1 -0
- package/dist/src/store/credential-env-bindings.js +61 -0
- package/dist/src/store/credential-store.d.ts +31 -0
- package/dist/src/store/credential-store.d.ts.map +1 -0
- package/dist/src/store/credential-store.js +57 -0
- package/dist/src/store/oidc-state-store.d.ts +15 -0
- package/dist/src/store/oidc-state-store.d.ts.map +1 -0
- package/dist/src/store/oidc-state-store.js +32 -0
- package/dist/src/store/session-store.d.ts +21 -0
- package/dist/src/store/session-store.d.ts.map +1 -0
- package/dist/src/store/session-store.js +69 -0
- package/dist/src/store/tip-store.d.ts +21 -0
- package/dist/src/store/tip-store.d.ts.map +1 -0
- package/dist/src/store/tip-store.js +60 -0
- package/dist/src/store/tool-approval-store.d.ts +44 -0
- package/dist/src/store/tool-approval-store.d.ts.map +1 -0
- package/dist/src/store/tool-approval-store.js +147 -0
- package/dist/src/tools/identity-approve-tool.d.ts +24 -0
- package/dist/src/tools/identity-approve-tool.d.ts.map +1 -0
- package/dist/src/tools/identity-approve-tool.js +36 -0
- package/dist/src/tools/identity-config.d.ts +13 -0
- package/dist/src/tools/identity-config.d.ts.map +1 -0
- package/dist/src/tools/identity-config.js +18 -0
- package/dist/src/tools/identity-fetch.d.ts +21 -0
- package/dist/src/tools/identity-fetch.d.ts.map +1 -0
- package/dist/src/tools/identity-fetch.js +63 -0
- package/dist/src/tools/identity-list-credentials.d.ts +15 -0
- package/dist/src/tools/identity-list-credentials.d.ts.map +1 -0
- package/dist/src/tools/identity-list-credentials.js +30 -0
- package/dist/src/tools/identity-list-risk-patterns.d.ts +13 -0
- package/dist/src/tools/identity-list-risk-patterns.d.ts.map +1 -0
- package/dist/src/tools/identity-list-risk-patterns.js +23 -0
- package/dist/src/tools/identity-list-tips.d.ts +13 -0
- package/dist/src/tools/identity-list-tips.d.ts.map +1 -0
- package/dist/src/tools/identity-list-tips.js +21 -0
- package/dist/src/tools/identity-login.d.ts +14 -0
- package/dist/src/tools/identity-login.d.ts.map +1 -0
- package/dist/src/tools/identity-login.js +40 -0
- package/dist/src/tools/identity-logout.d.ts +13 -0
- package/dist/src/tools/identity-logout.d.ts.map +1 -0
- package/dist/src/tools/identity-logout.js +24 -0
- package/dist/src/tools/identity-risk-check.d.ts +29 -0
- package/dist/src/tools/identity-risk-check.d.ts.map +1 -0
- package/dist/src/tools/identity-risk-check.js +54 -0
- package/dist/src/tools/identity-set-binding.d.ts +16 -0
- package/dist/src/tools/identity-set-binding.d.ts.map +1 -0
- package/dist/src/tools/identity-set-binding.js +31 -0
- package/dist/src/tools/identity-status.d.ts +13 -0
- package/dist/src/tools/identity-status.d.ts.map +1 -0
- package/dist/src/tools/identity-status.js +41 -0
- package/dist/src/tools/identity-unset-binding.d.ts +15 -0
- package/dist/src/tools/identity-unset-binding.d.ts.map +1 -0
- package/dist/src/tools/identity-unset-binding.js +25 -0
- package/dist/src/tools/identity-whoami.d.ts +13 -0
- package/dist/src/tools/identity-whoami.d.ts.map +1 -0
- package/dist/src/tools/identity-whoami.js +38 -0
- package/dist/src/types.d.ts +93 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +5 -0
- package/dist/src/utils/approval-channel.d.ts +11 -0
- package/dist/src/utils/approval-channel.d.ts.map +1 -0
- package/dist/src/utils/approval-channel.js +13 -0
- package/dist/src/utils/auth.d.ts +24 -0
- package/dist/src/utils/auth.d.ts.map +1 -0
- package/dist/src/utils/auth.js +44 -0
- package/dist/src/utils/derive-session-key.d.ts +78 -0
- package/dist/src/utils/derive-session-key.d.ts.map +1 -0
- package/dist/src/utils/derive-session-key.js +198 -0
- package/openclaw.plugin.json +162 -0
- package/package.json +33 -0
- package/skills/SKILL.md +230 -0
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified /identity command: login, status, logout, list-credentials, fetch, set.
|
|
3
|
+
* UserPool OIDC + credential hosting. Uses shared identity-actions for logic.
|
|
4
|
+
*/
|
|
5
|
+
import { runStatus, runLogin, runLogout, runListCredentials, runListTips, runConfig, runFetch, runSetBinding, runUnsetBinding, } from "../actions/identity-actions.js";
|
|
6
|
+
import { deriveSessionKey, deriveDeliveryTargetFromContext, } from "../utils/derive-session-key.js";
|
|
7
|
+
import { diagnoseRisk } from "../risk/diagnose-risk.js";
|
|
8
|
+
import { getRiskPatterns } from "../risk/classify-risk.js";
|
|
9
|
+
import * as toolApprovalStore from "../store/tool-approval-store.js";
|
|
10
|
+
const HELP_TEXT = `**/identity** – UserPool login, TIP token, credentials, and risk approval
|
|
11
|
+
|
|
12
|
+
Subcommands:
|
|
13
|
+
• \`whoami\` – Identity brief: sub, login time, TIP expiry
|
|
14
|
+
• \`status\` – Full status: session/TIP details (issued, expires, chain), credentials, bindings
|
|
15
|
+
• \`login\` – Log in via OIDC (returns auth URL if not logged in)
|
|
16
|
+
• \`logout\` – Clear session and TIP
|
|
17
|
+
• \`list-credentials\` or \`list [page]\` – List providers and credentials (paginated; shows bound env)
|
|
18
|
+
• \`list-tips\` – List all valid TIP tokens with delegation chain and bindings
|
|
19
|
+
• \`config\` – Show identity plugin configuration (redacted)
|
|
20
|
+
• \`fetch <provider> [--flow=oauth2-user|oauth2-m2m|apikey] [--redirectUrl=<url>] [--scopes=a,b]\` – Add credential
|
|
21
|
+
• \`set <provider> <envVar>\` – Bind credential to env var for tool injection
|
|
22
|
+
• \`unset <provider>\` – Remove credential env binding
|
|
23
|
+
• \`risk <command>\` – Diagnose risk for a shell command (e.g. exec)
|
|
24
|
+
• \`risk-patterns\` – List built-in dangerous commands and sensitive paths
|
|
25
|
+
• \`approve <approval_id>\` – Approve a pending high-risk tool call
|
|
26
|
+
• \`reject <approval_id>\` – Reject a pending high-risk tool call
|
|
27
|
+
|
|
28
|
+
Fetch: flow auto-inferred from control-plane provider type; override with \`--flow=oauth2-user|oauth2-m2m|apikey\`.
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
\`/identity\` – show this help
|
|
32
|
+
\`/identity whoami\` – brief identity
|
|
33
|
+
\`/identity status\` – full status with TIP details
|
|
34
|
+
\`/identity login\`
|
|
35
|
+
\`/identity fetch google\`
|
|
36
|
+
\`/identity fetch openai --flow=apikey\`
|
|
37
|
+
\`/identity list 2\` – load more (page 2)
|
|
38
|
+
\`/identity risk "rm -rf /"\` – check if command would require approval
|
|
39
|
+
\`/identity risk-patterns\` – list risky patterns
|
|
40
|
+
\`/identity approve abc123\` – approve pending tool call
|
|
41
|
+
\`/identity reject abc123\` – reject pending tool call
|
|
42
|
+
\`/identity set google GOOGLE_ACCESS_TOKEN\`
|
|
43
|
+
\`/identity unset google\``;
|
|
44
|
+
function formatTtl(ms) {
|
|
45
|
+
const s = Math.floor(ms / 1000);
|
|
46
|
+
if (s >= 3600)
|
|
47
|
+
return `${Math.floor(s / 3600)}h${Math.floor((s % 3600) / 60)}m`;
|
|
48
|
+
if (s >= 60)
|
|
49
|
+
return `${Math.floor(s / 60)}m${s % 60}s`;
|
|
50
|
+
return `${s}s`;
|
|
51
|
+
}
|
|
52
|
+
/** Wrap URL as markdown link so Feishu and other platforms render it as clickable. */
|
|
53
|
+
function asMarkdownLink(url, label) {
|
|
54
|
+
return `[${label}](${url})`;
|
|
55
|
+
}
|
|
56
|
+
function formatAgo(ms) {
|
|
57
|
+
const s = Math.floor(ms / 1000);
|
|
58
|
+
if (s >= 3600)
|
|
59
|
+
return `${Math.floor(s / 3600)}h${Math.floor((s % 3600) / 60)}m`;
|
|
60
|
+
if (s >= 60)
|
|
61
|
+
return `${Math.floor(s / 60)}m`;
|
|
62
|
+
return `${s}s`;
|
|
63
|
+
}
|
|
64
|
+
function formatTimestamp(ms) {
|
|
65
|
+
const d = new Date(ms);
|
|
66
|
+
return d.toISOString().replace("T", " ").slice(0, 19);
|
|
67
|
+
}
|
|
68
|
+
function parseSubcommand(args) {
|
|
69
|
+
const raw = (args ?? "").trim();
|
|
70
|
+
const space = raw.indexOf(" ");
|
|
71
|
+
if (space === -1)
|
|
72
|
+
return { sub: raw.toLowerCase(), rest: "" };
|
|
73
|
+
return {
|
|
74
|
+
sub: raw.slice(0, space).toLowerCase(),
|
|
75
|
+
rest: raw.slice(space + 1).trim(),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** Parse list args: optional page. E.g. "list", "list 2", "list --page 2". */
|
|
79
|
+
function parseListArgs(rest) {
|
|
80
|
+
const parts = rest.split(/\s+/).filter(Boolean);
|
|
81
|
+
const flags = {};
|
|
82
|
+
const positional = [];
|
|
83
|
+
for (const p of parts) {
|
|
84
|
+
if (p.startsWith("--")) {
|
|
85
|
+
const eq = p.indexOf("=");
|
|
86
|
+
if (eq > 2)
|
|
87
|
+
flags[p.slice(2, eq)] = p.slice(eq + 1);
|
|
88
|
+
}
|
|
89
|
+
else if (/^\d+$/.test(p)) {
|
|
90
|
+
positional.push(parseInt(p, 10));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const page = flags.page ? parseInt(flags.page, 10) : positional[0];
|
|
94
|
+
return { page: Number.isFinite(page) && page >= 1 ? page : 1 };
|
|
95
|
+
}
|
|
96
|
+
/** Parse fetch args: provider and flags (--flow, --redirectUrl, --scopes). flow can be omitted to auto-infer from provider. */
|
|
97
|
+
function parseFetchArgs(rest) {
|
|
98
|
+
const parts = rest.split(/\s+/).filter(Boolean);
|
|
99
|
+
const positional = [];
|
|
100
|
+
const flags = {};
|
|
101
|
+
for (const p of parts) {
|
|
102
|
+
if (p.startsWith("--")) {
|
|
103
|
+
const eq = p.indexOf("=");
|
|
104
|
+
if (eq > 2) {
|
|
105
|
+
flags[p.slice(2, eq)] = p.slice(eq + 1);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
positional.push(p);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const provider = positional[0]?.trim();
|
|
113
|
+
if (!provider) {
|
|
114
|
+
return {
|
|
115
|
+
error: "Usage: `/identity fetch <provider> [--flow=oauth2-user|oauth2-m2m|apikey] [--redirectUrl=<url>] [--scopes=a,b,c]`",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const flowRaw = flags.flow;
|
|
119
|
+
const flow = flowRaw === "oauth2-m2m"
|
|
120
|
+
? "oauth2-m2m"
|
|
121
|
+
: flowRaw === "apikey"
|
|
122
|
+
? "apikey"
|
|
123
|
+
: flowRaw === "oauth2-user"
|
|
124
|
+
? "oauth2-user"
|
|
125
|
+
: undefined;
|
|
126
|
+
const redirectUrl = flags.redirectUrl?.trim() || undefined;
|
|
127
|
+
const scopes = flags.scopes
|
|
128
|
+
? flags.scopes
|
|
129
|
+
.split(",")
|
|
130
|
+
.map((s) => s.trim())
|
|
131
|
+
.filter(Boolean)
|
|
132
|
+
: undefined;
|
|
133
|
+
return {
|
|
134
|
+
provider,
|
|
135
|
+
flow: flow ?? "oauth2-user",
|
|
136
|
+
flowExplicit: flowRaw != null,
|
|
137
|
+
redirectUrl: redirectUrl || undefined,
|
|
138
|
+
scopes,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function createIdentityHandler(deps) {
|
|
142
|
+
const { logger } = deps;
|
|
143
|
+
return async (ctx) => {
|
|
144
|
+
const { sub, rest } = parseSubcommand(ctx.args);
|
|
145
|
+
logger?.debug?.(`[identity] sub=${sub} rest=${rest.slice(0, 40)}...`);
|
|
146
|
+
const sessionKey = deriveSessionKey({
|
|
147
|
+
channel: ctx.channel,
|
|
148
|
+
senderId: ctx.senderId,
|
|
149
|
+
from: ctx.from,
|
|
150
|
+
to: ctx.to,
|
|
151
|
+
accountId: ctx.accountId,
|
|
152
|
+
config: ctx.config,
|
|
153
|
+
});
|
|
154
|
+
const needsSession = [
|
|
155
|
+
"login",
|
|
156
|
+
"logout",
|
|
157
|
+
"status",
|
|
158
|
+
"whoami",
|
|
159
|
+
"fetch",
|
|
160
|
+
"list-credentials",
|
|
161
|
+
"list",
|
|
162
|
+
"set",
|
|
163
|
+
"unset",
|
|
164
|
+
"approve",
|
|
165
|
+
"reject",
|
|
166
|
+
].includes(sub);
|
|
167
|
+
if (needsSession && !sessionKey) {
|
|
168
|
+
return {
|
|
169
|
+
text: "⚠️ /identity requires session context (channel + sender). Use it from an active chat.",
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
switch (sub) {
|
|
173
|
+
case "help":
|
|
174
|
+
case "":
|
|
175
|
+
return { text: HELP_TEXT };
|
|
176
|
+
case "whoami":
|
|
177
|
+
return handleWhoami(ctx, deps, sessionKey);
|
|
178
|
+
case "login":
|
|
179
|
+
return handleLogin(ctx, deps, sessionKey);
|
|
180
|
+
case "status":
|
|
181
|
+
return handleStatus(ctx, deps, sessionKey);
|
|
182
|
+
case "logout":
|
|
183
|
+
return handleLogout(deps, sessionKey);
|
|
184
|
+
case "list-credentials":
|
|
185
|
+
case "list":
|
|
186
|
+
return handleListCredentials(deps, sessionKey, rest);
|
|
187
|
+
case "fetch":
|
|
188
|
+
return handleFetch(ctx, deps, sessionKey, rest);
|
|
189
|
+
case "set":
|
|
190
|
+
return handleSet(deps, sessionKey, rest);
|
|
191
|
+
case "unset":
|
|
192
|
+
return handleUnset(deps, sessionKey, rest);
|
|
193
|
+
case "list-tips":
|
|
194
|
+
case "tips":
|
|
195
|
+
return handleListTips(deps);
|
|
196
|
+
case "config":
|
|
197
|
+
return handleConfig(deps);
|
|
198
|
+
case "risk":
|
|
199
|
+
return handleRisk(deps, rest);
|
|
200
|
+
case "risk-patterns":
|
|
201
|
+
return handleRiskPatterns();
|
|
202
|
+
case "approve":
|
|
203
|
+
return handleApprove(deps, sessionKey, rest);
|
|
204
|
+
case "reject":
|
|
205
|
+
return handleReject(deps, sessionKey, rest);
|
|
206
|
+
default:
|
|
207
|
+
return {
|
|
208
|
+
text: `Unknown subcommand: \`${sub}\`. Use \`/identity help\` for usage.`,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
async function handleWhoami(ctx, deps, sessionKey) {
|
|
214
|
+
const result = await runStatus(deps, sessionKey, ctx.config);
|
|
215
|
+
if (!result.loggedIn) {
|
|
216
|
+
return { text: "⚠ Not logged in. Run \`/identity login\`." };
|
|
217
|
+
}
|
|
218
|
+
const lines = [
|
|
219
|
+
`✓ Logged in as \`${result.sub}\``,
|
|
220
|
+
result.sessionLoginAt != null ? `Login: ${formatTimestamp(result.sessionLoginAt)}` : "",
|
|
221
|
+
result.hasTip
|
|
222
|
+
? result.tipExpiresAt != null
|
|
223
|
+
? `TIP: valid · expires ${formatTtl(result.tipExpiresAt - Date.now())}`
|
|
224
|
+
: "TIP: valid"
|
|
225
|
+
: "TIP: not refreshed (run \`/identity login\`)",
|
|
226
|
+
];
|
|
227
|
+
return { text: lines.filter(Boolean).join("\n") };
|
|
228
|
+
}
|
|
229
|
+
async function handleLogin(ctx, deps, sessionKey) {
|
|
230
|
+
const deliveryTarget = deriveDeliveryTargetFromContext(ctx);
|
|
231
|
+
const result = await runLogin(deps, sessionKey, {
|
|
232
|
+
config: ctx.config,
|
|
233
|
+
deliveryTarget,
|
|
234
|
+
});
|
|
235
|
+
if (result.kind === "already_logged_in") {
|
|
236
|
+
return { text: `✓ Already logged in as ${result.sub}. TIP refreshed.` };
|
|
237
|
+
}
|
|
238
|
+
if (result.kind === "auth_url") {
|
|
239
|
+
return {
|
|
240
|
+
text: `Open this URL to log in:\n\n${asMarkdownLink(result.authUrl, "Click to log in")}\n\nAfter authorization, you can close the page. A success message will be sent to this chat.`,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
return { text: `⚠️ OIDC login failed: ${result.message}` };
|
|
244
|
+
}
|
|
245
|
+
async function handleStatus(ctx, deps, sessionKey) {
|
|
246
|
+
const result = await runStatus(deps, sessionKey, ctx.config);
|
|
247
|
+
const lines = [];
|
|
248
|
+
const now = Date.now();
|
|
249
|
+
if (result.loggedIn) {
|
|
250
|
+
lines.push(`✓ Logged in as \`${result.sub}\``);
|
|
251
|
+
lines.push("");
|
|
252
|
+
lines.push("**Session**");
|
|
253
|
+
if (result.sessionLoginAt != null) {
|
|
254
|
+
lines.push(`• Login: ${formatTimestamp(result.sessionLoginAt)}`);
|
|
255
|
+
}
|
|
256
|
+
if (result.sessionExpiresAt != null) {
|
|
257
|
+
const diff = result.sessionExpiresAt - now;
|
|
258
|
+
lines.push(diff > 0
|
|
259
|
+
? `• Expires: ${formatTimestamp(result.sessionExpiresAt)} (in ${formatTtl(diff)})`
|
|
260
|
+
: `• Expired: ${formatTimestamp(result.sessionExpiresAt)}`);
|
|
261
|
+
}
|
|
262
|
+
lines.push("");
|
|
263
|
+
lines.push("**TIP Token**");
|
|
264
|
+
if (result.hasTip) {
|
|
265
|
+
if (result.tipIssuedAt != null) {
|
|
266
|
+
lines.push(`• Issued: ${formatTimestamp(result.tipIssuedAt)}`);
|
|
267
|
+
}
|
|
268
|
+
if (result.tipExpiresAt != null) {
|
|
269
|
+
const diff = result.tipExpiresAt - now;
|
|
270
|
+
lines.push(diff > 0
|
|
271
|
+
? `• Expires: ${formatTimestamp(result.tipExpiresAt)} (in ${formatTtl(diff)})`
|
|
272
|
+
: `• Expired: ${formatTimestamp(result.tipExpiresAt)}`);
|
|
273
|
+
}
|
|
274
|
+
if (result.tipChain && result.tipChain.length > 0) {
|
|
275
|
+
lines.push(`• Chain: ${result.tipChain.join(" → ")}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
lines.push("• Status: ⚠ not refreshed (run \`/identity login\`)");
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
lines.push("⚠ Not logged in. Run \`/identity login\`.");
|
|
284
|
+
}
|
|
285
|
+
const providers = Object.keys(result.credentials);
|
|
286
|
+
if (providers.length > 0) {
|
|
287
|
+
lines.push("");
|
|
288
|
+
lines.push("**Credentials:**");
|
|
289
|
+
for (const p of providers) {
|
|
290
|
+
const c = result.credentials[p];
|
|
291
|
+
const bind = result.bindings[p] ? ` → \`${result.bindings[p]}\`` : "";
|
|
292
|
+
if (c.type === "oauth2") {
|
|
293
|
+
const exp = c.expiresAt != null
|
|
294
|
+
? c.expiresAt < now
|
|
295
|
+
? `expired ${formatAgo(now - c.expiresAt)} ago`
|
|
296
|
+
: `expires in ${formatTtl(c.expiresAt - now)}`
|
|
297
|
+
: "";
|
|
298
|
+
const refresh = c.refreshToken ? ", has refresh" : "";
|
|
299
|
+
const scopes = c.scopes?.length ? ` [${c.scopes.join(", ")}]` : "";
|
|
300
|
+
lines.push(`• **${p}** (oauth2): ${c.status}${exp}${refresh}${scopes}${bind}`);
|
|
301
|
+
}
|
|
302
|
+
else if (c.type === "api_key") {
|
|
303
|
+
const src = c.valueFromEnv ? `from \`${c.valueFromEnv}\`` : c.value ? "stored" : "empty";
|
|
304
|
+
lines.push(`• **${p}** (api_key): key=\`${c.key}\`, ${src}${bind}`);
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
lines.push(`• **${p}**: ?${bind}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return { text: lines.join("\n") || "No status." };
|
|
312
|
+
}
|
|
313
|
+
async function handleLogout(deps, sessionKey) {
|
|
314
|
+
await runLogout(deps, sessionKey);
|
|
315
|
+
return { text: "✓ Logged out." };
|
|
316
|
+
}
|
|
317
|
+
async function handleListCredentials(deps, sessionKey, rest) {
|
|
318
|
+
const { page } = parseListArgs(rest);
|
|
319
|
+
const result = await runListCredentials(deps, sessionKey, page);
|
|
320
|
+
const lines = [];
|
|
321
|
+
if (result.providers.length > 0) {
|
|
322
|
+
lines.push(`**Available (page ${result.page}):**`);
|
|
323
|
+
for (const p of result.providers) {
|
|
324
|
+
const bind = p.binding ? ` → \`${p.binding}\`` : "";
|
|
325
|
+
lines.push(`• **${p.name}** (${p.type}): ${p.status}${bind}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (result.storedOnly.length > 0) {
|
|
329
|
+
if (lines.length)
|
|
330
|
+
lines.push("");
|
|
331
|
+
lines.push("**Your credentials:**");
|
|
332
|
+
for (const item of result.storedOnly) {
|
|
333
|
+
const bind = item.binding ? ` → \`${item.binding}\`` : "";
|
|
334
|
+
lines.push(`• **${item.name}**: ${item.status}${bind}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (lines.length === 0) {
|
|
338
|
+
return {
|
|
339
|
+
text: "No providers. Configure credential providers in the control plane, or use `/identity fetch <provider>` to add.",
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
const footer = [];
|
|
343
|
+
footer.push("Use `/identity set <provider> <envVar>` to bind.");
|
|
344
|
+
if (result.hasMore) {
|
|
345
|
+
footer.push(`\`/identity list ${result.page + 1}\` to load more.`);
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
text: `${lines.join("\n")}\n\n${footer.join(" ")}`,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
async function handleFetch(ctx, deps, sessionKey, rest) {
|
|
352
|
+
const parsed = parseFetchArgs(rest);
|
|
353
|
+
if ("error" in parsed) {
|
|
354
|
+
return { text: parsed.error };
|
|
355
|
+
}
|
|
356
|
+
const { provider, flow, flowExplicit, redirectUrl, scopes } = parsed;
|
|
357
|
+
const deliveryTarget = deriveDeliveryTargetFromContext(ctx);
|
|
358
|
+
const result = await runFetch(deps, sessionKey, {
|
|
359
|
+
provider,
|
|
360
|
+
flow,
|
|
361
|
+
flowExplicit,
|
|
362
|
+
redirectUrl,
|
|
363
|
+
scopes,
|
|
364
|
+
deliveryTarget,
|
|
365
|
+
config: ctx.config,
|
|
366
|
+
});
|
|
367
|
+
if (result.kind === "success")
|
|
368
|
+
return { text: result.message };
|
|
369
|
+
if (result.kind === "auth_url") {
|
|
370
|
+
return {
|
|
371
|
+
text: `Open this URL to authorize \`${provider}\`:\n\n${asMarkdownLink(result.authUrl, "Click to authorize")}\n\nAfter authorization, a success message will be sent here.`,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
return { text: `⚠️ ${result.message}` };
|
|
375
|
+
}
|
|
376
|
+
async function handleSet(deps, sessionKey, rest) {
|
|
377
|
+
const parts = rest.split(/\s+/).filter(Boolean);
|
|
378
|
+
if (parts.length < 2) {
|
|
379
|
+
return {
|
|
380
|
+
text: "Usage: `/identity set <provider> <envVar>`\nExample: `/identity set google GOOGLE_ACCESS_TOKEN`\n\n• If credential exists: binds it for injection as env var when tools run.\n• If not: imports from process.env[envVar] as api_key (gateway must have that env set).",
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
const provider = parts[0];
|
|
384
|
+
const envVar = parts[1];
|
|
385
|
+
const result = await runSetBinding(deps, sessionKey, { provider, envVar });
|
|
386
|
+
if (result.ok)
|
|
387
|
+
return { text: result.message ?? "✓ Bound." };
|
|
388
|
+
return { text: `⚠️ ${result.error}` };
|
|
389
|
+
}
|
|
390
|
+
async function handleConfig(deps) {
|
|
391
|
+
const result = await runConfig(deps);
|
|
392
|
+
if (Object.keys(result).length === 0) {
|
|
393
|
+
return { text: "No identity plugin config loaded." };
|
|
394
|
+
}
|
|
395
|
+
const lines = ["**Identity plugin config:**"];
|
|
396
|
+
const id = result.identity;
|
|
397
|
+
if (id && Object.keys(id).length > 0) {
|
|
398
|
+
lines.push("");
|
|
399
|
+
lines.push("**identity:**");
|
|
400
|
+
for (const [k, v] of Object.entries(id)) {
|
|
401
|
+
if (v != null)
|
|
402
|
+
lines.push(`• ${k}: \`${v}\``);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
lines.push("");
|
|
407
|
+
lines.push("**identity:** not configured");
|
|
408
|
+
}
|
|
409
|
+
const up = result.userpool;
|
|
410
|
+
if (up && Object.keys(up).length > 0) {
|
|
411
|
+
lines.push("");
|
|
412
|
+
lines.push("**userpool:**");
|
|
413
|
+
for (const [k, v] of Object.entries(up)) {
|
|
414
|
+
if (v != null)
|
|
415
|
+
lines.push(`• ${k}: \`${v}\``);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
lines.push("");
|
|
420
|
+
lines.push("**userpool:** not configured");
|
|
421
|
+
}
|
|
422
|
+
const authz = result.authz;
|
|
423
|
+
if (authz && Object.keys(authz).length > 0) {
|
|
424
|
+
lines.push("");
|
|
425
|
+
lines.push("**authz:**");
|
|
426
|
+
for (const [k, v] of Object.entries(authz)) {
|
|
427
|
+
if (v != null)
|
|
428
|
+
lines.push(`• ${k}: ${v}`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return { text: lines.join("\n") };
|
|
432
|
+
}
|
|
433
|
+
async function handleRisk(deps, rest) {
|
|
434
|
+
const command = rest.trim();
|
|
435
|
+
if (!command) {
|
|
436
|
+
return {
|
|
437
|
+
text: "Usage: `/identity risk <command>`\nExample: `/identity risk \"rm -rf /\"`\n\nDiagnoses risk for a shell command (as if run via exec). Use tools for tool-level checks.",
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
const llmConfig = deps.pluginConfig?.authz?.enableLlmRiskCheck && deps.pluginConfig?.authz?.llmRiskCheck
|
|
441
|
+
? deps.pluginConfig.authz.llmRiskCheck
|
|
442
|
+
: undefined;
|
|
443
|
+
const result = await diagnoseRisk("exec", { command }, llmConfig, deps.logger);
|
|
444
|
+
const riskEmoji = result.risk === "high" ? "🔴" : result.risk === "medium" ? "🟡" : "🟢";
|
|
445
|
+
const lines = [
|
|
446
|
+
`**Risk diagnosis** (${result.source}): ${riskEmoji} **${result.risk}**`,
|
|
447
|
+
`Command: \`${command.slice(0, 120)}${command.length > 120 ? "…" : ""}\``,
|
|
448
|
+
];
|
|
449
|
+
if (result.reason)
|
|
450
|
+
lines.push(`Reason: ${result.reason}`);
|
|
451
|
+
return { text: lines.join("\n") };
|
|
452
|
+
}
|
|
453
|
+
async function handleApprove(deps, sessionKey, rest) {
|
|
454
|
+
const approvalId = rest.trim();
|
|
455
|
+
if (!approvalId) {
|
|
456
|
+
return {
|
|
457
|
+
text: "Usage: `/identity approve <approval_id>`\nExample: `/identity approve abc123`\n\nUse the approval_id from the pending tool message. Must run from the same chat that triggered the approval request.",
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
const approvalTtlMs = (deps.pluginConfig?.authz?.approvalTtlSeconds ?? 300) * 1000;
|
|
461
|
+
const ok = toolApprovalStore.approve(approvalId, approvalTtlMs, sessionKey);
|
|
462
|
+
if (ok)
|
|
463
|
+
return { text: "✓ Tool call approved. You can retry the action now." };
|
|
464
|
+
return {
|
|
465
|
+
text: "⚠ Approval not found or expired. Run from the same chat that requested approval, or the request may have timed out.",
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
async function handleReject(deps, sessionKey, rest) {
|
|
469
|
+
const approvalId = rest.trim();
|
|
470
|
+
if (!approvalId) {
|
|
471
|
+
return {
|
|
472
|
+
text: "Usage: `/identity reject <approval_id>`\nExample: `/identity reject abc123`\n\nMust run from the same chat that triggered the approval request.",
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
const ok = toolApprovalStore.reject(approvalId, sessionKey);
|
|
476
|
+
if (ok)
|
|
477
|
+
return { text: "✓ Tool call rejected." };
|
|
478
|
+
return { text: "⚠ Approval not found or already expired. Run from the same chat that requested approval." };
|
|
479
|
+
}
|
|
480
|
+
async function handleRiskPatterns() {
|
|
481
|
+
const { commandPatterns, sensitivePaths } = getRiskPatterns();
|
|
482
|
+
const lines = [
|
|
483
|
+
"**Built-in risk patterns** (exec/process):",
|
|
484
|
+
"",
|
|
485
|
+
...commandPatterns.map((p) => `• \`${p.example}\` – ${p.reason}`),
|
|
486
|
+
"",
|
|
487
|
+
"**Sensitive paths** (write/edit/apply_patch):",
|
|
488
|
+
"",
|
|
489
|
+
...sensitivePaths.map((p) => `• \`${p}\``),
|
|
490
|
+
"",
|
|
491
|
+
"Commands or writes matching these require approval when authz is enabled.",
|
|
492
|
+
];
|
|
493
|
+
return { text: lines.join("\n") };
|
|
494
|
+
}
|
|
495
|
+
async function handleUnset(deps, sessionKey, rest) {
|
|
496
|
+
const provider = rest.split(/\s+/)[0]?.trim();
|
|
497
|
+
if (!provider) {
|
|
498
|
+
return {
|
|
499
|
+
text: "Usage: `/identity unset <provider>`\nExample: `/identity unset google`",
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
const result = await runUnsetBinding(deps, sessionKey, { provider });
|
|
503
|
+
if (result.ok)
|
|
504
|
+
return { text: result.message ?? "✓ Unset." };
|
|
505
|
+
return { text: result.error ?? "No binding found." };
|
|
506
|
+
}
|
|
507
|
+
function formatBindings(bindings) {
|
|
508
|
+
if (Object.keys(bindings).length === 0)
|
|
509
|
+
return "None.";
|
|
510
|
+
return Object.entries(bindings)
|
|
511
|
+
.map(([p, v]) => `• ${p} → \`${v}\``)
|
|
512
|
+
.join("\n");
|
|
513
|
+
}
|
|
514
|
+
async function handleListTips(deps) {
|
|
515
|
+
const result = await runListTips(deps);
|
|
516
|
+
const { bindingsBySession } = result;
|
|
517
|
+
if (result.tips.length === 0) {
|
|
518
|
+
return {
|
|
519
|
+
text: "No valid TIP tokens. Run `/identity login` to acquire one.",
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
const lines = ["**Valid TIP tokens:**"];
|
|
523
|
+
for (const v of result.tips) {
|
|
524
|
+
const shortKey = v.sessionKey.length > 40 ? v.sessionKey.slice(0, 36) + "…" : v.sessionKey;
|
|
525
|
+
const chainStr = v.chain.length > 0 ? ` (${v.chain.join(" → ")})` : "";
|
|
526
|
+
const expiresIn = v.ttlSec >= 3600
|
|
527
|
+
? `${Math.floor(v.ttlSec / 3600)}h${Math.floor((v.ttlSec % 3600) / 60)}m`
|
|
528
|
+
: `${v.ttlSec}s`;
|
|
529
|
+
lines.push(`• \`${shortKey}\` | sub: \`${v.sub}\`${chainStr} | expires in ${expiresIn}`);
|
|
530
|
+
}
|
|
531
|
+
lines.push("");
|
|
532
|
+
lines.push("**Env bindings (per session):**");
|
|
533
|
+
const allSessionKeys = new Set([
|
|
534
|
+
...result.tips.map((t) => t.sessionKey),
|
|
535
|
+
...Object.keys(bindingsBySession),
|
|
536
|
+
]);
|
|
537
|
+
if (allSessionKeys.size === 0) {
|
|
538
|
+
lines.push("None.");
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
for (const sk of [...allSessionKeys].sort()) {
|
|
542
|
+
const b = bindingsBySession[sk] ?? {};
|
|
543
|
+
if (Object.keys(b).length === 0)
|
|
544
|
+
continue;
|
|
545
|
+
const shortKey = sk.length > 40 ? sk.slice(0, 36) + "…" : sk;
|
|
546
|
+
lines.push(`\`${shortKey}\`:`);
|
|
547
|
+
lines.push(formatBindings(b));
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return { text: lines.join("\n") };
|
|
551
|
+
}
|
|
552
|
+
export function createIdentityCommand(deps) {
|
|
553
|
+
const handler = createIdentityHandler(deps);
|
|
554
|
+
return {
|
|
555
|
+
name: "identity",
|
|
556
|
+
description: "UserPool login, TIP token, credentials (list/fetch/set), risk check",
|
|
557
|
+
acceptsArgs: true,
|
|
558
|
+
requireAuth: true,
|
|
559
|
+
handler,
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
/** Alias command /id same as /identity */
|
|
563
|
+
export function createIdCommand(deps) {
|
|
564
|
+
const handler = createIdentityHandler(deps);
|
|
565
|
+
return {
|
|
566
|
+
name: "id",
|
|
567
|
+
description: "Alias for /identity (login, status, credentials, risk check)",
|
|
568
|
+
acceptsArgs: true,
|
|
569
|
+
requireAuth: true,
|
|
570
|
+
handler,
|
|
571
|
+
};
|
|
572
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* after_tool_call hook: propagate TIP token to child session on sessions_spawn.
|
|
3
|
+
* When parent spawns a sub-agent, inherit TIP with extended chain-of-custody.
|
|
4
|
+
*/
|
|
5
|
+
export type AfterToolCallDeps = {
|
|
6
|
+
storeDir: string;
|
|
7
|
+
logger: {
|
|
8
|
+
info?: (msg: string) => void;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export declare function createAfterToolCallHandler(deps: AfterToolCallDeps): (event: {
|
|
12
|
+
toolName: string;
|
|
13
|
+
params: Record<string, unknown>;
|
|
14
|
+
result?: unknown;
|
|
15
|
+
error?: string;
|
|
16
|
+
durationMs?: number;
|
|
17
|
+
}, ctx: {
|
|
18
|
+
agentId?: string;
|
|
19
|
+
sessionKey?: string;
|
|
20
|
+
toolName: string;
|
|
21
|
+
}) => Promise<void>;
|
|
22
|
+
//# sourceMappingURL=after-tool-call.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"after-tool-call.d.ts","sourceRoot":"","sources":["../../../src/hooks/after-tool-call.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CAC1C,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,iBAAiB,IAI9D,OAAO;IACL,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EACD,KAAK;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,KAC/D,OAAO,CAAC,IAAI,CAAC,CA4BjB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* after_tool_call hook: propagate TIP token to child session on sessions_spawn.
|
|
3
|
+
* When parent spawns a sub-agent, inherit TIP with extended chain-of-custody.
|
|
4
|
+
*/
|
|
5
|
+
import { getTIPToken, setTIPToken } from "../store/tip-store.js";
|
|
6
|
+
export function createAfterToolCallHandler(deps) {
|
|
7
|
+
const { storeDir, logger } = deps;
|
|
8
|
+
return async (event, ctx) => {
|
|
9
|
+
if (event.toolName !== "sessions_spawn")
|
|
10
|
+
return;
|
|
11
|
+
const result = event.result;
|
|
12
|
+
const childSessionKey = result?.childSessionKey;
|
|
13
|
+
if (!childSessionKey || typeof childSessionKey !== "string")
|
|
14
|
+
return;
|
|
15
|
+
const parentSessionKey = ctx.sessionKey;
|
|
16
|
+
if (!parentSessionKey)
|
|
17
|
+
return;
|
|
18
|
+
try {
|
|
19
|
+
const parentTIP = await getTIPToken(storeDir, parentSessionKey);
|
|
20
|
+
if (!parentTIP)
|
|
21
|
+
return;
|
|
22
|
+
const childTIP = {
|
|
23
|
+
...parentTIP,
|
|
24
|
+
chain: [...(parentTIP.chain ?? []), ctx.agentId ?? "unknown"],
|
|
25
|
+
parentSessionKey,
|
|
26
|
+
issuedAt: Date.now(),
|
|
27
|
+
};
|
|
28
|
+
await setTIPToken(storeDir, childSessionKey, childTIP);
|
|
29
|
+
logger.info?.(`agent-identity: TIP propagated to child ${childSessionKey.slice(0, 32)}...`);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
logger.info?.(`agent-identity: failed to propagate TIP to child: ${String(err)}`);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* before_agent_start hook: fetch TIP token and inject credentials into process.env.
|
|
3
|
+
* 1. Inject credentials into process.env per credential-env-bindings (per-session)
|
|
4
|
+
* 2. Look up userToken from session store by sessionKey
|
|
5
|
+
* 3. Call CIS GetWorkloadAccessTokenForJWT
|
|
6
|
+
* 4. On "token has expired", refresh userToken via refresh_token grant and retry
|
|
7
|
+
* 5. Store TIP token in tip-store for use by before_tool_call (AuthZ) and downstream
|
|
8
|
+
*/
|
|
9
|
+
import type { IdentityService } from "../services/identity-service.js";
|
|
10
|
+
import type { OIDCConfigForRefresh } from "../services/session-refresh.js";
|
|
11
|
+
export type BeforeAgentStartDeps = {
|
|
12
|
+
storeDir: string;
|
|
13
|
+
identityService: IdentityService;
|
|
14
|
+
/** When set, used to refresh userToken on expiry before retrying TIP fetch. */
|
|
15
|
+
getOidcConfigForRefresh?: () => Promise<OIDCConfigForRefresh>;
|
|
16
|
+
logger: {
|
|
17
|
+
info?: (msg: string) => void;
|
|
18
|
+
warn?: (msg: string) => void;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare function createBeforeAgentStartHandler(deps: BeforeAgentStartDeps): (_event: {
|
|
22
|
+
prompt: string;
|
|
23
|
+
messages?: unknown[];
|
|
24
|
+
}, ctx: {
|
|
25
|
+
agentId?: string;
|
|
26
|
+
sessionKey?: string;
|
|
27
|
+
}) => Promise<{
|
|
28
|
+
prependContext?: string;
|
|
29
|
+
} | void>;
|
|
30
|
+
//# sourceMappingURL=before-agent-start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"before-agent-start.d.ts","sourceRoot":"","sources":["../../../src/hooks/before-agent-start.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAQ3E,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,eAAe,CAAC;IACjC,+EAA+E;IAC/E,uBAAuB,CAAC,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC9D,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CACxE,CAAC;AAOF,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,oBAAoB,IAIpE,QAAQ;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,EAChD,KAAK;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KAC7C,OAAO,CAAC;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAgF/C"}
|