cuelo 0.9.5 → 0.9.6
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +9 -9
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.js +1 -1
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +3 -3
- package/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/updates/route.js +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +6 -6
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/index.segments/_full.segment.rsc +6 -6
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/.next/server/app/index.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/office/page_client-reference-manifest.js +1 -1
- package/.next/server/app/office-preview/page_client-reference-manifest.js +1 -1
- package/.next/server/app/office-preview.html +1 -1
- package/.next/server/app/office-preview.rsc +3 -3
- package/.next/server/app/office-preview.segments/_full.segment.rsc +3 -3
- package/.next/server/app/office-preview.segments/_head.segment.rsc +1 -1
- package/.next/server/app/office-preview.segments/_index.segment.rsc +3 -3
- package/.next/server/app/office-preview.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/office-preview.segments/office-preview/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/office-preview.segments/office-preview.segment.rsc +1 -1
- package/.next/server/app/office.html +1 -1
- package/.next/server/app/office.rsc +6 -6
- package/.next/server/app/office.segments/_full.segment.rsc +6 -6
- package/.next/server/app/office.segments/_head.segment.rsc +1 -1
- package/.next/server/app/office.segments/_index.segment.rsc +3 -3
- package/.next/server/app/office.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/office.segments/office/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/office.segments/office.segment.rsc +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/recover/page_client-reference-manifest.js +1 -1
- package/.next/server/app/recover.html +1 -1
- package/.next/server/app/recover.rsc +3 -3
- package/.next/server/app/recover.segments/_full.segment.rsc +3 -3
- package/.next/server/app/recover.segments/_head.segment.rsc +1 -1
- package/.next/server/app/recover.segments/_index.segment.rsc +3 -3
- package/.next/server/app/recover.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/recover.segments/recover/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/recover.segments/recover.segment.rsc +1 -1
- package/.next/server/app-paths-manifest.json +9 -9
- package/.next/server/chunks/5489.js +12 -12
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{9575-9eb94dc1e8bcd130.js → 9575-4a84cf066c2f1257.js} +12 -12
- package/.next/static/chunks/app/{layout-890e772919e033dc.js → layout-15c56b62f49b1c1d.js} +1 -1
- package/.next/static/css/00f20b26266e86ed.css +1 -0
- package/.next/static/css/7a264466e19eaafd.css +1 -0
- package/.next/trace +108 -108
- package/.next/trace-build +1 -1
- package/README.md +4 -0
- package/Tools/CUELO_Setup/files/native-runtime-patch.js +1 -1
- package/Tools/OMP_Global_Config/agent/AGENTS.md +6 -0
- package/Tools/OMP_Global_Config/agent/agents/maker.md +11 -5
- package/Tools/OMP_Global_Config/agent/extensions/gitnexus-autosync.ts +89 -19
- package/Tools/OMP_Global_Config/agent/extensions/jev-runtime.ts +194 -0
- package/Tools/OMP_Global_Config/agent/extensions/lib/maker-routing.ts +1 -1
- package/Tools/OMP_Global_Config/agent/prompt-copies/AGENTS.en.md +7 -1
- package/Tools/OMP_Global_Config/agent/rules/harness-policy.json +23 -8
- package/Tools/OMP_Global_Config/agent/rules/subagent.md +16 -2
- package/Tools/OMP_Global_Config/agent/sop/_writer.md +10 -4
- package/Tools/OMP_Global_Config/patches/apply-core-patch.mjs +158 -35
- package/install.mjs +1 -0
- package/package.json +1 -1
- package/.next/static/css/1ffe2d5d654f7eea.css +0 -1
- package/.next/static/css/81a05eb6255ef12e.css +0 -1
- /package/.next/static/{b4yL-hhdDIhd8tZ_DFHIS → kRJ4zgHxJf680foSBrfpf}/_buildManifest.js +0 -0
- /package/.next/static/{b4yL-hhdDIhd8tZ_DFHIS → kRJ4zgHxJf680foSBrfpf}/_ssgManifest.js +0 -0
|
@@ -68,6 +68,10 @@ description: SubAgent 위임 판단, 병렬 실행, 검수 계약과 Git·통신
|
|
|
68
68
|
아니라 남은 판단으로 고른다. 프론트 상태 경쟁은 코드·시스템이고 확정 시안 CSS는 자동 HARD가 아니다.
|
|
69
69
|
작은 routine은 계속 Main이 직접 끝낸다. 이미 위임할 가치가 있는 조각에서 적합한 가장 낮은 등급을
|
|
70
70
|
고른다. 검증·소유권·승인 경계는 낮추지 않는다.
|
|
71
|
+
- 관련 실측·실패 기록을 알고 있으면 과제 조건·하네스 revision·수용 품질·표본 한계를 함께
|
|
72
|
+
`assessment.facts`에 반영한다. 경로를 나눌 수 있다는 사실만으로 병렬 이득을 가정하지 않고,
|
|
73
|
+
공유 계약·발주 준비·재작업·통합 검수 비용과 실제 동시에 끝낼 수 있는 구간을 대조한다.
|
|
74
|
+
관측되지 않은 절감 시간은 만들지 않으며 한 사례를 줄 수·인원수 임계값이나 항상 단독 규칙으로 바꾸지 않는다.
|
|
71
75
|
- 발주 전 `maker_route`에 `context`·각 `name/task`와 최소 사실 `assessment`를 전달한다.
|
|
72
76
|
이 도구가 정본 criteria의 작업 분류·중심 난제·후보별 지원 effort·중복 여부·`ownerTarget`과
|
|
73
77
|
**위임 판단**(`routing.modelSelection.delegationCriteria`)을 한 번에 묻는다. 위임 판단은
|
|
@@ -113,6 +117,10 @@ description: SubAgent 위임 판단, 병렬 실행, 검수 계약과 Git·통신
|
|
|
113
117
|
실제 core 우선순위는 coarse effort > selector suffix > agent 기본 > pattern-derived다.
|
|
114
118
|
생성 기본 medium은 유지하되 발주 suffix가 덮는다. Auto를 suffix의 `auto`나 기본값 적용으로
|
|
115
119
|
대체하지 않는다. 발주 뒤 매 턴 재분류하지 않는다.
|
|
120
|
+
- 후보별 강도는 비용을 줄이는 가장 낮은 충분 단계가 아니라 결과 정확도에 맞는 단계로 판정한다.
|
|
121
|
+
열린 대안·경계를 넘는 불변식 결합·경쟁 원인·검사가 놓칠 수 있는 조건을 정본 criteria의 판단
|
|
122
|
+
특성과 대조하며 과소·과잉 모두 오분류다. 무조건 최고 단계, 구독 비용 환산, 선택 분포 맞추기를
|
|
123
|
+
하지 않고, 원인 미확정 표시·테스트 없음·위험·파일 수·재시도만으로 올리지 않는다.
|
|
116
124
|
- 입력은 목표·수용 조건·확인 범위/호출 관계·확정 방향/패턴 locator·남은 판단·보존 계약·검사다.
|
|
117
125
|
사실·가설·미확인을 구별하고 unknown은 null로 둔다. 현재/이전/희망 모델·등급·강도와 근거 없는
|
|
118
126
|
쉬움/복잡함을 공유 state 전체에서 제외한다. 원문·소스·diff·로그·비밀은 보내지 않는다.
|
|
@@ -143,8 +151,11 @@ description: SubAgent 위임 판단, 병렬 실행, 검수 계약과 Git·통신
|
|
|
143
151
|
- 체크포인트 라벨과 본문 규격은 `agent/sop/_writer.md`, 판단 정본은
|
|
144
152
|
`mainLane.workerReview.steeringCheckpoint`다. 체크포인트는 `write agent://Main` 한 통이고 비차단이다.
|
|
145
153
|
SubAgent에는 `wait`가 없으므로 Maker는 트리거 편집만 보류하고 read-only 조사와 비트리거 작업을
|
|
146
|
-
계속하며, 승인은 주입된 Main 메시지로 받는다. 독립 작업이 소진되면
|
|
147
|
-
|
|
154
|
+
계속하며, 승인은 주입된 Main 메시지로 받는다. 독립 작업이 소진되면 `yield`로 승인 대기·완료한
|
|
155
|
+
증거·착수하지 않은 작업을 blocked/partial로 보고한다. 산문만으로 턴을 끝내면 실행기는
|
|
156
|
+
`yield`를 요구하는 안내를 반복한다. 공유 작업공간 Maker는 Main의 첫 회신으로 재개하므로 같은
|
|
157
|
+
승인을 재개·상태 DM으로 중복 전송하지 않는다. 격리 작업공간은 terminal 뒤 재개되지 않으므로
|
|
158
|
+
인계 증거를 보존하고 Main이 후속 소유권을 정한다. 회신 없음은 승인이나 성공이 아니며 시간
|
|
148
159
|
기반 암묵 승인도 없다. Main은 받은 체크포인트마다 그 Maker에게 가는 첫 `write agent://<id>`로
|
|
149
160
|
한 줄(approved·retarget·scope)을 답한다.
|
|
150
161
|
Main 승인 때문에 owner가 막힌 경우, 다음 도구 행동은 승인에 필요한 좁은 확인과 회신이다.
|
|
@@ -351,6 +362,9 @@ Task Guard lock·budget·소유권·`FINDING_ID`, exit status, 파일·권한·
|
|
|
351
362
|
- `yield` 직전 자신이 만든 background job을 전부 회수하거나 `write proc://<id>/kill`로 취소한다(한 호출에 id 하나). 미회수 `[async-result]`가 종료 세션을 되살려 텍스트 전용 루프에 빠뜨릴 수 있고, 보고가 끝났는데 job은 `running`으로 남을 수 있다. 확인 결과가 필요 없는 명령은 처음부터 background로 띄우지 않는다.
|
|
352
363
|
- 살아 있어야 하는 서버·watcher·REPL은 `bash`에 `name`(필요하면 `ready`·`env`)을 준 서비스로 띄운다. **이름은 세션마다 고유하게 짓는다** — core 18.3.0은 살아 있는 같은 이름의 서비스를 owner와 무관하게 멈추고 교체하므로 흔한 이름은 다른 세션의 서버를 죽일 수 있다. 상태·최근 로그는 `read proc://<name>`, stdin은 `write proc://<name>`, 중지는 `write proc://<name>/kill`이다.
|
|
353
364
|
- 검증용으로 system Chrome을 `app.path`로 띄우지 않는다. 단일 인스턴스가 사용자의 기존 프로세스를 재사용할 수 있어, `browser.close({all:true, kill:true})`가 성공처럼 보여도 닫히지 않을 수 있다. 정리 실패는 재시도하거나 탭을 다시 열지 말고 남은 PID를 보고한다. managed Chromium 또는 relay를 사용한다.
|
|
365
|
+
검증 중 bash·eval에서 Chrome/Edge 실행 파일을 직접 띄우지 않는다(`Bun.spawn` 포함).
|
|
366
|
+
브라우저 helper나 프로젝트의 지원 검증 명령을 사용한다. 지원 명령의 프로필은 절대경로의
|
|
367
|
+
격리 위치를 써야 한다. headless라도 프로필 경로 오류는 초기화 중 사용자 데스크톱에 네이티브 창을 띄울 수 있다.
|
|
354
368
|
- Main은 위임한 조각의 구현·검증을 대신 실행하지 않고, 이미 받은 보고나 Maker가 한 조사를
|
|
355
369
|
다시 읽지 않는다. 대기 시간을 채우려고 검수·검증을 생략하지도 않는다.
|
|
356
370
|
|
|
@@ -104,10 +104,12 @@
|
|
|
104
104
|
an injected message; you have no `wait`, so the checkpoint never blocks the session. Never send a
|
|
105
105
|
diff body, raw output, file contents, or a second message per edit step. Only trigger code is held
|
|
106
106
|
for that reply: keep doing read-only investigation and the non-trigger work in the same slice.
|
|
107
|
-
When independent work runs out before the reply arrives,
|
|
108
|
-
checkpoint
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
When independent work runs out before the reply arrives, use `yield` to report the pending
|
|
108
|
+
checkpoint, completed evidence, and unstarted work as blocked/partial, never as accepted or done.
|
|
109
|
+
Prose alone ends a model turn but leaves the task executor asking for `yield`. A shared-workspace
|
|
110
|
+
Maker resumes on Main's first reply; an isolated worktree is not resumable after terminal yield,
|
|
111
|
+
so preserve the handoff for Main instead of promising a wake. No reply is never approval: trigger
|
|
112
|
+
edits require Main's explicit reply. Main retains the
|
|
111
113
|
approved location and invariants for the final drift check, so a revision that edited trigger
|
|
112
114
|
code without an approved checkpoint cannot be closed. This checkpoint is the first contact point
|
|
113
115
|
of review, not a separate gate: the final judgement covers only deltas not yet reviewed and the
|
|
@@ -146,6 +148,10 @@
|
|
|
146
148
|
build error. Never put a broken intermediate state on the user's screen. Use the user's browser
|
|
147
149
|
only when their live session is genuinely required, or when Main tells you to hand a FINISHED
|
|
148
150
|
surface over for judgement — do not open it on your own initiative.
|
|
151
|
+
Do not launch Chrome/Edge executables directly from bash or eval (including `Bun.spawn`) for
|
|
152
|
+
verification. Use the managed browser helpers or the project's supported verification commands.
|
|
153
|
+
Such commands must use an absolute, isolated profile path: even headless startup can show a
|
|
154
|
+
native desktop error dialog when its profile path is invalid.
|
|
149
155
|
- Run surface checks in the environment Main provides; create a common isolation environment or
|
|
150
156
|
run a full build yourself only when the brief explicitly delegates that run. When you do launch a
|
|
151
157
|
server (delegated, or no environment exists
|
|
@@ -85,6 +85,131 @@ const OPUS55_ROW_18410 = {
|
|
|
85
85
|
*/
|
|
86
86
|
const OPUS55_ROW_1851 = OPUS55_ROW_1846.patched.replace('"tps":95.2,', '"tps":93,');
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* learn topic upsert 적용본. 갱신 때 metadata 의 session_id/cwd 는 최초 저장자로 남고,
|
|
90
|
+
* updated_session_id/updated_cwd/updated_at 이 최신 정정자·시점이며 context 는 최신 이유다.
|
|
91
|
+
* first_context/first_timestamp 는 기존 revision 이 명시적으로 1 일 때만 갱신 직전 값으로 보존한다
|
|
92
|
+
* (revision 없음/2+ 는 최초 이유·시점을 알 수 없으므로 지어내지 않는다). `$` 중괄호와 백틱은 쓰지 않는다.
|
|
93
|
+
*/
|
|
94
|
+
const learnTopicUpsertBlock = `// HANSE: topic-key learn upsert
|
|
95
|
+
function upsertLearnTopic(
|
|
96
|
+
state: MnemopiSessionState,
|
|
97
|
+
params: LearnParams,
|
|
98
|
+
target: ReturnType<MnemopiSessionState["getScopedRetainTarget"]>,
|
|
99
|
+
): { id: string; revision: number } {
|
|
100
|
+
const topic = params.topic!.normalize("NFKC").trim().toLowerCase();
|
|
101
|
+
if (!topic) throw new Error("Learn topic must not be blank.");
|
|
102
|
+
if (redactMemorySecrets(topic) !== topic) throw new Error("Learn topic contains a credential.");
|
|
103
|
+
const db = target.memory.conn;
|
|
104
|
+
const existing = db.query(
|
|
105
|
+
"SELECT id, timestamp, metadata_json FROM working_memory WHERE json_extract(metadata_json, '$.topic_key') = ? ORDER BY timestamp DESC, id DESC LIMIT 1",
|
|
106
|
+
).get(topic) as { id: string; timestamp: string; metadata_json: string } | null;
|
|
107
|
+
const revision = existing ? (Number(JSON.parse(existing.metadata_json).revision) || 1) + 1 : 1;
|
|
108
|
+
if (existing) return db.transaction(() => {
|
|
109
|
+
const content = redactMemorySecrets(params.memory);
|
|
110
|
+
const stored = JSON.parse(existing.metadata_json);
|
|
111
|
+
const now = new Date().toISOString();
|
|
112
|
+
// HANSE: learn topic provenance keeps first and latest source
|
|
113
|
+
const firstSeen = stored.revision === 1 ? { first_context: stored.context ?? null, first_timestamp: existing.timestamp } : {};
|
|
114
|
+
const latest = { updated_session_id: state.sessionId, updated_cwd: state.session.sessionManager.getCwd(), updated_at: now };
|
|
115
|
+
db.query("UPDATE working_memory SET content = ?, embed_text = NULL, timestamp = ?, metadata_json = ? WHERE id = ?").run(
|
|
116
|
+
content, now,
|
|
117
|
+
JSON.stringify({ ...firstSeen, ...stored, context: params.context == null ? null : redactMemorySecrets(params.context), topic_key: topic, revision, ...latest }),
|
|
118
|
+
existing.id,
|
|
119
|
+
);
|
|
120
|
+
db.query("DELETE FROM memory_embeddings WHERE memory_id = ?").run(existing.id);
|
|
121
|
+
return { id: existing.id, revision };
|
|
122
|
+
})();
|
|
123
|
+
const id = state.rememberScoped(params.memory, {
|
|
124
|
+
source: "coding-agent-learn", importance: 0.8,
|
|
125
|
+
metadata: { session_id: state.sessionId, cwd: state.session.sessionManager.getCwd(), context: params.context ?? null, tool: "learn", topic_key: topic, revision },
|
|
126
|
+
scope: "bank", extract: true, extractEntities: true, veracity: "tool", memoryType: "fact",
|
|
127
|
+
}, target);
|
|
128
|
+
return { id, revision };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export class LearnTool implements AgentTool<LearnSchema> {`;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 회상 줄의 범위(global/project)·정정 표시 보조. 순수 표시이며 DB 와 RecallResult 원본은 바꾸지 않는다.
|
|
135
|
+
* 범위는 collectScopedRecallResults 가 고른 결과의 실제 bank 로 붙인 일시 필드(recallScope)에서만 읽는다.
|
|
136
|
+
* 정정 표시는 revision>1 일 때만, 최초 시점은 first_timestamp 가 있을 때만, 정정 시점은 updated_at 이 있을 때만 쓴다.
|
|
137
|
+
*/
|
|
138
|
+
const recallProvenanceBlock = String.raw`// HANSE: recall provenance note
|
|
139
|
+
type RecallProvenance = { scope?: string; revision: number; first?: string; corrected?: string };
|
|
140
|
+
function recallProvenance(result: RecallResult): RecallProvenance {
|
|
141
|
+
const scope = (result as { recallScope?: string }).recallScope;
|
|
142
|
+
let meta: Record<string, unknown> | null = null;
|
|
143
|
+
try {
|
|
144
|
+
const raw: unknown = result.metadata ?? (result.metadata_json ? JSON.parse(result.metadata_json) : null);
|
|
145
|
+
if (raw && typeof raw === "object") meta = raw as Record<string, unknown>;
|
|
146
|
+
} catch {
|
|
147
|
+
meta = null;
|
|
148
|
+
}
|
|
149
|
+
const day = (value: unknown): string | undefined =>
|
|
150
|
+
typeof value === "string" && /^\d{4}-\d{2}-\d{2}/.test(value) ? value.slice(0, 10) : undefined;
|
|
151
|
+
const revision = Number(meta?.revision);
|
|
152
|
+
return {
|
|
153
|
+
scope,
|
|
154
|
+
revision: Number.isInteger(revision) ? revision : 0,
|
|
155
|
+
first: day(meta?.first_timestamp),
|
|
156
|
+
corrected: day(meta?.updated_at),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function recallProvenanceNote(result: RecallResult): string {
|
|
160
|
+
const info = recallProvenance(result);
|
|
161
|
+
const parts: string[] = [];
|
|
162
|
+
if (info.scope) parts.push(info.scope);
|
|
163
|
+
if (info.revision > 1) {
|
|
164
|
+
parts.push("corrected r" + info.revision);
|
|
165
|
+
parts.push("first " + (info.first ?? "unknown"));
|
|
166
|
+
if (info.corrected) parts.push("corrected " + info.corrected);
|
|
167
|
+
}
|
|
168
|
+
return parts.length > 0 ? " {" + parts.join("; ") + "}" : "";
|
|
169
|
+
}
|
|
170
|
+
function recallRevisionFooter(results: readonly RecallResult[]): string {
|
|
171
|
+
return results.some(result => recallProvenance(result).revision > 1)
|
|
172
|
+
? "\n\nCorrected rows: read memory://<id> for the full metadata and correction reason."
|
|
173
|
+
: "";
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
`;
|
|
177
|
+
|
|
178
|
+
/** 출처 구분 이전 learn topic upsert 적용본. 새 판(learnTopicUpsertBlock)이 이 본문을 대체한다(legacyPatched). */
|
|
179
|
+
const learnTopicUpsertLegacyBlock = `// HANSE: topic-key learn upsert
|
|
180
|
+
function upsertLearnTopic(
|
|
181
|
+
state: MnemopiSessionState,
|
|
182
|
+
params: LearnParams,
|
|
183
|
+
target: ReturnType<MnemopiSessionState["getScopedRetainTarget"]>,
|
|
184
|
+
): { id: string; revision: number } {
|
|
185
|
+
const topic = params.topic!.normalize("NFKC").trim().toLowerCase();
|
|
186
|
+
if (!topic) throw new Error("Learn topic must not be blank.");
|
|
187
|
+
if (redactMemorySecrets(topic) !== topic) throw new Error("Learn topic contains a credential.");
|
|
188
|
+
const db = target.memory.conn;
|
|
189
|
+
const existing = db.query(
|
|
190
|
+
"SELECT id, metadata_json FROM working_memory WHERE json_extract(metadata_json, '$.topic_key') = ? ORDER BY timestamp DESC, id DESC LIMIT 1",
|
|
191
|
+
).get(topic) as { id: string; metadata_json: string } | null;
|
|
192
|
+
const revision = existing ? (Number(JSON.parse(existing.metadata_json).revision) || 1) + 1 : 1;
|
|
193
|
+
if (existing) return db.transaction(() => {
|
|
194
|
+
const content = redactMemorySecrets(params.memory);
|
|
195
|
+
db.query("UPDATE working_memory SET content = ?, embed_text = NULL, timestamp = ?, metadata_json = ? WHERE id = ?").run(
|
|
196
|
+
content, new Date().toISOString(),
|
|
197
|
+
JSON.stringify({ ...JSON.parse(existing.metadata_json), context: params.context == null ? null : redactMemorySecrets(params.context), topic_key: topic, revision }),
|
|
198
|
+
existing.id,
|
|
199
|
+
);
|
|
200
|
+
db.query("DELETE FROM memory_embeddings WHERE memory_id = ?").run(existing.id);
|
|
201
|
+
return { id: existing.id, revision };
|
|
202
|
+
})();
|
|
203
|
+
const id = state.rememberScoped(params.memory, {
|
|
204
|
+
source: "coding-agent-learn", importance: 0.8,
|
|
205
|
+
metadata: { session_id: state.sessionId, cwd: state.session.sessionManager.getCwd(), context: params.context ?? null, tool: "learn", topic_key: topic, revision },
|
|
206
|
+
scope: "bank", extract: true, extractEntities: true, veracity: "tool", memoryType: "fact",
|
|
207
|
+
}, target);
|
|
208
|
+
return { id, revision };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export class LearnTool implements AgentTool<LearnSchema> {`;
|
|
212
|
+
|
|
88
213
|
/**
|
|
89
214
|
* 기억 임베딩 (6) 항목의 본문. 0.9.3 은 recall 이 e5 여부로 dense 하한을 고르게 `usesE5Prefix` 를 export 한다.
|
|
90
215
|
* 0.9.2 적용본(export 없음)은 legacyPatched 로 남겨 같은 항목이 새 판으로 바꾼다.
|
|
@@ -5723,7 +5848,35 @@ function operationFromNative(op: string): Operation | undefined {
|
|
|
5723
5848
|
file: "src/mnemopi/state.ts",
|
|
5724
5849
|
marker: "// HANSE: recall line carries memory id",
|
|
5725
5850
|
anchor: "\t\treturn `- ${content}${source}${date}`;\n",
|
|
5726
|
-
patched: "\t\t// HANSE: recall line carries memory id\n\t\tconst memoryId = result.id ? ` (id: ${result.id})` : \"\";\n\t\treturn `- ${content}${source}${date}${memoryId}`;\n",
|
|
5851
|
+
patched: "\t\t// HANSE: recall line carries memory id\n\t\tconst memoryId = result.id ? ` (id: ${result.id})` : \"\";\n\t\treturn `- ${content}${source}${date}${recallProvenanceNote(result)}${memoryId}`;\n",
|
|
5852
|
+
legacyPatched: "\t\t// HANSE: recall line carries memory id\n\t\tconst memoryId = result.id ? ` (id: ${result.id})` : \"\";\n\t\treturn `- ${content}${source}${date}${memoryId}`;\n",
|
|
5853
|
+
},
|
|
5854
|
+
{
|
|
5855
|
+
// 위 항목의 짝. 범위·정정 표시 보조 함수와 정정 행이 있을 때만 붙는 한 줄 안내(상세는 memory://<id>).
|
|
5856
|
+
file: "src/mnemopi/state.ts",
|
|
5857
|
+
marker: "// HANSE: recall provenance note",
|
|
5858
|
+
anchor: "function formatRecallBlock(results: RecallResult[]): string {\n",
|
|
5859
|
+
patched: recallProvenanceBlock + "function formatRecallBlock(results: RecallResult[]): string {\n",
|
|
5860
|
+
},
|
|
5861
|
+
{
|
|
5862
|
+
file: "src/mnemopi/state.ts",
|
|
5863
|
+
marker: "${lines.join(\"\\n\\n\")}${recallRevisionFooter(results)}\\n</memories>",
|
|
5864
|
+
anchor: "${lines.join(\"\\n\\n\")}\\n</memories>`;\n",
|
|
5865
|
+
patched: "${lines.join(\"\\n\\n\")}${recallRevisionFooter(results)}\\n</memories>`;\n",
|
|
5866
|
+
},
|
|
5867
|
+
{
|
|
5868
|
+
// recall 도구 출력도 같은 표시를 쓴다.
|
|
5869
|
+
file: "src/mnemopi/state.ts",
|
|
5870
|
+
marker: "${source}${date}${recallProvenanceNote(result)}${confidence}",
|
|
5871
|
+
anchor: "\t\t\treturn `- ${result.content}${id}${source}${date}${confidence}`;\n\t\t});\n\t\treturn lines.join(\"\\n\\n\");\n",
|
|
5872
|
+
patched: "\t\t\treturn `- ${result.content}${id}${source}${date}${recallProvenanceNote(result)}${confidence}`;\n\t\t});\n\t\treturn lines.join(\"\\n\\n\") + recallRevisionFooter(results);\n",
|
|
5873
|
+
},
|
|
5874
|
+
{
|
|
5875
|
+
// 결과가 실제로 나온 bank 로 범위를 일시 표시한다(DB 저장 없음). 전역 bank 가 없는 구성은 추정하지 않는다.
|
|
5876
|
+
file: "src/mnemopi/state.ts",
|
|
5877
|
+
marker: "// HANSE: recall result carries its bank scope",
|
|
5878
|
+
anchor: "\t\t\t\t\tfor (const result of results) {\n\t\t\t\t\t\tmergeRecallResult(merged, byId, byContent, result);\n",
|
|
5879
|
+
patched: "\t\t\t\t\tfor (const result of results) {\n\t\t\t\t\t\t// HANSE: recall result carries its bank scope\n\t\t\t\t\t\tconst recallScope = this.scoped.global ? (target.bank === this.scoped.global.bank ? \"global\" : \"project\") : undefined;\n\t\t\t\t\t\tmergeRecallResult(merged, byId, byContent, { ...result, recallScope } as RecallResult);\n",
|
|
5727
5880
|
},
|
|
5728
5881
|
{
|
|
5729
5882
|
file: "src/tools/learn.ts",
|
|
@@ -5744,42 +5897,12 @@ function operationFromNative(op: string): Operation | undefined {
|
|
|
5744
5897
|
patched: '\t"topic?": type("string").describe("stable topic key; later lessons with this key replace the prior project lesson"),\n\t"scope?": type("\'project\' | \'global\'").describe(',
|
|
5745
5898
|
},
|
|
5746
5899
|
{
|
|
5900
|
+
// 출처 구분: 갱신해도 최초 session/cwd 는 남고 updated_* 가 최신 정정자다. legacyPatched 는 출처 구분 이전 적용본이다.
|
|
5747
5901
|
file: "src/tools/learn.ts",
|
|
5748
|
-
marker: "// HANSE: topic
|
|
5902
|
+
marker: "// HANSE: learn topic provenance keeps first and latest source",
|
|
5749
5903
|
anchor: "export class LearnTool implements AgentTool<LearnSchema> {",
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
state: MnemopiSessionState,
|
|
5753
|
-
params: LearnParams,
|
|
5754
|
-
target: ReturnType<MnemopiSessionState["getScopedRetainTarget"]>,
|
|
5755
|
-
): { id: string; revision: number } {
|
|
5756
|
-
const topic = params.topic!.normalize("NFKC").trim().toLowerCase();
|
|
5757
|
-
if (!topic) throw new Error("Learn topic must not be blank.");
|
|
5758
|
-
if (redactMemorySecrets(topic) !== topic) throw new Error("Learn topic contains a credential.");
|
|
5759
|
-
const db = target.memory.conn;
|
|
5760
|
-
const existing = db.query(
|
|
5761
|
-
"SELECT id, metadata_json FROM working_memory WHERE json_extract(metadata_json, '$.topic_key') = ? ORDER BY timestamp DESC, id DESC LIMIT 1",
|
|
5762
|
-
).get(topic) as { id: string; metadata_json: string } | null;
|
|
5763
|
-
const revision = existing ? (Number(JSON.parse(existing.metadata_json).revision) || 1) + 1 : 1;
|
|
5764
|
-
if (existing) return db.transaction(() => {
|
|
5765
|
-
const content = redactMemorySecrets(params.memory);
|
|
5766
|
-
db.query("UPDATE working_memory SET content = ?, embed_text = NULL, timestamp = ?, metadata_json = ? WHERE id = ?").run(
|
|
5767
|
-
content, new Date().toISOString(),
|
|
5768
|
-
JSON.stringify({ ...JSON.parse(existing.metadata_json), context: params.context == null ? null : redactMemorySecrets(params.context), topic_key: topic, revision }),
|
|
5769
|
-
existing.id,
|
|
5770
|
-
);
|
|
5771
|
-
db.query("DELETE FROM memory_embeddings WHERE memory_id = ?").run(existing.id);
|
|
5772
|
-
return { id: existing.id, revision };
|
|
5773
|
-
})();
|
|
5774
|
-
const id = state.rememberScoped(params.memory, {
|
|
5775
|
-
source: "coding-agent-learn", importance: 0.8,
|
|
5776
|
-
metadata: { session_id: state.sessionId, cwd: state.session.sessionManager.getCwd(), context: params.context ?? null, tool: "learn", topic_key: topic, revision },
|
|
5777
|
-
scope: "bank", extract: true, extractEntities: true, veracity: "tool", memoryType: "fact",
|
|
5778
|
-
}, target);
|
|
5779
|
-
return { id, revision };
|
|
5780
|
-
}
|
|
5781
|
-
|
|
5782
|
-
export class LearnTool implements AgentTool<LearnSchema> {`,
|
|
5904
|
+
legacyPatched: learnTopicUpsertLegacyBlock,
|
|
5905
|
+
patched: learnTopicUpsertBlock,
|
|
5783
5906
|
},
|
|
5784
5907
|
{
|
|
5785
5908
|
// learn 은 rememberScoped 가 돌려준 기억 id 를 버리고 "Lesson stored." 만 알렸다. 교훈을 뒤에서
|
package/install.mjs
CHANGED
|
@@ -170,6 +170,7 @@ export const PROFILE_DEFAULTS = {
|
|
|
170
170
|
memory: { backend: "mnemopi" },
|
|
171
171
|
mnemopi: { scoping: "per-project-tagged", embeddingVariant: "multilingual", autoRetain: false },
|
|
172
172
|
task: {
|
|
173
|
+
enableLsp: true,
|
|
173
174
|
softRequestBudget: 400,
|
|
174
175
|
maxConcurrency: 8,
|
|
175
176
|
eager: "preferred",
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.answer-dispatch{margin:4px 0 8px;border:1px solid var(--border);border-radius:var(--radius-control);background:var(--bg-panel);min-width:0;max-width:100%}.answer-dispatch-toggle,.answer-summary-toggle{display:flex;align-items:center;gap:8px;width:100%;min-height:44px;padding:6px 12px;border:none;background:transparent;color:var(--text);font:inherit;text-align:left;cursor:pointer;border-radius:var(--radius-control);touch-action:manipulation}.answer-dispatch-toggle:hover,.answer-summary-toggle:hover{background:var(--bg-hover)}.answer-delivery-remove:focus-visible,.answer-delivery-toggle:focus-visible,.answer-dispatch-toggle:focus-visible,.answer-link:focus-visible,.answer-summary-toggle:focus-visible{outline:2px solid var(--accent-ring,var(--accent));outline-offset:2px}.answer-dispatch-heading{flex-shrink:0;font-size:13px;font-weight:600}.answer-dispatch-tally{flex:1 1 auto;min-width:0;font-size:12px;color:var(--text-muted);overflow-wrap:anywhere}.answer-chevron{flex-shrink:0;color:var(--text-dim);transition:transform .15s}[aria-expanded=true]>.answer-chevron{transform:rotate(180deg)}.answer-dispatch-list{list-style:none;margin:0;padding:0 12px 8px;display:flex;flex-direction:column;gap:6px}.answer-dispatch-row{min-width:0;padding-top:6px;border-top:1px solid var(--border)}.answer-dispatch-line,.answer-summary-maker{display:flex;flex-wrap:wrap;align-items:baseline;column-gap:10px;row-gap:4px;min-width:0}.answer-dispatch-name{flex:1 1 12rem;min-width:0;font-size:13px;color:var(--text);overflow-wrap:anywhere}.answer-status-pair{display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px;font-size:12px;min-width:0}.answer-status-arrow{color:var(--text-dim)}.answer-status-run,.answer-status-verdict{padding:1px 7px;border:1px solid var(--border);border-radius:var(--radius-control);white-space:nowrap;color:var(--text-muted)}.answer-status-run[data-state=dispatching],.answer-status-run[data-state=pending],.answer-status-run[data-state=running]{color:var(--accent);border-color:var(--accent-line,var(--border))}.answer-status-run[data-state=aborted],.answer-status-run[data-state=failed]{color:var(--danger);border-color:var(--danger-line)}.answer-status-run[data-state=unobserved],.answer-status-verdict[data-verdict=none]{border-style:dashed;color:var(--text-dim)}.answer-status-verdict[data-verdict=accepted]{color:var(--success);border-color:var(--success-line)}.answer-status-verdict[data-verdict=held],.answer-status-verdict[data-verdict=rework]{color:var(--warning);border-color:var(--warning-line)}.answer-dispatch-detail{display:grid;grid-template-columns:minmax(0,1fr);gap:3px;margin:6px 0 2px;font-size:12px}.answer-dispatch-detail>div{display:flex;flex-wrap:wrap;column-gap:8px;min-width:0}.answer-dispatch-detail dt{flex:0 0 6.5rem;color:var(--text-dim)}.answer-dispatch-detail dd{flex:1 1 12rem;min-width:0;margin:0;color:var(--text-muted);overflow-wrap:anywhere}.answer-check-command,.answer-mono{font-family:var(--font-mono)}.answer-dispatch-links{display:flex;flex-wrap:wrap;gap:8px;padding:0 12px 8px}.answer-link{min-height:44px;padding:0 12px;border:1px solid var(--border);border-radius:var(--radius-control);background:transparent;color:var(--text);font:inherit;font-size:12px;cursor:pointer;touch-action:manipulation}.answer-link:hover{background:var(--bg-hover)}.answer-dispatch-flash{animation:answer-dispatch-flash 1.8s ease-out}@keyframes answer-dispatch-flash{0%,35%{background-color:var(--accent-soft);box-shadow:0 0 0 2px var(--accent-line)}}.answer-dispatch-row[data-focused] .answer-dispatch-name{font-weight:600}.run-status-line.answer-dock-line{align-items:center;inline-size:100%;font-weight:inherit;line-height:inherit;text-align:start;cursor:pointer;touch-action:manipulation}.run-status-line.answer-dock-line:hover{background:var(--bg-hover)}.run-status-line.answer-dock-line:focus-visible{outline:2px solid var(--accent-ring,var(--accent));outline-offset:2px}.answer-dock-counts{display:inline-flex;flex-shrink:0;gap:6px}.answer-dock-count{padding:0 6px;border:1px solid var(--border);border-radius:var(--radius-control);white-space:nowrap}.answer-dock-count[data-phase=running]{color:var(--accent);border-color:var(--accent-line,var(--border))}.answer-dock-count[data-phase=awaiting]{border-style:dashed;color:var(--text-muted)}.answer-dock-title{flex:1;min-inline-size:0;overflow:hidden;color:var(--text);text-overflow:ellipsis;white-space:nowrap}.answer-dock-go{flex-shrink:0;color:var(--text-dim)}.answer-summary{margin-top:6px;min-width:0}.answer-summary-toggle{width:auto;max-width:100%;padding:6px 8px;margin-left:-8px}.answer-summary-text{min-width:0;font-size:12px;color:var(--text-muted);overflow-wrap:anywhere}.answer-summary-text[data-unverified]{color:var(--warning)}.answer-summary-body{display:flex;flex-direction:column;gap:10px;padding:6px 0 4px;min-width:0}.answer-summary-heading{margin:0 0 4px;font-size:11px;font-weight:600;color:var(--text-dim)}.answer-summary-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--text-muted);min-width:0}.answer-summary-list>li{min-width:0;overflow-wrap:anywhere}.answer-check{display:flex;flex-wrap:wrap;align-items:baseline;column-gap:10px}.answer-check-command{flex:1 1 14rem;min-width:0;font-size:12px;color:var(--text);overflow-wrap:anywhere}.answer-check-result{white-space:nowrap;color:var(--text-dim)}.answer-check[data-state=passed] .answer-check-result{color:var(--success)}.answer-check[data-state=failed] .answer-check-result{color:var(--danger)}.answer-delivery-list{list-style:none;margin:0;padding:0}.answer-delivery-row{display:flex;flex-wrap:wrap;align-items:center;column-gap:8px;row-gap:2px;min-height:32px;padding:3px 4px 3px 10px;font-size:12px;color:var(--text-muted);min-width:0}.answer-delivery-kind{flex-shrink:0;padding:1px 7px;border:1px solid var(--border);border-radius:var(--radius-control);font-size:11px;color:var(--text-dim)}.answer-delivery-row[data-kind=steer] .answer-delivery-kind{color:var(--accent);border-color:var(--accent-line,var(--border))}.answer-delivery-text{flex:1 1 8rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.answer-delivery-stage{flex-shrink:0;font-size:11px;color:var(--text-dim)}.answer-delivery-row[data-stage=delivered] .answer-delivery-stage{color:var(--success)}.answer-delivery-row[data-stage=failed] .answer-delivery-stage{color:var(--danger)}.answer-delivery-row[data-stage=unconfirmed] .answer-delivery-stage{color:var(--warning)}.answer-delivery-remove{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;border-radius:var(--radius-control);background:transparent;color:var(--text-dim);cursor:pointer;touch-action:manipulation}.answer-delivery-remove:hover{background:var(--bg-hover);color:var(--text)}.answer-delivery-toggle{display:block;min-height:32px;padding:3px 10px;border:none;border-radius:var(--radius-control);background:transparent;color:var(--text-dim);font-size:11px;text-align:left;cursor:pointer;touch-action:manipulation}.answer-delivery-toggle:hover{background:var(--bg-hover);color:var(--text)}@media (max-width:640px),(pointer:coarse){.answer-delivery-remove{width:44px;height:44px}.answer-delivery-toggle{min-height:44px}.run-status-line.answer-dock-line{min-block-size:44px}}@media (prefers-reduced-motion:reduce){.answer-chevron{transition:none}.answer-dispatch-flash{animation:none;outline:2px solid var(--accent-line);outline-offset:2px}}.SearchableSelect_root__FMhaH{position:relative;width:100%;min-width:0;font-family:var(--font-mono)}.SearchableSelect_trigger__eqMdt{width:100%;min-width:0;height:34px;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:0 9px 0 10px;border:1px solid var(--border);border-radius:6px;background:var(--bg);color:var(--text);cursor:pointer;font:inherit;font-size:11px;text-align:left}.SearchableSelect_trigger__eqMdt:hover:not(:disabled){border-color:color-mix(in srgb,var(--accent) 55%,var(--border));background:var(--bg-hover)}.SearchableSelect_trigger__eqMdt:focus-visible{outline:none;border-color:var(--accent)}.SearchableSelect_trigger__eqMdt:disabled{cursor:wait;opacity:.55}.SearchableSelect_placeholder__Hkg33,.SearchableSelect_value__eJ2RU{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.SearchableSelect_placeholder__Hkg33{color:var(--text-dim)}.SearchableSelect_chevron__DSTnM{width:12px;height:12px;flex:0 0 auto;fill:none;stroke:var(--text-dim);stroke-linecap:round;stroke-linejoin:round;stroke-width:1.4}.SearchableSelect_popover__5VxMd{position:absolute;z-index:120;right:0;display:flex;flex-direction:column;width:max(100%,240px);overflow:hidden;border:1px solid color-mix(in srgb,var(--border) 82%,var(--accent));border-radius:8px;background:var(--bg-panel);box-shadow:0 14px 34px color-mix(in srgb,var(--bg) 72%,transparent)}.SearchableSelect_searchWrap__IoKKk{position:relative;flex:0 0 auto;padding:7px;border-bottom:1px solid var(--border)}.SearchableSelect_searchIcon__A6f0C{position:absolute;left:16px;top:50%;width:13px;height:13px;transform:translateY(-50%);fill:none;stroke:var(--text-dim);stroke-linecap:round;stroke-width:1.3;pointer-events:none}.SearchableSelect_search__W_1al{width:100%;height:31px;padding:0 9px 0 29px;border:1px solid var(--border);border-radius:5px;outline:none;background:var(--bg);color:var(--text);font:11px var(--font-mono)}.SearchableSelect_search__W_1al:focus{border-color:var(--accent)}.SearchableSelect_search__W_1al::placeholder{color:var(--text-dim)}.SearchableSelect_options__tjHyi{max-height:250px;overflow-y:auto;overscroll-behavior:contain;padding:5px}.SearchableSelect_option__LRRH9{width:100%;min-height:32px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:6px 8px;border:0;border-radius:5px;background:transparent;color:var(--text-muted);cursor:pointer;font:11px/1.3 var(--font-mono);text-align:left}.SearchableSelect_option__LRRH9[data-active=true]{background:var(--bg-hover);color:var(--text)}.SearchableSelect_option__LRRH9[data-selected=true]{color:var(--accent)}.SearchableSelect_option__LRRH9:disabled{cursor:not-allowed;opacity:.45}.SearchableSelect_optionCopy__W87H8{min-width:0;display:flex;flex-direction:column;gap:2px}.SearchableSelect_optionDescription__cE_cC,.SearchableSelect_optionLabel__G7jIg{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.SearchableSelect_optionDescription__cE_cC{color:var(--text-dim);font-size:9.5px}.SearchableSelect_check__1Likw{width:12px;height:12px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.8}.SearchableSelect_empty__vZzXQ{padding:18px 12px;color:var(--text-dim);font:10px var(--font-mono);text-align:center}.SettingsConfig_backdrop__i6KYG{position:fixed;inset:0;z-index:1000;display:grid;place-items:center;padding:18px;background:color-mix(in srgb,#000 48%,transparent);backdrop-filter:blur(8px)}.SettingsConfig_window__m7dcs{width:min(1180px,calc(100vw - 36px));height:min(860px,calc(100dvh - 36px));display:grid;grid-template-columns:238px minmax(0,1fr);overflow:hidden;border:1px solid var(--border);border-radius:14px;background:var(--bg);color:var(--text);box-shadow:0 24px 80px rgba(0,0,0,.34)}.SettingsConfig_sidebar__vEMEr{min-width:0;display:flex;flex-direction:column;border-right:1px solid var(--border);background:var(--bg-panel)}.SettingsConfig_brand__DlYlu{padding:20px 18px 13px}.SettingsConfig_eyebrow__uTa5R{margin-bottom:5px;color:var(--accent);font:700 10px/1 var(--font-mono);letter-spacing:.14em;text-transform:uppercase}.SettingsConfig_title__DWTnA{margin:0;font-size:20px;font-weight:760;letter-spacing:-.025em}.SettingsConfig_context__N0fl0{display:block;margin-top:6px;overflow:hidden;color:var(--text-dim);font:10px/1.35 var(--font-mono);text-overflow:ellipsis;white-space:nowrap}.SettingsConfig_searchWrap___PWrc{position:relative;padding:0 12px 10px}.SettingsConfig_searchIcon__8_YYE{position:absolute;top:9px;left:23px;width:13px;height:13px;color:var(--text-dim);pointer-events:none}.SettingsConfig_search__DUhSs{width:100%;height:32px;padding:0 10px 0 31px;border:1px solid var(--border);border-radius:8px;outline:none;background:var(--bg);color:var(--text);font:12px var(--font-mono)}.SettingsConfig_search__DUhSs:focus{border-color:var(--accent)}.SettingsConfig_nav__V8P9S{flex:1;overflow-y:auto;padding:2px 8px 14px}.SettingsConfig_navLabel__M1wMP{padding:13px 10px 5px;color:var(--text-dim);font:700 9px/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase}.SettingsConfig_navButton__CUOqu{width:100%;height:34px;display:flex;align-items:center;gap:9px;padding:0 10px;border:0;border-radius:8px;background:transparent;color:var(--text-muted);cursor:pointer;font:500 12px/1 var(--font-mono);text-align:left;transition:background .12s ease,color .12s ease}.SettingsConfig_navButton__CUOqu:hover:not(:disabled){background:var(--bg-hover);color:var(--text)}.SettingsConfig_navButton__CUOqu[data-active=true]{background:var(--bg-selected);color:var(--text);font-weight:700}.SettingsConfig_navButton__CUOqu:disabled{cursor:not-allowed;opacity:.36}.SettingsConfig_navIcon__Wagpr{width:15px;height:15px;flex:0 0 auto}.SettingsConfig_closeRail__PW3pT{padding:10px 12px;border-top:1px solid var(--border)}.SettingsConfig_closeButton__5y_6F{width:100%;height:34px;border:1px solid var(--border);border-radius:8px;background:transparent;color:var(--text-muted);cursor:pointer;font:12px var(--font-mono)}.SettingsConfig_closeButton__5y_6F:hover{background:var(--bg-hover);color:var(--text)}.SettingsConfig_content__n_a5Z{min-width:0;min-height:0;position:relative;overflow:hidden;background:var(--bg)}.SettingsConfig_scrollContent__03BsO{height:100%;overflow-y:auto;padding:32px clamp(24px,5vw,56px) 56px}.SettingsConfig_contentHeader__tNmzv{max-width:820px;margin:0 auto 26px;padding-bottom:20px;border-bottom:1px solid var(--border)}.SettingsConfig_contentTitle__oiHOO{margin:0 0 7px;font-size:24px;font-weight:750;letter-spacing:-.035em}.SettingsConfig_contentDescription___l2QU{margin:0;max-width:700px;color:var(--text-muted);font-size:12px;line-height:1.6}.SettingsConfig_reloadNotice__enzeE{margin-top:14px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 10px;border:1px solid var(--border);border-radius:8px;background:var(--bg-panel);color:var(--text-muted);font:10px/1.4 var(--font-mono)}.SettingsConfig_reloadNotice__enzeE button{flex:0 0 auto;height:28px;padding:0 9px;border:0;border-radius:6px;background:var(--accent);color:var(--bg);cursor:pointer;font:700 10px var(--font-mono)}.SettingsConfig_reloadNotice__enzeE button:disabled{cursor:wait;opacity:.55}.SettingsConfig_settingsBody__QRFVu{max-width:820px;margin:0 auto}.SettingsConfig_group__JQ_dy{margin:0 0 30px}.SettingsConfig_groupTitle__0SrM9{margin:0 0 8px;color:var(--text-dim);font:700 10px/1 var(--font-mono);letter-spacing:.1em;text-transform:uppercase}.SettingsConfig_settingRow__Jy73r{min-height:62px;display:grid;grid-template-columns:minmax(0,1fr) minmax(170px,260px);align-items:center;gap:24px;padding:13px 0;border-bottom:1px solid color-mix(in srgb,var(--border) 70%,transparent)}.SettingsConfig_settingRow__Jy73r:first-of-type{border-top:1px solid color-mix(in srgb,var(--border) 70%,transparent)}.SettingsConfig_settingLabel__n8vtU{margin-bottom:4px;font-size:13px;font-weight:650}.SettingsConfig_settingDescription__TGWfP{color:var(--text-dim);font-size:11px;line-height:1.45}.SettingsConfig_settingControl__oz5Gn{min-width:0;display:flex;justify-content:flex-end}.SettingsConfig_jsonEditor__yTYDb,.SettingsConfig_numberInput__TVVeJ,.SettingsConfig_select__A5aGy,.SettingsConfig_textInput___NjZ2{width:100%;border:1px solid var(--border);border-radius:8px;outline:none;background:var(--bg-panel);color:var(--text);font:11px var(--font-mono)}.SettingsConfig_numberInput__TVVeJ,.SettingsConfig_select__A5aGy,.SettingsConfig_textInput___NjZ2{height:34px;padding:0 10px}.SettingsConfig_jsonEditor__yTYDb:focus,.SettingsConfig_numberInput__TVVeJ:focus,.SettingsConfig_select__A5aGy:focus,.SettingsConfig_textInput___NjZ2:focus{border-color:var(--accent)}.SettingsConfig_switch__5UYqz{width:38px;height:22px;position:relative;padding:0;border:1px solid var(--border);border-radius:999px;background:var(--bg-hover);cursor:pointer;transition:background .16s,border-color .16s}.SettingsConfig_switch__5UYqz:after{content:"";position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:var(--text-muted);transition:transform .16s,background .16s}.SettingsConfig_switch__5UYqz[data-on=true]{border-color:var(--accent);background:var(--accent)}.SettingsConfig_switch__5UYqz[data-on=true]:after{transform:translateX(16px);background:var(--bg)}.SettingsConfig_switch__5UYqz:disabled{cursor:wait;opacity:.55}.SettingsConfig_multiSelect__PTjyr{width:100%;display:flex;flex-wrap:wrap;justify-content:flex-end;gap:5px}.SettingsConfig_choice__Os8WR{display:inline-flex;align-items:center;gap:5px;padding:5px 7px;border:1px solid var(--border);border-radius:6px;background:var(--bg-panel);color:var(--text-muted);font:10px var(--font-mono)}.SettingsConfig_choiceToggle__lyl75{padding:0;border:0;background:transparent;color:inherit;cursor:pointer;font:inherit}.SettingsConfig_choice__Os8WR[data-selected=true]{border-color:var(--accent);color:var(--accent)}.SettingsConfig_reorder__JR6tX{display:inline-flex;gap:2px}.SettingsConfig_reorder__JR6tX button{border:0;background:transparent;color:inherit;cursor:pointer;padding:0 2px}.SettingsConfig_error__j6wEj,.SettingsConfig_saveState__1tIL4{margin-top:5px;color:var(--danger);font:10px var(--font-mono)}.SettingsConfig_saveState__1tIL4{color:var(--text-dim)}.SettingsConfig_themeGrid__7Lw8A{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-bottom:30px}.SettingsConfig_themeCard__DQFsT{position:relative;overflow:visible;border:1px solid var(--border);border-radius:12px;background:var(--bg-panel)}.SettingsConfig_themeCard__DQFsT:focus-within{z-index:10}.SettingsConfig_themePreview__QzqXK{height:118px;overflow:hidden;padding:14px;border-radius:11px 11px 0 0;background:var(--seed-color-bg-layer-default)}.SettingsConfig_themePreviewBar__ZbchX{width:62%;height:7px;border-radius:var(--seed-radius-r1);background:var(--seed-color-fg-neutral);opacity:.9}.SettingsConfig_themePreviewPanel__YN9ty{height:62px;margin-top:12px;padding:10px;border:1px solid var(--seed-color-stroke-neutral-muted);border-radius:7px;background:var(--seed-color-bg-layer-floating)}.SettingsConfig_themePreviewLine__jP0qg{width:74%;height:5px;margin-bottom:7px;border-radius:3px;background:var(--seed-color-fg-neutral)}.SettingsConfig_themePreviewLine__jP0qg:last-child{width:44%;background:var(--seed-color-fg-neutral-muted)}.SettingsConfig_themeCardBody__xiOe6{padding:12px;border-top:1px solid var(--border)}.SettingsConfig_themeCardHeader__YPRN2{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.SettingsConfig_themeSlot__vGn9a{font:700 10px var(--font-mono);text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted)}.SettingsConfig_themeActive__PNmdk{font:9px var(--font-mono);color:var(--accent)}.SettingsConfig_mcpLayout__ek_Fi{display:grid;grid-template-columns:250px minmax(0,1fr);min-height:490px;border:1px solid var(--border);border-radius:12px;overflow:hidden}.SettingsConfig_mcpList__gZ9_o{display:flex;flex-direction:column;border-right:1px solid var(--border);background:var(--bg-panel)}.SettingsConfig_scopeTabs__9bybS{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:8px;border-bottom:1px solid var(--border)}.SettingsConfig_scopeButton__d4XPe{height:29px;border:0;border-radius:6px;background:transparent;color:var(--text-dim);cursor:pointer;font:10px var(--font-mono)}.SettingsConfig_scopeButton__d4XPe[data-active=true]{background:var(--bg-selected);color:var(--text)}.SettingsConfig_serverRows__JSJy0{flex:1;overflow-y:auto;padding:7px}.SettingsConfig_serverRow__6gJdE{width:100%;display:flex;align-items:center;gap:3px;padding:3px;border-radius:7px;background:transparent;color:var(--text-muted);font:11px var(--font-mono)}.SettingsConfig_serverRow__6gJdE[data-active=true]{background:var(--bg-selected);color:var(--text)}.SettingsConfig_serverSelect__cuYFx{min-width:0;flex:1;display:flex;align-items:center;gap:8px;padding:5px;border:0;background:transparent;color:inherit;cursor:pointer;font:inherit;text-align:left}.SettingsConfig_serverToggle__X5N_o{width:30px;height:23px;flex:0 0 auto;padding:0;border:1px solid var(--border);border-radius:5px;background:var(--bg);color:var(--text-dim);cursor:pointer;font:700 8px var(--font-mono)}.SettingsConfig_serverToggle__X5N_o[data-on=true]{border-color:color-mix(in srgb,var(--success) 55%,var(--border));color:var(--success)}.SettingsConfig_serverToggle__X5N_o:disabled{cursor:wait;opacity:.5}.SettingsConfig_serverName__lbfcK{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.SettingsConfig_sourceBadge__XDE2u{max-width:76px;overflow:hidden;text-overflow:ellipsis;padding:2px 4px;border:1px solid var(--border);border-radius:4px;color:var(--text-dim);font-size:8px;white-space:nowrap}.SettingsConfig_serverListEmpty___icit{padding:22px 10px;color:var(--text-dim);font:10px/1.5 var(--font-mono);text-align:center}.SettingsConfig_statusDot__dVcD4{width:7px;height:7px;border-radius:50%;background:var(--success)}.SettingsConfig_statusDot__dVcD4[data-off=true]{background:var(--text-dim)}.SettingsConfig_addServer__g0ivB{margin:8px;height:31px;border:1px dashed var(--border);border-radius:7px;background:transparent;color:var(--text-muted);cursor:pointer;font:11px var(--font-mono)}.SettingsConfig_mcpEditor__XGcLp{min-width:0;padding:20px}.SettingsConfig_editorHeader__qDvAk{display:flex;gap:8px;margin-bottom:14px}.SettingsConfig_jsonEditor__yTYDb{min-height:290px;resize:vertical;padding:12px;line-height:1.55}.SettingsConfig_readOnlyNotice__KNzML{margin:-5px 0 10px;color:var(--text-dim);font:10px var(--font-mono)}.SettingsConfig_jsonEditor__yTYDb:read-only,.SettingsConfig_textInput___NjZ2:read-only{background:var(--bg-subtle);color:var(--text-muted);cursor:default}.SettingsConfig_editorActions__h9p7Y{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:12px}.SettingsConfig_linkButton__0DH3I{display:inline-flex;align-items:center;height:33px;padding:0 13px;border:1px solid var(--border);border-radius:7px;color:var(--text);text-decoration:none;font:700 11px var(--font-mono)}.SettingsConfig_linkButton__0DH3I:hover{background:var(--bg-hover)}.SettingsConfig_dangerButton__XF_f_,.SettingsConfig_primaryButton__Eocwv{height:33px;padding:0 13px;border:0;border-radius:7px;background:var(--accent);color:var(--bg);cursor:pointer;font:700 11px var(--font-mono)}.SettingsConfig_dangerButton__XF_f_{border:1px solid var(--border);background:transparent;color:var(--danger)}.SettingsConfig_primaryButton__Eocwv:disabled{cursor:wait;opacity:.5}.SettingsConfig_empty__erg3A{height:100%;display:grid;place-items:center;padding:30px;color:var(--text-dim);font:12px/1.6 var(--font-mono);text-align:center}@media (max-width:760px){.SettingsConfig_backdrop__i6KYG{padding:8px}.SettingsConfig_window__m7dcs{width:calc(100vw - 16px);height:calc(100dvh - 16px);grid-template-columns:82px minmax(0,1fr);border-radius:10px}.SettingsConfig_brand__DlYlu{padding:14px 6px 9px;text-align:center}.SettingsConfig_closeButton__5y_6F span:first-child,.SettingsConfig_context__N0fl0,.SettingsConfig_eyebrow__uTa5R,.SettingsConfig_navLabel__M1wMP,.SettingsConfig_searchWrap___PWrc{display:none}.SettingsConfig_title__DWTnA{font-size:12px}.SettingsConfig_nav__V8P9S{padding-inline:6px}.SettingsConfig_navButton__CUOqu{height:45px;flex-direction:column;justify-content:center;gap:3px;padding:0 3px}.SettingsConfig_navButton__CUOqu span{display:block;width:100%;overflow:hidden;font-size:8px;text-align:center;text-overflow:ellipsis;white-space:nowrap}.SettingsConfig_closeButton__5y_6F{display:grid;place-items:center}.SettingsConfig_closeButton__5y_6F span:last-child{display:inline}.SettingsConfig_scrollContent__03BsO{padding:24px 16px 40px}.SettingsConfig_settingRow__Jy73r{grid-template-columns:1fr;gap:10px}.SettingsConfig_multiSelect__PTjyr,.SettingsConfig_settingControl__oz5Gn{justify-content:flex-start}.SettingsConfig_mcpLayout__ek_Fi,.SettingsConfig_themeGrid__7Lw8A{grid-template-columns:1fr}.SettingsConfig_mcpList__gZ9_o{min-height:180px;border-right:0;border-bottom:1px solid var(--border)}}
|