@tonyclaw/agent-inspector 2.0.15 → 2.0.17
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/.output/cli.js +399 -28
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-B6WCFRJq.js → CompareDrawer-DDg7Cs4N.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-CofGRJoO.js → ProxyViewerContainer-DbbK1y7N.js} +24 -24
- package/.output/public/assets/{ReplayDialog-O_53zkX8.js → ReplayDialog-C1zWNkoz.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-CqBSMZv5.js → RequestAnatomy-DR8OICOJ.js} +1 -1
- package/.output/public/assets/{ResponseView-BvbA6zot.js → ResponseView-Dh9iSj6h.js} +1 -1
- package/.output/public/assets/{StreamingChunkSequence-Bnf6djjc.js → StreamingChunkSequence-B_xElyH3.js} +1 -1
- package/.output/public/assets/_sessionId-gv1a_NNu.js +1 -0
- package/.output/public/assets/index-u-LwDaeH.js +1 -0
- package/.output/public/assets/{main-Biir9ZGe.js → main-bwZlEXw2.js} +2 -2
- package/.output/server/{_sessionId-B77Gh4IL.mjs → _sessionId-BEuJJhqT.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-D4-RHFqW.mjs → CompareDrawer-yTO93GMz.mjs} +2 -2
- package/.output/server/_ssr/{ProxyViewerContainer-YP28-_2H.mjs → ProxyViewerContainer-C8qCkHGB.mjs} +72 -22
- package/.output/server/_ssr/{ReplayDialog-D9rQlrcY.mjs → ReplayDialog-DRF9PG7Z.mjs} +3 -3
- package/.output/server/_ssr/{RequestAnatomy-BXCRWD9H.mjs → RequestAnatomy-DBcuV_jV.mjs} +2 -2
- package/.output/server/_ssr/{ResponseView-DEwWMqSS.mjs → ResponseView-JJm78HZT.mjs} +2 -2
- package/.output/server/_ssr/{StreamingChunkSequence-CdrTPf5v.mjs → StreamingChunkSequence-DyGKjBYx.mjs} +2 -2
- package/.output/server/_ssr/{index-Chf1DYqT.mjs → index-T7JG28t6.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-BHXU5jWm.mjs → router-BJob8RN3.mjs} +2 -2
- package/.output/server/{_tanstack-start-manifest_v-D1dtacWy.mjs → _tanstack-start-manifest_v-CuiFi3XC.mjs} +1 -1
- package/.output/server/index.mjs +57 -57
- package/README.md +22 -5
- package/package.json +3 -3
- package/scripts/setup-agent-skills.mjs +64 -0
- package/src/cli/onboard.ts +407 -13
- package/src/cli/templates/codex-skill-onboard.ts +13 -4
- package/src/cli/templates/command-onboard.ts +12 -4
- package/src/cli/templates/skill-onboard.ts +30 -8
- package/src/components/OnboardingBanner.tsx +35 -7
- package/src/components/providers/SettingsDialog.tsx +22 -4
- package/src/lib/useOnboarding.ts +9 -1
- package/.output/public/assets/_sessionId-9ICCw6YA.js +0 -1
- package/.output/public/assets/index-DVkMYH8H.js +0 -1
- package/scripts/setup-codex-skill.mjs +0 -38
|
@@ -76,7 +76,19 @@ Default proxy port: \`${port}\` (override with \`PORT=<n> agent-inspector\` or \
|
|
|
76
76
|
|
|
77
77
|
**EXPLAIN:** "Before we do anything, let me see what's already set up. If some of the steps are already done, we can skip them."
|
|
78
78
|
|
|
79
|
-
**DO:**
|
|
79
|
+
**DO:** First check whether the generated onboarding files match the installed npm package. If any
|
|
80
|
+
entry is \`outdated\` or \`missing\`, tell the user to run \`agent-inspector onboard --force\` before
|
|
81
|
+
continuing so they are not guided by stale instructions.
|
|
82
|
+
|
|
83
|
+
\`\`\`bash
|
|
84
|
+
agent-inspector onboard --status
|
|
85
|
+
\`\`\`
|
|
86
|
+
|
|
87
|
+
\`\`\`powershell
|
|
88
|
+
agent-inspector onboard --status
|
|
89
|
+
\`\`\`
|
|
90
|
+
|
|
91
|
+
**DO:** Then probe the three pieces of state this skill touches. Use targeted checks — do **not** read large JSON files into the conversation.
|
|
80
92
|
|
|
81
93
|
\`\`\`bash
|
|
82
94
|
# 1. Is the proxy already up?
|
|
@@ -226,11 +238,13 @@ if ($null) { Write-Host 'claude-code: present' } else { Write-Host 'claude-code:
|
|
|
226
238
|
\`\`\`
|
|
227
239
|
## Welcome to Agent Inspector!
|
|
228
240
|
|
|
229
|
-
Agent Inspector is an agent observability and knowledge-capture platform for AI coding tools. The \`agent-inspector\` CLI runs a transparent local proxy + Web UI, so you can see
|
|
241
|
+
Agent Inspector is an agent observability and knowledge-capture platform for AI coding tools. The \`agent-inspector\` CLI runs a transparent local proxy + Web UI, so you can see model requests and responses, system prompts, tool definitions, message history, timing, and token counts captured live in a browser tab.
|
|
242
|
+
|
|
243
|
+
Agent Inspector starts in **Simple mode** by default. Simple mode is the right habit for everyday use: it keeps requests, responses, tools, timing, and token usage while avoiding heavier raw headers, raw response, and detailed SSE chunk artifacts. Use **Full mode** only when the user is debugging provider headers, raw response payloads, or SSE stream details.
|
|
230
244
|
|
|
231
245
|
**What we'll do in the next ~10 minutes:**
|
|
232
246
|
1. Add your first LLM provider (Anthropic or OpenAI key)
|
|
233
|
-
2. Start the proxy
|
|
247
|
+
2. Start the proxy in Simple mode
|
|
234
248
|
3. Wire your AI tool to use it
|
|
235
249
|
4. Capture a first request end-to-end
|
|
236
250
|
5. Tour the key UI affordances
|
|
@@ -346,7 +360,7 @@ $json | Set-Content -Path $file -Encoding UTF8
|
|
|
346
360
|
|
|
347
361
|
## Phase 3: Start proxy
|
|
348
362
|
|
|
349
|
-
**EXPLAIN:** "Time to start the proxy. It binds to port ${port} by default, reuses an already-running healthy agent-inspector, and prints the URL. Use \`--force-restart\` only when you intentionally want to replace the existing process."
|
|
363
|
+
**EXPLAIN:** "Time to start the proxy. It binds to port ${port} by default, starts in Simple mode for lower overhead, reuses an already-running healthy agent-inspector, and prints the URL. Use \`--force-restart\` only when you intentionally want to replace the existing process. If the user is diagnosing raw headers, raw response, or SSE chunks, restart with \`agent-inspector --mode full\`."
|
|
350
364
|
|
|
351
365
|
**DO:** Skip this phase entirely if the Phase 0 health check already reported \`PROXY: up\` and the user opted to skip done phases.
|
|
352
366
|
|
|
@@ -354,7 +368,7 @@ $json | Set-Content -Path $file -Encoding UTF8
|
|
|
354
368
|
|
|
355
369
|
\`\`\`bash
|
|
356
370
|
# Unix / macOS / WSL
|
|
357
|
-
agent-inspector --background --no-open > /tmp/agent-inspector.log 2>&1
|
|
371
|
+
agent-inspector --mode simple --background --no-open > /tmp/agent-inspector.log 2>&1
|
|
358
372
|
\`\`\`
|
|
359
373
|
|
|
360
374
|
\`\`\`powershell
|
|
@@ -367,14 +381,14 @@ $err = Join-Path $env:TEMP 'agent-inspector.err.log'
|
|
|
367
381
|
$found = Get-Command agent-inspector -ErrorAction SilentlyContinue
|
|
368
382
|
if ($found) {
|
|
369
383
|
$shim = $found.Source
|
|
370
|
-
$args = '--background','--no-open'
|
|
384
|
+
$args = '--mode','simple','--background','--no-open'
|
|
371
385
|
} elseif (Test-Path (Join-Path $env:APPDATA 'npm/agent-inspector.cmd')) {
|
|
372
386
|
$shim = Join-Path $env:APPDATA 'npm/agent-inspector.cmd'
|
|
373
|
-
$args = '--background','--no-open'
|
|
387
|
+
$args = '--mode','simple','--background','--no-open'
|
|
374
388
|
} else {
|
|
375
389
|
# bin not on PATH and not at the default npm prefix — let cmd resolve it
|
|
376
390
|
$shim = 'cmd.exe'
|
|
377
|
-
$args = '/c','agent-inspector','--background','--no-open'
|
|
391
|
+
$args = '/c','agent-inspector','--mode','simple','--background','--no-open'
|
|
378
392
|
}
|
|
379
393
|
Start-Process -FilePath $shim -ArgumentList $args -RedirectStandardOutput $log -RedirectStandardError $err -WindowStyle Hidden
|
|
380
394
|
\`\`\`
|
|
@@ -394,6 +408,12 @@ done
|
|
|
394
408
|
curl -sS "http://localhost:${port}/api/health"
|
|
395
409
|
\`\`\`
|
|
396
410
|
|
|
411
|
+
**DO:** Read \`/api/config\` and tell the user which capture mode is active. If it is not \`simple\` during onboarding, explain that an existing process is already running and offer to restart with \`agent-inspector --mode simple --force-restart\`.
|
|
412
|
+
|
|
413
|
+
\`\`\`bash
|
|
414
|
+
curl -sS "http://localhost:${port}/api/config" | grep -o '"captureMode":"[^"]*"'
|
|
415
|
+
\`\`\`
|
|
416
|
+
|
|
397
417
|
> **PAUSE** — if the health check fails, show the user the log file (\`/tmp/agent-inspector.log\` or \`%TEMP%\\agent-inspector.log\`) and diagnose. Common issues: another process on the port, firewall, missing providers. Use \`AskUserQuestion\` with header \`Proxy up?\` and options \`["Yes, proxy is up", "No, I see an error in the log"]\`. Wait for the answer.
|
|
398
418
|
|
|
399
419
|
---
|
|
@@ -538,6 +558,8 @@ done
|
|
|
538
558
|
\`\`\`
|
|
539
559
|
|
|
540
560
|
- **Re-run onboard**: \`agent-inspector onboard --force\` refreshes this skill.
|
|
561
|
+
- **Check onboard files**: \`agent-inspector onboard --status\` shows whether generated skills are
|
|
562
|
+
current, outdated, missing, newer, or custom.
|
|
541
563
|
- **Full docs**: see the project README (linked from the Web UI footer).
|
|
542
564
|
|
|
543
565
|
> **PAUSE** — use \`AskUserQuestion\` with header \`All set?\` and options \`["All set, I'm done", "Wait, I want to revisit a phase"]\`. Wait for the answer.
|
|
@@ -7,10 +7,12 @@ import { useOnboarding } from "../lib/useOnboarding";
|
|
|
7
7
|
* dismissal through the server runtime config.
|
|
8
8
|
*/
|
|
9
9
|
export function OnboardingBanner(): JSX.Element | null {
|
|
10
|
-
const { hasSeenOnboarding, isLoading, markSeen } = useOnboarding();
|
|
10
|
+
const { hasSeenOnboarding, captureMode, isLoading, markSeen } = useOnboarding();
|
|
11
11
|
|
|
12
12
|
if (isLoading || hasSeenOnboarding) return null;
|
|
13
13
|
|
|
14
|
+
const isFullMode = captureMode === "full";
|
|
15
|
+
|
|
14
16
|
return (
|
|
15
17
|
<div
|
|
16
18
|
role="note"
|
|
@@ -19,17 +21,43 @@ export function OnboardingBanner(): JSX.Element | null {
|
|
|
19
21
|
>
|
|
20
22
|
<div className="min-w-0 flex-1">
|
|
21
23
|
<div className="mb-1 font-medium text-amber-600 dark:text-amber-400">
|
|
22
|
-
|
|
24
|
+
{isFullMode
|
|
25
|
+
? "Agent Inspector is ready in Full mode"
|
|
26
|
+
: "Agent Inspector is ready in Simple mode"}
|
|
23
27
|
</div>
|
|
24
28
|
<ul className="space-y-0.5 text-xs leading-relaxed text-muted-foreground">
|
|
29
|
+
{isFullMode ? (
|
|
30
|
+
<>
|
|
31
|
+
<li>
|
|
32
|
+
<strong>Full mode</strong>: raw headers, raw response, and SSE chunks are captured
|
|
33
|
+
for diagnostics.
|
|
34
|
+
</li>
|
|
35
|
+
<li>
|
|
36
|
+
<strong>Daily work</strong>: restart with <code>agent-inspector --mode simple</code>{" "}
|
|
37
|
+
to reduce capture overhead.
|
|
38
|
+
</li>
|
|
39
|
+
</>
|
|
40
|
+
) : (
|
|
41
|
+
<>
|
|
42
|
+
<li>
|
|
43
|
+
<strong>Simple mode</strong>: lightweight capture for requests, responses, tools,
|
|
44
|
+
timing, and token usage.
|
|
45
|
+
</li>
|
|
46
|
+
<li>
|
|
47
|
+
<strong>Need diagnostics?</strong> Restart with{" "}
|
|
48
|
+
<code>agent-inspector --mode full</code> for raw headers, raw response, and SSE
|
|
49
|
+
chunks.
|
|
50
|
+
</li>
|
|
51
|
+
</>
|
|
52
|
+
)}
|
|
25
53
|
<li>
|
|
26
|
-
<strong>
|
|
27
|
-
|
|
28
|
-
<li>
|
|
29
|
-
<strong>Replay</strong>: resend captured requests and compare provider behavior.
|
|
54
|
+
<strong>Replay and Memory</strong>: available in both modes for provider checks and
|
|
55
|
+
reviewable knowledge candidates.
|
|
30
56
|
</li>
|
|
31
57
|
<li>
|
|
32
|
-
<strong>
|
|
58
|
+
<strong>Agent setup</strong>: run <code>agent-inspector onboard --status</code>, then
|
|
59
|
+
use <code>/agent-inspector:onboard</code> in Claude Code or ask Codex to use{" "}
|
|
60
|
+
<code>agent-inspector-onboard</code>.
|
|
33
61
|
</li>
|
|
34
62
|
</ul>
|
|
35
63
|
</div>
|
|
@@ -75,7 +75,7 @@ export function SettingsDialog(): JSX.Element {
|
|
|
75
75
|
<TabsTrigger value="onboarding">Onboarding</TabsTrigger>
|
|
76
76
|
</TabsList>
|
|
77
77
|
|
|
78
|
-
<div className="mt-4 overflow-y-auto
|
|
78
|
+
<div className="mt-4 flex-1 overflow-x-hidden overflow-y-auto pr-3">
|
|
79
79
|
<TabsContent value="providers">
|
|
80
80
|
<ProvidersPanel
|
|
81
81
|
externalProviders={providers}
|
|
@@ -119,7 +119,7 @@ function CopyableSetupValue({
|
|
|
119
119
|
}): JSX.Element {
|
|
120
120
|
const copied = copiedId === id;
|
|
121
121
|
return (
|
|
122
|
-
<div className="rounded-md border border-border bg-muted/20 px-3 py-2">
|
|
122
|
+
<div className="min-w-0 rounded-md border border-border bg-muted/20 px-3 py-2">
|
|
123
123
|
<div className="mb-1 text-xs font-medium text-muted-foreground">{label}</div>
|
|
124
124
|
<div className="flex min-w-0 items-center gap-2">
|
|
125
125
|
<code className="min-w-0 flex-1 truncate font-mono text-xs text-foreground">{value}</code>
|
|
@@ -146,10 +146,28 @@ function OnboardingSettingsTab(): JSX.Element {
|
|
|
146
146
|
}, []);
|
|
147
147
|
const values = useMemo(
|
|
148
148
|
() => [
|
|
149
|
-
{ id: "
|
|
149
|
+
{ id: "status", label: "Check onboarding", value: "agent-inspector onboard --status" },
|
|
150
|
+
{
|
|
151
|
+
id: "status-json",
|
|
152
|
+
label: "Check onboarding JSON",
|
|
153
|
+
value: "agent-inspector onboard --status --json",
|
|
154
|
+
},
|
|
155
|
+
{ id: "refresh", label: "Refresh generated files", value: "agent-inspector onboard --force" },
|
|
156
|
+
{
|
|
157
|
+
id: "uninstall",
|
|
158
|
+
label: "Remove matching generated files",
|
|
159
|
+
value: "agent-inspector onboard --uninstall",
|
|
160
|
+
},
|
|
161
|
+
{ id: "claude", label: "Claude Code command", value: "/agent-inspector:onboard" },
|
|
162
|
+
{
|
|
163
|
+
id: "codex",
|
|
164
|
+
label: "Codex prompt",
|
|
165
|
+
value: "Use the agent-inspector-onboard skill",
|
|
166
|
+
},
|
|
150
167
|
{ id: "mcp", label: "MCP URL", value: `${origin}/api/mcp` },
|
|
151
168
|
{ id: "proxy", label: "Proxy URL", value: `${origin}/proxy` },
|
|
152
169
|
{ id: "anthropic", label: "Anthropic base", value: `ANTHROPIC_BASE_URL=${origin}/proxy` },
|
|
170
|
+
{ id: "openai", label: "OpenAI base", value: `OPENAI_BASE_URL=${origin}/proxy` },
|
|
153
171
|
],
|
|
154
172
|
[origin],
|
|
155
173
|
);
|
|
@@ -162,7 +180,7 @@ function OnboardingSettingsTab(): JSX.Element {
|
|
|
162
180
|
}, []);
|
|
163
181
|
|
|
164
182
|
return (
|
|
165
|
-
<div className="space-y-4">
|
|
183
|
+
<div className="min-w-0 space-y-4">
|
|
166
184
|
<div className="flex items-center gap-2">
|
|
167
185
|
<Terminal className="size-4 text-muted-foreground" />
|
|
168
186
|
<h3 className="text-sm font-semibold">Agent onboarding</h3>
|
package/src/lib/useOnboarding.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import useSWR, { type SWRResponse, useSWRConfig } from "swr";
|
|
2
2
|
import { fetchJson } from "./apiClient";
|
|
3
3
|
import {
|
|
4
|
+
DEFAULT_CAPTURE_MODE,
|
|
4
5
|
DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
5
6
|
DEFAULT_TIME_DISPLAY_FORMAT,
|
|
6
7
|
RuntimeConfigSchema,
|
|
8
|
+
type CaptureMode,
|
|
7
9
|
type RuntimeConfig,
|
|
8
10
|
} from "./runtimeConfig";
|
|
9
11
|
|
|
10
12
|
export const ONBOARDING_SWR_KEY = "/api/config";
|
|
11
13
|
|
|
14
|
+
type RuntimeConfigPatch = Partial<Omit<RuntimeConfig, "captureMode">>;
|
|
15
|
+
|
|
12
16
|
async function fetcher(url: string): Promise<RuntimeConfig> {
|
|
13
17
|
return fetchJson(
|
|
14
18
|
url,
|
|
@@ -18,7 +22,7 @@ async function fetcher(url: string): Promise<RuntimeConfig> {
|
|
|
18
22
|
);
|
|
19
23
|
}
|
|
20
24
|
|
|
21
|
-
async function patchRuntimeConfig(patch:
|
|
25
|
+
async function patchRuntimeConfig(patch: RuntimeConfigPatch): Promise<RuntimeConfig> {
|
|
22
26
|
return fetchJson(
|
|
23
27
|
ONBOARDING_SWR_KEY,
|
|
24
28
|
RuntimeConfigSchema,
|
|
@@ -33,6 +37,7 @@ async function patchRuntimeConfig(patch: Partial<RuntimeConfig>): Promise<Runtim
|
|
|
33
37
|
|
|
34
38
|
export type UseOnboarding = {
|
|
35
39
|
hasSeenOnboarding: boolean;
|
|
40
|
+
captureMode: CaptureMode;
|
|
36
41
|
isLoading: boolean;
|
|
37
42
|
markSeen: () => Promise<void>;
|
|
38
43
|
};
|
|
@@ -59,6 +64,7 @@ export function useOnboarding(): UseOnboarding {
|
|
|
59
64
|
const { mutate: globalMutate } = useSWRConfig();
|
|
60
65
|
|
|
61
66
|
const hasSeenOnboarding = response.data?.hasSeenOnboarding ?? false;
|
|
67
|
+
const captureMode = response.data?.captureMode ?? DEFAULT_CAPTURE_MODE;
|
|
62
68
|
|
|
63
69
|
const markSeen = async (): Promise<void> => {
|
|
64
70
|
await globalMutate(ONBOARDING_SWR_KEY, patchRuntimeConfig({ hasSeenOnboarding: true }), {
|
|
@@ -68,6 +74,7 @@ export function useOnboarding(): UseOnboarding {
|
|
|
68
74
|
slowResponseThresholdSeconds:
|
|
69
75
|
response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
70
76
|
timeDisplayFormat: response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT,
|
|
77
|
+
captureMode,
|
|
71
78
|
},
|
|
72
79
|
rollbackOnError: true,
|
|
73
80
|
revalidate: false,
|
|
@@ -76,6 +83,7 @@ export function useOnboarding(): UseOnboarding {
|
|
|
76
83
|
|
|
77
84
|
return {
|
|
78
85
|
hasSeenOnboarding,
|
|
86
|
+
captureMode,
|
|
79
87
|
isLoading: response.isLoading,
|
|
80
88
|
markSeen,
|
|
81
89
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{R as s,j as e}from"./main-Biir9ZGe.js";import{P as i}from"./ProxyViewerContainer-CofGRJoO.js";function t(){const{sessionId:o}=s.useParams();return e.jsx(i,{initialSessionId:o},o)}export{t as component};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as o}from"./ProxyViewerContainer-CofGRJoO.js";import"./main-Biir9ZGe.js";const r=o;export{r as component};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { spawnSync } from "node:child_process";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
-
|
|
7
|
-
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const packageRoot = dirname(scriptDir);
|
|
9
|
-
const cliEntry = join(packageRoot, ".output", "cli.js");
|
|
10
|
-
const codexHome = process.env["CODEX_HOME"] ?? join(homedir(), ".codex");
|
|
11
|
-
|
|
12
|
-
function shouldSkip() {
|
|
13
|
-
return (
|
|
14
|
-
process.env["AGENT_INSPECTOR_SKIP_CODEX_SKILL"] === "1" ||
|
|
15
|
-
!existsSync(cliEntry) ||
|
|
16
|
-
(!existsSync(codexHome) && process.env["AGENT_INSPECTOR_INSTALL_CODEX_SKILL"] !== "1")
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function main() {
|
|
21
|
-
if (shouldSkip()) return;
|
|
22
|
-
|
|
23
|
-
const result = spawnSync(process.execPath, [cliEntry, "onboard", "--codex-only"], {
|
|
24
|
-
stdio: "ignore",
|
|
25
|
-
windowsHide: true,
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
if (result.status !== 0) {
|
|
29
|
-
console.warn("Skipping Codex onboard skill installation.");
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
main();
|
|
35
|
-
} catch (error) {
|
|
36
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
37
|
-
console.warn(`Skipping Codex onboard skill installation: ${message}`);
|
|
38
|
-
}
|