@kaitranntt/ccs 7.79.1-dev.9 → 8.0.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/dist/bin/codex-runtime-router.d.ts.map +1 -1
- package/dist/bin/codex-runtime-router.js +38 -12
- package/dist/bin/codex-runtime-router.js.map +1 -1
- package/dist/ccs.js +2 -1
- package/dist/ccs.js.map +1 -1
- package/dist/cliproxy/ai-providers/codex-plan-compatibility.js +2 -2
- package/dist/cliproxy/ai-providers/codex-plan-compatibility.js.map +1 -1
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.d.ts +2 -2
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.d.ts.map +1 -1
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.js +16 -8
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.js.map +1 -1
- package/dist/cliproxy/ai-providers/model-id-normalizer.d.ts +1 -1
- package/dist/cliproxy/ai-providers/model-id-normalizer.d.ts.map +1 -1
- package/dist/cliproxy/ai-providers/model-id-normalizer.js +1 -1
- package/dist/cliproxy/ai-providers/model-id-normalizer.js.map +1 -1
- package/dist/cliproxy/auth/oauth-handler.d.ts +13 -1
- package/dist/cliproxy/auth/oauth-handler.d.ts.map +1 -1
- package/dist/cliproxy/auth/oauth-handler.js +111 -34
- package/dist/cliproxy/auth/oauth-handler.js.map +1 -1
- package/dist/cliproxy/auth/oauth-trace/redactor.d.ts.map +1 -1
- package/dist/cliproxy/auth/oauth-trace/redactor.js +9 -1
- package/dist/cliproxy/auth/oauth-trace/redactor.js.map +1 -1
- package/dist/cliproxy/config/generator.d.ts.map +1 -1
- package/dist/cliproxy/config/generator.js +5 -2
- package/dist/cliproxy/config/generator.js.map +1 -1
- package/dist/cliproxy/config/thinking-config.js +6 -6
- package/dist/cliproxy/config/thinking-config.js.map +1 -1
- package/dist/cliproxy/executor/env-resolver.js +1 -1
- package/dist/cliproxy/executor/env-resolver.js.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher-claude.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher-claude.js +35 -4
- package/dist/cliproxy/quota/quota-fetcher-claude.js.map +1 -1
- package/dist/cliproxy/quota/quota-manager.d.ts +1 -0
- package/dist/cliproxy/quota/quota-manager.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-manager.js +53 -2
- package/dist/cliproxy/quota/quota-manager.js.map +1 -1
- package/dist/cliproxy/services/oauth-usage-log-transformer.d.ts.map +1 -1
- package/dist/cliproxy/services/oauth-usage-log-transformer.js +5 -0
- package/dist/cliproxy/services/oauth-usage-log-transformer.js.map +1 -1
- package/dist/codex-auth/codex-profile-resources.d.ts +6 -0
- package/dist/codex-auth/codex-profile-resources.d.ts.map +1 -0
- package/dist/codex-auth/codex-profile-resources.js +119 -0
- package/dist/codex-auth/codex-profile-resources.js.map +1 -0
- package/dist/codex-auth/commands/create-command.d.ts.map +1 -1
- package/dist/codex-auth/commands/create-command.js +20 -6
- package/dist/codex-auth/commands/create-command.js.map +1 -1
- package/dist/codex-auth/index.d.ts +1 -0
- package/dist/codex-auth/index.d.ts.map +1 -1
- package/dist/codex-auth/index.js +4 -1
- package/dist/codex-auth/index.js.map +1 -1
- package/dist/commands/cliproxy/variant-subcommand.js +1 -1
- package/dist/commands/cliproxy/variant-subcommand.js.map +1 -1
- package/dist/commands/command-catalog.d.ts +1 -1
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +10 -1
- package/dist/commands/command-catalog.js.map +1 -1
- package/dist/commands/completion-backend.d.ts.map +1 -1
- package/dist/commands/completion-backend.js +2 -0
- package/dist/commands/completion-backend.js.map +1 -1
- package/dist/commands/config-command.d.ts +2 -0
- package/dist/commands/config-command.d.ts.map +1 -1
- package/dist/commands/config-command.js +31 -20
- package/dist/commands/config-command.js.map +1 -1
- package/dist/commands/docker/finalize-key-rotation-subcommand.d.ts +2 -0
- package/dist/commands/docker/finalize-key-rotation-subcommand.d.ts.map +1 -0
- package/dist/commands/docker/finalize-key-rotation-subcommand.js +79 -0
- package/dist/commands/docker/finalize-key-rotation-subcommand.js.map +1 -0
- package/dist/commands/docker/help-subcommand.d.ts.map +1 -1
- package/dist/commands/docker/help-subcommand.js +6 -0
- package/dist/commands/docker/help-subcommand.js.map +1 -1
- package/dist/commands/docker/index.d.ts.map +1 -1
- package/dist/commands/docker/index.js +4 -0
- package/dist/commands/docker/index.js.map +1 -1
- package/dist/commands/docker/show-key-subcommand.d.ts +2 -0
- package/dist/commands/docker/show-key-subcommand.d.ts.map +1 -0
- package/dist/commands/docker/show-key-subcommand.js +96 -0
- package/dist/commands/docker/show-key-subcommand.js.map +1 -0
- package/dist/commands/docker/up-subcommand.d.ts.map +1 -1
- package/dist/commands/docker/up-subcommand.js +4 -0
- package/dist/commands/docker/up-subcommand.js.map +1 -1
- package/dist/commands/persist-command.d.ts.map +1 -1
- package/dist/commands/persist-command.js +77 -5
- package/dist/commands/persist-command.js.map +1 -1
- package/dist/docker/docker-bootstrap.d.ts +1 -1
- package/dist/docker/docker-bootstrap.d.ts.map +1 -1
- package/dist/docker/docker-bootstrap.js +99 -3
- package/dist/docker/docker-bootstrap.js.map +1 -1
- package/dist/docker/docker-executor.d.ts +3 -0
- package/dist/docker/docker-executor.d.ts.map +1 -1
- package/dist/docker/docker-executor.js +53 -0
- package/dist/docker/docker-executor.js.map +1 -1
- package/dist/docker/docker-key-rotation.d.ts +48 -0
- package/dist/docker/docker-key-rotation.d.ts.map +1 -0
- package/dist/docker/docker-key-rotation.js +179 -0
- package/dist/docker/docker-key-rotation.js.map +1 -0
- package/dist/management/checks/config-check.d.ts.map +1 -1
- package/dist/management/checks/config-check.js +10 -1
- package/dist/management/checks/config-check.js.map +1 -1
- package/dist/management/doctor.d.ts +1 -0
- package/dist/management/doctor.d.ts.map +1 -1
- package/dist/management/doctor.js +23 -0
- package/dist/management/doctor.js.map +1 -1
- package/dist/proxy/proxy-daemon.d.ts.map +1 -1
- package/dist/proxy/proxy-daemon.js +15 -3
- package/dist/proxy/proxy-daemon.js.map +1 -1
- package/dist/proxy/server/messages-route.d.ts.map +1 -1
- package/dist/proxy/server/messages-route.js +27 -1
- package/dist/proxy/server/messages-route.js.map +1 -1
- package/dist/shared/claude-extension-setup.d.ts.map +1 -1
- package/dist/shared/claude-extension-setup.js +21 -1
- package/dist/shared/claude-extension-setup.js.map +1 -1
- package/dist/shared/stale-codex-translator-settings.d.ts +4 -0
- package/dist/shared/stale-codex-translator-settings.d.ts.map +1 -0
- package/dist/shared/stale-codex-translator-settings.js +35 -0
- package/dist/shared/stale-codex-translator-settings.js.map +1 -0
- package/dist/targets/codex-adapter.d.ts.map +1 -1
- package/dist/targets/codex-adapter.js +64 -5
- package/dist/targets/codex-adapter.js.map +1 -1
- package/dist/ui/assets/{Trans-J6qQqjkU.js → Trans-dEd8UC39.js} +1 -1
- package/dist/ui/assets/{accounts-B9Y9uOFl.js → accounts-B2THsSu_.js} +1 -1
- package/dist/ui/assets/{alert-dialog-B7gsksZn.js → alert-dialog-Vurq1xzV.js} +1 -1
- package/dist/ui/assets/{api-Cz8U6P7R.js → api-CjLfG9mL.js} +1 -1
- package/dist/ui/assets/{auth-section-C8dzvYje.js → auth-section-iGkrMaT4.js} +1 -1
- package/dist/ui/assets/{backups-section-D0dn59k8.js → backups-section-DUGG_4KP.js} +1 -1
- package/dist/ui/assets/{channels-BEmwDrRW.js → channels-CimlCc2d.js} +1 -1
- package/dist/ui/assets/{checkbox-DD0s2D_O.js → checkbox-HiMHasEB.js} +1 -1
- package/dist/ui/assets/claude-extension-B2v9bsN9.js +1 -0
- package/dist/ui/assets/{cliproxy-ai-providers-B440rPlH.js → cliproxy-ai-providers-2lI5jSHb.js} +6 -6
- package/dist/ui/assets/{cliproxy-control-panel-Bo-Y41B_.js → cliproxy-control-panel-63gDI-e5.js} +1 -1
- package/dist/ui/assets/cliproxy-fai69Vyd.js +4 -0
- package/dist/ui/assets/{codex-DPe04ol4.js → codex-i_hfI4Tv.js} +1 -1
- package/dist/ui/assets/{confirm-dialog-MQNmqmha.js → confirm-dialog-B_6SrSxL.js} +1 -1
- package/dist/ui/assets/{copilot-COZj29YU.js → copilot-BgG5x_X6.js} +2 -2
- package/dist/ui/assets/{cursor-D0occhsH.js → cursor-DF63lFcy.js} +1 -1
- package/dist/ui/assets/droid-CqlQmFtN.js +2 -0
- package/dist/ui/assets/{globalenv-section-BwuNrdbO.js → globalenv-section-CYNmD12i.js} +1 -1
- package/dist/ui/assets/{health-DjNOO9K-.js → health-7ZO5PEm9.js} +1 -1
- package/dist/ui/assets/{index-Bnzie_zG.js → index-BC5ssPfF.js} +1 -1
- package/dist/ui/assets/index-BMoGhs28.css +1 -0
- package/dist/ui/assets/{index-i2MPNni3.js → index-Bgcd4FYK.js} +1 -1
- package/dist/ui/assets/{index-CmOBelFi.js → index-CFu0saCM.js} +1 -1
- package/dist/ui/assets/index-CqsmdQoA.js +1 -0
- package/dist/ui/assets/{index-CjM3Ehb8.js → index-D3kxCuJ7.js} +1 -1
- package/dist/ui/assets/{index-CSlgRg0s.js → index-DmV9wJET.js} +3 -3
- package/dist/ui/assets/{index-Bm_0r3qk.js → index-hHb9o079.js} +1 -1
- package/dist/ui/assets/{logs-7bWvuc1l.js → logs-Dy-yZhIK.js} +1 -1
- package/dist/ui/assets/{masked-input-D_amxi96.js → masked-input-BSLeznEs.js} +1 -1
- package/dist/ui/assets/{proxy-status-widget-BkC-wCtI.js → proxy-status-widget-hRH1agF9.js} +1 -1
- package/dist/ui/assets/{raw-json-settings-editor-panel-CVP5Bjfm.js → raw-json-settings-editor-panel-Bs83yILR.js} +1 -1
- package/dist/ui/assets/{searchable-select-e5sY7o6g.js → searchable-select-pXUC_0Ih.js} +1 -1
- package/dist/ui/assets/{separator-BR5bmtI7.js → separator-FZR_61I9.js} +1 -1
- package/dist/ui/assets/{shared-CsqW2cFN.js → shared-BiIwM7--.js} +1 -1
- package/dist/ui/assets/{table-DPheAd4c.js → table-_9IusQ8G.js} +1 -1
- package/dist/ui/assets/{updates-D07RjKLJ.js → updates-ButNfJqt.js} +1 -1
- package/dist/ui/assets/{use-accounts-CWVR2NXQ.js → use-accounts-BdtI0lBv.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/utils/claude-subcommand-detector.d.ts +7 -0
- package/dist/utils/claude-subcommand-detector.d.ts.map +1 -1
- package/dist/utils/claude-subcommand-detector.js +52 -9
- package/dist/utils/claude-subcommand-detector.js.map +1 -1
- package/dist/web-server/routes/cliproxy-stats-routes.d.ts +8 -0
- package/dist/web-server/routes/cliproxy-stats-routes.d.ts.map +1 -1
- package/dist/web-server/routes/cliproxy-stats-routes.js +13 -26
- package/dist/web-server/routes/cliproxy-stats-routes.js.map +1 -1
- package/dist/web-server/services/cliproxy-dashboard-restart-service.d.ts +21 -0
- package/dist/web-server/services/cliproxy-dashboard-restart-service.d.ts.map +1 -0
- package/dist/web-server/services/cliproxy-dashboard-restart-service.js +49 -0
- package/dist/web-server/services/cliproxy-dashboard-restart-service.js.map +1 -0
- package/dist/web-server/services/codex-dashboard-service.d.ts.map +1 -1
- package/dist/web-server/services/codex-dashboard-service.js +30 -3
- package/dist/web-server/services/codex-dashboard-service.js.map +1 -1
- package/dist/web-server/usage/aggregator.d.ts +13 -7
- package/dist/web-server/usage/aggregator.d.ts.map +1 -1
- package/dist/web-server/usage/aggregator.js +37 -22
- package/dist/web-server/usage/aggregator.js.map +1 -1
- package/dist/web-server/usage/handlers.d.ts +1 -0
- package/dist/web-server/usage/handlers.d.ts.map +1 -1
- package/dist/web-server/usage/handlers.js +16 -8
- package/dist/web-server/usage/handlers.js.map +1 -1
- package/dist/web-server/usage/profile-filter.d.ts +13 -0
- package/dist/web-server/usage/profile-filter.d.ts.map +1 -0
- package/dist/web-server/usage/profile-filter.js +30 -0
- package/dist/web-server/usage/profile-filter.js.map +1 -0
- package/dist/web-server/usage/types.d.ts +8 -0
- package/dist/web-server/usage/types.d.ts.map +1 -1
- package/lib/mcp/ccs-browser-server.cjs +217 -12
- package/package.json +1 -1
- package/scripts/docker-dashboard-sunset-guard.js +171 -0
- package/dist/ui/assets/claude-extension-DHVBsw6b.js +0 -1
- package/dist/ui/assets/cliproxy-BMlbpAIO.js +0 -4
- package/dist/ui/assets/droid-CSaYFApd.js +0 -2
- package/dist/ui/assets/index-D9HfyuQr.js +0 -1
- package/dist/ui/assets/index-G3mgTfgR.css +0 -1
|
@@ -83,6 +83,16 @@ const TOOL_HOVER = 'browser_hover';
|
|
|
83
83
|
const TOOL_QUERY = 'browser_query';
|
|
84
84
|
const TOOL_TAKE_ELEMENT_SCREENSHOT = 'browser_take_element_screenshot';
|
|
85
85
|
const TOOL_WAIT_FOR_EVENT = 'browser_wait_for_event';
|
|
86
|
+
const SENSITIVE_INTERCEPT_HEADER_NAMES = new Set([
|
|
87
|
+
'authorization',
|
|
88
|
+
'cookie',
|
|
89
|
+
'cookie2',
|
|
90
|
+
'proxy-authorization',
|
|
91
|
+
'x-api-key',
|
|
92
|
+
'x-api-token',
|
|
93
|
+
'x-auth-token',
|
|
94
|
+
]);
|
|
95
|
+
|
|
86
96
|
const TOOL_NAMES = [
|
|
87
97
|
TOOL_SESSION_INFO,
|
|
88
98
|
TOOL_URL_TITLE,
|
|
@@ -612,10 +622,15 @@ function getTools() {
|
|
|
612
622
|
urlRegex: { type: 'string' },
|
|
613
623
|
headerMatchers: {
|
|
614
624
|
type: 'array',
|
|
625
|
+
description:
|
|
626
|
+
'Match non-sensitive request headers. Cookie, Authorization, and token headers are not allowed.',
|
|
615
627
|
items: {
|
|
616
628
|
type: 'object',
|
|
617
629
|
properties: {
|
|
618
|
-
name: {
|
|
630
|
+
name: {
|
|
631
|
+
type: 'string',
|
|
632
|
+
description: 'Non-sensitive request header name to match.',
|
|
633
|
+
},
|
|
619
634
|
valueIncludes: { type: 'string' },
|
|
620
635
|
valueRegex: { type: 'string' },
|
|
621
636
|
},
|
|
@@ -624,7 +639,7 @@ function getTools() {
|
|
|
624
639
|
},
|
|
625
640
|
},
|
|
626
641
|
priority: { type: 'integer' },
|
|
627
|
-
action: { type: 'string', enum:
|
|
642
|
+
action: { type: 'string', enum: getInterceptActionEnum() },
|
|
628
643
|
statusCode: { type: 'integer', minimum: 100, maximum: 599 },
|
|
629
644
|
responseHeaders: {
|
|
630
645
|
type: 'array',
|
|
@@ -1194,7 +1209,18 @@ function getTools() {
|
|
|
1194
1209
|
},
|
|
1195
1210
|
event: {
|
|
1196
1211
|
type: 'object',
|
|
1197
|
-
description:
|
|
1212
|
+
description:
|
|
1213
|
+
'Required event selector. request events require urlIncludes; download events require urlIncludes or suggestedFilenameIncludes. URLs in returned details are redacted.',
|
|
1214
|
+
properties: {
|
|
1215
|
+
kind: { type: 'string', enum: ['dialog', 'navigation', 'request', 'download'] },
|
|
1216
|
+
dialogType: { type: 'string' },
|
|
1217
|
+
messageIncludes: { type: 'string' },
|
|
1218
|
+
urlIncludes: { type: 'string' },
|
|
1219
|
+
method: { type: 'string' },
|
|
1220
|
+
suggestedFilenameIncludes: { type: 'string' },
|
|
1221
|
+
},
|
|
1222
|
+
required: ['kind'],
|
|
1223
|
+
additionalProperties: false,
|
|
1198
1224
|
},
|
|
1199
1225
|
},
|
|
1200
1226
|
required: ['event'],
|
|
@@ -1277,9 +1303,30 @@ function parseOptionalPageId(toolArgs) {
|
|
|
1277
1303
|
: '';
|
|
1278
1304
|
}
|
|
1279
1305
|
|
|
1306
|
+
function getBrowserInterceptFulfillMode() {
|
|
1307
|
+
return String(process.env.CCS_BROWSER_INTERCEPT_FULFILL_MODE || 'disabled').trim() === 'enabled'
|
|
1308
|
+
? 'enabled'
|
|
1309
|
+
: 'disabled';
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
function isBrowserInterceptFulfillEnabled() {
|
|
1313
|
+
return getBrowserInterceptFulfillMode() === 'enabled';
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
function getInterceptActionEnum() {
|
|
1317
|
+
return isBrowserInterceptFulfillEnabled()
|
|
1318
|
+
? ['continue', 'fail', 'fulfill']
|
|
1319
|
+
: ['continue', 'fail'];
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1280
1322
|
function parseInterceptAction(value) {
|
|
1323
|
+
if (value === 'fulfill' && !isBrowserInterceptFulfillEnabled()) {
|
|
1324
|
+
throw new Error(
|
|
1325
|
+
'action fulfill is disabled by CCS_BROWSER_INTERCEPT_FULFILL_MODE=disabled; set it to enabled only for trusted local testing'
|
|
1326
|
+
);
|
|
1327
|
+
}
|
|
1281
1328
|
if (value !== 'continue' && value !== 'fail' && value !== 'fulfill') {
|
|
1282
|
-
throw new Error(
|
|
1329
|
+
throw new Error(`action must be one of: ${getInterceptActionEnum().join(', ')}`);
|
|
1283
1330
|
}
|
|
1284
1331
|
return value;
|
|
1285
1332
|
}
|
|
@@ -1379,6 +1426,10 @@ function parseOptionalPriority(value) {
|
|
|
1379
1426
|
return value;
|
|
1380
1427
|
}
|
|
1381
1428
|
|
|
1429
|
+
function isSensitiveInterceptHeaderName(name) {
|
|
1430
|
+
return SENSITIVE_INTERCEPT_HEADER_NAMES.has(name.toLowerCase());
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1382
1433
|
function parseOptionalHeaderMatchers(value) {
|
|
1383
1434
|
if (value === undefined) {
|
|
1384
1435
|
return [];
|
|
@@ -1391,6 +1442,9 @@ function parseOptionalHeaderMatchers(value) {
|
|
|
1391
1442
|
throw new Error('headerMatchers entries must be objects');
|
|
1392
1443
|
}
|
|
1393
1444
|
const name = requireNonEmptyString(entry.name, 'headerMatchers.name');
|
|
1445
|
+
if (isSensitiveInterceptHeaderName(name)) {
|
|
1446
|
+
throw new Error(`headerMatchers.name cannot target sensitive request header: ${name}`);
|
|
1447
|
+
}
|
|
1394
1448
|
const valueIncludes =
|
|
1395
1449
|
entry.valueIncludes === undefined
|
|
1396
1450
|
? ''
|
|
@@ -3305,24 +3359,80 @@ function parseEventCondition(value) {
|
|
|
3305
3359
|
};
|
|
3306
3360
|
}
|
|
3307
3361
|
if (value.kind === 'request') {
|
|
3362
|
+
const urlIncludes = value.urlIncludes ? String(value.urlIncludes) : undefined;
|
|
3363
|
+
if (!urlIncludes) {
|
|
3364
|
+
throw new Error('request events require urlIncludes to limit network metadata exposure');
|
|
3365
|
+
}
|
|
3308
3366
|
return {
|
|
3309
3367
|
kind: 'request',
|
|
3310
|
-
urlIncludes
|
|
3368
|
+
urlIncludes,
|
|
3311
3369
|
method: value.method ? String(value.method) : undefined,
|
|
3312
3370
|
};
|
|
3313
3371
|
}
|
|
3314
3372
|
if (value.kind === 'download') {
|
|
3373
|
+
const urlIncludes = value.urlIncludes ? String(value.urlIncludes) : undefined;
|
|
3374
|
+
const suggestedFilenameIncludes = value.suggestedFilenameIncludes
|
|
3375
|
+
? String(value.suggestedFilenameIncludes)
|
|
3376
|
+
: undefined;
|
|
3377
|
+
if (!urlIncludes && !suggestedFilenameIncludes) {
|
|
3378
|
+
throw new Error(
|
|
3379
|
+
'download events require urlIncludes or suggestedFilenameIncludes to limit metadata exposure'
|
|
3380
|
+
);
|
|
3381
|
+
}
|
|
3315
3382
|
return {
|
|
3316
3383
|
kind: 'download',
|
|
3317
|
-
urlIncludes
|
|
3318
|
-
suggestedFilenameIncludes
|
|
3319
|
-
? String(value.suggestedFilenameIncludes)
|
|
3320
|
-
: undefined,
|
|
3384
|
+
urlIncludes,
|
|
3385
|
+
suggestedFilenameIncludes,
|
|
3321
3386
|
};
|
|
3322
3387
|
}
|
|
3323
3388
|
throw new Error(`unknown event kind: ${String(value.kind || '')}`);
|
|
3324
3389
|
}
|
|
3325
3390
|
|
|
3391
|
+
function redactUrlForModel(value, options = {}) {
|
|
3392
|
+
const rawUrl = String(value || '');
|
|
3393
|
+
if (!rawUrl) {
|
|
3394
|
+
return '';
|
|
3395
|
+
}
|
|
3396
|
+
try {
|
|
3397
|
+
const url = new URL(rawUrl);
|
|
3398
|
+
if (options.originOnly) {
|
|
3399
|
+
return url.origin;
|
|
3400
|
+
}
|
|
3401
|
+
url.username = '';
|
|
3402
|
+
url.password = '';
|
|
3403
|
+
url.search = '';
|
|
3404
|
+
url.hash = '';
|
|
3405
|
+
return url.toString();
|
|
3406
|
+
} catch {
|
|
3407
|
+
return '[redacted-url]';
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
|
|
3411
|
+
function redactObservedEvent(event, observed) {
|
|
3412
|
+
if (!observed || typeof observed !== 'object') {
|
|
3413
|
+
return observed;
|
|
3414
|
+
}
|
|
3415
|
+
if (event.kind === 'request') {
|
|
3416
|
+
return {
|
|
3417
|
+
url: redactUrlForModel(observed.url, { originOnly: true }),
|
|
3418
|
+
method: observed.method || '',
|
|
3419
|
+
};
|
|
3420
|
+
}
|
|
3421
|
+
if (event.kind === 'download') {
|
|
3422
|
+
return {
|
|
3423
|
+
url: redactUrlForModel(observed.url, { originOnly: true }),
|
|
3424
|
+
suggestedFilename: observed.suggestedFilename || '',
|
|
3425
|
+
};
|
|
3426
|
+
}
|
|
3427
|
+
if (event.kind === 'navigation' && Object.prototype.hasOwnProperty.call(observed, 'url')) {
|
|
3428
|
+
return {
|
|
3429
|
+
...observed,
|
|
3430
|
+
url: redactUrlForModel(observed.url, { originOnly: true }),
|
|
3431
|
+
};
|
|
3432
|
+
}
|
|
3433
|
+
return observed;
|
|
3434
|
+
}
|
|
3435
|
+
|
|
3326
3436
|
function matchesObservedEvent(event, observed) {
|
|
3327
3437
|
if (event.kind === 'dialog') {
|
|
3328
3438
|
return (
|
|
@@ -4776,7 +4886,8 @@ async function handleWaitForEvent(toolArgs) {
|
|
|
4776
4886
|
);
|
|
4777
4887
|
const event = parseEventCondition(toolArgs.event);
|
|
4778
4888
|
const observed = await waitForMatchingEvent({ page, pageIndex, timeoutMs, event });
|
|
4779
|
-
|
|
4889
|
+
const safeObserved = redactObservedEvent(event, observed);
|
|
4890
|
+
return `pageIndex: ${pageIndex}\nevent: ${event.kind}\nstatus: observed\ndetail: ${JSON.stringify(safeObserved)}`;
|
|
4780
4891
|
}
|
|
4781
4892
|
|
|
4782
4893
|
function findInterceptRuleIndex(ruleId) {
|
|
@@ -5381,7 +5492,10 @@ function buildRecordingInstallExpression(recordingPayload) {
|
|
|
5381
5492
|
const recordingPayload = JSON.parse(${JSON.stringify(JSON.stringify(recordingPayload))});
|
|
5382
5493
|
const existing = globalThis.__CCS_BROWSER_RECORDING_RECORDER__;
|
|
5383
5494
|
if (existing && existing.installed === true) {
|
|
5384
|
-
|
|
5495
|
+
if (typeof existing.teardown === 'function') {
|
|
5496
|
+
existing.teardown();
|
|
5497
|
+
}
|
|
5498
|
+
delete globalThis.__CCS_BROWSER_RECORDING_RECORDER__;
|
|
5385
5499
|
}
|
|
5386
5500
|
|
|
5387
5501
|
const events = Array.isArray(recordingPayload.events) ? [...recordingPayload.events] : [];
|
|
@@ -5413,8 +5527,42 @@ function buildRecordingInstallExpression(recordingPayload) {
|
|
|
5413
5527
|
timestamp: Date.now(),
|
|
5414
5528
|
});
|
|
5415
5529
|
};
|
|
5530
|
+
const sensitiveInputTypes = new Set(['password', 'hidden']);
|
|
5531
|
+
const sensitiveAttributePattern = /(?:pass(?:word|code|phrase)?|pwd|secret|token|api[-_ ]?key|access[-_ ]?key|private[-_ ]?key|credential|otp|one[-_ ]?time[-_ ]?(?:code|password)|verif(?:ication)?[-_ ]?code|security[-_ ]?code|pin|auth(?:orization)?[-_ ]?(?:code|token)|mfa|2fa)/i;
|
|
5532
|
+
const sensitiveAutocompleteValues = new Set([
|
|
5533
|
+
'current-password',
|
|
5534
|
+
'new-password',
|
|
5535
|
+
'one-time-code',
|
|
5536
|
+
'cc-number',
|
|
5537
|
+
'cc-csc',
|
|
5538
|
+
]);
|
|
5539
|
+
const isSensitiveTextTarget = (target) => {
|
|
5540
|
+
if (!target || !(target instanceof Element)) {
|
|
5541
|
+
return false;
|
|
5542
|
+
}
|
|
5543
|
+
if (target instanceof HTMLInputElement) {
|
|
5544
|
+
const inputType = String(target.type || '').toLowerCase();
|
|
5545
|
+
if (sensitiveInputTypes.has(inputType)) {
|
|
5546
|
+
return true;
|
|
5547
|
+
}
|
|
5548
|
+
}
|
|
5549
|
+
const autocompleteTokens = String(target.getAttribute('autocomplete') || '')
|
|
5550
|
+
.toLowerCase()
|
|
5551
|
+
.split(/\s+/)
|
|
5552
|
+
.filter(Boolean);
|
|
5553
|
+
if (autocompleteTokens.some((token) => sensitiveAutocompleteValues.has(token))) {
|
|
5554
|
+
return true;
|
|
5555
|
+
}
|
|
5556
|
+
const attributesToInspect = ['id', 'name', 'placeholder', 'aria-label', 'data-testid'];
|
|
5557
|
+
return attributesToInspect.some((attributeName) =>
|
|
5558
|
+
sensitiveAttributePattern.test(String(target.getAttribute(attributeName) || ''))
|
|
5559
|
+
);
|
|
5560
|
+
};
|
|
5416
5561
|
const onInput = (event) => {
|
|
5417
5562
|
const target = event.target;
|
|
5563
|
+
if (isSensitiveTextTarget(target)) {
|
|
5564
|
+
return;
|
|
5565
|
+
}
|
|
5418
5566
|
let text = '';
|
|
5419
5567
|
if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {
|
|
5420
5568
|
text = target.value;
|
|
@@ -5425,7 +5573,19 @@ function buildRecordingInstallExpression(recordingPayload) {
|
|
|
5425
5573
|
}
|
|
5426
5574
|
pushEvent({ kind: 'type', selector: getSelector(target), text, timestamp: Date.now() });
|
|
5427
5575
|
};
|
|
5576
|
+
const isRecordableKey = (event) => {
|
|
5577
|
+
if (isSensitiveTextTarget(event.target)) {
|
|
5578
|
+
return false;
|
|
5579
|
+
}
|
|
5580
|
+
if (typeof event.key !== 'string' || event.key.length !== 1) {
|
|
5581
|
+
return true;
|
|
5582
|
+
}
|
|
5583
|
+
return event.altKey === true || event.ctrlKey === true || event.metaKey === true;
|
|
5584
|
+
};
|
|
5428
5585
|
const onKeyDown = (event) => {
|
|
5586
|
+
if (!isRecordableKey(event)) {
|
|
5587
|
+
return;
|
|
5588
|
+
}
|
|
5429
5589
|
const modifiers = [];
|
|
5430
5590
|
if (event.altKey) modifiers.push('Alt');
|
|
5431
5591
|
if (event.ctrlKey) modifiers.push('Control');
|
|
@@ -5493,7 +5653,19 @@ async function finalizeRecordingCapture(session) {
|
|
|
5493
5653
|
};
|
|
5494
5654
|
|
|
5495
5655
|
const response = await sendCdpCommand(page, 'Runtime.evaluate', {
|
|
5496
|
-
expression: `(() =>
|
|
5656
|
+
expression: `(() => {
|
|
5657
|
+
const recorder = globalThis.__CCS_BROWSER_RECORDING_RECORDER__;
|
|
5658
|
+
if (!recorder) {
|
|
5659
|
+
return { events: [], warnings: [] };
|
|
5660
|
+
}
|
|
5661
|
+
const events = Array.isArray(recorder.events) ? [...recorder.events] : [];
|
|
5662
|
+
const warnings = Array.isArray(recorder.warnings) ? [...recorder.warnings] : [];
|
|
5663
|
+
if (typeof recorder.teardown === 'function') {
|
|
5664
|
+
recorder.teardown();
|
|
5665
|
+
}
|
|
5666
|
+
delete globalThis.__CCS_BROWSER_RECORDING_RECORDER__;
|
|
5667
|
+
return { events, warnings };
|
|
5668
|
+
})()`,
|
|
5497
5669
|
returnByValue: true,
|
|
5498
5670
|
awaitPromise: true,
|
|
5499
5671
|
});
|
|
@@ -5513,6 +5685,28 @@ async function finalizeRecordingCapture(session) {
|
|
|
5513
5685
|
session.warnings = warnings.map((warning) => String(warning.message || warning));
|
|
5514
5686
|
}
|
|
5515
5687
|
|
|
5688
|
+
async function teardownRecordingCapture(session) {
|
|
5689
|
+
if (!session || !session.pageWebSocketDebuggerUrl) {
|
|
5690
|
+
return;
|
|
5691
|
+
}
|
|
5692
|
+
const page = {
|
|
5693
|
+
id: session.pageId,
|
|
5694
|
+
webSocketDebuggerUrl: session.pageWebSocketDebuggerUrl,
|
|
5695
|
+
};
|
|
5696
|
+
await sendCdpCommand(page, 'Runtime.evaluate', {
|
|
5697
|
+
expression: `(() => {
|
|
5698
|
+
const recorder = globalThis.__CCS_BROWSER_RECORDING_RECORDER__;
|
|
5699
|
+
if (recorder && typeof recorder.teardown === 'function') {
|
|
5700
|
+
recorder.teardown();
|
|
5701
|
+
}
|
|
5702
|
+
delete globalThis.__CCS_BROWSER_RECORDING_RECORDER__;
|
|
5703
|
+
return { installed: false };
|
|
5704
|
+
})()`,
|
|
5705
|
+
returnByValue: true,
|
|
5706
|
+
awaitPromise: true,
|
|
5707
|
+
});
|
|
5708
|
+
}
|
|
5709
|
+
|
|
5516
5710
|
async function handleStartRecording(toolArgs) {
|
|
5517
5711
|
if (activeRecordingSession) {
|
|
5518
5712
|
throw new Error('recording already active');
|
|
@@ -5563,6 +5757,11 @@ async function handleStopRecording() {
|
|
|
5563
5757
|
} catch (error) {
|
|
5564
5758
|
finalizeError = error instanceof Error ? error : new Error(String(error));
|
|
5565
5759
|
session.warnings.push(`recording capture finalization failed: ${finalizeError.message}`);
|
|
5760
|
+
try {
|
|
5761
|
+
await teardownRecordingCapture(session);
|
|
5762
|
+
} catch {
|
|
5763
|
+
// Preserve the original finalization failure for the caller.
|
|
5764
|
+
}
|
|
5566
5765
|
}
|
|
5567
5766
|
session.status = 'stopped';
|
|
5568
5767
|
session.stoppedAt = new Date().toISOString();
|
|
@@ -5583,6 +5782,12 @@ async function handleClearRecording() {
|
|
|
5583
5782
|
if (!latestRecordingSession && !activeRecordingSession) {
|
|
5584
5783
|
throw new Error('no recording available');
|
|
5585
5784
|
}
|
|
5785
|
+
const session = activeRecordingSession || latestRecordingSession;
|
|
5786
|
+
try {
|
|
5787
|
+
await teardownRecordingCapture(session);
|
|
5788
|
+
} catch {
|
|
5789
|
+
// Clearing session-local recording state should still succeed if the page is already gone.
|
|
5790
|
+
}
|
|
5586
5791
|
activeRecordingSession = null;
|
|
5587
5792
|
latestRecordingSession = null;
|
|
5588
5793
|
return 'status: cleared';
|
package/package.json
CHANGED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const { execFileSync } = require('node:child_process');
|
|
6
|
+
|
|
7
|
+
function parseStableVersion(value) {
|
|
8
|
+
const match = String(value || '').match(/^v?([0-9]+)\.([0-9]+)\.([0-9]+)$/);
|
|
9
|
+
if (!match) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
major: Number(match[1]),
|
|
14
|
+
minor: Number(match[2]),
|
|
15
|
+
patch: Number(match[3]),
|
|
16
|
+
raw: `v${Number(match[1])}.${Number(match[2])}.${Number(match[3])}`,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function compareVersions(left, right) {
|
|
21
|
+
for (const key of ['major', 'minor', 'patch']) {
|
|
22
|
+
if (left[key] !== right[key]) {
|
|
23
|
+
return left[key] - right[key];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function stableVersionKey(version) {
|
|
30
|
+
return `${version.major}.${version.minor}.${version.patch}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parseArgs(argv) {
|
|
34
|
+
const args = {};
|
|
35
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
36
|
+
const arg = argv[i];
|
|
37
|
+
if (!arg.startsWith('--')) {
|
|
38
|
+
throw new Error(`Unexpected argument: ${arg}`);
|
|
39
|
+
}
|
|
40
|
+
const key = arg.slice(2);
|
|
41
|
+
if (key === 'tags-stdin') {
|
|
42
|
+
args.tagsStdin = true;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const value = argv[i + 1];
|
|
46
|
+
if (!value || value.startsWith('--')) {
|
|
47
|
+
throw new Error(`Missing value for --${key}`);
|
|
48
|
+
}
|
|
49
|
+
args[key] = value;
|
|
50
|
+
i += 1;
|
|
51
|
+
}
|
|
52
|
+
return args;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function readStableTagsFromGit() {
|
|
56
|
+
const output = execFileSync('git', ['tag', '--list', 'v*'], {
|
|
57
|
+
encoding: 'utf8',
|
|
58
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
59
|
+
});
|
|
60
|
+
return output.split(/\r?\n/).filter(Boolean);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function parseStableTags(tags) {
|
|
64
|
+
const byKey = new Map();
|
|
65
|
+
for (const tag of tags) {
|
|
66
|
+
const version = parseStableVersion(tag.trim());
|
|
67
|
+
if (version) {
|
|
68
|
+
byKey.set(stableVersionKey(version), version);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return Array.from(byKey.values()).sort(compareVersions);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function evaluateDashboardSunset({ targetTag, baselineVersion, releaseWindow, stableTags }) {
|
|
75
|
+
const target = parseStableVersion(targetTag);
|
|
76
|
+
if (!target) {
|
|
77
|
+
throw new Error(`Target tag must be stable semver like v1.2.3, got: ${targetTag}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const baseline = parseStableVersion(baselineVersion);
|
|
81
|
+
if (!baseline) {
|
|
82
|
+
throw new Error(`DEPRECATION_BASELINE_VERSION must be stable semver, got: ${baselineVersion}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!Number.isInteger(releaseWindow) || releaseWindow < 1) {
|
|
86
|
+
throw new Error(`STABLE_RELEASE_WINDOW must be a positive integer, got: ${releaseWindow}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (compareVersions(target, baseline) < 0) {
|
|
90
|
+
return {
|
|
91
|
+
publish: true,
|
|
92
|
+
elapsed: 0,
|
|
93
|
+
reason: `${target.raw} is before dashboard deprecation baseline ${baseline.raw}`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const versions = parseStableTags(stableTags);
|
|
98
|
+
const hasBaseline = versions.some((version) => compareVersions(version, baseline) === 0);
|
|
99
|
+
if (compareVersions(target, baseline) > 0 && !hasBaseline) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
`Cannot count dashboard sunset releases: baseline tag ${baseline.raw} is missing from git tags`,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!versions.some((version) => compareVersions(version, target) === 0)) {
|
|
106
|
+
versions.push(target);
|
|
107
|
+
versions.sort(compareVersions);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const elapsed = versions.filter(
|
|
111
|
+
(version) => compareVersions(version, baseline) > 0 && compareVersions(version, target) <= 0,
|
|
112
|
+
).length;
|
|
113
|
+
const publish = elapsed < releaseWindow;
|
|
114
|
+
const reason = publish
|
|
115
|
+
? `legacy dashboard publish is still inside sunset window (${elapsed}/${releaseWindow} stable releases elapsed since ${baseline.raw})`
|
|
116
|
+
: `legacy dashboard sunset reached (${elapsed}/${releaseWindow} stable releases elapsed since ${baseline.raw})`;
|
|
117
|
+
|
|
118
|
+
return { publish, elapsed, reason };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function appendGithubOutput(values) {
|
|
122
|
+
if (!process.env.GITHUB_OUTPUT) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const lines = Object.entries(values).map(([key, value]) => `${key}=${String(value)}`);
|
|
126
|
+
fs.appendFileSync(process.env.GITHUB_OUTPUT, `${lines.join('\n')}\n`);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function main() {
|
|
130
|
+
const args = parseArgs(process.argv.slice(2));
|
|
131
|
+
const targetTag = args.target || process.env.TARGET_TAG;
|
|
132
|
+
const baselineVersion = args.baseline || process.env.DEPRECATION_BASELINE_VERSION;
|
|
133
|
+
const windowValue = args.window || process.env.STABLE_RELEASE_WINDOW || '2';
|
|
134
|
+
const releaseWindow = Number(windowValue);
|
|
135
|
+
const stableTags = args.tagsStdin
|
|
136
|
+
? fs.readFileSync(0, 'utf8').split(/\r?\n/).filter(Boolean)
|
|
137
|
+
: readStableTagsFromGit();
|
|
138
|
+
|
|
139
|
+
const result = evaluateDashboardSunset({
|
|
140
|
+
targetTag,
|
|
141
|
+
baselineVersion,
|
|
142
|
+
releaseWindow,
|
|
143
|
+
stableTags,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
appendGithubOutput({
|
|
147
|
+
publish: result.publish ? 'true' : 'false',
|
|
148
|
+
elapsed: result.elapsed,
|
|
149
|
+
reason: result.reason,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const status = result.publish ? '[OK]' : '[i]';
|
|
153
|
+
console.log(`${status} ${result.reason}`);
|
|
154
|
+
if (!result.publish) {
|
|
155
|
+
console.log('[i] Skipping ghcr.io/kaitranntt/ccs-dashboard publish; use ghcr.io/kaitranntt/ccs.');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (require.main === module) {
|
|
160
|
+
try {
|
|
161
|
+
main();
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error(`[X] ${error.message}`);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
module.exports = {
|
|
169
|
+
evaluateDashboardSunset,
|
|
170
|
+
parseStableVersion,
|
|
171
|
+
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as e}from"./radix-ui-nu4wz29m.js";import{r as W}from"./react-vendor-Bjx91N7w.js";import{a as q,bf as Ce,B as f,d as P,n as te,C as x,j as p,k as v,_ as j,b as g,I as G,r as ne,s as ie,t as le,v as de,w as re,x as $,Q as we,R as Ve,U as oe,V as ce,c as fe,W as ke}from"./index-CSlgRg0s.js";import{u as J,a as K,b as M}from"./tanstack-bhJxV1h8.js";import{t as C}from"./notifications-B4_o8bcr.js";import{aa as De,a9 as Be,L as Q,au as Ie,at as Te,R as Re,T as ue,ai as Ae,a7 as qe}from"./icons-DzKUh8vG.js";import"./utils-CzKF5WmX.js";import"./form-utils-CuHzLhJZ.js";import"./charts-eIPy2oG6.js";const U=["claude-extension-bindings"];async function w(s,n){const t=await fetch(Ce(s),{headers:{"Content-Type":"application/json"},...n});if(!t.ok){const l=await t.json().catch(()=>null);throw new Error(l?.error||`Request failed (${t.status})`)}return t.status===204?void 0:await t.json()}function Ue(){return J({queryKey:["claude-extension-options"],queryFn:()=>w("/claude-extension/profiles")})}function Fe(s,n="vscode"){return J({queryKey:["claude-extension-setup",s,n],enabled:!!s,queryFn:()=>w(`/claude-extension/setup?profile=${encodeURIComponent(s||"")}&host=${encodeURIComponent(n)}`)})}function Le(){return J({queryKey:U,queryFn:()=>w("/claude-extension/bindings")})}function Oe(s){return J({queryKey:["claude-extension-binding-status",s],enabled:!!s,queryFn:()=>w(`/claude-extension/bindings/${encodeURIComponent(s||"")}/verify`)})}function Qe(){const s=K();return M({mutationFn:n=>w("/claude-extension/bindings",{method:"POST",body:JSON.stringify(n)}),onSuccess:()=>{s.invalidateQueries({queryKey:U}),C.success("Binding created")},onError:n=>C.error(n.message)})}function $e(){const s=K(),{t:n}=q();return M({mutationFn:({id:t,binding:l})=>w(`/claude-extension/bindings/${encodeURIComponent(t)}`,{method:"PUT",body:JSON.stringify(l)}),onSuccess:(t,l)=>{s.invalidateQueries({queryKey:U}),s.invalidateQueries({queryKey:["claude-extension-binding-status",l.id]}),C.success(n("claudeExtensionPage.bindingSaved"))},onError:t=>C.error(t.message)})}function Je(){const s=K(),{t:n}=q();return M({mutationFn:t=>w(`/claude-extension/bindings/${encodeURIComponent(t)}`,{method:"DELETE"}),onSuccess:()=>{s.invalidateQueries({queryKey:U}),C.success(n("claudeExtensionPage.bindingDeleted"))},onError:t=>C.error(t.message)})}function pe(s,n){const t=K();return M({mutationFn:({id:l,target:S})=>w(`/claude-extension/bindings/${encodeURIComponent(l)}/${s}`,{method:"POST",body:JSON.stringify({target:S})}),onSuccess:l=>{t.invalidateQueries({queryKey:U}),t.setQueryData(["claude-extension-binding-status",l.bindingId],l),C.success(n)},onError:l=>C.error(l.message)})}function Ke(){const{t:s}=q();return pe("apply",s("claudeExtensionPage.bindingApplied"))}function Me(){const{t:s}=q();return pe("reset",s("claudeExtensionPage.managedValuesRemoved"))}const He=[];function xe(s){return{name:"",profile:s,host:"vscode",ideSettingsPath:"",notes:""}}function T(s){return{name:s.name,profile:s.profile,host:s.host,ideSettingsPath:s.ideSettingsPath||"",notes:s.notes||""}}function _e(s){return{name:s.name.trim(),profile:s.profile.trim(),host:s.host,ideSettingsPath:s.ideSettingsPath.trim()||void 0,notes:s.notes.trim()||void 0}}function ge(s){return s?.state==="applied"}function ze({state:s}){const n=s==="applied"?"border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300":s==="drifted"?"border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300":s==="missing"?"border-destructive/30 bg-destructive/10 text-destructive":"border-border bg-muted text-muted-foreground";return e.jsx(f,{variant:"outline",className:n,children:s})}function We(s){return s.replace(/[\\/]/g,"$&")}function o({label:s,value:n,mono:t=!1,copyValue:l}){const S=typeof l=="string"&&l.trim().length>0;return e.jsxs("div",{className:"grid gap-2 text-sm sm:grid-cols-[112px_minmax(0,1fr)] sm:items-start",children:[e.jsx("span",{className:"text-muted-foreground",children:s}),S?e.jsxs("div",{className:"flex min-w-0 items-start gap-2",children:[e.jsx("div",{className:"min-w-0 flex-1 rounded-md border bg-muted/25 px-3 py-2",children:e.jsx("span",{className:"block text-left font-mono text-xs leading-5 [overflow-wrap:anywhere]",children:We(n)})}),e.jsx($,{value:l,label:`Copy ${s.toLowerCase()}`,className:"shrink-0"})]}):e.jsx("span",{className:fe("text-left sm:text-right",t&&"font-mono text-xs leading-5 [overflow-wrap:anywhere]"),children:n})]})}function me({title:s,description:n,value:t}){return e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsx(p,{className:"pb-3",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx(v,{className:"text-base",children:s}),e.jsx(j,{className:"mt-1",children:n})]}),e.jsx($,{value:t,label:`Copy ${s}`})]})}),e.jsx(g,{children:e.jsx("pre",{className:"max-h-[360px] overflow-auto rounded-lg border bg-muted/30 p-4 text-xs leading-6",children:t})})]})}function he({title:s,description:n,status:t,applyLabel:l,resetLabel:S,onApply:F,onReset:m,disabled:b,busy:V}){return e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsx(p,{className:"pb-3",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx(v,{className:"text-base",children:s}),e.jsx(j,{className:"mt-1",children:n})]}),t?e.jsx(ze,{state:t.state}):null]})}),e.jsxs(g,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{label:"Path",value:t?.path||"Save a binding first",mono:!0,copyValue:t?.path}),e.jsx(o,{label:"File",value:t?t.exists?"Present":"Not created yet":"Unavailable"})]}),e.jsx("div",{className:"rounded-lg border bg-muted/25 p-3 text-sm text-muted-foreground",children:t?.message||ke.t("claudeExtensionPage.verifyAfterSaving",{defaultValue:"Verify the binding after saving to inspect the current file state."})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(P,{size:"sm",className:"flex-1",onClick:F,disabled:b||V,children:[V?e.jsx(Q,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}):null,l]}),e.jsx(P,{size:"sm",variant:"outline",className:"flex-1",onClick:m,disabled:b||V,children:S})]})]})]})}function Ge({binding:s,isSelected:n,onSelect:t}){return e.jsx("button",{onClick:t,className:fe("w-full rounded-lg border px-3 py-3 text-left transition-colors",n?"border-primary/40 bg-primary/10":"border-border/60 bg-card hover:bg-muted/40"),children:e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-sm font-medium",children:s.name}),e.jsxs("div",{className:"mt-1 text-xs text-muted-foreground",children:[s.profile," · ",s.host]})]}),e.jsx(f,{variant:"outline",className:"shrink-0",children:s.usesDefaultIdeSettingsPath?"Default path":"Custom path"})]})})}function ls(){const{t:s}=q(),n=Ue(),t=Le(),l=Qe(),S=$e(),F=Je(),m=Ke(),b=Me(),V=n.data?.profiles??[],Y=n.data?.hosts??[],E=t.data?.bindings??He,ve=V[0]?.name??"default",[je,D]=W.useState(!1),[L,B]=W.useState(null),[X,k]=W.useState(()=>xe("default")),c=je||E.length===0,N=!c&&E.length>0?E.find(a=>a.id===L)??(L?null:E[0]):null,h=N?.id??null,d=c||!N||L?X:T(N),Z=Fe(d.profile,d.host),R=Oe(c?void 0:h||void 0),r=Y.find(a=>a.id===d.host),H=V.find(a=>a.name===d.profile),_=n.error||t.error||Z.error||R.error,be=`${E.length} saved`,ee=l.isPending||S.isPending,Ne=m.isPending&&m.variables?.target==="shared"||b.isPending&&b.variables?.target==="shared",ye=m.isPending&&m.variables?.target==="ide"||b.isPending&&b.variables?.target==="ide",se=d.name.trim().length>0&&d.profile.trim().length>0,i=Z.data,u=R.data,ae=Math.max((i?.env.length??0)-6,0),Pe=i?.env.slice(0,6)??[];function z(){D(!0),B(null),k(xe(ve))}async function Se(){if(!se)return;const a=_e(d);if(!c&&h){const O=await S.mutateAsync({id:h,binding:a});D(!1),B(O.binding.id),k(T(O.binding));return}const y=await l.mutateAsync(a);D(!1),B(y.binding.id),k(T(y.binding))}async function Ee(){if(!h||!N||!window.confirm(s("claudeExtensionPage.deleteBindingConfirm",{name:N.name,defaultValue:'Delete binding "{{name}}"?'})))return;await F.mutateAsync(h);const a=E.filter(y=>y.id!==h);a.length>0?(B(a[0].id),D(!1),k(T(a[0]))):z()}function A(a,y){if(!c&&N&&!L){B(N.id),k({...T(N),[a]:y}),D(!1);return}k(O=>({...O,[a]:y}))}function I(a,y){if(h){if(y==="apply"){m.mutate({id:h,target:a});return}b.mutate({id:h,target:a})}}return e.jsxs("div",{className:"flex h-full min-h-0 overflow-hidden",children:[e.jsxs("div",{className:"flex w-[348px] shrink-0 flex-col border-r bg-muted/30 xl:w-[372px]",children:[e.jsx("div",{className:"border-b bg-background p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"rounded-lg border bg-muted/40 p-2",children:e.jsx(De,{className:"h-5 w-5 text-primary"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"font-semibold",children:s("claudeExtensionPage.title")}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s("claudeExtensionPage.savedBindingsSubtitle",{defaultValue:"Saved IDE bindings for CCS profiles"})})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(f,{variant:"secondary",children:be}),r?e.jsx(f,{variant:"outline",children:r.label}):null]})]}),e.jsxs(P,{size:"sm",onClick:z,className:"gap-1.5",children:[e.jsx(Be,{className:"h-3.5 w-3.5"}),s("claudeExtensionPage.new",{defaultValue:"New"})]})]})}),e.jsx(te,{className:"flex-1",children:e.jsxs("div",{className:"space-y-4 p-5",children:[e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsxs(p,{children:[e.jsx(v,{className:"text-base",children:c?s("claudeExtensionPage.createBinding",{defaultValue:"Create binding"}):s("claudeExtensionPage.bindingEditor",{defaultValue:"Binding editor"})}),e.jsx(j,{children:s("claudeExtensionPage.bindingEditorDescription",{defaultValue:"Save a profile + IDE path once, then apply or reset it from the dashboard."})})]}),e.jsxs(g,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:s("settingsPage.thinkingSection.bindingName")}),e.jsx(G,{value:d.name,onChange:a=>A("name",a.target.value),placeholder:s("claudeExtensionPage.bindingNamePlaceholder",{defaultValue:"VS Code · work profile"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:s("claudeExtensionPage.ccsProfile",{defaultValue:"CCS profile"})}),e.jsxs(ne,{value:d.profile,onValueChange:a=>A("profile",a),children:[e.jsx(ie,{children:e.jsx(le,{placeholder:s("claudeExtensionPage.selectProfile",{defaultValue:"Select a profile"})})}),e.jsx(de,{children:V.map(a=>e.jsxs(re,{value:a.name,children:[a.label," (",a.profileType,")"]},a.name))})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:H?.description||s("claudeExtensionPage.chooseProfileHint",{defaultValue:"Choose which CCS profile the IDE should inherit."})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:s("settingsPage.thinkingSection.ideHost")}),e.jsxs(ne,{value:d.host,onValueChange:a=>A("host",a),children:[e.jsx(ie,{children:e.jsx(le,{placeholder:s("claudeExtensionPage.selectHost",{defaultValue:"Select a host"})})}),e.jsx(de,{children:Y.map(a=>e.jsx(re,{value:a.id,children:a.label},a.id))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:s("settingsPage.thinkingSection.ideSettingsPath")}),e.jsx(G,{value:d.ideSettingsPath,onChange:a=>A("ideSettingsPath",a.target.value),placeholder:r?.defaultSettingsPath||s("claudeExtensionPage.ideSettingsPathPlaceholder",{defaultValue:"Leave blank for the default user settings path"})}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[s("claudeExtensionPage.ideSettingsPathHint",{defaultValue:"Leave blank to use the default user settings path for"})," ",r?.label||"this IDE","."]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:s("settingsPage.thinkingSection.notes")}),e.jsx(G,{value:d.notes,onChange:a=>A("notes",a.target.value),placeholder:s("claudeExtensionPage.notesPlaceholder",{defaultValue:"Optional reminder for this machine or workspace"})})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(P,{className:"flex-1 gap-1.5",onClick:()=>void Se(),disabled:!se||ee,children:[ee?e.jsx(Q,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(Ie,{className:"h-3.5 w-3.5"}),c?s("claudeExtensionPage.create",{defaultValue:"Create"}):s("claudeExtensionPage.save",{defaultValue:"Save"})]}),e.jsx(P,{variant:"outline",onClick:z,children:s("claudeExtensionPage.resetForm",{defaultValue:"Reset form"})})]}),c?null:e.jsxs(P,{variant:"outline",className:"w-full gap-1.5 text-destructive hover:text-destructive",onClick:()=>void Ee(),disabled:F.isPending,children:[e.jsx(Te,{className:"h-3.5 w-3.5"}),s("claudeExtensionPage.deleteBinding",{defaultValue:"Delete binding"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"px-1 text-xs font-medium uppercase tracking-wide text-muted-foreground",children:s("claudeExtensionPage.savedBindings",{defaultValue:"Saved bindings"})}),e.jsx("div",{className:"space-y-2",children:E.length>0?E.map(a=>e.jsx(Ge,{binding:a,isSelected:a.id===h&&!c,onSelect:()=>{D(!1),B(a.id),k(T(a))}},a.id)):e.jsx(x,{className:"border-dashed border-border/60 bg-card/60",children:e.jsx(g,{className:"pt-6 text-sm text-muted-foreground",children:s("claudeExtensionPage.emptyBindings",{defaultValue:"No saved bindings yet. Create one to manage apply, reset, and drift checks from the dashboard."})})})})]})]})})]}),e.jsx("div",{className:"min-w-0 flex-1",children:e.jsx(te,{className:"h-full",children:e.jsxs("div",{className:"w-full space-y-6 p-6 xl:p-7 2xl:p-8",children:[e.jsxs("div",{className:"flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[H?e.jsx(f,{variant:"outline",children:H.label}):null,r?e.jsx(f,{variant:"outline",children:r.label}):null,c?e.jsx(f,{variant:"secondary",children:s("settingsPage.thinkingSection.draft")}):null,u?.sharedSettings&&ge(u.sharedSettings)&&ge(u.ideSettings)?e.jsx(f,{className:"bg-emerald-600 hover:bg-emerald-600",children:s("settingsPage.thinkingSection.inSync")}):null]}),e.jsxs("div",{className:"max-w-5xl",children:[e.jsx("h2",{className:"text-2xl font-semibold tracking-tight",children:N?.name||s("claudeExtensionPage.defaultBindingName",{defaultValue:"Claude extension binding"})}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:s("claudeExtensionPage.bindingDescription",{defaultValue:"Manage the shared Claude settings file and the IDE-local settings file as two scoped targets."})})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(P,{variant:"outline",onClick:()=>void R.refetch(),disabled:c||R.isFetching,children:[R.isFetching?e.jsx(Q,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}):e.jsx(Re,{className:"mr-1.5 h-3.5 w-3.5"}),s("claudeExtensionPage.verify",{defaultValue:"Verify"})]}),i?e.jsx($,{value:i.sharedSettings.command,label:"Copy persist command"}):null]})]}),_?e.jsx(x,{className:"border-destructive/40 bg-destructive/5",children:e.jsxs(g,{className:"flex items-start gap-3 pt-6 text-sm text-destructive",children:[e.jsx(ue,{className:"mt-0.5 h-4 w-4 shrink-0"}),e.jsx("div",{children:_.message})]})}):null,_?null:e.jsxs(we,{defaultValue:"overview",className:"flex flex-col gap-6",children:[e.jsxs(Ve,{className:"w-full justify-start",children:[e.jsx(oe,{value:"overview",children:s("claudeExtensionPage.overview",{defaultValue:"Overview"})})," ",e.jsx(oe,{value:"advanced",children:s("settingsPage.thinkingSection.advanced")})]}),e.jsxs(ce,{value:"overview",className:"mt-0 space-y-6",children:[e.jsxs("div",{className:"grid gap-6 xl:grid-cols-2",children:[e.jsx(he,{title:s("claudeExtensionPage.sharedClaudeSettings",{defaultValue:"Shared Claude settings"}),description:s("claudeExtensionPage.sharedClaudeSettingsDescription",{defaultValue:"Writes the managed env block inside ~/.claude/settings.json so CLI and IDE behavior stay aligned."}),status:u?.sharedSettings,applyLabel:s("claudeExtensionPage.applyShared",{defaultValue:"Apply shared"}),resetLabel:s("claudeExtensionPage.resetShared",{defaultValue:"Reset shared"}),onApply:()=>I("shared","apply"),onReset:()=>I("shared","reset"),disabled:c,busy:Ne}),e.jsx(he,{title:`${r?.label||"IDE"} settings.json`,description:"Writes only the Anthropic extension keys so unrelated editor preferences stay untouched.",status:u?.ideSettings,applyLabel:s("claudeExtensionPage.applyIde",{defaultValue:"Apply IDE"}),resetLabel:s("claudeExtensionPage.resetIde",{defaultValue:"Reset IDE"}),onApply:()=>I("ide","apply"),onReset:()=>I("ide","reset"),disabled:c,busy:ye})]}),e.jsxs("div",{className:"grid gap-6 xl:grid-cols-[minmax(0,1.15fr)_minmax(320px,0.85fr)]",children:[e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsxs(p,{children:[e.jsx(v,{className:"text-base",children:s("settingsPage.thinkingSection.resolvedBinding")}),e.jsx(j,{children:s("claudeExtensionPage.resolvedBindingDescription",{defaultValue:"The binding uses the same profile resolution as `ccs persist` and `ccs env`."})})]}),e.jsxs(g,{className:"space-y-3",children:[e.jsx(o,{label:s("claudeExtensionPage.profile",{defaultValue:"Profile"}),value:i?.profile.label||d.profile||"Not selected"}),e.jsx(o,{label:s("claudeExtensionPage.profileType",{defaultValue:"Profile type"}),value:i?.profile.profileType||"Unknown"}),e.jsx(o,{label:"IDE host",value:r?.label||"Not selected"}),e.jsx(o,{label:s("claudeExtensionPage.idePathMode",{defaultValue:"IDE path mode"}),value:d.ideSettingsPath.trim()?s("claudeExtensionPage.customPath",{defaultValue:"Custom path"}):s("claudeExtensionPage.defaultUserPath",{defaultValue:"Default user path"})}),e.jsx(o,{label:s("claudeExtensionPage.effectiveIdePath",{defaultValue:"Effective IDE path"}),value:u?.ideSettings.path||d.ideSettingsPath.trim()||r?.defaultSettingsPath||"Unavailable",mono:!0,copyValue:u?.ideSettings.path||d.ideSettingsPath.trim()||r?.defaultSettingsPath}),e.jsx(o,{label:s("claudeExtensionPage.persistCommand",{defaultValue:"Persist command"}),value:i?.sharedSettings.command||s("claudeExtensionPage.saveValidBindingFirst",{defaultValue:"Save a valid binding first"}),mono:!0}),d.notes.trim()?e.jsx(o,{label:s("settingsPage.thinkingSection.notes"),value:d.notes.trim()}):null]})]}),e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsxs(p,{children:[e.jsx(v,{className:"text-base",children:s("settingsPage.thinkingSection.managedPayload")}),e.jsx(j,{children:s("claudeExtensionPage.managedPayloadDescription",{defaultValue:"Keep the main view short. The full JSON stays in the Advanced tab."})})]}),e.jsxs(g,{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap gap-2",children:[Pe.map(a=>e.jsx(f,{variant:"secondary",className:"font-mono text-[10px]",children:a.name},a.name)),ae>0?e.jsxs(f,{variant:"outline",children:["+",ae," more"]}):null]}),e.jsx("div",{className:"rounded-lg border bg-muted/25 p-4 text-sm",children:i?.env.length?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"font-medium",children:s("claudeExtensionPage.envInjected",{count:i.env.length,defaultValue:"CCS will inject {{count}} environment values."})}),e.jsx("div",{className:"text-muted-foreground",children:s("claudeExtensionPage.envInjectedDescription",{defaultValue:"The IDE-local target receives the extension schema. The shared target receives the same env block through Claude settings."})})]}):e.jsx("div",{className:"text-muted-foreground",children:s("claudeExtensionPage.nativeDefaultsDescription",{defaultValue:"This profile resolves to native Claude defaults, so apply/reset mainly clears existing CCS-managed overrides."})})}),c?e.jsx("div",{className:"rounded-lg border border-dashed bg-muted/15 p-4 text-sm text-muted-foreground",children:s("claudeExtensionPage.saveDraftToUnlock",{defaultValue:"Save this draft to unlock apply, reset, and verify actions."})}):e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(P,{className:"flex-1",onClick:()=>I("all","apply"),disabled:m.isPending,children:[m.isPending&&m.variables?.target==="all"?e.jsx(Q,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}):null,s("claudeExtensionPage.applyBothTargets",{defaultValue:"Apply both targets"})]}),e.jsx(P,{variant:"outline",className:"flex-1",onClick:()=>I("all","reset"),disabled:b.isPending,children:s("claudeExtensionPage.resetBothTargets",{defaultValue:"Reset both targets"})})]})]})]})]}),i&&(i.warnings.length>0||i.notes.length>0)?e.jsxs("div",{className:"grid gap-6 xl:grid-cols-2",children:[e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsxs(p,{children:[e.jsx(v,{className:"text-base",children:s("settingsPage.thinkingSection.warnings")}),e.jsx(j,{children:"Operational details that can break the binding even when JSON is correct."})]}),e.jsx(g,{className:"space-y-3",children:i.warnings.length>0?i.warnings.map(a=>e.jsxs("div",{className:"flex items-start gap-3 rounded-lg border border-amber-400/40 bg-amber-50/60 p-3 text-sm dark:bg-amber-950/10",children:[e.jsx(ue,{className:"mt-0.5 h-4 w-4 shrink-0 text-amber-600"}),e.jsx("span",{children:a})]},a)):e.jsx("div",{className:"rounded-lg border bg-muted/20 p-3 text-sm text-muted-foreground",children:"No runtime warnings for this binding."})})]}),e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsxs(p,{children:[e.jsx(v,{className:"text-base",children:s("settingsPage.thinkingSection.notes")}),e.jsx(j,{children:"Short context from CCS about account continuity and host-specific behavior."})]}),e.jsx(g,{className:"space-y-3",children:i.notes.length>0?i.notes.map(a=>e.jsxs("div",{className:"flex items-start gap-3 rounded-lg border bg-muted/30 p-3 text-sm",children:[e.jsx(Ae,{className:"mt-0.5 h-4 w-4 shrink-0 text-muted-foreground"}),e.jsx("span",{children:a})]},a)):e.jsx("div",{className:"rounded-lg border bg-muted/20 p-3 text-sm text-muted-foreground",children:"No extra notes for this binding."})})]})]}):null]}),e.jsx(ce,{value:"advanced",className:"mt-0 space-y-6",children:i?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-6 xl:grid-cols-2",children:[e.jsx(me,{title:s("claudeExtensionPage.sharedSettingsJson",{defaultValue:"Shared Claude settings JSON"}),description:s("claudeExtensionPage.sharedSettingsJsonDescription",{defaultValue:"Managed env block for ~/.claude/settings.json."}),value:i.sharedSettings.json}),e.jsx(me,{title:`${r?.label||"IDE"} settings JSON`,description:s("claudeExtensionPage.ideSettingsJsonDescription",{label:r?.settingsTargetLabel||"settings.json",defaultValue:"Anthropic extension snippet for {{label}}."}),value:i.ideSettings.json})]}),e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsx(p,{children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx(v,{className:"text-base",children:s("claudeExtensionPage.resolvedEnvironmentPayload",{defaultValue:"Resolved environment payload"})}),e.jsx(j,{children:s("claudeExtensionPage.resolvedEnvironmentPayloadDescription",{defaultValue:"Exact environment values that the extension receives after CCS expands this profile."})})]}),e.jsx($,{value:JSON.stringify(i.env,null,2),label:s("claudeExtensionPage.copyEnvironmentPayload",{defaultValue:"Copy environment payload"})})]})}),e.jsx(g,{children:i.env.length>0?e.jsx("pre",{className:"max-h-[420px] overflow-auto rounded-lg border bg-muted/30 p-4 text-xs leading-6",children:JSON.stringify(i.env,null,2)}):e.jsx("div",{className:"rounded-lg border bg-muted/20 p-4 text-sm text-muted-foreground",children:"No env payload. This binding resolves to native Claude defaults."})})]}),e.jsxs("div",{className:"grid gap-6 xl:grid-cols-2",children:[e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsxs(p,{children:[e.jsx(v,{className:"text-base",children:"Shared target metadata"}),e.jsx(j,{children:"Useful when debugging drift or comparing with manual edits."})]}),e.jsxs(g,{className:"space-y-3",children:[e.jsx(o,{label:"Target path",value:u?.sharedSettings.path||i.sharedSettings.path,mono:!0,copyValue:u?.sharedSettings.path||i.sharedSettings.path}),e.jsx(o,{label:"Command",value:i.sharedSettings.command,mono:!0}),e.jsx(o,{label:"Current state",value:u?.sharedSettings.state||"Not verified"})]})]}),e.jsxs(x,{className:"border-border/60 bg-card/80",children:[e.jsxs(p,{children:[e.jsx(v,{className:"text-base",children:"IDE target metadata"}),e.jsx(j,{children:"Current file path plus the extension setting key used for this host."})]}),e.jsxs(g,{className:"space-y-3",children:[e.jsx(o,{label:"Target path",value:u?.ideSettings.path||d.ideSettingsPath.trim()||r?.defaultSettingsPath||i.ideSettings.path,mono:!0,copyValue:u?.ideSettings.path||d.ideSettingsPath.trim()||r?.defaultSettingsPath||i.ideSettings.path}),e.jsx(o,{label:"Settings key",value:r?.settingsKey||"Unknown",mono:!0}),e.jsx(o,{label:"Current state",value:u?.ideSettings.state||"Not verified"})]})]})]})]}):e.jsx(x,{className:"border-border/60 bg-card/80",children:e.jsxs(g,{className:"flex min-h-[240px] items-center justify-center gap-3 text-sm text-muted-foreground",children:[e.jsx(qe,{className:"h-5 w-5"}),"Choose a profile and IDE host to preview the generated payload."]})})})]})]})})})]})}export{ls as ClaudeExtensionPage};
|