cortico 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/package.json +1 -1
- package/src/boot.ts +29 -0
- package/src/bot.ts +40 -5
- package/src/core/README.md +12 -2
- package/src/core/blobs.ts +23 -2
- package/src/core/config-schema.ts +1 -1
- package/src/core/config.ts +2 -16
- package/src/core/core.ts +18 -6
- package/src/core/generation.ts +66 -9
- package/src/core/instance-lock.ts +6 -0
- package/src/core/loop.ts +62 -32
- package/src/core/secrets.ts +2 -4
- package/src/core/session.ts +3 -2
- package/src/core/timers.ts +8 -6
- package/src/core/types.ts +23 -4
- package/src/core/util.ts +15 -0
- package/src/deploy.ts +5 -4
- package/src/extensions/README.md +6 -4
- package/src/extensions/dry-mount.ts +34 -6
- package/src/extensions/manifest.ts +21 -11
- package/src/extensions.ts +147 -23
- package/src/launcher.ts +30 -22
- package/src/protocol/open-responses/context-helpers.ts +3 -1
- package/src/protocol/open-responses/context-log.ts +37 -9
- package/src/providers/README.md +44 -12
- package/src/providers/base.ts +2 -0
- package/src/providers/console/config.ts +36 -0
- package/src/providers/console/hub.ts +307 -0
- package/src/providers/console/settings.ts +30 -26
- package/src/providers/console/strings.ts +14 -0
- package/src/providers/console/types.ts +5 -0
- package/src/providers/hub-api.ts +3 -0
- package/src/providers/llamacpp/config.ts +38 -0
- package/src/providers/llamacpp/console/models-panel.ts +87 -4
- package/src/providers/llamacpp/console/runtime-panel.ts +36 -73
- package/src/providers/llamacpp/console/server.ts +47 -4
- package/src/providers/llamacpp/huggingface.ts +93 -0
- package/src/providers/llamacpp/index.ts +5 -1
- package/src/providers/llamacpp/native.ts +10 -5
- package/src/providers/llamacpp/options.ts +2 -0
- package/src/providers/llamacpp/strings.ts +42 -0
- package/src/providers/name.ts +13 -0
- package/src/providers/openai-responses-compat/config.ts +33 -0
- package/src/providers/openai-responses-compat/console/client.ts +5 -0
- package/src/providers/openai-responses-compat/console/reasoning-panel.ts +84 -0
- package/src/providers/openai-responses-compat/console/server.ts +135 -0
- package/src/providers/openai-responses-compat/index.ts +40 -12
- package/src/providers/openai-responses-compat/native.ts +15 -5
- package/src/providers/openai-responses-compat/strings.ts +62 -1
- package/src/providers/pricebook.ts +5 -5
- package/src/providers/registry.ts +24 -10
- package/src/providers/strings.ts +2 -0
- package/src/providers/transport/errors.ts +9 -0
- package/src/providers/transport/response-http.ts +7 -3
- package/src/providers/transport/responses-input.ts +59 -10
- package/src/web/README.md +15 -3
- package/src/web/auth.ts +80 -0
- package/src/web/client/console-pages/builtins/llm-settings/panel.ts +42 -35
- package/src/web/client/console-pages/builtins/llm-settings/pricing-panel.ts +22 -8
- package/src/web/client/console-pages/builtins/llm-settings/strings.ts +2 -4
- package/src/web/client/console-pages/host.ts +22 -5
- package/src/web/client/core/api.ts +5 -1
- package/src/web/client/core/router.ts +15 -0
- package/src/web/client/features/extensions/index.ts +276 -41
- package/src/web/client/features/extensions/strings.ts +84 -10
- package/src/web/client/features/feature.ts +1 -1
- package/src/web/client/features/live/diagnostics.ts +32 -0
- package/src/web/client/features/live/index.ts +27 -11
- package/src/web/client/features/live/protocol.ts +1 -0
- package/src/web/client/features/live/strings.ts +9 -3
- package/src/web/client/features/providers/detail.ts +309 -0
- package/src/web/client/features/providers/drafts.ts +23 -0
- package/src/web/client/features/providers/index.ts +179 -87
- package/src/web/client/features/providers/strings.ts +48 -17
- package/src/web/client/features/providers/types.ts +15 -0
- package/src/web/client/features/settings/general.ts +12 -0
- package/src/web/client/features/settings/strings.ts +6 -0
- package/src/web/client/main.ts +4 -0
- package/src/web/client/shell/index.ts +1 -1
- package/src/web/client/ui/fields.ts +3 -1
- package/src/web/client/ui/icons.ts +9 -1
- package/src/web/client/ui/prompt-input.tsx +17 -5
- package/src/web/client/ui/strings.ts +0 -2
- package/src/web/diagnostics.ts +133 -0
- package/src/web/public/login.html +67 -0
- package/src/web/public/styles.css +130 -18
- package/src/web/server.ts +229 -21
- package/src/web/shared/client-panel.ts +3 -0
- package/src/web/shared/console-protocol.ts +16 -1
- package/src/worlds/bilibili/README.md +1 -1
- package/src/worlds/bilibili/overlay/server.ts +4 -2
- package/src/worlds/minecraft/ADAPT.md +66 -0
- package/src/worlds/minecraft/README.md +8 -0
- package/src/worlds/minecraft/client-launch.ts +11 -2
- package/src/worlds/minecraft/client.ts +4 -0
- package/src/worlds/minecraft/mineflayer-fixes.ts +55 -1
- package/src/worlds/qq/normalize.ts +14 -0
- package/src/worlds/qq/world.ts +56 -10
- package/src/worlds/terminal/world.ts +3 -4
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 诊断包:一次导出把排查一场跑要看的记录收进一个 JSON —— 运行指纹、状态快照、常驻 session
|
|
3
|
+
* 的上下文、事件、运行日志、工具调用、交接边界、用量与脱敏配置。
|
|
4
|
+
*
|
|
5
|
+
* 每段各有条数上限,取到上限的段名列在 `truncated` 里;配置里键名含 secret / token / key /
|
|
6
|
+
* password 的值在写出前抹掉。缺席的接缝(未挂载调试通道、未挂载用量)那一段为空。
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { dirname, join } from 'node:path';
|
|
10
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
11
|
+
import type { ContextRecord } from '../protocol/open-responses/context.ts';
|
|
12
|
+
import type { EventEnvelope, LogRecord } from '../core/types.ts';
|
|
13
|
+
import type { SessionStats } from '../core/sessions.ts';
|
|
14
|
+
import { redactSecrets } from '../core/util.ts';
|
|
15
|
+
import { logPredicate, readRunsIndex, readTailRecordsWhere, type RunIndexRow } from './files.ts';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 每段取最近多少条,与 `/api/log` 的缺省条数一致。事件段非它不可:`store.range` 不给 limit
|
|
19
|
+
* 会把事件库整份读出来。取到这个数的段名进 `truncated`,拿到包的人据此知道还有更早的记录。
|
|
20
|
+
*/
|
|
21
|
+
export const DIAGNOSTICS_TAIL = 200;
|
|
22
|
+
|
|
23
|
+
export interface DiagnosticsToolSchema {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
parameters: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** 活数据由 WebApp 现取交进来;落盘记录由本模块按 `dataDir` 与 `runId` 自己读。 */
|
|
30
|
+
export interface DiagnosticsSources {
|
|
31
|
+
dataDir: string;
|
|
32
|
+
runId: string | null;
|
|
33
|
+
exportedAt: Date;
|
|
34
|
+
status: Record<string, unknown>;
|
|
35
|
+
/** 常驻 session 的上下文与合成开头;没挂调试通道时为 null。 */
|
|
36
|
+
session: { messages: readonly ContextRecord[]; head: readonly ContextRecord[] } | null;
|
|
37
|
+
sessions: readonly SessionStats[];
|
|
38
|
+
toolSchemas: readonly DiagnosticsToolSchema[];
|
|
39
|
+
events: readonly EventEnvelope[];
|
|
40
|
+
latestCursor: number | null;
|
|
41
|
+
worlds: readonly unknown[];
|
|
42
|
+
/** `/api/usage` 那份聚合;没挂用量时为 null。 */
|
|
43
|
+
usage: unknown;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface DiagnosticsBundle {
|
|
47
|
+
kind: 'cortico-diagnostics';
|
|
48
|
+
version: 1;
|
|
49
|
+
exportedAt: string;
|
|
50
|
+
run: { id: string | null; index: RunIndexRow | null; manifest: unknown };
|
|
51
|
+
status: Record<string, unknown>;
|
|
52
|
+
worlds: readonly unknown[];
|
|
53
|
+
session: { messages: readonly ContextRecord[]; head: readonly ContextRecord[] } | null;
|
|
54
|
+
sessions: readonly SessionStats[];
|
|
55
|
+
toolSchemas: readonly DiagnosticsToolSchema[];
|
|
56
|
+
events: { latestCursor: number | null; items: readonly EventEnvelope[] };
|
|
57
|
+
/** `warn` 是 warn 及以上,`tail` 不论级别取最近几条。 */
|
|
58
|
+
log: { warn: LogRecord[]; tail: LogRecord[] };
|
|
59
|
+
toolcalls: unknown[];
|
|
60
|
+
/** transcript 里的 handoff / clear / prefix-reload 记号。 */
|
|
61
|
+
transcriptBoundaries: unknown[];
|
|
62
|
+
usage: { aggregate: unknown; rows: unknown[] };
|
|
63
|
+
config: unknown;
|
|
64
|
+
truncated: string[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function readJson(file: string): unknown {
|
|
68
|
+
return existsSync(file) ? (JSON.parse(readFileSync(file, 'utf8')) as unknown) : null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function buildDiagnostics(sources: DiagnosticsSources): DiagnosticsBundle {
|
|
72
|
+
const { dataDir, runId } = sources;
|
|
73
|
+
const runDir = runId ? join(dataDir, 'runs', runId) : null;
|
|
74
|
+
const warn = runDir
|
|
75
|
+
? readTailRecordsWhere<LogRecord>(join(runDir, 'log.jsonl'), DIAGNOSTICS_TAIL, logPredicate({ level: 'warn' }))
|
|
76
|
+
: [];
|
|
77
|
+
const tail = runDir
|
|
78
|
+
? readTailRecordsWhere<LogRecord>(join(runDir, 'log.jsonl'), DIAGNOSTICS_TAIL, () => true)
|
|
79
|
+
: [];
|
|
80
|
+
const toolcalls = runDir
|
|
81
|
+
? readTailRecordsWhere<unknown>(join(runDir, 'toolcalls.jsonl'), DIAGNOSTICS_TAIL, () => true)
|
|
82
|
+
: [];
|
|
83
|
+
const boundaries = runDir
|
|
84
|
+
? readTailRecordsWhere<{ kind?: string }>(
|
|
85
|
+
join(runDir, 'transcript.jsonl'),
|
|
86
|
+
DIAGNOSTICS_TAIL,
|
|
87
|
+
(r) => r?.kind === 'boundary',
|
|
88
|
+
)
|
|
89
|
+
: [];
|
|
90
|
+
const usageRows = runId
|
|
91
|
+
? readTailRecordsWhere<{ run?: string }>(
|
|
92
|
+
join(dataDir, 'usage.jsonl'),
|
|
93
|
+
DIAGNOSTICS_TAIL,
|
|
94
|
+
(r) => r?.run === runId,
|
|
95
|
+
)
|
|
96
|
+
: [];
|
|
97
|
+
const events = sources.events.slice(-DIAGNOSTICS_TAIL);
|
|
98
|
+
|
|
99
|
+
const truncated: string[] = [];
|
|
100
|
+
for (const [name, rows] of [
|
|
101
|
+
['events', events],
|
|
102
|
+
['log.warn', warn],
|
|
103
|
+
['log.tail', tail],
|
|
104
|
+
['toolcalls', toolcalls],
|
|
105
|
+
['transcriptBoundaries', boundaries],
|
|
106
|
+
['usage.rows', usageRows],
|
|
107
|
+
] as const) {
|
|
108
|
+
if (rows.length >= DIAGNOSTICS_TAIL) truncated.push(name);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const index = runId
|
|
112
|
+
? readRunsIndex(join(dataDir, 'runs', 'index.jsonl')).find((row) => row.run === runId) ?? null
|
|
113
|
+
: null;
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
kind: 'cortico-diagnostics',
|
|
117
|
+
version: 1,
|
|
118
|
+
exportedAt: sources.exportedAt.toISOString(),
|
|
119
|
+
run: { id: runId, index, manifest: runDir ? readJson(join(runDir, 'run.json')) : null },
|
|
120
|
+
status: sources.status,
|
|
121
|
+
worlds: sources.worlds,
|
|
122
|
+
session: sources.session,
|
|
123
|
+
sessions: sources.sessions,
|
|
124
|
+
toolSchemas: sources.toolSchemas,
|
|
125
|
+
events: { latestCursor: sources.latestCursor, items: events },
|
|
126
|
+
log: { warn, tail },
|
|
127
|
+
toolcalls,
|
|
128
|
+
transcriptBoundaries: boundaries,
|
|
129
|
+
usage: { aggregate: sources.usage, rows: usageRows },
|
|
130
|
+
config: redactSecrets(readJson(join(dirname(dataDir), 'config.json'))),
|
|
131
|
+
truncated,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>登录 · Cortico</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root { color-scheme: light dark; --bg: #f4f5f4; --card: #fff; --ink: #1d2321; --dim: #66706c; --line: #d5dad7; --accent: #2f7d62; --bad: #b3261e; }
|
|
9
|
+
@media (prefers-color-scheme: dark) {
|
|
10
|
+
:root { --bg: #141716; --card: #1d2120; --ink: #e6ebe8; --dim: #98a39e; --line: #333a37; --accent: #5fc29f; --bad: #f2867f; }
|
|
11
|
+
}
|
|
12
|
+
* { box-sizing: border-box; }
|
|
13
|
+
body { margin: 0; min-height: 100vh; display: grid; place-items: center; background: var(--bg); color: var(--ink); font: 15px/1.5 system-ui, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; }
|
|
14
|
+
form { width: min(360px, calc(100vw - 32px)); padding: 28px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; }
|
|
15
|
+
h1 { margin: 0 0 4px; font-size: 18px; font-weight: 600; }
|
|
16
|
+
p { margin: 0 0 20px; color: var(--dim); font-size: 13px; }
|
|
17
|
+
label { display: block; margin-bottom: 6px; font-size: 13px; color: var(--dim); }
|
|
18
|
+
input { width: 100%; padding: 9px 11px; font: inherit; color: inherit; background: var(--bg); border: 1px solid var(--line); border-radius: 8px; }
|
|
19
|
+
input:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
20
|
+
button { width: 100%; margin-top: 16px; padding: 9px 11px; font: inherit; font-weight: 600; color: var(--card); background: var(--accent); border: 0; border-radius: 8px; cursor: pointer; }
|
|
21
|
+
button:disabled { opacity: .6; cursor: default; }
|
|
22
|
+
#error { min-height: 20px; margin: 12px 0 0; color: var(--bad); font-size: 13px; }
|
|
23
|
+
</style>
|
|
24
|
+
</head>
|
|
25
|
+
<body>
|
|
26
|
+
<form id="login" autocomplete="on">
|
|
27
|
+
<h1 data-t="title"></h1>
|
|
28
|
+
<p data-t="hint"></p>
|
|
29
|
+
<label for="password" data-t="label"></label>
|
|
30
|
+
<input id="password" name="password" type="password" autocomplete="current-password" required autofocus>
|
|
31
|
+
<button type="submit" data-t="submit"></button>
|
|
32
|
+
<div id="error" role="alert"></div>
|
|
33
|
+
</form>
|
|
34
|
+
<script>
|
|
35
|
+
(() => {
|
|
36
|
+
const en = document.documentElement.lang === 'en';
|
|
37
|
+
const T = en
|
|
38
|
+
? { title: 'Cortico console', hint: 'This console is protected by an access password.', label: 'Password', submit: 'Sign in', wrong: 'Wrong password.', failed: 'Sign-in failed: ' }
|
|
39
|
+
: { title: 'Cortico 控制台', hint: '这个控制台设置了访问密码。', label: '密码', submit: '登录', wrong: '密码不对。', failed: '登录失败:' };
|
|
40
|
+
document.title = (en ? 'Sign in' : '登录') + ' · Cortico';
|
|
41
|
+
for (const el of document.querySelectorAll('[data-t]')) el.textContent = T[el.dataset.t];
|
|
42
|
+
const form = document.getElementById('login');
|
|
43
|
+
const input = document.getElementById('password');
|
|
44
|
+
const button = form.querySelector('button');
|
|
45
|
+
const error = document.getElementById('error');
|
|
46
|
+
form.addEventListener('submit', async (event) => {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
button.disabled = true;
|
|
49
|
+
error.textContent = '';
|
|
50
|
+
try {
|
|
51
|
+
const res = await fetch('/api/auth/login', {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: { 'Content-Type': 'application/json' },
|
|
54
|
+
body: JSON.stringify({ password: input.value }),
|
|
55
|
+
});
|
|
56
|
+
if (res.ok) { location.reload(); return; }
|
|
57
|
+
error.textContent = res.status === 401 ? T.wrong : T.failed + 'HTTP ' + res.status;
|
|
58
|
+
} catch (err) {
|
|
59
|
+
error.textContent = T.failed + String(err);
|
|
60
|
+
}
|
|
61
|
+
button.disabled = false;
|
|
62
|
+
input.select();
|
|
63
|
+
});
|
|
64
|
+
})();
|
|
65
|
+
</script>
|
|
66
|
+
</body>
|
|
67
|
+
</html>
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
--shadow-soft: color-mix(in srgb, var(--ink) 7%, transparent);
|
|
55
55
|
--shadow-strong: color-mix(in srgb, var(--ink) 20%, transparent);
|
|
56
56
|
--overlay: color-mix(in srgb, var(--ink) 44%, transparent);
|
|
57
|
-
--sans: -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", "Noto Sans SC", sans-serif;
|
|
58
|
-
--mono: ui-monospace, "Cascadia Mono", "Sarasa Mono SC", Consolas,
|
|
57
|
+
--sans: -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", "Noto Sans CJK SC", sans-serif;
|
|
58
|
+
--mono: ui-monospace, "Cascadia Mono", "Sarasa Mono SC", Consolas, monospace;
|
|
59
59
|
--background: var(--paper);
|
|
60
60
|
--surface: var(--sheet);
|
|
61
61
|
--surface-hover: var(--sheet-2);
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
.pagedesc { font-size: 13px; color: var(--ink-soft); max-width: 68ch; }
|
|
160
160
|
|
|
161
161
|
.scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 30px 40px; }
|
|
162
|
-
.measure { max-width:
|
|
162
|
+
.measure { max-width: var(--content-width); }
|
|
163
163
|
|
|
164
164
|
|
|
165
165
|
.subtabs { display: flex; gap: 4px; flex-wrap: wrap; padding: 12px 30px 0; flex: none; }
|
|
@@ -221,12 +221,14 @@
|
|
|
221
221
|
}
|
|
222
222
|
.btn:hover { color: var(--ink); border-color: var(--line-strong); background: var(--sheet); }
|
|
223
223
|
.btn:disabled { opacity: .45; cursor: default; }
|
|
224
|
-
.btn.primary { background: var(--accent); color:
|
|
225
|
-
.btn.primary:hover { filter: brightness(1.06); color:
|
|
224
|
+
.btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
|
|
225
|
+
.btn.primary:hover { filter: brightness(1.06); color: #fff; }
|
|
226
226
|
.btn.warn:hover { color: var(--warn); border-color: var(--warn); }
|
|
227
227
|
.btn.danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 42%, transparent); }
|
|
228
228
|
.btn.danger:hover { background: color-mix(in srgb, var(--danger) 9%, transparent); border-color: var(--danger); }
|
|
229
229
|
.btn.sm { padding: 4px 11px; font-size: var(--text-detail); }
|
|
230
|
+
.btn-ico { display: inline-flex; align-items: center; gap: 6px; }
|
|
231
|
+
.btn-ico .icon { width: 14px; height: 14px; }
|
|
230
232
|
|
|
231
233
|
.msgline { font: var(--text-detail)/1.45 var(--sans); min-height: 16px; color: var(--ok); }
|
|
232
234
|
.msgline:empty { display: none; }
|
|
@@ -639,7 +641,7 @@
|
|
|
639
641
|
min-height: 36px;
|
|
640
642
|
transition: background-color .15s ease, color .15s ease, border-color .15s ease, opacity .15s ease;
|
|
641
643
|
}
|
|
642
|
-
.btn.primary, .seg.active { background: var(--accent); border-color: var(--accent); color:
|
|
644
|
+
.btn.primary, .seg.active { background: var(--accent); border-color: var(--accent); color: #fff; }
|
|
643
645
|
input.field, select.field, textarea.field { min-height: 40px; }
|
|
644
646
|
input:focus-visible, textarea:focus-visible, select:focus-visible, button:focus-visible, [tabindex]:focus-visible {
|
|
645
647
|
outline: 2px solid color-mix(in srgb, var(--accent) 45%, transparent); outline-offset: 2px;
|
|
@@ -989,17 +991,19 @@
|
|
|
989
991
|
overflow-x: hidden;
|
|
990
992
|
overflow-y: auto;
|
|
991
993
|
padding: 30px var(--page-gutter) 56px;
|
|
992
|
-
scrollbar-gutter: stable;
|
|
994
|
+
scrollbar-gutter: stable both-edges;
|
|
993
995
|
}
|
|
994
996
|
.providerchrome {
|
|
997
|
+
overflow: hidden;
|
|
998
|
+
scrollbar-gutter: stable both-edges;
|
|
995
999
|
flex: none;
|
|
996
1000
|
min-width: 0;
|
|
997
1001
|
padding: 30px var(--page-gutter) 0;
|
|
998
1002
|
}
|
|
999
1003
|
.panelslot { padding-top: 8px; }
|
|
1000
|
-
.featureslot > :not(.viewport-overlay),
|
|
1004
|
+
.featureslot > :where(:not(.viewport-overlay)),
|
|
1001
1005
|
.providerchrome > *,
|
|
1002
|
-
.panelslot > :not(.viewport-overlay) {
|
|
1006
|
+
.panelslot > :where(:not(.viewport-overlay)) {
|
|
1003
1007
|
flex: none;
|
|
1004
1008
|
width: 100%;
|
|
1005
1009
|
max-width: var(--content-width);
|
|
@@ -1012,9 +1016,8 @@
|
|
|
1012
1016
|
padding: 0;
|
|
1013
1017
|
}
|
|
1014
1018
|
.coreview .measure {
|
|
1015
|
-
width: min(100%, var(--
|
|
1016
|
-
margin-
|
|
1017
|
-
margin-left: 0;
|
|
1019
|
+
width: min(100%, var(--content-width));
|
|
1020
|
+
margin-inline: auto;
|
|
1018
1021
|
}
|
|
1019
1022
|
.featureslot-live > *,
|
|
1020
1023
|
.featureslot-core > * {
|
|
@@ -1035,7 +1038,7 @@
|
|
|
1035
1038
|
.providerintro .msgline { margin-top: 10px; }
|
|
1036
1039
|
.pagetitle { margin-top: 7px; font: 600 22px/1.3 var(--sans); letter-spacing: -.025em; }
|
|
1037
1040
|
.pagedesc { margin-top: 5px; color: var(--muted-foreground); font-size: 13px; line-height: 1.55; }
|
|
1038
|
-
.scroll { padding: 22px var(--page-gutter) 48px; scrollbar-gutter: stable; }
|
|
1041
|
+
.scroll { padding: 22px var(--page-gutter) 48px; scrollbar-gutter: stable both-edges; }
|
|
1039
1042
|
.measure { width: min(100%, var(--content-width)); margin-inline: auto; }
|
|
1040
1043
|
.subtabs {
|
|
1041
1044
|
width: 100%;
|
|
@@ -1068,6 +1071,11 @@
|
|
|
1068
1071
|
details.sheet.fold { margin-bottom: 10px; }
|
|
1069
1072
|
details.sheet.fold > summary { padding: 0; }
|
|
1070
1073
|
details.sheet.fold > .foldbody { padding: 14px 0 0; }
|
|
1074
|
+
/* 整张点开详细页的卡(npm 搜索结果)。取值与 .connection-card 一致。 */
|
|
1075
|
+
.iocard-open { cursor: pointer; transition: background .15s, border-color .15s; }
|
|
1076
|
+
.iocard-open:hover { border-color: var(--border-strong); background: color-mix(in srgb, var(--surface) 92%, transparent); }
|
|
1077
|
+
.iocard-open:focus-visible { outline: 2px solid var(--ink-dim); outline-offset: 1px; }
|
|
1078
|
+
.iocard-open.is-installed { border-color: var(--accent); box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 12%, transparent); }
|
|
1071
1079
|
.featureslot > :not(.sheet) + .sheet,
|
|
1072
1080
|
.featureslot > .sheet + .sheet,
|
|
1073
1081
|
.panelslot > :not(.sheet) + .sheet,
|
|
@@ -1150,7 +1158,7 @@
|
|
|
1150
1158
|
}
|
|
1151
1159
|
.prompt-toolbar .msgline { min-width: 0; overflow-wrap: anywhere; }
|
|
1152
1160
|
.featureslot-prompts > .prompt-library,
|
|
1153
|
-
.panelslot > .prompt-library { margin-top:
|
|
1161
|
+
.panelslot > .prompt-library { margin-top: 0; }
|
|
1154
1162
|
.prompt-card textarea.field {
|
|
1155
1163
|
width: 100%;
|
|
1156
1164
|
min-height: 300px;
|
|
@@ -1432,7 +1440,7 @@
|
|
|
1432
1440
|
box-shadow: none;
|
|
1433
1441
|
}
|
|
1434
1442
|
.btn:hover { background: var(--hover); color: var(--foreground); border-color: transparent; box-shadow: none; }
|
|
1435
|
-
.btn.primary { background: var(--accent); border-color: var(--accent); color:
|
|
1443
|
+
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
|
|
1436
1444
|
.btn.primary:hover { background: color-mix(in srgb, var(--accent) 90%, var(--ink)); filter: none; }
|
|
1437
1445
|
:root[data-theme-scheme="mint"] .btn.primary {
|
|
1438
1446
|
background: color-mix(in srgb, var(--accent) 78%, var(--sheet-2));
|
|
@@ -1452,6 +1460,15 @@
|
|
|
1452
1460
|
font-family: var(--sans);
|
|
1453
1461
|
font-size: 13px;
|
|
1454
1462
|
}
|
|
1463
|
+
select.field:not([multiple]):not([size]) {
|
|
1464
|
+
appearance: none;
|
|
1465
|
+
padding-right: 36px;
|
|
1466
|
+
background-image: linear-gradient(45deg, transparent 50%, var(--muted-foreground) 50%),
|
|
1467
|
+
linear-gradient(135deg, var(--muted-foreground) 50%, transparent 50%);
|
|
1468
|
+
background-position: right 18px center, right 14px center;
|
|
1469
|
+
background-size: 4px 4px;
|
|
1470
|
+
background-repeat: no-repeat;
|
|
1471
|
+
}
|
|
1455
1472
|
input.field:focus, select.field:focus, textarea.field:focus { border-color: var(--border-strong); }
|
|
1456
1473
|
.fieldrow .fieldlabel { margin-bottom: 6px; color: var(--muted-foreground); font-size: 11px; letter-spacing: 0; text-transform: none; }
|
|
1457
1474
|
.segwrap { gap: 2px; padding: 2px; background: var(--surface-hover); border: 0; border-radius: var(--radius-md); }
|
|
@@ -1590,7 +1607,7 @@
|
|
|
1590
1607
|
.providerhub .panelslot { display: block; flex: none; padding: 0; overflow: visible; container: none; }
|
|
1591
1608
|
.providerhub .panelslot { margin-top: 22px; }
|
|
1592
1609
|
.providerhub .providerchrome > *,
|
|
1593
|
-
.providerhub .panelslot > :not(.viewport-overlay) { max-width: none; }
|
|
1610
|
+
.providerhub .panelslot > :where(:not(.viewport-overlay)) { max-width: none; }
|
|
1594
1611
|
.providerhub .providerintro .pagetitle { margin: 0; font-size: 18px; }
|
|
1595
1612
|
.providerhub .providerintro .pagedesc { margin-top: 4px; }
|
|
1596
1613
|
.providerhub .providerintro .rowbar { margin-top: 10px; }
|
|
@@ -1621,7 +1638,7 @@
|
|
|
1621
1638
|
|
|
1622
1639
|
@media (max-width: 900px) {
|
|
1623
1640
|
#rail { width: 232px; }
|
|
1624
|
-
|
|
1641
|
+
:root { --page-gutter: 20px; }
|
|
1625
1642
|
.settings-layout { grid-template-columns: minmax(0, 1fr); gap: 20px; }
|
|
1626
1643
|
.settings-index { position: static; flex-direction: row; overflow-x: auto; }
|
|
1627
1644
|
.settings-jump { width: auto; white-space: nowrap; }
|
|
@@ -1724,5 +1741,100 @@
|
|
|
1724
1741
|
.ob-btn:hover:not(:disabled) { background: var(--hover); }
|
|
1725
1742
|
.ob-btn .icon { width: 14px; height: 14px; }
|
|
1726
1743
|
.ob-btn:disabled { opacity: .55; cursor: not-allowed; }
|
|
1727
|
-
.ob-btn.ob-go { background: var(--accent); color:
|
|
1744
|
+
.ob-btn.ob-go { background: var(--accent); color: #fff; }
|
|
1728
1745
|
.ob-btn.ob-go:hover:not(:disabled) { filter: brightness(1.06); }
|
|
1746
|
+
.connection-hub{display:grid;grid-template-columns:minmax(210px,280px) minmax(0,1fr);gap:24px;align-items:start}
|
|
1747
|
+
.connection-index{position:sticky;top:16px;min-width:0;max-height:calc(100vh - 140px);overflow:auto;padding:4px}
|
|
1748
|
+
.connection-cards{display:grid;gap:12px;padding:3px}
|
|
1749
|
+
.connection-card{min-width:0;border:1px solid var(--line);border-radius:12px;padding:14px;background:var(--paper);cursor:pointer;transition:background .15s,border-color .15s}
|
|
1750
|
+
.connection-card.is-active{border-color:var(--accent);box-shadow:0 0 8px color-mix(in srgb,var(--accent) 12%,transparent)}
|
|
1751
|
+
.connection-card.is-selected{background:color-mix(in srgb,var(--ink) 5%,var(--paper));outline:2px solid var(--ink-dim);outline-offset:1px}
|
|
1752
|
+
.connection-name,.connection-status,.connection-secondary{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
1753
|
+
.connection-name{font:700 17px/1.25 var(--sans)}
|
|
1754
|
+
.connection-facts{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px;min-width:0}
|
|
1755
|
+
.connection-facts .kv{max-width:100%}.connection-facts .kv-v{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1756
|
+
.kv-kind{--kv-line:color-mix(in srgb,var(--ink-blue) 60%,transparent)}.kv-model{--kv-line:color-mix(in srgb,var(--accent-2) 75%,transparent)}.kv-baseUrl{--kv-line:var(--line-strong)}
|
|
1757
|
+
.connection-status{font-size:12px;margin-top:14px}.connection-secondary{font-size:11px;color:var(--ink-dim)}
|
|
1758
|
+
.connection-detail{min-width:0}.connection-detail .sheet{margin-bottom:16px}
|
|
1759
|
+
.connection-identity{background:var(--paper-2);border-color:var(--line-2)}
|
|
1760
|
+
.connection-identity+.connection-flow{margin-top:22px;padding-top:18px;border-top:1px dashed var(--line-2)}
|
|
1761
|
+
.connection-flow{counter-reset:step}.connection-step{counter-increment:step;min-width:0}
|
|
1762
|
+
.connection-step td.mono{white-space:normal;overflow-wrap:anywhere}
|
|
1763
|
+
.connection-step table.data .btn{white-space:nowrap}
|
|
1764
|
+
.connection-step>.sheet>h3::before,.connection-step>details.sheet>summary>h3::before{content:counter(step);display:inline-grid;place-items:center;width:20px;height:20px;margin-right:9px;border-radius:50%;background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent);font:600 11px/1 var(--mono);vertical-align:2px}
|
|
1765
|
+
.connection-detail .connection-field{margin-bottom:15px}.connection-detail input:not([type=checkbox]),.connection-detail select,.connection-detail textarea{max-width:100%;width:100%}
|
|
1766
|
+
.connection-detail .field-error{color:var(--danger,#b43c38);font-size:12px;min-height:0}.connection-shared{color:var(--ink-dim);font-size:12px;line-height:1.7;margin:20px 0 12px}
|
|
1767
|
+
.connection-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.connection-actions .grow{flex:1}
|
|
1768
|
+
@media(max-width:760px){.connection-hub{grid-template-columns:1fr}.connection-index{position:static;max-height:320px}.connection-cards{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}}
|
|
1769
|
+
|
|
1770
|
+
.live-summary { flex-wrap:wrap; }
|
|
1771
|
+
.live-connection { display:inline-flex; align-items:center; gap:7px; min-width:0; max-width:48%; background:none; border:0; color:var(--ink-soft); cursor:pointer; padding:0; font:11.5px/1 var(--sans); }
|
|
1772
|
+
.live-connection-label { flex-shrink:0; }
|
|
1773
|
+
.live-connection-value { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; padding:4px 8px; border-radius:7px; background:var(--hover); border:1px solid var(--border); color:var(--ink-blue); font-weight:600; }
|
|
1774
|
+
.live-connection:hover .live-connection-value { border-color:var(--accent); }
|
|
1775
|
+
.live-connection:focus-visible { outline:2px solid var(--accent); outline-offset:3px; border-radius:7px; }
|
|
1776
|
+
@media(max-width:760px) { .live-connection { max-width:100%; margin-left:auto; } }
|
|
1777
|
+
|
|
1778
|
+
.connection-detail .msgline:not(.bad) { color:var(--ink-soft); }
|
|
1779
|
+
.connection-detail .tdesc { margin:6px 0 12px; }
|
|
1780
|
+
|
|
1781
|
+
/* Page headings stay above the shared content origin while each page scrolls. */
|
|
1782
|
+
.featureslot:has(> .featureintro) { padding-top:0; }
|
|
1783
|
+
.featureintro { padding-bottom:16px; border-bottom:1px solid var(--border); }
|
|
1784
|
+
.featureslot > .featureintro { position:sticky; top:0; z-index:20; padding-top:30px; margin-bottom:24px; background:var(--background); }
|
|
1785
|
+
.featureslot > .featureintro + * { margin-top:0; }
|
|
1786
|
+
.featureslot > .featureintro + .sheet { margin-top:0; }
|
|
1787
|
+
.providerchrome { padding-bottom:0; }
|
|
1788
|
+
.providerchrome + .panelslot { padding-top:24px; }
|
|
1789
|
+
.coreview > .pagehead { padding-bottom:16px; }
|
|
1790
|
+
.connection-index { padding-top:0; top:100px; }
|
|
1791
|
+
.connection-detail > div > div:first-child > .sheet:first-child { padding-top:0; }
|
|
1792
|
+
.connection-hub .btn { border:1px solid var(--border-strong); }
|
|
1793
|
+
.connection-hub .btn:hover { border-color:var(--ink-soft); }
|
|
1794
|
+
.connection-hub .btn.danger { border-color:currentColor; }
|
|
1795
|
+
.connection-hub .btn.primary, .connection-hub .btn.primary:hover { color:#fff; border-color:var(--accent); }
|
|
1796
|
+
.connection-module-readonly:disabled { opacity:1; background-color:var(--surface); color:var(--foreground); cursor:default; }
|
|
1797
|
+
.field-note, .tdesc, .trow .tdesc, .sheet .sh-desc, .pagedesc, p.muted, small.muted,
|
|
1798
|
+
.connection-detail .msgline:not(.bad), .connection-shared {
|
|
1799
|
+
font:var(--text-detail)/1.55 var(--sans); color:var(--muted-foreground);
|
|
1800
|
+
}
|
|
1801
|
+
.field-note { margin:10px 0; }
|
|
1802
|
+
.field-note:empty { display:none; }
|
|
1803
|
+
.pricing-rules, .pricing-snapshot { margin-top:16px; }
|
|
1804
|
+
.pricing-rules > textarea, .pricing-snapshot > pre { margin-top:10px; }
|
|
1805
|
+
|
|
1806
|
+
.coreview > .pagehead { position:relative; border-bottom:0; }
|
|
1807
|
+
.coreview > .pagehead::after { content:''; position:absolute; bottom:0; left:var(--page-gutter); right:var(--page-gutter); height:1px; background:var(--border); }
|
|
1808
|
+
.coreview > .subtabs { margin-top:24px; }
|
|
1809
|
+
|
|
1810
|
+
.providerchrome > .featureintro + * { margin-top: 24px; }
|
|
1811
|
+
.providerchrome > .pagedesc { margin-bottom: 10px; }
|
|
1812
|
+
.providerchrome > .rowbar { margin-bottom: 10px; }
|
|
1813
|
+
.coreview > .scroll { scrollbar-gutter: auto; }
|
|
1814
|
+
.panelslot > :first-child > .sheet:first-child { padding-top: 0; }
|
|
1815
|
+
|
|
1816
|
+
/* 卡片:连接在右上,删除在右下,图标底边对齐状态行。 */
|
|
1817
|
+
.connection-create { margin-bottom:16px; }
|
|
1818
|
+
.connection-create-hint { margin:7px 2px 0; font:var(--text-detail)/1.5 var(--sans); color:var(--muted-foreground); }
|
|
1819
|
+
.connection-create > .btn { width:100%; }
|
|
1820
|
+
.connection-card { position:relative; padding-right:64px; }
|
|
1821
|
+
.connection-erase { position:absolute; bottom:13px; right:13px; display:flex; align-items:center; gap:0; height:28px; padding:0 4px; border:1px solid transparent; border-radius:8px; background:none; color:var(--ink-dim); cursor:pointer; transition:color .14s ease, background .14s ease, border-color .14s ease, gap .18s ease; }
|
|
1822
|
+
.connection-erase .icon { width:20px; height:20px; flex:none; }
|
|
1823
|
+
.connection-erase:hover { color:var(--danger,#b43c38); background:var(--hover); }
|
|
1824
|
+
.connection-erase-text { display:grid; grid-template-columns:0fr; overflow:hidden; font:600 12px/1 var(--sans); white-space:nowrap; transition:grid-template-columns .18s ease; }
|
|
1825
|
+
.connection-erase-text > span { overflow:hidden; }
|
|
1826
|
+
.connection-erase.is-armed { gap:6px; color:var(--danger,#b43c38); border-color:currentColor; background:var(--paper); }
|
|
1827
|
+
.connection-erase.is-armed .connection-erase-text { grid-template-columns:1fr; }
|
|
1828
|
+
.connection-connect { position:absolute; top:12px; right:12px; width:32px; text-align:center; }
|
|
1829
|
+
.connection-connect[hidden] { display:none; }
|
|
1830
|
+
.connection-hub .btn.connection-activate { display:block; width:32px; height:28px; min-height:28px; padding:0; border:0; font-size:17px; line-height:28px; }
|
|
1831
|
+
.connection-connect-label { display:block; font-size:10px; line-height:14px; color:var(--muted-foreground); }
|
|
1832
|
+
.connection-index { scrollbar-width:none; }
|
|
1833
|
+
.connection-index::-webkit-scrollbar { display:none; }
|
|
1834
|
+
.required-mark { color:var(--danger); }
|
|
1835
|
+
.connection-test { gap:12px; align-items:center; }
|
|
1836
|
+
.connection-test .msgline { margin:0; }
|
|
1837
|
+
.connection-status[data-tone="active"] { color:var(--accent); }
|
|
1838
|
+
.connection-status[data-tone="ready"] { color:var(--ok); }
|
|
1839
|
+
.connection-status[data-tone="error"], .connection-secondary[data-tone="error"] { color:var(--danger); }
|
|
1840
|
+
.connection-status[data-tone="draft"], .connection-secondary[data-tone="draft"] { color:var(--foreground); }
|