@klarkxy/dsh-mood 0.1.2 → 0.1.4
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/docs/README.zh-CN.md +4 -3
- package/lib/client.inner.cjs +0 -9
- package/lib/client.inner.cjs.map +1 -1
- package/lib/client.js +0 -9
- package/lib/contracts.d.ts +3 -1
- package/lib/contracts.js +8 -1
- package/lib/contracts.js.map +1 -1
- package/lib/index.js +6 -6
- package/lib/index.js.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -4,16 +4,16 @@ Default-enabled requirements clarification at the Host `agent/pre-step` boundary
|
|
|
4
4
|
|
|
5
5
|
[简体中文](https://github.com/klarkxy/dsh-editor/blob/main/packages/dsh-mood/docs/README.zh-CN.md)
|
|
6
6
|
|
|
7
|
-
Requires Node.js ≥22 and DSH `0.1.7-
|
|
7
|
+
Requires Node.js ≥22 and DSH `0.1.7-rc.2`. The bundle entry starts enabled and remains independently switchable. Mood does not replace native permissions or writing proposal confirmation.
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
10
|
dsh plugin --profile web add @klarkxy/dsh-ai-services
|
|
11
11
|
dsh plugin --profile web add @klarkxy/dsh-mood
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Enable or disable the feature under **Settings → Plugins**. When enabled, it uses automatic clarification. The chat card uses seat `dsh-editor.chat.events` with `{sessionId, locale}`.
|
|
15
15
|
|
|
16
|
-
Clear requests do not call `mood.analyze`. Auto mode only asks when a conservative check finds material ambiguity or risk. Clarification waits in the same pre-step, then resumes that intercepted request once.
|
|
16
|
+
Clear requests do not call `mood.analyze`. Auto mode only asks when a conservative check finds material ambiguity or risk. Clarification waits in the same pre-step, then resumes that intercepted request once.
|
|
17
17
|
|
|
18
18
|
From the repository root:
|
|
19
19
|
|
package/docs/README.zh-CN.md
CHANGED
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
[English](https://github.com/klarkxy/dsh-editor/blob/main/packages/dsh-mood/README.md)
|
|
6
6
|
|
|
7
|
-
需要 Node.js ≥22 和 DSH `0.1.7-
|
|
7
|
+
需要 Node.js ≥22 和 DSH `0.1.7-rc.2`。插件安装后默认启用,也可在插件设置中关闭。它不会替代原生权限或写作提案确认。
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
+
dsh plugin --profile web add @klarkxy/dsh-ai-services
|
|
10
11
|
dsh plugin --profile web add @klarkxy/dsh-mood
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
在「设置 → 插件」开关需求澄清。启用后按自动模式运行,不再提供单独设置页。对话卡片使用座位 `dsh-editor.chat.events`,参数 `{sessionId, locale}`。
|
|
14
15
|
|
|
15
|
-
表述清楚的请求不调用 `mood.analyze`。自动模式只在确定存在实质含糊或风险时提问。澄清在同一次 pre-step 内等待,然后只恢复这次被拦住的请求。
|
|
16
|
+
表述清楚的请求不调用 `mood.analyze`。自动模式只在确定存在实质含糊或风险时提问。澄清在同一次 pre-step 内等待,然后只恢复这次被拦住的请求。
|
|
16
17
|
|
|
17
18
|
```sh
|
|
18
19
|
pnpm --filter @klarkxy/dsh-mood typecheck
|
package/lib/client.inner.cjs
CHANGED
|
@@ -597,15 +597,6 @@ function apply(ctx) {
|
|
|
597
597
|
document.head.appendChild(style);
|
|
598
598
|
return () => style.remove();
|
|
599
599
|
}, "dsh-mood.styles");
|
|
600
|
-
ctx.effect(() => client.slots.inject("settings.section", () => client.slots.register({
|
|
601
|
-
name: "settings.section",
|
|
602
|
-
id: "mood",
|
|
603
|
-
order: 55,
|
|
604
|
-
label: "需求澄清"
|
|
605
|
-
}, (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MoodSettings, {
|
|
606
|
-
client,
|
|
607
|
-
props
|
|
608
|
-
}))), "dsh-mood.settings");
|
|
609
600
|
ctx.effect(() => client.slots.inject(CHAT_EVENTS_SLOT, () => client.slots.register({
|
|
610
601
|
name: CHAT_EVENTS_SLOT,
|
|
611
602
|
id: "mood",
|
package/lib/client.inner.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.inner.cjs","names":["useSyncExternalStore","useCallback","useRef","useId","useState","useRef"],"sources":["../../dsh-ai-services/src/client-utils.ts","../src/contracts.ts","../src/client.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useSyncExternalStore } from 'react'\n\nexport interface NativeSurfaceClient {\n sessions: {\n binding?(sessionId: string): { eventSource: { subscribe(listener: () => void): () => void } } | undefined\n }\n uiWorkspace: { current?: { getSnapshot(): { sessionId: string } | undefined; subscribe(listener: () => void): () => void } }\n uiSession: { adapter: { current: { getSnapshot(): { key?: string }; subscribe(listener: () => void): () => void } } }\n locale: { getSnapshot(): { active: string }; subscribe(listener: () => void): () => void }\n connection?: { generation?: { subscribe(listener: () => void): () => void } }\n}\n\n/** The Editor retains its manuscript session separately; native DSH exposes the main-view binding. */\nexport function selectedSessionId(client: Pick<NativeSurfaceClient, 'uiWorkspace' | 'uiSession'>): string {\n return client.uiWorkspace.current\n ? client.uiWorkspace.current.getSnapshot()?.sessionId ?? ''\n : client.uiSession.adapter.current.getSnapshot().key ?? ''\n}\n\n/** Owner props win; native settings only supplies close, so resolve its selected session. */\nexport function useNativeSeat(client: NativeSurfaceClient, props: unknown) {\n const current = useSyncExternalStore(\n useCallback((fn: () => void) => (client.uiWorkspace.current ?? client.uiSession.adapter.current).subscribe(fn), [client]),\n useCallback(() => selectedSessionId(client), [client]),\n () => '',\n )\n const language = useSyncExternalStore(\n useCallback((fn: () => void) => client.locale.subscribe(fn), [client]),\n useCallback(() => client.locale.getSnapshot().active, [client]),\n () => 'en',\n )\n const row = props && typeof props === 'object' ? props as Record<string, unknown> : {}\n const owner = row.owner && typeof row.owner === 'object' ? row.owner as Record<string, unknown> : {}\n const sessionId = typeof row.sessionId === 'string' ? row.sessionId\n : typeof owner.sessionId === 'string' ? owner.sessionId : current\n const requestedLocale = row.locale ?? owner.locale ?? language\n return { sessionId, locale: (String(requestedLocale).startsWith('zh') ? 'zh' : 'en') as 'zh' | 'en',\n hidden: row.hidden === true || owner.hidden === true }\n}\n\n/** Refresh on native log boundaries/reconnect/focus. Read-only settling is bounded to an observed job. */\nexport function useFeatureRefresh(\n client: NativeSurfaceClient, sessionId: string, refresh: () => void,\n working = false, enabled = true,\n): void {\n const refreshRef = useRef(refresh)\n refreshRef.current = refresh\n useEffect(() => {\n if (!enabled) return\n let timer: ReturnType<typeof setTimeout> | undefined\n const queue = () => {\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return\n clearTimeout(timer)\n timer = setTimeout(() => refreshRef.current(), 150)\n }\n const source = sessionId ? client.sessions.binding?.(sessionId)?.eventSource : undefined\n const stopEvents = source?.subscribe(queue)\n const stopConnection = client.connection?.generation?.subscribe(queue)\n const visibility = () => { if (document.visibilityState === 'visible') queue() }\n window.addEventListener('focus', queue)\n document.addEventListener('visibilitychange', visibility)\n // Details are collapsed by default; opening an existing panel must get current state.\n document.addEventListener('toggle', queue, true)\n return () => {\n clearTimeout(timer)\n stopEvents?.(); stopConnection?.()\n window.removeEventListener('focus', queue)\n document.removeEventListener('visibilitychange', visibility)\n document.removeEventListener('toggle', queue, true)\n }\n }, [client, sessionId, enabled])\n useEffect(() => {\n if (!enabled || !working) return\n let delay = 250\n const until = Date.now() + 300_000\n let timer: ReturnType<typeof setTimeout>\n const tick = () => {\n if (Date.now() >= until) return\n if (document.visibilityState !== 'hidden') refreshRef.current()\n delay = Math.min(delay * 2, 2000)\n timer = setTimeout(tick, delay)\n }\n timer = setTimeout(tick, delay)\n return () => clearTimeout(timer)\n }, [client, sessionId, working, enabled])\n}\n","/** Browser-safe Mood contracts. Shared TaskContract fields match frozen @klarkxy/dsh-ai-services. */\nimport type { AiFeatureScope, EvidenceRef, ProducerMessageSource, RpcResult, TaskContract } from '@klarkxy/dsh-ai-services/contracts'\n\nexport type { AiFeatureScope, EvidenceRef, ProducerMessageSource, RpcResult, TaskContract }\nexport { projectIdFromCwd } from '@klarkxy/dsh-ai-services/contracts'\n\n/** Frozen shared chat-events seat. Must stay equal to @klarkxy/dsh-ai-services CHAT_EVENTS_SLOT. */\nexport const CHAT_EVENTS_SLOT = 'dsh-editor.chat.events'\nexport const MOOD_PLUGIN = '@klarkxy/dsh-mood'\nexport const MOOD_SOURCE_KIND = 'plugin:@klarkxy/dsh-mood' as const\n/** Production activate identity after scoped pluginName support. */\nexport const MOOD_AI_PLUGIN = MOOD_PLUGIN\nexport const MOOD_RPC_CHANNEL = '/dsh-mood'\nexport const MOOD_ANALYZE_PURPOSE = 'mood.analyze'\nexport const CONTRACT_SECTION = 'dsh-mood:contract'\nexport const PROMPT_VERSION = 'mood.analyze.v1'\nexport const SCHEMA_VERSION = 'mood-contract.v1'\nexport const MAX_QUESTIONS = 3\nexport const MAX_EXCERPT_CHARS = 200\nexport const MAX_PROJECT_ID_CHARS = 32_768\nexport const DEFAULT_QUESTION = '这次要改哪些内容,做到什么程度算完成?'\n\nexport type MoodMode = 'auto' | 'manual' | 'strict'\nexport type ClarificationStatus = 'pending' | 'answered' | 'skipped' | 'cancelled' | 'stale'\nexport type MoodLocale = 'zh' | 'en'\n\nexport interface MoodSettings {\n revision: number\n mode: MoodMode\n}\n\nexport const defaultSettings = (): MoodSettings => ({ revision: 0, mode: 'auto' })\n\nexport interface ClarificationItem {\n id: string\n question: string\n status: ClarificationStatus\n answer?: string\n}\n\nexport interface HeldRequest {\n sourceVersion: string\n trigger: 'material' | 'risk' | 'mild' | 'clear'\n messages: unknown[]\n}\n\nexport interface MoodSessionView {\n sessionId: string\n projectId?: string\n contract?: TaskContract\n clarification: ClarificationItem[]\n pendingManual: boolean\n held: boolean\n}\n\nexport interface MoodStatus {\n settings: MoodSettings\n storageFailed: boolean\n session?: MoodSessionView\n}\n\n/** Native `@deepseek-ai/dsh-user-questions` AskUserQuestionItem. */\nexport interface AskUserQuestionOption {\n label: string\n description?: string\n}\n\nexport interface AskUserQuestionItem {\n id: string\n question: string\n detail?: string\n header?: string\n options?: AskUserQuestionOption[]\n multiSelect?: boolean\n}\n\nexport interface AskUserQuestionAnswerItem {\n id: string\n selected: string[]\n custom?: string\n}\n\nexport interface AskUserQuestionAnswer {\n answers: AskUserQuestionAnswerItem[]\n}\n\nexport interface AskUserRequest {\n questions: AskUserQuestionItem[]\n agent?: unknown\n signal?: AbortSignal\n}\n\nexport function ok<T>(value: T): RpcResult<T> {\n return { ok: true, value }\n}\n\nexport function fail(code: string, message: string): RpcResult<never> {\n return { ok: false, error: { code, message } }\n}\n\nexport function isMoodMode(value: unknown): value is MoodMode {\n return value === 'auto' || value === 'manual' || value === 'strict'\n}\n\nexport function parseSessionId(payload: unknown): string | undefined {\n if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return undefined\n const sessionId = (payload as { sessionId?: unknown }).sessionId\n return typeof sessionId === 'string' && sessionId.length > 0 && sessionId.length <= 200 ? sessionId : undefined\n}\n\nexport function excerptOf(text: string, limit = MAX_EXCERPT_CHARS): string {\n const trimmed = text.replace(/\\s+/g, ' ').trim()\n if (!trimmed) return ''\n return trimmed.length <= limit ? trimmed : `${trimmed.slice(0, limit - 1)}…`\n}\n\nexport function sessionIdOf(agent: { id?: unknown; session?: { id?: unknown } } | undefined): string {\n const fromSession = agent?.session?.id\n if (fromSession != null && String(fromSession).length > 0) return String(fromSession)\n if (agent?.id != null && String(agent.id).length > 0) return String(agent.id)\n return ''\n}\n\nexport function cloneContract(contract: TaskContract): TaskContract {\n return structuredClone(contract)\n}\n\nexport function readinessLabel(readiness: TaskContract['readiness']): string {\n if (readiness === 'clear-request') return '表述清楚'\n if (readiness === 'user-confirmed') return '作者已确认'\n if (readiness === 'disclosed-assumptions') return '按已披露假定继续'\n if (readiness === 'cancelled') return '已取消,未确认'\n if (readiness === 'stale') return '已过期'\n return '待确认'\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport { useFeatureRefresh, useNativeSeat, type NativeSurfaceClient } from '@klarkxy/dsh-ai-services/client-utils'\nimport { useEffect, useId, useRef, useState } from 'react'\nimport {\n CHAT_EVENTS_SLOT, MOOD_RPC_CHANNEL, defaultSettings, type ClarificationItem, type MoodLocale, type MoodMode,\n type MoodStatus, type RpcResult, type TaskContract,\n} from './contracts.ts'\nimport { readinessLabel } from './contracts.ts'\n\nexport const name = 'dsh-mood-client'\nexport const inject = ['slots', 'connection', 'sessions', 'locale', 'uiWorkspace', 'uiSession'] as const\n\ntype Client = NativeSurfaceClient & {\n connection: {\n rpc: { call(channel: string, endpoint: string, payload: unknown): Promise<unknown> }\n generation?: { subscribe(listener: () => void): () => void }\n }\n slots: {\n inject(key: string, callback: () => unknown): () => void\n register(spec: { name: string; id: string; label: string; order: number }, render: unknown): () => void\n }\n}\n\nexport interface MoodSeatProps {\n sessionId?: string\n locale?: MoodLocale\n hidden?: boolean\n}\n\nfunction unwrap<T>(result: RpcResult<T> | unknown): T {\n const row = result as RpcResult<T>\n if (!row || typeof row !== 'object' || !('ok' in row)) throw new Error('请求失败。')\n if (!row.ok) throw new Error(row.error.message)\n return row.value\n}\n\nexport function copy(locale: MoodLocale) {\n if (locale === 'en') {\n return {\n settings: 'Requirements',\n auto: 'Auto',\n manual: 'Manual',\n strict: 'Strict',\n hint: 'Clear requests skip analysis. Confirmation is not file or publish approval.',\n card: 'Task contract',\n amend: 'Amend',\n reanalyze: 'Reanalyze',\n retry: 'Retry original',\n save: 'Save',\n loading: 'Loading…',\n empty: 'No contract yet.',\n goal: 'Goal',\n evidence: 'Evidence',\n questions: 'Questions',\n recovery: 'The original request is waiting. Retry or reanalyze it; it has not been executed.',\n sessionHint: 'Select a session to view its task contract.',\n }\n }\n return {\n settings: '需求澄清',\n auto: '自动',\n manual: '手动',\n strict: '严格',\n hint: '表述清楚的请求不调用分析。确认需求不能代替文件或发布审批。',\n card: '任务约定',\n amend: '修订',\n reanalyze: '重新分析',\n retry: '按原请求重试',\n save: '保存',\n loading: '正在读取…',\n empty: '还没有任务约定。',\n goal: '目标',\n evidence: '证据',\n questions: '澄清',\n recovery: '原请求尚未执行。可重试或手动分析,不会另造一条提问。',\n sessionHint: '选择一个会话后可以查看该会话的任务约定。',\n }\n}\n\nexport function modeFromKey(current: MoodMode, key: string): MoodMode | undefined {\n const order: MoodMode[] = ['auto', 'manual', 'strict']\n const index = order.indexOf(current)\n if (key === 'Home') return 'auto'\n if (key === 'End') return 'strict'\n if (key === 'ArrowRight' || key === 'ArrowDown') return order[(index + 1) % order.length]\n if (key === 'ArrowLeft' || key === 'ArrowUp') return order[(index + order.length - 1) % order.length]\n return undefined\n}\n\nexport function shouldShowCard(\n hidden: boolean,\n contract: TaskContract | undefined,\n pendingManual: boolean,\n recovery = false,\n): boolean {\n if (hidden) return false\n return Boolean(contract) || pendingManual || recovery\n}\n\nexport function isCurrentMoodRequest(input: {\n mounted: boolean\n sessionId: string\n viewSessionId: string\n requestId: number\n latestRequestId: number\n}): boolean {\n return input.mounted && input.sessionId === input.viewSessionId && input.requestId === input.latestRequestId\n}\n\nexport function shouldSkipMoodRefresh(input: { busy: boolean; editing?: boolean }): boolean {\n return input.busy || input.editing === true\n}\n\n/** Read-only status peek; does not bump request generation or abort an in-flight edit. */\nexport async function peekMoodStatus(input: {\n call: (endpoint: string, payload: unknown) => Promise<unknown>\n sessionId: string\n requestId: number\n latestRequestId: () => number\n viewSessionId: () => string\n mounted: () => boolean\n busy: () => boolean\n editing?: () => boolean\n}): Promise<MoodStatus | undefined> {\n if (shouldSkipMoodRefresh({ busy: input.busy(), editing: input.editing?.() === true })) return undefined\n if (!input.sessionId || input.requestId === 0) return undefined\n try {\n const next = unwrap<MoodStatus>(await input.call('status', { sessionId: input.sessionId }) as RpcResult<MoodStatus>)\n if (shouldSkipMoodRefresh({ busy: input.busy(), editing: input.editing?.() === true })) return undefined\n if (!isCurrentMoodRequest({\n mounted: input.mounted(),\n sessionId: input.sessionId,\n viewSessionId: input.viewSessionId(),\n requestId: input.requestId,\n latestRequestId: input.latestRequestId(),\n })) return undefined\n return next\n } catch {\n return undefined\n }\n}\n\nexport function shouldOfferRecovery(status: MoodStatus | undefined): boolean {\n const session = status?.session\n if (!session) return false\n if (session.held || session.pendingManual) return true\n const readiness = session.contract?.readiness\n if (readiness === 'pending' || readiness === 'cancelled') return true\n return session.clarification.some(item => item.status === 'pending' || item.status === 'cancelled')\n}\n\nfunction MoodModePanel({ client, locale }: { client: Client; locale: MoodLocale }) {\n const text = copy(locale)\n const groupId = useId()\n const [status, setStatus] = useState<MoodStatus>()\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState('')\n const [note, setNote] = useState('')\n const requestId = useRef(0)\n\n async function call<T>(endpoint: string, payload: unknown = {}): Promise<T> {\n return unwrap(await client.connection.rpc.call(MOOD_RPC_CHANNEL, endpoint, payload) as RpcResult<T>)\n }\n useEffect(() => {\n const id = ++requestId.current\n let mounted = true\n void call<MoodStatus>('status').then(next => {\n if (!isCurrentMoodRequest({ mounted, sessionId: '', viewSessionId: '', requestId: id, latestRequestId: requestId.current })) return\n setStatus(next)\n }).catch(() => {\n if (mounted && id === requestId.current) setError('无法读取需求澄清设置。')\n })\n return () => { mounted = false }\n }, [client])\n\n async function action(run: () => Promise<void>) {\n setBusy(true); setNote(''); setError('')\n try { await run() }\n catch (cause) { setError(cause instanceof Error ? cause.message : '操作失败。') }\n finally { setBusy(false) }\n }\n\n const mode = status?.settings.mode ?? defaultSettings().mode\n return <section className=\"mood-settings\" data-testid=\"mood-settings\">\n <h3>{text.settings}</h3>\n {error ? <p role=\"alert\">{error}</p> : null}\n {note ? <p role=\"status\">{note}</p> : null}\n {!status ? <p role=\"status\">{text.loading}</p> : null}\n <div role=\"radiogroup\" aria-label={text.settings} onKeyDown={event => {\n const next = modeFromKey(mode, event.key)\n if (!next || busy || !status) return\n event.preventDefault()\n void action(async () => {\n const updated = await call<MoodStatus>('mode', { mode: next, expectedRevision: status.settings.revision })\n setStatus(updated)\n setNote('已保存。')\n })\n }}>\n {([['auto', text.auto], ['manual', text.manual], ['strict', text.strict]] as const).map(([value, label]) => (\n <label key={value}>\n <input id={`${groupId}-${value}`} type=\"radio\" name={groupId} value={value}\n checked={mode === value} disabled={busy || !status}\n onChange={() => {\n if (!status) return\n void action(async () => {\n const updated = await call<MoodStatus>('mode', { mode: value, expectedRevision: status.settings.revision })\n setStatus(updated)\n setNote('已保存。')\n })\n }} />\n {label}\n </label>\n ))}\n </div>\n <p className=\"mood-meta\">{text.hint}</p>\n </section>\n}\n\nfunction MoodContractCard({ client, sessionId, locale, hidden, surface = 'chat' }: MoodSeatProps & {\n client: Client\n surface?: 'chat' | 'settings'\n}) {\n const text = copy(locale === 'en' ? 'en' : 'zh')\n const [status, setStatus] = useState<MoodStatus>()\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState('')\n const [editing, setEditing] = useState(false)\n const [goal, setGoal] = useState('')\n const requestId = useRef(0)\n const viewSession = useRef(sessionId ?? '')\n const liveRef = useRef(true)\n const busyRef = useRef(false)\n const editingRef = useRef(false)\n busyRef.current = busy\n editingRef.current = editing\n\n async function call<T>(endpoint: string, payload: unknown): Promise<T> {\n return unwrap(await client.connection.rpc.call(MOOD_RPC_CHANNEL, endpoint, payload) as RpcResult<T>)\n }\n useEffect(() => {\n liveRef.current = true\n return () => { liveRef.current = false }\n }, [])\n useEffect(() => {\n viewSession.current = sessionId ?? ''\n const id = ++requestId.current\n setStatus(undefined)\n setEditing(false)\n setError('')\n if (!sessionId) return\n let mounted = true\n void call<MoodStatus>('status', { sessionId }).then(next => {\n if (!isCurrentMoodRequest({\n mounted,\n sessionId,\n viewSessionId: viewSession.current,\n requestId: id,\n latestRequestId: requestId.current,\n })) return\n setStatus(next)\n setGoal(next.session?.contract?.goal ?? '')\n }).catch(() => {\n if (!isCurrentMoodRequest({\n mounted,\n sessionId,\n viewSessionId: viewSession.current,\n requestId: id,\n latestRequestId: requestId.current,\n })) return\n setError('无法读取任务约定。')\n })\n return () => { mounted = false }\n }, [client, sessionId])\n\n useFeatureRefresh(client, sessionId ?? '', () => {\n void peekMoodStatus({\n call: (endpoint, payload) => client.connection.rpc.call(MOOD_RPC_CHANNEL, endpoint, payload),\n sessionId: viewSession.current,\n requestId: requestId.current,\n latestRequestId: () => requestId.current,\n viewSessionId: () => viewSession.current,\n mounted: () => liveRef.current,\n busy: () => busyRef.current,\n editing: () => editingRef.current,\n }).then(next => {\n if (!next) return\n setStatus(next)\n if (!editingRef.current) setGoal(next.session?.contract?.goal ?? '')\n })\n }, Boolean(status?.session?.pendingManual) && !busy, Boolean(sessionId) && (surface === 'settings' || !hidden))\n\n const contract = status?.session?.contract\n const pendingManual = Boolean(status?.session?.pendingManual)\n const recovery = shouldOfferRecovery(status)\n if (surface !== 'settings' && !shouldShowCard(Boolean(hidden), contract, pendingManual, recovery)) return null\n\n async function action(run: () => Promise<void>) {\n const id = requestId.current\n const view = viewSession.current\n setBusy(true); setError('')\n try {\n await run()\n } catch (cause) {\n if (!isCurrentMoodRequest({\n mounted: true,\n sessionId: view,\n viewSessionId: viewSession.current,\n requestId: id,\n latestRequestId: requestId.current,\n })) return\n setError(cause instanceof Error ? cause.message : '操作失败。')\n } finally {\n if (isCurrentMoodRequest({\n mounted: true,\n sessionId: view,\n viewSessionId: viewSession.current,\n requestId: id,\n latestRequestId: requestId.current,\n })) setBusy(false)\n }\n }\n\n return <article className=\"mood-card\" data-testid=\"mood-contract-card\" data-session={sessionId || undefined}>\n <header>\n <h3>{text.card}</h3>\n {contract ? <span className=\"mood-meta\">{readinessLabel(contract.readiness)}</span> : null}\n </header>\n {error ? <p role=\"alert\">{error}</p> : null}\n {recovery ? <p role=\"status\">{text.recovery}</p> : null}\n {contract ? <p>{text.goal}:{contract.goal || text.empty}</p> : <p>{text.empty}</p>}\n {contract?.evidence.length ? <ul aria-label={text.evidence}>\n {contract.evidence.map((item: { kind: string; seq: number; excerpt?: string }) => (\n <li key={`${item.kind}-${item.seq}`}>{item.excerpt ?? `#${item.seq}`}</li>\n ))}\n </ul> : null}\n {(status?.session?.clarification ?? []).length ? <ul aria-label={text.questions}>\n {(status?.session?.clarification ?? []).map((item: ClarificationItem) => (\n <li key={item.id}>[{item.status}] {item.question}{item.answer ? ` → ${item.answer}` : ''}</li>\n ))}\n </ul> : null}\n {editing ? <label>{text.goal}\n <textarea aria-label={text.goal} rows={3} value={goal} disabled={busy}\n onChange={event => setGoal(event.target.value)} />\n </label> : null}\n <div className=\"mood-actions\">\n <button type=\"button\" disabled={busy || !contract} onClick={() => {\n if (editing && contract && sessionId) {\n const view = sessionId\n const id = requestId.current\n void action(async () => {\n const next = await call<MoodStatus>('edit', {\n sessionId: view, expectedRevision: contract.revision, patch: { goal },\n })\n if (!isCurrentMoodRequest({\n mounted: true, sessionId: view, viewSessionId: viewSession.current, requestId: id, latestRequestId: requestId.current,\n })) return\n setStatus(next)\n setEditing(false)\n })\n return\n }\n setEditing(true)\n }}>{editing ? text.save : text.amend}</button>\n <button type=\"button\" disabled={busy || !sessionId} onClick={() => {\n const view = sessionId\n if (!view) return\n const id = requestId.current\n void action(async () => {\n const next = await call<MoodStatus>('manual', { sessionId: view })\n if (!isCurrentMoodRequest({\n mounted: true, sessionId: view, viewSessionId: viewSession.current, requestId: id, latestRequestId: requestId.current,\n })) return\n setStatus(next)\n })\n }}>{text.reanalyze}</button>\n {recovery ? <button type=\"button\" disabled={busy || !sessionId || !status?.session?.held} onClick={() => {\n const view = sessionId\n if (!view) return\n const id = requestId.current\n void action(async () => {\n const next = await call<MoodStatus>('retry', { sessionId: view })\n if (!isCurrentMoodRequest({\n mounted: true, sessionId: view, viewSessionId: viewSession.current, requestId: id, latestRequestId: requestId.current,\n })) return\n setStatus(next)\n })\n }}>{text.retry}</button> : null}\n </div>\n </article>\n}\n\nexport function moodPanelKey(sessionId: string, locale: MoodLocale): string {\n return `${sessionId}:${locale}`\n}\n\nexport function MoodSettings({ client, props }: { client: Client; props: unknown }) {\n const seat = useNativeSeat(client, props)\n const text = copy(seat.locale)\n return <div className=\"mood-settings-root\" data-testid=\"mood-settings-root\" data-session={seat.sessionId || undefined}>\n <MoodModePanel client={client} locale={seat.locale} />\n {seat.sessionId\n ? <MoodContractCard key={`contract:${moodPanelKey(seat.sessionId, seat.locale)}`} client={client}\n sessionId={seat.sessionId} locale={seat.locale} surface=\"settings\" />\n : <p className=\"mood-meta\">{text.sessionHint}</p>}\n </div>\n}\n\nexport function MoodChatCard({ client, props }: { client: Client; props: unknown }) {\n const seat = useNativeSeat(client, props)\n if (seat.hidden || !seat.sessionId) return null\n return <MoodContractCard key={moodPanelKey(seat.sessionId, seat.locale)} client={client}\n sessionId={seat.sessionId} locale={seat.locale} hidden={seat.hidden} />\n}\n\nconst styles = `\n.mood-settings-root,.mood-settings,.mood-card{max-width:760px;display:grid;gap:12px;color:inherit;font:400 var(--font-size-2,14px)/1.5 var(--default-font-family,system-ui,sans-serif)}\n.mood-settings-root{gap:16px}\n.mood-settings h3,.mood-card h3{margin:0;font-size:var(--font-size-3,16px);font-weight:600}\n.mood-settings p,.mood-card p,.mood-settings-root p{margin:0;line-height:1.5}\n.mood-meta{font-size:var(--font-size-1,13px);color:var(--gray-11,inherit)}\n.mood-settings [role=\"radiogroup\"]{display:flex;flex-wrap:wrap;gap:12px 20px}\n.mood-settings label{display:flex;gap:8px;align-items:center;min-height:32px}\n.mood-card header{display:flex;justify-content:space-between;gap:12px;align-items:center}\n.mood-card ul{margin:0;padding-left:1.2em}\n.mood-card{padding:14px 16px;border:1px solid var(--gray-6,color-mix(in srgb,currentColor 15%,transparent));border-radius:12px}\n.mood-card textarea{box-sizing:border-box;width:100%;min-width:0;padding:8px 10px;border:1px solid var(--gray-6,color-mix(in srgb,currentColor 22%,transparent));border-radius:8px;background:var(--color-surface,transparent);color:inherit;font:inherit;transition:border-color 150ms ease,box-shadow 150ms ease}\n.mood-card textarea:focus{border-color:var(--accent-9,#3b82f6);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent-9,#3b82f6) 25%,transparent)}\n.mood-actions{display:flex;flex-wrap:wrap;gap:8px}\n.mood-settings button,.mood-card button{min-height:34px;padding:6px 12px;border:1px solid color-mix(in srgb,currentColor 25%,transparent);border-radius:8px;background:transparent;color:inherit;cursor:pointer;font:inherit;transition:background-color 150ms ease,color 150ms ease,border-color 150ms ease,box-shadow 150ms ease,transform 150ms ease}\n.mood-settings button:hover:not(:disabled),.mood-card button:hover:not(:disabled){background:var(--gray-3,color-mix(in srgb,currentColor 6%,transparent));border-color:color-mix(in srgb,currentColor 35%,transparent)}\n.mood-settings button:active:not(:disabled),.mood-card button:active:not(:disabled){transform:scale(.97)}\n.mood-settings button:disabled,.mood-card button:disabled{opacity:.45;cursor:not-allowed}\n.mood-settings :focus-visible,.mood-card :focus-visible,.mood-settings-root :focus-visible{outline:2px solid var(--accent-9,currentColor);outline-offset:3px}\n@media(prefers-reduced-motion:reduce){.mood-settings button,.mood-card button,.mood-card textarea{transition:none}}\n`\n\nexport function apply(ctx: Context): void {\n const client = ctx as unknown as Client\n ctx.effect(() => {\n if (typeof document === 'undefined') return () => {}\n const style = document.createElement('style')\n style.setAttribute('data-plugin', '@klarkxy/dsh-mood')\n style.textContent = styles\n document.head.appendChild(style)\n return () => style.remove()\n }, 'dsh-mood.styles')\n ctx.effect(() => client.slots.inject('settings.section', () => client.slots.register({\n name: 'settings.section', id: 'mood', order: 55, label: '需求澄清',\n }, (props: unknown) => <MoodSettings client={client} props={props} />)), 'dsh-mood.settings')\n ctx.effect(() => client.slots.inject(CHAT_EVENTS_SLOT, () => client.slots.register({\n name: CHAT_EVENTS_SLOT, id: 'mood', order: 10, label: '需求约定',\n }, (props: unknown) => <MoodChatCard client={client} props={props} />)), 'dsh-mood.card')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.inner.cjs","names":["useSyncExternalStore","useCallback","useRef","useId","useState","useRef"],"sources":["../../dsh-ai-services/src/client-utils.ts","../src/contracts.ts","../src/client.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useSyncExternalStore } from 'react'\n\nexport interface NativeSurfaceClient {\n sessions: {\n binding?(sessionId: string): { eventSource: { subscribe(listener: () => void): () => void } } | undefined\n }\n uiWorkspace: { current?: { getSnapshot(): { sessionId: string } | undefined; subscribe(listener: () => void): () => void } }\n uiSession: { adapter: { current: { getSnapshot(): { key?: string }; subscribe(listener: () => void): () => void } } }\n locale: { getSnapshot(): { active: string }; subscribe(listener: () => void): () => void }\n connection?: { generation?: { subscribe(listener: () => void): () => void } }\n}\n\n/** The Editor retains its manuscript session separately; native DSH exposes the main-view binding. */\nexport function selectedSessionId(client: Pick<NativeSurfaceClient, 'uiWorkspace' | 'uiSession'>): string {\n return client.uiWorkspace.current\n ? client.uiWorkspace.current.getSnapshot()?.sessionId ?? ''\n : client.uiSession.adapter.current.getSnapshot().key ?? ''\n}\n\n/** Owner props win; native settings only supplies close, so resolve its selected session. */\nexport function useNativeSeat(client: NativeSurfaceClient, props: unknown) {\n const current = useSyncExternalStore(\n useCallback((fn: () => void) => (client.uiWorkspace.current ?? client.uiSession.adapter.current).subscribe(fn), [client]),\n useCallback(() => selectedSessionId(client), [client]),\n () => '',\n )\n const language = useSyncExternalStore(\n useCallback((fn: () => void) => client.locale.subscribe(fn), [client]),\n useCallback(() => client.locale.getSnapshot().active, [client]),\n () => 'en',\n )\n const row = props && typeof props === 'object' ? props as Record<string, unknown> : {}\n const owner = row.owner && typeof row.owner === 'object' ? row.owner as Record<string, unknown> : {}\n const sessionId = typeof row.sessionId === 'string' ? row.sessionId\n : typeof owner.sessionId === 'string' ? owner.sessionId : current\n const requestedLocale = row.locale ?? owner.locale ?? language\n return { sessionId, locale: (String(requestedLocale).startsWith('zh') ? 'zh' : 'en') as 'zh' | 'en',\n hidden: row.hidden === true || owner.hidden === true }\n}\n\n/** Refresh on native log boundaries/reconnect/focus. Read-only settling is bounded to an observed job. */\nexport function useFeatureRefresh(\n client: NativeSurfaceClient, sessionId: string, refresh: () => void,\n working = false, enabled = true,\n): void {\n const refreshRef = useRef(refresh)\n refreshRef.current = refresh\n useEffect(() => {\n if (!enabled) return\n let timer: ReturnType<typeof setTimeout> | undefined\n const queue = () => {\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return\n clearTimeout(timer)\n timer = setTimeout(() => refreshRef.current(), 150)\n }\n const source = sessionId ? client.sessions.binding?.(sessionId)?.eventSource : undefined\n const stopEvents = source?.subscribe(queue)\n const stopConnection = client.connection?.generation?.subscribe(queue)\n const visibility = () => { if (document.visibilityState === 'visible') queue() }\n window.addEventListener('focus', queue)\n document.addEventListener('visibilitychange', visibility)\n // Details are collapsed by default; opening an existing panel must get current state.\n document.addEventListener('toggle', queue, true)\n return () => {\n clearTimeout(timer)\n stopEvents?.(); stopConnection?.()\n window.removeEventListener('focus', queue)\n document.removeEventListener('visibilitychange', visibility)\n document.removeEventListener('toggle', queue, true)\n }\n }, [client, sessionId, enabled])\n useEffect(() => {\n if (!enabled || !working) return\n let delay = 250\n const until = Date.now() + 300_000\n let timer: ReturnType<typeof setTimeout>\n const tick = () => {\n if (Date.now() >= until) return\n if (document.visibilityState !== 'hidden') refreshRef.current()\n delay = Math.min(delay * 2, 2000)\n timer = setTimeout(tick, delay)\n }\n timer = setTimeout(tick, delay)\n return () => clearTimeout(timer)\n }, [client, sessionId, working, enabled])\n}\n","/** Browser-safe Mood contracts. Shared TaskContract fields match frozen @klarkxy/dsh-ai-services. */\nimport type { AiFeatureScope, EvidenceRef, ProducerMessageSource, RpcResult, TaskContract } from '@klarkxy/dsh-ai-services/contracts'\n\nexport type { AiFeatureScope, EvidenceRef, ProducerMessageSource, RpcResult, TaskContract }\nexport { projectIdFromCwd } from '@klarkxy/dsh-ai-services/contracts'\n\n/** Frozen shared chat-events seat. Must stay equal to @klarkxy/dsh-ai-services CHAT_EVENTS_SLOT. */\nexport const CHAT_EVENTS_SLOT = 'dsh-editor.chat.events'\nexport const MOOD_PLUGIN = '@klarkxy/dsh-mood'\nexport const MOOD_SOURCE_KIND = 'plugin:@klarkxy/dsh-mood' as const\n/** Production activate identity after scoped pluginName support. */\nexport const MOOD_AI_PLUGIN = MOOD_PLUGIN\nexport const MOOD_RPC_CHANNEL = '/dsh-mood'\nexport const MOOD_ANALYZE_PURPOSE = 'mood.analyze'\nexport const CONTRACT_SECTION = 'dsh-mood:contract'\nexport const PROMPT_VERSION = 'mood.analyze.v1'\nexport const SCHEMA_VERSION = 'mood-contract.v1'\nexport const MAX_QUESTIONS = 3\nexport const MAX_EXCERPT_CHARS = 200\nexport const MAX_PROJECT_ID_CHARS = 32_768\nexport const DEFAULT_QUESTION = '这次要改哪些内容,做到什么程度算完成?'\n\nexport type MoodMode = 'auto' | 'manual' | 'strict'\nexport type ClarificationStatus = 'pending' | 'answered' | 'skipped' | 'cancelled' | 'stale'\nexport type MoodLocale = 'zh' | 'en'\n\nexport interface MoodSettings {\n revision: number\n mode: MoodMode\n}\n\nexport const defaultSettings = (): MoodSettings => ({ revision: 0, mode: 'auto' })\n\n/** Enabled Mood always runs auto; persisted manual/strict flags are ignored. */\nexport function operationalSettings(settings: MoodSettings): MoodSettings {\n return { revision: settings.revision, mode: 'auto' }\n}\n\nexport interface ClarificationItem {\n id: string\n question: string\n status: ClarificationStatus\n answer?: string\n}\n\nexport interface HeldRequest {\n sourceVersion: string\n trigger: 'material' | 'risk' | 'mild' | 'clear'\n messages: unknown[]\n}\n\nexport interface MoodSessionView {\n sessionId: string\n projectId?: string\n contract?: TaskContract\n clarification: ClarificationItem[]\n pendingManual: boolean\n held: boolean\n}\n\nexport interface MoodStatus {\n settings: MoodSettings\n storageFailed: boolean\n session?: MoodSessionView\n}\n\n/** Native `@deepseek-ai/dsh-user-questions` AskUserQuestionItem. */\nexport interface AskUserQuestionOption {\n label: string\n description?: string\n}\n\nexport interface AskUserQuestionItem {\n id: string\n question: string\n detail?: string\n header?: string\n options?: AskUserQuestionOption[]\n multiSelect?: boolean\n}\n\nexport interface AskUserQuestionAnswerItem {\n id: string\n selected: string[]\n custom?: string\n}\n\nexport interface AskUserQuestionAnswer {\n answers: AskUserQuestionAnswerItem[]\n}\n\nexport interface AskUserRequest {\n questions: AskUserQuestionItem[]\n agent?: unknown\n signal?: AbortSignal\n}\n\nexport function ok<T>(value: T): RpcResult<T> {\n return { ok: true, value }\n}\n\nexport function fail(code: string, message: string): RpcResult<never> {\n return { ok: false, error: { code, message } }\n}\n\nexport function isMoodMode(value: unknown): value is MoodMode {\n return value === 'auto' || value === 'manual' || value === 'strict'\n}\n\nexport function parseSessionId(payload: unknown): string | undefined {\n if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return undefined\n const sessionId = (payload as { sessionId?: unknown }).sessionId\n return typeof sessionId === 'string' && sessionId.length > 0 && sessionId.length <= 200 ? sessionId : undefined\n}\n\nexport function excerptOf(text: string, limit = MAX_EXCERPT_CHARS): string {\n const trimmed = text.replace(/\\s+/g, ' ').trim()\n if (!trimmed) return ''\n return trimmed.length <= limit ? trimmed : `${trimmed.slice(0, limit - 1)}…`\n}\n\nexport function sessionIdOf(agent: { id?: unknown; session?: { id?: unknown } } | undefined): string {\n const fromSession = agent?.session?.id\n if (fromSession != null && String(fromSession).length > 0) return String(fromSession)\n if (agent?.id != null && String(agent.id).length > 0) return String(agent.id)\n return ''\n}\n\nexport function cloneContract(contract: TaskContract): TaskContract {\n return structuredClone(contract)\n}\n\nexport function readinessLabel(readiness: TaskContract['readiness']): string {\n if (readiness === 'clear-request') return '表述清楚'\n if (readiness === 'user-confirmed') return '作者已确认'\n if (readiness === 'disclosed-assumptions') return '按已披露假定继续'\n if (readiness === 'cancelled') return '已取消,未确认'\n if (readiness === 'stale') return '已过期'\n return '待确认'\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport { useFeatureRefresh, useNativeSeat, type NativeSurfaceClient } from '@klarkxy/dsh-ai-services/client-utils'\nimport { useEffect, useId, useRef, useState } from 'react'\nimport {\n CHAT_EVENTS_SLOT, MOOD_RPC_CHANNEL, defaultSettings, type ClarificationItem, type MoodLocale, type MoodMode,\n type MoodStatus, type RpcResult, type TaskContract,\n} from './contracts.ts'\nimport { readinessLabel } from './contracts.ts'\n\nexport const name = 'dsh-mood-client'\nexport const inject = ['slots', 'connection', 'sessions', 'locale', 'uiWorkspace', 'uiSession'] as const\n\ntype Client = NativeSurfaceClient & {\n connection: {\n rpc: { call(channel: string, endpoint: string, payload: unknown): Promise<unknown> }\n generation?: { subscribe(listener: () => void): () => void }\n }\n slots: {\n inject(key: string, callback: () => unknown): () => void\n register(spec: { name: string; id: string; label: string; order: number }, render: unknown): () => void\n }\n}\n\nexport interface MoodSeatProps {\n sessionId?: string\n locale?: MoodLocale\n hidden?: boolean\n}\n\nfunction unwrap<T>(result: RpcResult<T> | unknown): T {\n const row = result as RpcResult<T>\n if (!row || typeof row !== 'object' || !('ok' in row)) throw new Error('请求失败。')\n if (!row.ok) throw new Error(row.error.message)\n return row.value\n}\n\nexport function copy(locale: MoodLocale) {\n if (locale === 'en') {\n return {\n settings: 'Requirements',\n auto: 'Auto',\n manual: 'Manual',\n strict: 'Strict',\n hint: 'Clear requests skip analysis. Confirmation is not file or publish approval.',\n card: 'Task contract',\n amend: 'Amend',\n reanalyze: 'Reanalyze',\n retry: 'Retry original',\n save: 'Save',\n loading: 'Loading…',\n empty: 'No contract yet.',\n goal: 'Goal',\n evidence: 'Evidence',\n questions: 'Questions',\n recovery: 'The original request is waiting. Retry or reanalyze it; it has not been executed.',\n sessionHint: 'Select a session to view its task contract.',\n }\n }\n return {\n settings: '需求澄清',\n auto: '自动',\n manual: '手动',\n strict: '严格',\n hint: '表述清楚的请求不调用分析。确认需求不能代替文件或发布审批。',\n card: '任务约定',\n amend: '修订',\n reanalyze: '重新分析',\n retry: '按原请求重试',\n save: '保存',\n loading: '正在读取…',\n empty: '还没有任务约定。',\n goal: '目标',\n evidence: '证据',\n questions: '澄清',\n recovery: '原请求尚未执行。可重试或手动分析,不会另造一条提问。',\n sessionHint: '选择一个会话后可以查看该会话的任务约定。',\n }\n}\n\nexport function modeFromKey(current: MoodMode, key: string): MoodMode | undefined {\n const order: MoodMode[] = ['auto', 'manual', 'strict']\n const index = order.indexOf(current)\n if (key === 'Home') return 'auto'\n if (key === 'End') return 'strict'\n if (key === 'ArrowRight' || key === 'ArrowDown') return order[(index + 1) % order.length]\n if (key === 'ArrowLeft' || key === 'ArrowUp') return order[(index + order.length - 1) % order.length]\n return undefined\n}\n\nexport function shouldShowCard(\n hidden: boolean,\n contract: TaskContract | undefined,\n pendingManual: boolean,\n recovery = false,\n): boolean {\n if (hidden) return false\n return Boolean(contract) || pendingManual || recovery\n}\n\nexport function isCurrentMoodRequest(input: {\n mounted: boolean\n sessionId: string\n viewSessionId: string\n requestId: number\n latestRequestId: number\n}): boolean {\n return input.mounted && input.sessionId === input.viewSessionId && input.requestId === input.latestRequestId\n}\n\nexport function shouldSkipMoodRefresh(input: { busy: boolean; editing?: boolean }): boolean {\n return input.busy || input.editing === true\n}\n\n/** Read-only status peek; does not bump request generation or abort an in-flight edit. */\nexport async function peekMoodStatus(input: {\n call: (endpoint: string, payload: unknown) => Promise<unknown>\n sessionId: string\n requestId: number\n latestRequestId: () => number\n viewSessionId: () => string\n mounted: () => boolean\n busy: () => boolean\n editing?: () => boolean\n}): Promise<MoodStatus | undefined> {\n if (shouldSkipMoodRefresh({ busy: input.busy(), editing: input.editing?.() === true })) return undefined\n if (!input.sessionId || input.requestId === 0) return undefined\n try {\n const next = unwrap<MoodStatus>(await input.call('status', { sessionId: input.sessionId }) as RpcResult<MoodStatus>)\n if (shouldSkipMoodRefresh({ busy: input.busy(), editing: input.editing?.() === true })) return undefined\n if (!isCurrentMoodRequest({\n mounted: input.mounted(),\n sessionId: input.sessionId,\n viewSessionId: input.viewSessionId(),\n requestId: input.requestId,\n latestRequestId: input.latestRequestId(),\n })) return undefined\n return next\n } catch {\n return undefined\n }\n}\n\nexport function shouldOfferRecovery(status: MoodStatus | undefined): boolean {\n const session = status?.session\n if (!session) return false\n if (session.held || session.pendingManual) return true\n const readiness = session.contract?.readiness\n if (readiness === 'pending' || readiness === 'cancelled') return true\n return session.clarification.some(item => item.status === 'pending' || item.status === 'cancelled')\n}\n\nfunction MoodModePanel({ client, locale }: { client: Client; locale: MoodLocale }) {\n const text = copy(locale)\n const groupId = useId()\n const [status, setStatus] = useState<MoodStatus>()\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState('')\n const [note, setNote] = useState('')\n const requestId = useRef(0)\n\n async function call<T>(endpoint: string, payload: unknown = {}): Promise<T> {\n return unwrap(await client.connection.rpc.call(MOOD_RPC_CHANNEL, endpoint, payload) as RpcResult<T>)\n }\n useEffect(() => {\n const id = ++requestId.current\n let mounted = true\n void call<MoodStatus>('status').then(next => {\n if (!isCurrentMoodRequest({ mounted, sessionId: '', viewSessionId: '', requestId: id, latestRequestId: requestId.current })) return\n setStatus(next)\n }).catch(() => {\n if (mounted && id === requestId.current) setError('无法读取需求澄清设置。')\n })\n return () => { mounted = false }\n }, [client])\n\n async function action(run: () => Promise<void>) {\n setBusy(true); setNote(''); setError('')\n try { await run() }\n catch (cause) { setError(cause instanceof Error ? cause.message : '操作失败。') }\n finally { setBusy(false) }\n }\n\n const mode = status?.settings.mode ?? defaultSettings().mode\n return <section className=\"mood-settings\" data-testid=\"mood-settings\">\n <h3>{text.settings}</h3>\n {error ? <p role=\"alert\">{error}</p> : null}\n {note ? <p role=\"status\">{note}</p> : null}\n {!status ? <p role=\"status\">{text.loading}</p> : null}\n <div role=\"radiogroup\" aria-label={text.settings} onKeyDown={event => {\n const next = modeFromKey(mode, event.key)\n if (!next || busy || !status) return\n event.preventDefault()\n void action(async () => {\n const updated = await call<MoodStatus>('mode', { mode: next, expectedRevision: status.settings.revision })\n setStatus(updated)\n setNote('已保存。')\n })\n }}>\n {([['auto', text.auto], ['manual', text.manual], ['strict', text.strict]] as const).map(([value, label]) => (\n <label key={value}>\n <input id={`${groupId}-${value}`} type=\"radio\" name={groupId} value={value}\n checked={mode === value} disabled={busy || !status}\n onChange={() => {\n if (!status) return\n void action(async () => {\n const updated = await call<MoodStatus>('mode', { mode: value, expectedRevision: status.settings.revision })\n setStatus(updated)\n setNote('已保存。')\n })\n }} />\n {label}\n </label>\n ))}\n </div>\n <p className=\"mood-meta\">{text.hint}</p>\n </section>\n}\n\nfunction MoodContractCard({ client, sessionId, locale, hidden, surface = 'chat' }: MoodSeatProps & {\n client: Client\n surface?: 'chat' | 'settings'\n}) {\n const text = copy(locale === 'en' ? 'en' : 'zh')\n const [status, setStatus] = useState<MoodStatus>()\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState('')\n const [editing, setEditing] = useState(false)\n const [goal, setGoal] = useState('')\n const requestId = useRef(0)\n const viewSession = useRef(sessionId ?? '')\n const liveRef = useRef(true)\n const busyRef = useRef(false)\n const editingRef = useRef(false)\n busyRef.current = busy\n editingRef.current = editing\n\n async function call<T>(endpoint: string, payload: unknown): Promise<T> {\n return unwrap(await client.connection.rpc.call(MOOD_RPC_CHANNEL, endpoint, payload) as RpcResult<T>)\n }\n useEffect(() => {\n liveRef.current = true\n return () => { liveRef.current = false }\n }, [])\n useEffect(() => {\n viewSession.current = sessionId ?? ''\n const id = ++requestId.current\n setStatus(undefined)\n setEditing(false)\n setError('')\n if (!sessionId) return\n let mounted = true\n void call<MoodStatus>('status', { sessionId }).then(next => {\n if (!isCurrentMoodRequest({\n mounted,\n sessionId,\n viewSessionId: viewSession.current,\n requestId: id,\n latestRequestId: requestId.current,\n })) return\n setStatus(next)\n setGoal(next.session?.contract?.goal ?? '')\n }).catch(() => {\n if (!isCurrentMoodRequest({\n mounted,\n sessionId,\n viewSessionId: viewSession.current,\n requestId: id,\n latestRequestId: requestId.current,\n })) return\n setError('无法读取任务约定。')\n })\n return () => { mounted = false }\n }, [client, sessionId])\n\n useFeatureRefresh(client, sessionId ?? '', () => {\n void peekMoodStatus({\n call: (endpoint, payload) => client.connection.rpc.call(MOOD_RPC_CHANNEL, endpoint, payload),\n sessionId: viewSession.current,\n requestId: requestId.current,\n latestRequestId: () => requestId.current,\n viewSessionId: () => viewSession.current,\n mounted: () => liveRef.current,\n busy: () => busyRef.current,\n editing: () => editingRef.current,\n }).then(next => {\n if (!next) return\n setStatus(next)\n if (!editingRef.current) setGoal(next.session?.contract?.goal ?? '')\n })\n }, Boolean(status?.session?.pendingManual) && !busy, Boolean(sessionId) && (surface === 'settings' || !hidden))\n\n const contract = status?.session?.contract\n const pendingManual = Boolean(status?.session?.pendingManual)\n const recovery = shouldOfferRecovery(status)\n if (surface !== 'settings' && !shouldShowCard(Boolean(hidden), contract, pendingManual, recovery)) return null\n\n async function action(run: () => Promise<void>) {\n const id = requestId.current\n const view = viewSession.current\n setBusy(true); setError('')\n try {\n await run()\n } catch (cause) {\n if (!isCurrentMoodRequest({\n mounted: true,\n sessionId: view,\n viewSessionId: viewSession.current,\n requestId: id,\n latestRequestId: requestId.current,\n })) return\n setError(cause instanceof Error ? cause.message : '操作失败。')\n } finally {\n if (isCurrentMoodRequest({\n mounted: true,\n sessionId: view,\n viewSessionId: viewSession.current,\n requestId: id,\n latestRequestId: requestId.current,\n })) setBusy(false)\n }\n }\n\n return <article className=\"mood-card\" data-testid=\"mood-contract-card\" data-session={sessionId || undefined}>\n <header>\n <h3>{text.card}</h3>\n {contract ? <span className=\"mood-meta\">{readinessLabel(contract.readiness)}</span> : null}\n </header>\n {error ? <p role=\"alert\">{error}</p> : null}\n {recovery ? <p role=\"status\">{text.recovery}</p> : null}\n {contract ? <p>{text.goal}:{contract.goal || text.empty}</p> : <p>{text.empty}</p>}\n {contract?.evidence.length ? <ul aria-label={text.evidence}>\n {contract.evidence.map((item: { kind: string; seq: number; excerpt?: string }) => (\n <li key={`${item.kind}-${item.seq}`}>{item.excerpt ?? `#${item.seq}`}</li>\n ))}\n </ul> : null}\n {(status?.session?.clarification ?? []).length ? <ul aria-label={text.questions}>\n {(status?.session?.clarification ?? []).map((item: ClarificationItem) => (\n <li key={item.id}>[{item.status}] {item.question}{item.answer ? ` → ${item.answer}` : ''}</li>\n ))}\n </ul> : null}\n {editing ? <label>{text.goal}\n <textarea aria-label={text.goal} rows={3} value={goal} disabled={busy}\n onChange={event => setGoal(event.target.value)} />\n </label> : null}\n <div className=\"mood-actions\">\n <button type=\"button\" disabled={busy || !contract} onClick={() => {\n if (editing && contract && sessionId) {\n const view = sessionId\n const id = requestId.current\n void action(async () => {\n const next = await call<MoodStatus>('edit', {\n sessionId: view, expectedRevision: contract.revision, patch: { goal },\n })\n if (!isCurrentMoodRequest({\n mounted: true, sessionId: view, viewSessionId: viewSession.current, requestId: id, latestRequestId: requestId.current,\n })) return\n setStatus(next)\n setEditing(false)\n })\n return\n }\n setEditing(true)\n }}>{editing ? text.save : text.amend}</button>\n <button type=\"button\" disabled={busy || !sessionId} onClick={() => {\n const view = sessionId\n if (!view) return\n const id = requestId.current\n void action(async () => {\n const next = await call<MoodStatus>('manual', { sessionId: view })\n if (!isCurrentMoodRequest({\n mounted: true, sessionId: view, viewSessionId: viewSession.current, requestId: id, latestRequestId: requestId.current,\n })) return\n setStatus(next)\n })\n }}>{text.reanalyze}</button>\n {recovery ? <button type=\"button\" disabled={busy || !sessionId || !status?.session?.held} onClick={() => {\n const view = sessionId\n if (!view) return\n const id = requestId.current\n void action(async () => {\n const next = await call<MoodStatus>('retry', { sessionId: view })\n if (!isCurrentMoodRequest({\n mounted: true, sessionId: view, viewSessionId: viewSession.current, requestId: id, latestRequestId: requestId.current,\n })) return\n setStatus(next)\n })\n }}>{text.retry}</button> : null}\n </div>\n </article>\n}\n\nexport function moodPanelKey(sessionId: string, locale: MoodLocale): string {\n return `${sessionId}:${locale}`\n}\n\nexport function MoodSettings({ client, props }: { client: Client; props: unknown }) {\n const seat = useNativeSeat(client, props)\n const text = copy(seat.locale)\n return <div className=\"mood-settings-root\" data-testid=\"mood-settings-root\" data-session={seat.sessionId || undefined}>\n <MoodModePanel client={client} locale={seat.locale} />\n {seat.sessionId\n ? <MoodContractCard key={`contract:${moodPanelKey(seat.sessionId, seat.locale)}`} client={client}\n sessionId={seat.sessionId} locale={seat.locale} surface=\"settings\" />\n : <p className=\"mood-meta\">{text.sessionHint}</p>}\n </div>\n}\n\nexport function MoodChatCard({ client, props }: { client: Client; props: unknown }) {\n const seat = useNativeSeat(client, props)\n if (seat.hidden || !seat.sessionId) return null\n return <MoodContractCard key={moodPanelKey(seat.sessionId, seat.locale)} client={client}\n sessionId={seat.sessionId} locale={seat.locale} hidden={seat.hidden} />\n}\n\nconst styles = `\n.mood-settings-root,.mood-settings,.mood-card{max-width:760px;display:grid;gap:12px;color:inherit;font:400 var(--font-size-2,14px)/1.5 var(--default-font-family,system-ui,sans-serif)}\n.mood-settings-root{gap:16px}\n.mood-settings h3,.mood-card h3{margin:0;font-size:var(--font-size-3,16px);font-weight:600}\n.mood-settings p,.mood-card p,.mood-settings-root p{margin:0;line-height:1.5}\n.mood-meta{font-size:var(--font-size-1,13px);color:var(--gray-11,inherit)}\n.mood-settings [role=\"radiogroup\"]{display:flex;flex-wrap:wrap;gap:12px 20px}\n.mood-settings label{display:flex;gap:8px;align-items:center;min-height:32px}\n.mood-card header{display:flex;justify-content:space-between;gap:12px;align-items:center}\n.mood-card ul{margin:0;padding-left:1.2em}\n.mood-card{padding:14px 16px;border:1px solid var(--gray-6,color-mix(in srgb,currentColor 15%,transparent));border-radius:12px}\n.mood-card textarea{box-sizing:border-box;width:100%;min-width:0;padding:8px 10px;border:1px solid var(--gray-6,color-mix(in srgb,currentColor 22%,transparent));border-radius:8px;background:var(--color-surface,transparent);color:inherit;font:inherit;transition:border-color 150ms ease,box-shadow 150ms ease}\n.mood-card textarea:focus{border-color:var(--accent-9,#3b82f6);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent-9,#3b82f6) 25%,transparent)}\n.mood-actions{display:flex;flex-wrap:wrap;gap:8px}\n.mood-settings button,.mood-card button{min-height:34px;padding:6px 12px;border:1px solid color-mix(in srgb,currentColor 25%,transparent);border-radius:8px;background:transparent;color:inherit;cursor:pointer;font:inherit;transition:background-color 150ms ease,color 150ms ease,border-color 150ms ease,box-shadow 150ms ease,transform 150ms ease}\n.mood-settings button:hover:not(:disabled),.mood-card button:hover:not(:disabled){background:var(--gray-3,color-mix(in srgb,currentColor 6%,transparent));border-color:color-mix(in srgb,currentColor 35%,transparent)}\n.mood-settings button:active:not(:disabled),.mood-card button:active:not(:disabled){transform:scale(.97)}\n.mood-settings button:disabled,.mood-card button:disabled{opacity:.45;cursor:not-allowed}\n.mood-settings :focus-visible,.mood-card :focus-visible,.mood-settings-root :focus-visible{outline:2px solid var(--accent-9,currentColor);outline-offset:3px}\n@media(prefers-reduced-motion:reduce){.mood-settings button,.mood-card button,.mood-card textarea{transition:none}}\n`\n\nexport function apply(ctx: Context): void {\n const client = ctx as unknown as Client\n ctx.effect(() => {\n if (typeof document === 'undefined') return () => {}\n const style = document.createElement('style')\n style.setAttribute('data-plugin', '@klarkxy/dsh-mood')\n style.textContent = styles\n document.head.appendChild(style)\n return () => style.remove()\n }, 'dsh-mood.styles')\n ctx.effect(() => client.slots.inject(CHAT_EVENTS_SLOT, () => client.slots.register({\n name: CHAT_EVENTS_SLOT, id: 'mood', order: 10, label: '需求约定',\n }, (props: unknown) => <MoodChatCard client={client} props={props} />)), 'dsh-mood.card')\n}\n"],"mappings":"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"}
|
package/lib/client.js
CHANGED
|
@@ -764,15 +764,6 @@ function apply(ctx) {
|
|
|
764
764
|
document.head.appendChild(style);
|
|
765
765
|
return () => style.remove();
|
|
766
766
|
}, "dsh-mood.styles");
|
|
767
|
-
ctx.effect(() => client.slots.inject("settings.section", () => client.slots.register({
|
|
768
|
-
name: "settings.section",
|
|
769
|
-
id: "mood",
|
|
770
|
-
order: 55,
|
|
771
|
-
label: "需求澄清"
|
|
772
|
-
}, (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MoodSettings, {
|
|
773
|
-
client,
|
|
774
|
-
props
|
|
775
|
-
}))), "dsh-mood.settings");
|
|
776
767
|
ctx.effect(() => client.slots.inject(CHAT_EVENTS_SLOT, () => client.slots.register({
|
|
777
768
|
name: CHAT_EVENTS_SLOT,
|
|
778
769
|
id: "mood",
|
package/lib/contracts.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ interface MoodSettings {
|
|
|
23
23
|
mode: MoodMode;
|
|
24
24
|
}
|
|
25
25
|
declare const defaultSettings: () => MoodSettings;
|
|
26
|
+
/** Enabled Mood always runs auto; persisted manual/strict flags are ignored. */
|
|
27
|
+
declare function operationalSettings(settings: MoodSettings): MoodSettings;
|
|
26
28
|
interface ClarificationItem {
|
|
27
29
|
id: string;
|
|
28
30
|
question: string;
|
|
@@ -87,5 +89,5 @@ declare function sessionIdOf(agent: {
|
|
|
87
89
|
declare function cloneContract(contract: TaskContract): TaskContract;
|
|
88
90
|
declare function readinessLabel(readiness: TaskContract['readiness']): string;
|
|
89
91
|
//#endregion
|
|
90
|
-
export { type AiFeatureScope, AskUserQuestionAnswer, AskUserQuestionAnswerItem, AskUserQuestionItem, AskUserQuestionOption, AskUserRequest, CHAT_EVENTS_SLOT, CONTRACT_SECTION, ClarificationItem, ClarificationStatus, DEFAULT_QUESTION, type EvidenceRef, HeldRequest, MAX_EXCERPT_CHARS, MAX_PROJECT_ID_CHARS, MAX_QUESTIONS, MOOD_AI_PLUGIN, MOOD_ANALYZE_PURPOSE, MOOD_PLUGIN, MOOD_RPC_CHANNEL, MOOD_SOURCE_KIND, MoodLocale, MoodMode, MoodSessionView, MoodSettings, MoodStatus, PROMPT_VERSION, type ProducerMessageSource, type RpcResult, SCHEMA_VERSION, type TaskContract, cloneContract, defaultSettings, excerptOf, fail, isMoodMode, ok, parseSessionId, projectIdFromCwd, readinessLabel, sessionIdOf };
|
|
92
|
+
export { type AiFeatureScope, AskUserQuestionAnswer, AskUserQuestionAnswerItem, AskUserQuestionItem, AskUserQuestionOption, AskUserRequest, CHAT_EVENTS_SLOT, CONTRACT_SECTION, ClarificationItem, ClarificationStatus, DEFAULT_QUESTION, type EvidenceRef, HeldRequest, MAX_EXCERPT_CHARS, MAX_PROJECT_ID_CHARS, MAX_QUESTIONS, MOOD_AI_PLUGIN, MOOD_ANALYZE_PURPOSE, MOOD_PLUGIN, MOOD_RPC_CHANNEL, MOOD_SOURCE_KIND, MoodLocale, MoodMode, MoodSessionView, MoodSettings, MoodStatus, PROMPT_VERSION, type ProducerMessageSource, type RpcResult, SCHEMA_VERSION, type TaskContract, cloneContract, defaultSettings, excerptOf, fail, isMoodMode, ok, operationalSettings, parseSessionId, projectIdFromCwd, readinessLabel, sessionIdOf };
|
|
91
93
|
//# sourceMappingURL=contracts.d.ts.map
|
package/lib/contracts.js
CHANGED
|
@@ -19,6 +19,13 @@ const defaultSettings = () => ({
|
|
|
19
19
|
revision: 0,
|
|
20
20
|
mode: "auto"
|
|
21
21
|
});
|
|
22
|
+
/** Enabled Mood always runs auto; persisted manual/strict flags are ignored. */
|
|
23
|
+
function operationalSettings(settings) {
|
|
24
|
+
return {
|
|
25
|
+
revision: settings.revision,
|
|
26
|
+
mode: "auto"
|
|
27
|
+
};
|
|
28
|
+
}
|
|
22
29
|
function ok(value) {
|
|
23
30
|
return {
|
|
24
31
|
ok: true,
|
|
@@ -65,6 +72,6 @@ function readinessLabel(readiness) {
|
|
|
65
72
|
return "待确认";
|
|
66
73
|
}
|
|
67
74
|
//#endregion
|
|
68
|
-
export { CHAT_EVENTS_SLOT, CONTRACT_SECTION, DEFAULT_QUESTION, MAX_EXCERPT_CHARS, MAX_PROJECT_ID_CHARS, MAX_QUESTIONS, MOOD_AI_PLUGIN, MOOD_ANALYZE_PURPOSE, MOOD_PLUGIN, MOOD_RPC_CHANNEL, MOOD_SOURCE_KIND, PROMPT_VERSION, SCHEMA_VERSION, cloneContract, defaultSettings, excerptOf, fail, isMoodMode, ok, parseSessionId, projectIdFromCwd, readinessLabel, sessionIdOf };
|
|
75
|
+
export { CHAT_EVENTS_SLOT, CONTRACT_SECTION, DEFAULT_QUESTION, MAX_EXCERPT_CHARS, MAX_PROJECT_ID_CHARS, MAX_QUESTIONS, MOOD_AI_PLUGIN, MOOD_ANALYZE_PURPOSE, MOOD_PLUGIN, MOOD_RPC_CHANNEL, MOOD_SOURCE_KIND, PROMPT_VERSION, SCHEMA_VERSION, cloneContract, defaultSettings, excerptOf, fail, isMoodMode, ok, operationalSettings, parseSessionId, projectIdFromCwd, readinessLabel, sessionIdOf };
|
|
69
76
|
|
|
70
77
|
//# sourceMappingURL=contracts.js.map
|
package/lib/contracts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","names":[],"sources":["../src/contracts.ts"],"sourcesContent":["/** Browser-safe Mood contracts. Shared TaskContract fields match frozen @klarkxy/dsh-ai-services. */\nimport type { AiFeatureScope, EvidenceRef, ProducerMessageSource, RpcResult, TaskContract } from '@klarkxy/dsh-ai-services/contracts'\n\nexport type { AiFeatureScope, EvidenceRef, ProducerMessageSource, RpcResult, TaskContract }\nexport { projectIdFromCwd } from '@klarkxy/dsh-ai-services/contracts'\n\n/** Frozen shared chat-events seat. Must stay equal to @klarkxy/dsh-ai-services CHAT_EVENTS_SLOT. */\nexport const CHAT_EVENTS_SLOT = 'dsh-editor.chat.events'\nexport const MOOD_PLUGIN = '@klarkxy/dsh-mood'\nexport const MOOD_SOURCE_KIND = 'plugin:@klarkxy/dsh-mood' as const\n/** Production activate identity after scoped pluginName support. */\nexport const MOOD_AI_PLUGIN = MOOD_PLUGIN\nexport const MOOD_RPC_CHANNEL = '/dsh-mood'\nexport const MOOD_ANALYZE_PURPOSE = 'mood.analyze'\nexport const CONTRACT_SECTION = 'dsh-mood:contract'\nexport const PROMPT_VERSION = 'mood.analyze.v1'\nexport const SCHEMA_VERSION = 'mood-contract.v1'\nexport const MAX_QUESTIONS = 3\nexport const MAX_EXCERPT_CHARS = 200\nexport const MAX_PROJECT_ID_CHARS = 32_768\nexport const DEFAULT_QUESTION = '这次要改哪些内容,做到什么程度算完成?'\n\nexport type MoodMode = 'auto' | 'manual' | 'strict'\nexport type ClarificationStatus = 'pending' | 'answered' | 'skipped' | 'cancelled' | 'stale'\nexport type MoodLocale = 'zh' | 'en'\n\nexport interface MoodSettings {\n revision: number\n mode: MoodMode\n}\n\nexport const defaultSettings = (): MoodSettings => ({ revision: 0, mode: 'auto' })\n\nexport interface ClarificationItem {\n id: string\n question: string\n status: ClarificationStatus\n answer?: string\n}\n\nexport interface HeldRequest {\n sourceVersion: string\n trigger: 'material' | 'risk' | 'mild' | 'clear'\n messages: unknown[]\n}\n\nexport interface MoodSessionView {\n sessionId: string\n projectId?: string\n contract?: TaskContract\n clarification: ClarificationItem[]\n pendingManual: boolean\n held: boolean\n}\n\nexport interface MoodStatus {\n settings: MoodSettings\n storageFailed: boolean\n session?: MoodSessionView\n}\n\n/** Native `@deepseek-ai/dsh-user-questions` AskUserQuestionItem. */\nexport interface AskUserQuestionOption {\n label: string\n description?: string\n}\n\nexport interface AskUserQuestionItem {\n id: string\n question: string\n detail?: string\n header?: string\n options?: AskUserQuestionOption[]\n multiSelect?: boolean\n}\n\nexport interface AskUserQuestionAnswerItem {\n id: string\n selected: string[]\n custom?: string\n}\n\nexport interface AskUserQuestionAnswer {\n answers: AskUserQuestionAnswerItem[]\n}\n\nexport interface AskUserRequest {\n questions: AskUserQuestionItem[]\n agent?: unknown\n signal?: AbortSignal\n}\n\nexport function ok<T>(value: T): RpcResult<T> {\n return { ok: true, value }\n}\n\nexport function fail(code: string, message: string): RpcResult<never> {\n return { ok: false, error: { code, message } }\n}\n\nexport function isMoodMode(value: unknown): value is MoodMode {\n return value === 'auto' || value === 'manual' || value === 'strict'\n}\n\nexport function parseSessionId(payload: unknown): string | undefined {\n if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return undefined\n const sessionId = (payload as { sessionId?: unknown }).sessionId\n return typeof sessionId === 'string' && sessionId.length > 0 && sessionId.length <= 200 ? sessionId : undefined\n}\n\nexport function excerptOf(text: string, limit = MAX_EXCERPT_CHARS): string {\n const trimmed = text.replace(/\\s+/g, ' ').trim()\n if (!trimmed) return ''\n return trimmed.length <= limit ? trimmed : `${trimmed.slice(0, limit - 1)}…`\n}\n\nexport function sessionIdOf(agent: { id?: unknown; session?: { id?: unknown } } | undefined): string {\n const fromSession = agent?.session?.id\n if (fromSession != null && String(fromSession).length > 0) return String(fromSession)\n if (agent?.id != null && String(agent.id).length > 0) return String(agent.id)\n return ''\n}\n\nexport function cloneContract(contract: TaskContract): TaskContract {\n return structuredClone(contract)\n}\n\nexport function readinessLabel(readiness: TaskContract['readiness']): string {\n if (readiness === 'clear-request') return '表述清楚'\n if (readiness === 'user-confirmed') return '作者已确认'\n if (readiness === 'disclosed-assumptions') return '按已披露假定继续'\n if (readiness === 'cancelled') return '已取消,未确认'\n if (readiness === 'stale') return '已过期'\n return '待确认'\n}\n"],"mappings":";;;AAOA,MAAa,mBAAmB;AAChC,MAAa,cAAc;AAC3B,MAAa,mBAAmB;;AAEhC,MAAa,iBAAiB;AAC9B,MAAa,mBAAmB;AAChC,MAAa,uBAAuB;AACpC,MAAa,mBAAmB;AAChC,MAAa,iBAAiB;AAC9B,MAAa,iBAAiB;AAC9B,MAAa,gBAAgB;AAC7B,MAAa,oBAAoB;AACjC,MAAa,uBAAuB;AACpC,MAAa,mBAAmB;AAWhC,MAAa,yBAAuC;CAAE,UAAU;CAAG,MAAM;AAAO;
|
|
1
|
+
{"version":3,"file":"contracts.js","names":[],"sources":["../src/contracts.ts"],"sourcesContent":["/** Browser-safe Mood contracts. Shared TaskContract fields match frozen @klarkxy/dsh-ai-services. */\nimport type { AiFeatureScope, EvidenceRef, ProducerMessageSource, RpcResult, TaskContract } from '@klarkxy/dsh-ai-services/contracts'\n\nexport type { AiFeatureScope, EvidenceRef, ProducerMessageSource, RpcResult, TaskContract }\nexport { projectIdFromCwd } from '@klarkxy/dsh-ai-services/contracts'\n\n/** Frozen shared chat-events seat. Must stay equal to @klarkxy/dsh-ai-services CHAT_EVENTS_SLOT. */\nexport const CHAT_EVENTS_SLOT = 'dsh-editor.chat.events'\nexport const MOOD_PLUGIN = '@klarkxy/dsh-mood'\nexport const MOOD_SOURCE_KIND = 'plugin:@klarkxy/dsh-mood' as const\n/** Production activate identity after scoped pluginName support. */\nexport const MOOD_AI_PLUGIN = MOOD_PLUGIN\nexport const MOOD_RPC_CHANNEL = '/dsh-mood'\nexport const MOOD_ANALYZE_PURPOSE = 'mood.analyze'\nexport const CONTRACT_SECTION = 'dsh-mood:contract'\nexport const PROMPT_VERSION = 'mood.analyze.v1'\nexport const SCHEMA_VERSION = 'mood-contract.v1'\nexport const MAX_QUESTIONS = 3\nexport const MAX_EXCERPT_CHARS = 200\nexport const MAX_PROJECT_ID_CHARS = 32_768\nexport const DEFAULT_QUESTION = '这次要改哪些内容,做到什么程度算完成?'\n\nexport type MoodMode = 'auto' | 'manual' | 'strict'\nexport type ClarificationStatus = 'pending' | 'answered' | 'skipped' | 'cancelled' | 'stale'\nexport type MoodLocale = 'zh' | 'en'\n\nexport interface MoodSettings {\n revision: number\n mode: MoodMode\n}\n\nexport const defaultSettings = (): MoodSettings => ({ revision: 0, mode: 'auto' })\n\n/** Enabled Mood always runs auto; persisted manual/strict flags are ignored. */\nexport function operationalSettings(settings: MoodSettings): MoodSettings {\n return { revision: settings.revision, mode: 'auto' }\n}\n\nexport interface ClarificationItem {\n id: string\n question: string\n status: ClarificationStatus\n answer?: string\n}\n\nexport interface HeldRequest {\n sourceVersion: string\n trigger: 'material' | 'risk' | 'mild' | 'clear'\n messages: unknown[]\n}\n\nexport interface MoodSessionView {\n sessionId: string\n projectId?: string\n contract?: TaskContract\n clarification: ClarificationItem[]\n pendingManual: boolean\n held: boolean\n}\n\nexport interface MoodStatus {\n settings: MoodSettings\n storageFailed: boolean\n session?: MoodSessionView\n}\n\n/** Native `@deepseek-ai/dsh-user-questions` AskUserQuestionItem. */\nexport interface AskUserQuestionOption {\n label: string\n description?: string\n}\n\nexport interface AskUserQuestionItem {\n id: string\n question: string\n detail?: string\n header?: string\n options?: AskUserQuestionOption[]\n multiSelect?: boolean\n}\n\nexport interface AskUserQuestionAnswerItem {\n id: string\n selected: string[]\n custom?: string\n}\n\nexport interface AskUserQuestionAnswer {\n answers: AskUserQuestionAnswerItem[]\n}\n\nexport interface AskUserRequest {\n questions: AskUserQuestionItem[]\n agent?: unknown\n signal?: AbortSignal\n}\n\nexport function ok<T>(value: T): RpcResult<T> {\n return { ok: true, value }\n}\n\nexport function fail(code: string, message: string): RpcResult<never> {\n return { ok: false, error: { code, message } }\n}\n\nexport function isMoodMode(value: unknown): value is MoodMode {\n return value === 'auto' || value === 'manual' || value === 'strict'\n}\n\nexport function parseSessionId(payload: unknown): string | undefined {\n if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return undefined\n const sessionId = (payload as { sessionId?: unknown }).sessionId\n return typeof sessionId === 'string' && sessionId.length > 0 && sessionId.length <= 200 ? sessionId : undefined\n}\n\nexport function excerptOf(text: string, limit = MAX_EXCERPT_CHARS): string {\n const trimmed = text.replace(/\\s+/g, ' ').trim()\n if (!trimmed) return ''\n return trimmed.length <= limit ? trimmed : `${trimmed.slice(0, limit - 1)}…`\n}\n\nexport function sessionIdOf(agent: { id?: unknown; session?: { id?: unknown } } | undefined): string {\n const fromSession = agent?.session?.id\n if (fromSession != null && String(fromSession).length > 0) return String(fromSession)\n if (agent?.id != null && String(agent.id).length > 0) return String(agent.id)\n return ''\n}\n\nexport function cloneContract(contract: TaskContract): TaskContract {\n return structuredClone(contract)\n}\n\nexport function readinessLabel(readiness: TaskContract['readiness']): string {\n if (readiness === 'clear-request') return '表述清楚'\n if (readiness === 'user-confirmed') return '作者已确认'\n if (readiness === 'disclosed-assumptions') return '按已披露假定继续'\n if (readiness === 'cancelled') return '已取消,未确认'\n if (readiness === 'stale') return '已过期'\n return '待确认'\n}\n"],"mappings":";;;AAOA,MAAa,mBAAmB;AAChC,MAAa,cAAc;AAC3B,MAAa,mBAAmB;;AAEhC,MAAa,iBAAiB;AAC9B,MAAa,mBAAmB;AAChC,MAAa,uBAAuB;AACpC,MAAa,mBAAmB;AAChC,MAAa,iBAAiB;AAC9B,MAAa,iBAAiB;AAC9B,MAAa,gBAAgB;AAC7B,MAAa,oBAAoB;AACjC,MAAa,uBAAuB;AACpC,MAAa,mBAAmB;AAWhC,MAAa,yBAAuC;CAAE,UAAU;CAAG,MAAM;AAAO;;AAGhF,SAAgB,oBAAoB,UAAsC;CACxE,OAAO;EAAE,UAAU,SAAS;EAAU,MAAM;CAAO;AACrD;AA6DA,SAAgB,GAAM,OAAwB;CAC5C,OAAO;EAAE,IAAI;EAAM;CAAM;AAC3B;AAEA,SAAgB,KAAK,MAAc,SAAmC;CACpE,OAAO;EAAE,IAAI;EAAO,OAAO;GAAE;GAAM;EAAQ;CAAE;AAC/C;AAEA,SAAgB,WAAW,OAAmC;CAC5D,OAAO,UAAU,UAAU,UAAU,YAAY,UAAU;AAC7D;AAEA,SAAgB,eAAe,SAAsC;CACnE,IAAI,CAAC,WAAW,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG,OAAO,KAAA;CAC9E,MAAM,YAAa,QAAoC;CACvD,OAAO,OAAO,cAAc,YAAY,UAAU,SAAS,KAAK,UAAU,UAAU,MAAM,YAAY,KAAA;AACxG;AAEA,SAAgB,UAAU,MAAc,QAAA,KAAmC;CACzE,MAAM,UAAU,KAAK,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;CAC/C,IAAI,CAAC,SAAS,OAAO;CACrB,OAAO,QAAQ,UAAU,QAAQ,UAAU,GAAG,QAAQ,MAAM,GAAG,QAAQ,CAAC,EAAE;AAC5E;AAEA,SAAgB,YAAY,OAAyE;CACnG,MAAM,cAAc,OAAO,SAAS;CACpC,IAAI,eAAe,QAAQ,OAAO,WAAW,CAAC,CAAC,SAAS,GAAG,OAAO,OAAO,WAAW;CACpF,IAAI,OAAO,MAAM,QAAQ,OAAO,MAAM,EAAE,CAAC,CAAC,SAAS,GAAG,OAAO,OAAO,MAAM,EAAE;CAC5E,OAAO;AACT;AAEA,SAAgB,cAAc,UAAsC;CAClE,OAAO,gBAAgB,QAAQ;AACjC;AAEA,SAAgB,eAAe,WAA8C;CAC3E,IAAI,cAAc,iBAAiB,OAAO;CAC1C,IAAI,cAAc,kBAAkB,OAAO;CAC3C,IAAI,cAAc,yBAAyB,OAAO;CAClD,IAAI,cAAc,aAAa,OAAO;CACtC,IAAI,cAAc,SAAS,OAAO;CAClC,OAAO;AACT"}
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CHAT_EVENTS_SLOT, CONTRACT_SECTION, DEFAULT_QUESTION, MAX_PROJECT_ID_CHARS, MOOD_AI_PLUGIN, MOOD_ANALYZE_PURPOSE, MOOD_PLUGIN, MOOD_RPC_CHANNEL, MOOD_SOURCE_KIND, PROMPT_VERSION, SCHEMA_VERSION, cloneContract, defaultSettings, excerptOf, fail, isMoodMode, ok, parseSessionId, projectIdFromCwd, readinessLabel, sessionIdOf } from "./contracts.js";
|
|
1
|
+
import { CHAT_EVENTS_SLOT, CONTRACT_SECTION, DEFAULT_QUESTION, MAX_PROJECT_ID_CHARS, MOOD_AI_PLUGIN, MOOD_ANALYZE_PURPOSE, MOOD_PLUGIN, MOOD_RPC_CHANNEL, MOOD_SOURCE_KIND, PROMPT_VERSION, SCHEMA_VERSION, cloneContract, defaultSettings, excerptOf, fail, isMoodMode, ok, operationalSettings, parseSessionId, projectIdFromCwd, readinessLabel, sessionIdOf } from "./contracts.js";
|
|
2
2
|
import { registerHostRpc } from "@klarkxy/dsh-ai-services/host-rpc";
|
|
3
3
|
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -469,7 +469,7 @@ var MoodService = class {
|
|
|
469
469
|
settings: defaultSettings(),
|
|
470
470
|
sessions: {}
|
|
471
471
|
});
|
|
472
|
-
this.settings = loaded.settings;
|
|
472
|
+
this.settings = operationalSettings(loaded.settings);
|
|
473
473
|
for (const [sessionId, row] of Object.entries(loaded.sessions)) this.sessions.set(sessionId, {
|
|
474
474
|
...row,
|
|
475
475
|
clarification: row.clarification ?? [],
|
|
@@ -807,15 +807,15 @@ var MoodService = class {
|
|
|
807
807
|
});
|
|
808
808
|
input.inner;
|
|
809
809
|
}
|
|
810
|
-
async updateMode(
|
|
810
|
+
async updateMode(_mode, expectedRevision) {
|
|
811
811
|
return this.serialize(async () => {
|
|
812
812
|
this.assertLive();
|
|
813
813
|
if (expectedRevision !== this.settings.revision) coded("MOOD_STALE", "需求澄清设置已更新,请刷新后重试。");
|
|
814
814
|
const proposed = this.snapshot();
|
|
815
|
-
proposed.settings = {
|
|
816
|
-
mode,
|
|
815
|
+
proposed.settings = operationalSettings({
|
|
816
|
+
mode: "auto",
|
|
817
817
|
revision: this.settings.revision + 1
|
|
818
|
-
};
|
|
818
|
+
});
|
|
819
819
|
await this.persistProposed(proposed);
|
|
820
820
|
this.commitState(proposed);
|
|
821
821
|
return this.status();
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["asRecord","asString"],"sources":["../src/evidence.ts","../src/inject.ts","../src/analyze.ts","../src/trigger.ts","../src/questions.ts","../src/schema.ts","../src/service.ts","../src/storage.ts","../src/index.ts"],"sourcesContent":["import {\n CONTRACT_SECTION, MOOD_PLUGIN, MOOD_SOURCE_KIND, excerptOf, type EvidenceRef,\n} from './contracts.ts'\n\nexport interface ContentBlockLike { type?: string; text?: string }\nexport interface MessageSourceLike { kind?: string; plugin?: string; form?: string; sections?: Array<{ name?: string }> }\nexport interface UserMessageLike {\n id?: unknown\n role?: string\n content?: ContentBlockLike[]\n source?: MessageSourceLike\n}\nexport interface SessionEventLike {\n seq: number\n type: string\n data?: unknown\n}\n\nexport function textFromContent(content: unknown): string {\n if (typeof content === 'string') return content\n if (!Array.isArray(content)) return ''\n const parts: string[] = []\n for (const block of content) {\n if (!block || typeof block !== 'object') continue\n const row = block as ContentBlockLike\n if (row.type === 'text' && typeof row.text === 'string') parts.push(row.text)\n }\n return parts.join('\\n')\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nexport function messageSource(value: unknown): MessageSourceLike | undefined {\n const row = asRecord(value)\n const source = asRecord(row?.source) ?? asRecord(asRecord(row?.message)?.source)\n return source as MessageSourceLike | undefined\n}\n\nexport function isHumanUserMessage(message: UserMessageLike | undefined): boolean {\n return message?.source?.kind === 'user'\n}\n\nexport function isMoodMessage(message: UserMessageLike | undefined): boolean {\n if (message?.source?.kind !== MOOD_SOURCE_KIND || message.source.plugin !== MOOD_PLUGIN) return false\n if (message.source.form === 'snapshot') {\n return Boolean(message.source.sections?.some(section => section.name === CONTRACT_SECTION))\n }\n return true\n}\n\nexport function incomingAreAuxiliaryOnly(messages: readonly UserMessageLike[]): boolean {\n if (messages.length === 0) return true\n return messages.every(message => !isHumanUserMessage(message))\n}\n\nexport interface HumanTurn {\n id: string\n seq?: number\n text: string\n}\n\nexport function humanTextOf(message: UserMessageLike): string {\n return textFromContent(message.content)\n}\n\nfunction messageIdOf(value: unknown): string | undefined {\n if (typeof value === 'string' && value.length > 0) return value\n return undefined\n}\n\nexport function collectLogHumans(sessionId: string, events: readonly SessionEventLike[]): Array<HumanTurn & { evidence: EvidenceRef }> {\n const humans: Array<HumanTurn & { evidence: EvidenceRef }> = []\n for (const event of events) {\n if (event.type !== 'user/message') continue\n const source = messageSource(event.data)\n if (source?.kind !== 'user') continue\n const data = asRecord(event.data)\n const text = textFromContent(data?.content)\n const excerpt = excerptOf(text)\n if (!excerpt) continue\n const id = messageIdOf(data?.id) ?? `log:${event.seq}`\n humans.push({\n id,\n seq: event.seq,\n text,\n evidence: excerpt ? { sessionId, seq: event.seq, kind: 'user', excerpt } : { sessionId, seq: event.seq, kind: 'user' },\n })\n }\n return humans\n}\n\nexport function collectClaimedHumans(messages: readonly UserMessageLike[]): HumanTurn[] {\n const humans: HumanTurn[] = []\n for (const message of messages) {\n if (!isHumanUserMessage(message)) continue\n const id = messageIdOf(message.id)\n if (!id) continue\n const text = humanTextOf(message)\n if (!text.trim()) continue\n humans.push({ id, text })\n }\n return humans\n}\n\nexport function latestUserSeq(events: readonly SessionEventLike[]): number {\n let seq = 0\n for (const event of events) {\n if (event.type === 'user/message' && messageSource(event.data)?.kind === 'user') seq = event.seq\n }\n return seq\n}\n\n/** Immutable claimed user-message ids only. Previous turn seq is not this request. */\nexport function sourceVersionOf(humans: readonly HumanTurn[]): string {\n return humans.map(item => item.id).filter(Boolean).join('|')\n}\n\nexport function evidenceForRequest(\n sessionId: string,\n events: readonly SessionEventLike[],\n claimed: readonly HumanTurn[],\n): EvidenceRef[] {\n const ids = new Set(claimed.map(item => item.id))\n if (ids.size === 0) return []\n const refs: EvidenceRef[] = []\n for (const event of events) {\n if (event.type !== 'user/message') continue\n const data = asRecord(event.data)\n const id = messageIdOf(data?.id)\n if (!id || !ids.has(id)) continue\n if (messageSource(event.data)?.kind !== 'user') continue\n const excerpt = excerptOf(textFromContent(data?.content))\n refs.push(excerpt ? { sessionId, seq: event.seq, kind: 'user', excerpt } : { sessionId, seq: event.seq, kind: 'user' })\n }\n return refs\n}\n\nexport function latestHumanText(events: readonly SessionEventLike[], messages: readonly UserMessageLike[]): string {\n const claimed = collectClaimedHumans(messages)\n if (claimed.length) return claimed.at(-1)!.text\n return collectLogHumans('', events).at(-1)?.text ?? ''\n}\n","import { createUserMessage } from '@deepseek-ai/dsh-llm'\nimport {\n CONTRACT_SECTION, MOOD_PLUGIN, MOOD_SOURCE_KIND, readinessLabel, type ClarificationItem, type ProducerMessageSource, type TaskContract,\n} from './contracts.ts'\nimport { isMoodMessage, type UserMessageLike } from './evidence.ts'\n\nexport interface ContractMessageInput {\n source: ProducerMessageSource & {\n kind: typeof MOOD_SOURCE_KIND\n plugin: typeof MOOD_PLUGIN\n form: 'snapshot'\n sections: Array<{ name: string; text: string }>\n }\n content: Array<{ type: 'text'; text: string }>\n}\n\nexport function contractMessageInput(text: string): ContractMessageInput {\n return {\n source: {\n kind: MOOD_SOURCE_KIND,\n plugin: MOOD_PLUGIN,\n form: 'snapshot',\n sections: [{ name: CONTRACT_SECTION, text }],\n },\n content: [{ type: 'text', text }],\n }\n}\n\nexport function createMoodContextMessage(text: string): unknown {\n return createUserMessage(contractMessageInput(text))\n}\n\nexport function formatContract(contract: TaskContract, clarification: readonly ClarificationItem[] = []): string {\n const lines = [\n `【需求约定 · ${readinessLabel(contract.readiness)}】`,\n contract.goal ? `目标:${contract.goal}` : '',\n contract.deliverables.length ? `交付:${contract.deliverables.join(';')}` : '',\n contract.inScope.length ? `范围内:${contract.inScope.join(';')}` : '',\n contract.outOfScope.length ? `范围外:${contract.outOfScope.join(';')}` : '',\n contract.constraints.length ? `约束:${contract.constraints.join(';')}` : '',\n contract.acceptance.length ? `验收:${contract.acceptance.join(';')}` : '',\n contract.assumptions.length ? `假定:${contract.assumptions.join(';')}` : '',\n ]\n if (clarification.length) {\n lines.push('澄清:')\n for (const item of clarification) {\n const answer = item.answer ? ` → ${item.answer}` : ''\n lines.push(`- [${item.status}] ${item.question}${answer}`)\n }\n } else if (contract.questions.length) {\n lines.push(`待确认:${contract.questions.join(';')}`)\n }\n if (contract.evidence.length) {\n lines.push('证据:' + contract.evidence.map((item: { seq: number; excerpt?: string }) => `#${item.seq}${item.excerpt ? `「${item.excerpt}」` : ''}`).join(' '))\n }\n lines.push('本约定不能代替文件修改或发布审批。未确认前不要当作已授权。')\n return lines.filter(Boolean).join('\\n')\n}\n\nexport function mergeContractMessage(\n messages: readonly unknown[],\n extra: unknown,\n): unknown[] {\n const kept = messages.filter(message => !isMoodMessage(message as UserMessageLike))\n return [...kept, extra]\n}\n","import type { EvidenceRef, TaskContract } from './contracts.ts'\nimport { DEFAULT_QUESTION, MAX_QUESTIONS } from './contracts.ts'\nimport type { TriggerKind } from './trigger.ts'\n\nexport interface AnalysisDraft {\n goal: string\n deliverables: string[]\n inScope: string[]\n outOfScope: string[]\n constraints: string[]\n acceptance: string[]\n assumptions: string[]\n questions: string[]\n}\n\nfunction asString(value: unknown): string {\n return typeof value === 'string' ? value.trim() : ''\n}\n\nfunction asList(value: unknown, max = 16): string[] {\n if (!Array.isArray(value)) return []\n const items: string[] = []\n for (const entry of value) {\n const text = asString(entry)\n if (!text) continue\n items.push(text.slice(0, 400))\n if (items.length >= max) break\n }\n return items\n}\n\nexport function parseAnalysis(text: string): AnalysisDraft | undefined {\n const trimmed = text.trim()\n if (!trimmed) return undefined\n const fence = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n const raw = fence?.[1]?.trim() ?? trimmed\n const start = raw.indexOf('{')\n const end = raw.lastIndexOf('}')\n if (start < 0 || end <= start) return undefined\n try {\n const parsed: unknown = JSON.parse(raw.slice(start, end + 1))\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return undefined\n const row = parsed as Record<string, unknown>\n const goal = asString(row.goal).slice(0, 2000)\n const questions = asList(row.questions, MAX_QUESTIONS)\n return {\n goal,\n deliverables: asList(row.deliverables),\n inScope: asList(row.inScope),\n outOfScope: asList(row.outOfScope),\n constraints: asList(row.constraints),\n acceptance: asList(row.acceptance),\n assumptions: asList(row.assumptions),\n questions,\n }\n } catch {\n return undefined\n }\n}\n\nexport function boundQuestions(questions: readonly string[], kind: TriggerKind): string[] {\n const unique: string[] = []\n for (const question of questions) {\n const text = question.trim()\n if (!text) continue\n if (unique.includes(text)) continue\n unique.push(text.slice(0, 400))\n if (unique.length === MAX_QUESTIONS) return unique\n }\n if (unique.length === 0 && (kind === 'material' || kind === 'risk')) return [DEFAULT_QUESTION]\n return unique\n}\n\nexport const ANALYZE_SYSTEM = [\n '你在确认写作任务需求。只根据给定的真实用户原文归纳。',\n '不要编造未给出的文件、人物、字数或验收条件。',\n '不要把需求确认写成文件修改或发布授权。',\n '返回一个 JSON 对象,不要 Markdown。',\n '键:goal, deliverables, inScope, outOfScope, constraints, acceptance, assumptions, questions。',\n `questions 最多 ${MAX_QUESTIONS} 条,仅在存在实质含糊或风险时提出;原文已经可执行则 questions 为空数组。`,\n].join('\\n')\n\nexport function thinContract(input: {\n id: string\n sessionId: string\n sourceVersion: string\n revision: number\n goal: string\n evidence: EvidenceRef[]\n readiness: TaskContract['readiness']\n now: number\n extra?: Partial<Pick<TaskContract, 'deliverables' | 'inScope' | 'outOfScope' | 'constraints' | 'acceptance' | 'assumptions' | 'questions'>>\n}): TaskContract {\n return {\n id: input.id,\n sessionId: input.sessionId,\n sourceVersion: input.sourceVersion,\n revision: input.revision,\n goal: input.goal.slice(0, 2000),\n deliverables: input.extra?.deliverables ?? [],\n inScope: input.extra?.inScope ?? [],\n outOfScope: input.extra?.outOfScope ?? [],\n constraints: input.extra?.constraints ?? [],\n acceptance: input.extra?.acceptance ?? [],\n assumptions: input.extra?.assumptions ?? [],\n questions: input.extra?.questions ?? [],\n evidence: input.evidence,\n readiness: input.readiness,\n updatedAt: input.now,\n }\n}\n\nexport function contractFromDraft(input: {\n id: string\n sessionId: string\n sourceVersion: string\n revision: number\n goalFallback: string\n evidence: EvidenceRef[]\n draft: AnalysisDraft | undefined\n questions: string[]\n readiness: TaskContract['readiness']\n now: number\n}): TaskContract {\n const draft = input.draft\n return thinContract({\n id: input.id,\n sessionId: input.sessionId,\n sourceVersion: input.sourceVersion,\n revision: input.revision,\n goal: draft?.goal || input.goalFallback,\n evidence: input.evidence,\n readiness: input.readiness,\n now: input.now,\n extra: {\n deliverables: draft?.deliverables ?? [],\n inScope: draft?.inScope ?? [],\n outOfScope: draft?.outOfScope ?? [],\n constraints: draft?.constraints ?? [],\n acceptance: draft?.acceptance ?? [],\n assumptions: draft?.assumptions ?? [],\n questions: input.questions,\n },\n })\n}\n\nexport const analyzePurpose = {\n id: 'mood.analyze',\n label: '需求澄清',\n defaultTarget: { kind: 'role' as const, role: 'normal' as const },\n maxOutputTokens: 1024,\n timeoutMs: 60_000,\n}\n","export type TriggerKind = 'skip' | 'clear' | 'mild' | 'material' | 'risk'\nexport type MoodMode = 'auto' | 'manual' | 'strict'\n\nconst ACK = /^(好的?|嗯+|行|ok|okay|收到|谢谢[.。!!]?|thanks[.!]?)$/i\nconst CONTINUE = /^(继续|接着(?:做|写|改)?|go on|continue)$/i\nconst VAGUE = /帮我(?:看|改|写|弄)?一下|改一下|写一下|处理一下|优化一下|弄好|随便|看情况|你决定|都行|无所谓|或者就|怎么写都行|看着办|帮我改改|改改/\nconst RISK = /删除全部|全部删除|清空(?:全书|所有|全部)?|覆盖原文|覆盖所有|重写全|全部重写|并发布|发布到|永久删除|替换所有/\nconst PATH = /\\.[A-Za-z][A-Za-z0-9]{0,7}\\b|第[一二三四五六七八九十百0-9]+章|[A-Za-z]:\\\\|\\//\nconst BOUND = /不超过|不少于|至少|最多|保持|不要|仅|只|必须|字以内|<=|≥|\\d+\\s*(?:字|句|段|行)/\nconst NAMED = /[\\u4e00-\\u9fff]{2,6}(?:的)?(?:对白|对话|语气|出场)|“[^”]{2,40}”/\nconst EXPLAIN = /解释什么是|^什么是|explain\\s+what/i\nconst TRANSLATE = /翻译成|译成|translate\\s+.+\\s+into/i\nconst LOCAL_EDIT = /把第[一二三四五六七八九十百0-9]+[行句段]|修正拼写|重命名为|把错字|typo/i\n\nexport function classifyRequest(text: string, options: { hasConfirmedContract?: boolean } = {}): TriggerKind {\n const trimmed = text.replace(/\\s+/g, ' ').trim()\n if (!trimmed) return 'skip'\n if (ACK.test(trimmed)) return 'skip'\n if (CONTINUE.test(trimmed)) return options.hasConfirmedContract ? 'skip' : 'material'\n if (RISK.test(trimmed)) return 'risk'\n if (EXPLAIN.test(trimmed) || TRANSLATE.test(trimmed) || LOCAL_EDIT.test(trimmed)) return 'clear'\n if (VAGUE.test(trimmed)) return 'material'\n const specific = PATH.test(trimmed) || NAMED.test(trimmed)\n const bounded = BOUND.test(trimmed)\n if (specific && bounded && trimmed.length >= 16) return 'clear'\n if (specific || bounded) return 'mild'\n return 'clear'\n}\n\nexport function shouldAnalyze(kind: TriggerKind, mode: MoodMode, pendingManual: boolean): boolean {\n if (kind === 'skip') return false\n if (pendingManual) return true\n if (mode === 'manual') return false\n if (mode === 'strict') return true\n return kind === 'material' || kind === 'risk'\n}\n\nexport function shouldWriteClearContract(kind: TriggerKind, pendingManual: boolean, mode: MoodMode = 'auto'): boolean {\n return kind === 'clear' && !pendingManual && mode === 'auto'\n}\n\nexport function isBlockingKind(kind: TriggerKind): boolean {\n return kind === 'material' || kind === 'risk'\n}\n","import type {\n AskUserQuestionAnswer, AskUserQuestionItem, ClarificationItem, ClarificationStatus,\n} from './contracts.ts'\nimport { isBlockingKind, type TriggerKind } from './trigger.ts'\n\n/** Native option label; selecting it without custom text is not an answer. */\nexport const ASK_DETAIL_OPTION = '补充说明'\n\nexport function toAskItems(items: readonly ClarificationItem[]): AskUserQuestionItem[] {\n return items.filter(item => item.status === 'pending').map(item => ({\n id: item.id,\n header: '澄清',\n question: item.question,\n options: [\n { label: ASK_DETAIL_OPTION, description: '在自定义输入中写明范围、约束或验收标准' },\n ],\n }))\n}\n\nexport function pendingClarifications(questions: readonly string[]): ClarificationItem[] {\n return questions.map((question, index) => ({\n id: `q${index + 1}`,\n question,\n status: 'pending',\n }))\n}\n\nfunction answerText(item: { selected: string[]; custom?: string }): string {\n const selected = item.selected.map(entry => entry.trim()).filter(Boolean).filter(entry => entry !== ASK_DETAIL_OPTION)\n const custom = item.custom?.trim() ?? ''\n if (custom && selected.length) return `${selected.join(';')};${custom}`\n if (custom) return custom\n return selected.join(';')\n}\n\nexport function applyAnswers(\n items: readonly ClarificationItem[],\n answer: AskUserQuestionAnswer | undefined,\n): ClarificationItem[] {\n const byId = new Map((answer?.answers ?? []).map(entry => [entry.id, entry]))\n return items.map(item => {\n if (item.status !== 'pending') return item\n const entry = byId.get(item.id)\n if (!entry) return { ...item, status: 'skipped' as const }\n const text = answerText(entry)\n if (!text) return { ...item, status: 'skipped' as const }\n return { ...item, status: 'answered' as const, answer: text.slice(0, 400) }\n })\n}\n\nexport function markClarification(items: readonly ClarificationItem[], status: ClarificationStatus): ClarificationItem[] {\n return items.map(item => item.status === 'pending' ? { ...item, status } : item)\n}\n\nexport function readinessAfterAnswers(\n items: readonly ClarificationItem[],\n kind: TriggerKind = 'mild',\n): 'user-confirmed' | 'disclosed-assumptions' | 'pending' {\n if (items.some(item => item.status === 'pending')) return 'pending'\n if (items.length === 0) return 'user-confirmed'\n if (items.every(item => item.status === 'answered')) return 'user-confirmed'\n if (isBlockingKind(kind)) return 'pending'\n return 'disclosed-assumptions'\n}\n\nexport function answeredNotes(items: readonly ClarificationItem[]): string[] {\n return items.filter(item => item.status === 'answered' && item.answer).map(item => `${item.question}:${item.answer}`)\n}\n\nexport function isAskAborted(error: unknown): boolean {\n if (!error || typeof error !== 'object') return false\n const row = error as { name?: unknown; code?: unknown }\n if (row.code === 'ASK_ABORTED' || row.code === 'ASK_CANCELLED') return true\n const name = String(row.name ?? '')\n return name === 'AbortError' || name === 'TimeoutError'\n}\n\nexport function isAbortLike(error: unknown, signal?: AbortSignal): boolean {\n if (signal?.aborted) return true\n if (!error || typeof error !== 'object') return false\n const row = error as { name?: unknown; code?: unknown }\n const name = String(row.name ?? '')\n const code = String(row.code ?? '')\n return name === 'AbortError' || name === 'TimeoutError' || code === 'ABORT_ERR' || code === 'ABORTED' || isAskAborted(error)\n}\n","import type { MoodMode, TaskContract } from './contracts.ts'\nimport { isMoodMode, parseSessionId } from './contracts.ts'\n\nexport interface ModeUpdate {\n expectedRevision: number\n mode: MoodMode\n}\n\nexport interface ManualRequest {\n sessionId: string\n}\n\nexport interface ContractEdit {\n sessionId: string\n expectedRevision: number\n patch: Partial<Pick<TaskContract, 'goal' | 'deliverables' | 'inScope' | 'outOfScope' | 'constraints' | 'acceptance' | 'assumptions' | 'questions'>>\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nfunction asString(value: unknown, max: number): string | undefined {\n if (typeof value !== 'string') return undefined\n const text = value.trim()\n if (text.length > max) return undefined\n return text\n}\n\nfunction asStringList(value: unknown, maxItems: number, maxChars: number): string[] | undefined {\n if (!Array.isArray(value) || value.length > maxItems) return undefined\n const items: string[] = []\n for (const entry of value) {\n if (typeof entry !== 'string' || entry.length > maxChars) return undefined\n items.push(entry)\n }\n return items\n}\n\nexport function parseModeUpdate(payload: unknown): ModeUpdate | undefined {\n const row = asRecord(payload)\n if (!row) return undefined\n if (typeof row.expectedRevision !== 'number' || !Number.isInteger(row.expectedRevision) || row.expectedRevision < 0) return undefined\n if (!isMoodMode(row.mode)) return undefined\n return { expectedRevision: row.expectedRevision, mode: row.mode }\n}\n\nexport function parseManual(payload: unknown): ManualRequest | undefined {\n const sessionId = parseSessionId(payload)\n return sessionId ? { sessionId } : undefined\n}\n\nconst PATCH_KEYS = ['goal', 'deliverables', 'inScope', 'outOfScope', 'constraints', 'acceptance', 'assumptions', 'questions'] as const\n\nexport function parseEdit(payload: unknown): ContractEdit | undefined {\n const row = asRecord(payload)\n if (!row) return undefined\n const sessionId = parseSessionId(row)\n if (!sessionId) return undefined\n if (typeof row.expectedRevision !== 'number' || !Number.isInteger(row.expectedRevision) || row.expectedRevision < 0) return undefined\n const patchRow = asRecord(row.patch)\n if (!patchRow) return undefined\n const patch: ContractEdit['patch'] = {}\n for (const key of Object.keys(patchRow)) {\n if (!(PATCH_KEYS as readonly string[]).includes(key)) return undefined\n }\n if (patchRow.goal !== undefined) {\n const goal = asString(patchRow.goal, 2000)\n if (goal === undefined) return undefined\n patch.goal = goal\n }\n for (const key of ['deliverables', 'inScope', 'outOfScope', 'constraints', 'acceptance', 'assumptions', 'questions'] as const) {\n if (patchRow[key] === undefined) continue\n const list = asStringList(patchRow[key], 16, 400)\n if (!list) return undefined\n patch[key] = list\n }\n if (Object.keys(patch).length === 0) return undefined\n return { sessionId, expectedRevision: row.expectedRevision, patch }\n}\n","import { randomUUID } from 'node:crypto'\nimport type { AiFeatureScope, AuxiliaryResult, RpcResult, TaskContract } from '@klarkxy/dsh-ai-services/contracts'\nimport {\n MOOD_ANALYZE_PURPOSE, PROMPT_VERSION, SCHEMA_VERSION, cloneContract, defaultSettings, excerptOf, fail, ok,\n parseSessionId, projectIdFromCwd, sessionIdOf, type AskUserRequest, type AskUserQuestionAnswer, type ClarificationItem,\n type HeldRequest, type MoodMode, type MoodSessionView, type MoodSettings, type MoodStatus,\n} from './contracts.ts'\nimport { ANALYZE_SYSTEM, analyzePurpose, boundQuestions, contractFromDraft, parseAnalysis, thinContract } from './analyze.ts'\nimport {\n collectClaimedHumans, evidenceForRequest, incomingAreAuxiliaryOnly, latestUserSeq, sourceVersionOf,\n type SessionEventLike, type UserMessageLike,\n} from './evidence.ts'\nimport { createMoodContextMessage, formatContract, mergeContractMessage } from './inject.ts'\nimport {\n answeredNotes, applyAnswers, isAbortLike, markClarification, pendingClarifications, readinessAfterAnswers, toAskItems,\n} from './questions.ts'\nimport { parseEdit, parseManual, parseModeUpdate } from './schema.ts'\nimport { classifyRequest, isBlockingKind, shouldAnalyze, shouldWriteClearContract, type TriggerKind } from './trigger.ts'\n\nexport interface MoodPersistedState {\n settings: MoodSettings\n sessions: Record<string, MoodStoredSession>\n}\n\nexport interface MoodStoredSession {\n contract?: TaskContract\n clarification: ClarificationItem[]\n lastHandledVersion?: string\n pendingManual: boolean\n projectId?: string\n heldRequest?: HeldRequest\n}\n\nexport interface MoodStore {\n load(): MoodPersistedState\n save(state: MoodPersistedState): Promise<void>\n}\n\nexport interface SessionLike {\n id?: unknown\n header?: { cwd?: string }\n meta?: { cwd?: string }\n}\n\nexport interface PreStepPayload {\n agent: { id?: unknown; session?: SessionLike }\n messages: UserMessageLike[]\n turn: number\n step: number\n signal: AbortSignal\n}\n\nexport type PreStepDecision = { kind: 'reject' } | { kind: 'enter'; messages: unknown[]; startsRequestSeries?: true }\n\nexport interface MoodServiceOptions {\n store?: MoodStore\n now?: () => number\n id?: () => string\n readEvents: (sessionId: string) => readonly SessionEventLike[] | undefined\n liveSession?: (sessionId: string) => SessionLike | undefined\n activateAi?: () => AiFeatureScope | undefined\n askUser?: (request: AskUserRequest) => Promise<AskUserQuestionAnswer>\n createInjectMessage?: (text: string) => unknown\n resumeHeld?: (sessionId: string, messages: unknown[]) => Promise<void>\n}\n\ntype InternalSession = MoodStoredSession & {\n generation: number\n work?: AbortController\n inflightVersion?: string\n}\n\nexport class MoodService {\n private settings: MoodSettings\n private sessions = new Map<string, InternalSession>()\n private storageFailed = false\n private active = true\n private ai?: AiFeatureScope\n private unregisterPurpose?: () => void\n private pending = Promise.resolve()\n private readonly now: () => number\n private readonly nextId: () => string\n\n constructor(private readonly options: MoodServiceOptions) {\n const loaded = cloneState(options.store?.load() ?? { settings: defaultSettings(), sessions: {} })\n this.settings = loaded.settings\n for (const [sessionId, row] of Object.entries(loaded.sessions)) {\n this.sessions.set(sessionId, {\n ...row,\n clarification: row.clarification ?? [],\n pendingManual: Boolean(row.pendingManual),\n generation: 0,\n })\n }\n this.now = options.now ?? Date.now\n this.nextId = options.id ?? randomUUID\n this.syncAi()\n }\n\n getContract(sessionId: string): TaskContract | undefined {\n const contract = this.sessions.get(sessionId)?.contract\n return contract ? cloneContract(contract) : undefined\n }\n\n status(sessionId?: string): MoodStatus {\n const status: MoodStatus = {\n settings: { ...this.settings },\n storageFailed: this.storageFailed,\n }\n if (!sessionId) return status\n const row = this.ensure(sessionId)\n status.session = this.view(sessionId, row)\n return status\n }\n\n isActive(): boolean {\n return this.active\n }\n\n async dispose(): Promise<void> {\n this.active = false\n for (const row of this.sessions.values()) {\n row.generation += 1\n row.work?.abort()\n row.work = undefined\n }\n this.detachAi()\n await this.pending\n }\n\n async call(endpoint: string, payload: unknown, signal: AbortSignal): Promise<RpcResult> {\n if (!this.active) return fail('MOOD_DISABLED', '需求澄清已关闭。')\n if (signal.aborted) return fail('MOOD_CANCELLED', '请求已取消。')\n try {\n if (endpoint === 'status') return ok(this.status(parseSessionId(payload)))\n if (endpoint === 'contract') {\n const sessionId = this.hostSessionId(parseSessionId(payload), false)\n if (!sessionId) return fail('MOOD_INVALID', '缺少会话。')\n return ok(this.getContract(sessionId) ?? null)\n }\n if (endpoint === 'mode') {\n const parsed = parseModeUpdate(payload)\n if (!parsed) return fail('MOOD_INVALID', '模式格式无效。')\n return ok(await this.updateMode(parsed.mode, parsed.expectedRevision))\n }\n if (endpoint === 'manual') {\n const parsed = parseManual(payload)\n if (!parsed) return fail('MOOD_INVALID', '缺少会话。')\n const sessionId = this.hostSessionId(parsed.sessionId, true)\n if (!sessionId) return fail('MOOD_SESSION_NOT_FOUND', '会话不在当前 Host。')\n return ok(await this.requestManual(sessionId))\n }\n if (endpoint === 'retry') {\n const parsed = parseManual(payload)\n if (!parsed) return fail('MOOD_INVALID', '缺少会话。')\n const sessionId = this.hostSessionId(parsed.sessionId, true)\n if (!sessionId) return fail('MOOD_SESSION_NOT_FOUND', '会话不在当前 Host。')\n return ok(await this.requestRetry(sessionId))\n }\n if (endpoint === 'edit') {\n const parsed = parseEdit(payload)\n if (!parsed) return fail('MOOD_INVALID', '修订格式无效。')\n const sessionId = this.hostSessionId(parsed.sessionId, true)\n if (!sessionId) return fail('MOOD_SESSION_NOT_FOUND', '会话不在当前 Host。')\n return ok(await this.editContract(sessionId, parsed.expectedRevision, parsed.patch))\n }\n return fail('MOOD_INVALID', '未知操作。')\n } catch (error) {\n const code = error && typeof error === 'object' && 'code' in error ? String((error as { code: unknown }).code) : 'MOOD_FAILED'\n return fail(code, error instanceof Error ? error.message : '需求澄清操作失败。')\n }\n }\n\n async handlePreStep(payload: PreStepPayload, next: () => Promise<PreStepDecision>): Promise<PreStepDecision> {\n const inner = await next()\n if (!this.active) return inner\n if (inner.kind !== 'enter') return inner\n payload.signal.throwIfAborted()\n const sessionId = sessionIdOf(payload.agent)\n if (!sessionId) return inner\n const claimedMessages = payload.messages\n const state = this.ensure(sessionId)\n state.projectId = projectIdFromCwd(payload.agent.session?.header?.cwd ?? payload.agent.session?.meta?.cwd)\n ?? projectIdFromCwd(this.options.liveSession?.(sessionId)?.header?.cwd ?? this.options.liveSession?.(sessionId)?.meta?.cwd)\n ?? state.projectId\n\n if (incomingAreAuxiliaryOnly(claimedMessages) && !state.pendingManual) {\n if (this.isBlocked(state)) return { kind: 'reject' }\n return this.enter(inner, state.contract, state.clarification)\n }\n\n const claimed = collectClaimedHumans(claimedMessages)\n const sourceVersion = sourceVersionOf(claimed)\n const events = this.options.readEvents(sessionId) ?? []\n const evidence = evidenceForRequest(sessionId, events, claimed)\n const text = claimed.at(-1)?.text ?? ''\n\n if (claimed.length) this.supersedeIfNew(sessionId, sourceVersion)\n\n const live = this.ensure(sessionId)\n if (live.lastHandledVersion === sourceVersion && !live.pendingManual && isSettled(live.contract?.readiness)) {\n return this.enter(inner, live.contract, live.clarification)\n }\n\n const kind = classifyRequest(text, { hasConfirmedContract: isSettled(live.contract?.readiness) })\n if (kind === 'skip' && !live.pendingManual) {\n return this.enter(inner, live.contract, live.clarification)\n }\n\n if (shouldWriteClearContract(kind, live.pendingManual, this.settings.mode)) {\n const generation = live.generation\n const contract = thinContract({\n id: this.nextId(),\n sessionId,\n sourceVersion,\n revision: nextRevision(live.contract),\n goal: text.slice(0, 2000),\n evidence,\n readiness: 'clear-request',\n now: this.now(),\n })\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification: [],\n lastHandledVersion: sourceVersion,\n pendingManual: false,\n heldRequest: undefined,\n projectId: live.projectId,\n })\n if (!wrote) return this.afterStale(inner)\n return this.enter(inner, contract, [])\n }\n\n if (!shouldAnalyze(kind, this.settings.mode, live.pendingManual)) {\n return inner\n }\n\n const generation = live.generation\n live.inflightVersion = sourceVersion\n const work = this.replaceWork(sessionId)\n const combined = combineSignals(payload.signal, work.signal, this.ai?.signal)\n let draft = undefined as ReturnType<typeof parseAnalysis>\n try {\n draft = await this.runAnalysis({ sessionId, sourceVersion, text, evidence, signal: combined, generation })\n } catch (error) {\n if (!this.generationCurrent(sessionId, generation)) return this.afterStale(inner)\n const status = isAbortLike(error, combined) ? 'cancelled' : 'pending'\n await this.blockUnresolved({\n sessionId, generation, sourceVersion, text, evidence, kind, claimed: claimedMessages, status, inner,\n })\n return { kind: 'reject' }\n }\n\n if (!this.generationCurrent(sessionId, generation)) return this.afterStale(inner)\n\n const questions = boundQuestions(draft?.questions ?? [], kind)\n const clarification = pendingClarifications(questions)\n let contract = contractFromDraft({\n id: this.nextId(),\n sessionId,\n sourceVersion,\n revision: nextRevision(this.ensure(sessionId).contract),\n goalFallback: text.slice(0, 2000),\n evidence,\n draft,\n questions,\n readiness: questions.length || isBlockingKind(kind) ? 'pending' : 'disclosed-assumptions',\n now: this.now(),\n })\n\n if (questions.length > 0) {\n const asked = await this.askOnce(payload.agent, clarification, combined)\n if (!this.generationCurrent(sessionId, generation)) return this.afterStale(inner)\n if (asked.kind === 'aborted' || asked.kind === 'failed') {\n const status = asked.kind === 'aborted' ? 'cancelled' : 'pending'\n await this.blockUnresolved({\n sessionId, generation, sourceVersion, text, evidence, kind, claimed: claimedMessages, status, inner,\n contract, clarification: asked.kind === 'aborted' ? markClarification(clarification, 'cancelled') : clarification,\n })\n return { kind: 'reject' }\n }\n const answered = applyAnswers(clarification, asked.answer)\n const readiness = readinessAfterAnswers(answered, kind)\n if (isBlockingKind(kind) && readiness !== 'user-confirmed') {\n contract = {\n ...contract,\n readiness: 'pending',\n assumptions: draft?.assumptions ?? contract.assumptions,\n constraints: [...contract.constraints, ...answeredNotes(answered)],\n questions: answered.filter(item => item.status !== 'answered').map(item => item.question),\n updatedAt: this.now(),\n }\n await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification: answered,\n pendingManual: false,\n lastHandledVersion: undefined,\n heldRequest: holdOf(sourceVersion, kind, claimedMessages),\n projectId: this.ensure(sessionId).projectId,\n })\n return { kind: 'reject' }\n }\n contract = {\n ...contract,\n readiness,\n assumptions: [\n ...contract.assumptions,\n ...(isBlockingKind(kind) ? [] : answered.filter(item => item.status === 'skipped').map(item => `未回答:${item.question}`)),\n ],\n constraints: [...contract.constraints, ...answeredNotes(answered)],\n questions: answered.filter(item => item.status !== 'answered').map(item => item.question),\n updatedAt: this.now(),\n }\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification: answered,\n lastHandledVersion: sourceVersion,\n pendingManual: false,\n heldRequest: undefined,\n projectId: this.ensure(sessionId).projectId,\n })\n if (!wrote) return this.afterStale(inner)\n return this.enter(inner, contract, answered)\n }\n\n if (isBlockingKind(kind) && contract.readiness === 'pending') {\n await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification,\n pendingManual: false,\n lastHandledVersion: undefined,\n heldRequest: holdOf(sourceVersion, kind, claimedMessages),\n projectId: this.ensure(sessionId).projectId,\n })\n return { kind: 'reject' }\n }\n\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification,\n lastHandledVersion: sourceVersion,\n pendingManual: false,\n heldRequest: undefined,\n projectId: this.ensure(sessionId).projectId,\n })\n if (!wrote) return this.afterStale(inner)\n return this.enter(inner, contract, clarification)\n }\n\n private async runAnalysis(input: {\n sessionId: string\n sourceVersion: string\n text: string\n evidence: TaskContract['evidence']\n signal: AbortSignal\n generation: number\n }): Promise<ReturnType<typeof parseAnalysis>> {\n const scope = this.ai\n if (!scope?.active) return undefined\n input.signal.throwIfAborted()\n const result: AuxiliaryResult = await scope.run({\n purpose: MOOD_ANALYZE_PURPOSE,\n sessionId: input.sessionId,\n sourceVersion: input.sourceVersion,\n promptVersion: PROMPT_VERSION,\n schemaVersion: SCHEMA_VERSION,\n system: ANALYZE_SYSTEM,\n input: JSON.stringify({\n text: input.text,\n evidence: input.evidence,\n }),\n signal: input.signal,\n priority: 'interactive',\n isCurrent: () => this.generationCurrent(input.sessionId, input.generation) && !input.signal.aborted,\n })\n if (result.receipt.status !== 'success') return undefined\n if (!this.generationCurrent(input.sessionId, input.generation)) return undefined\n return parseAnalysis(result.text)\n }\n\n private async askOnce(\n agent: unknown,\n clarification: ClarificationItem[],\n signal: AbortSignal,\n ): Promise<{ kind: 'answered'; answer: AskUserQuestionAnswer } | { kind: 'aborted' } | { kind: 'failed' }> {\n const ask = this.options.askUser\n const items = toAskItems(clarification)\n if (!items.length || !ask) return { kind: 'failed' }\n try {\n const answer = await ask({ agent, questions: items, signal })\n return { kind: 'answered', answer }\n } catch (error) {\n if (isAbortLike(error, signal)) return { kind: 'aborted' }\n return { kind: 'failed' }\n }\n }\n\n private afterStale(inner: Extract<PreStepDecision, { kind: 'enter' }>): PreStepDecision {\n if (!this.active) return inner\n return { kind: 'reject' }\n }\n\n private enter(\n decision: Extract<PreStepDecision, { kind: 'enter' }>,\n contract: TaskContract | undefined,\n clarification: readonly ClarificationItem[],\n ): PreStepDecision {\n if (!this.active || !contract) return decision\n if (contract.readiness === 'pending' || contract.readiness === 'cancelled' || contract.readiness === 'stale') {\n return decision\n }\n const text = formatContract(contract, clarification)\n const extra = this.options.createInjectMessage\n ? this.options.createInjectMessage(text)\n : createMoodContextMessage(text)\n return { ...decision, messages: mergeContractMessage(decision.messages ?? [], extra) }\n }\n\n private async blockUnresolved(input: {\n sessionId: string\n generation: number\n sourceVersion: string\n text: string\n evidence: TaskContract['evidence']\n kind: TriggerKind\n claimed: unknown[]\n status: 'pending' | 'cancelled' | 'stale'\n inner: Extract<PreStepDecision, { kind: 'enter' }>\n contract?: TaskContract\n clarification?: ClarificationItem[]\n }): Promise<void> {\n if (!this.generationCurrent(input.sessionId, input.generation)) return\n const state = this.ensure(input.sessionId)\n const questions = boundQuestions(input.contract?.questions ?? [], input.kind)\n const clarification = input.clarification ?? markClarification(\n pendingClarifications(questions),\n input.status === 'pending' ? 'pending' : input.status,\n )\n const contract = input.contract\n ? { ...input.contract, readiness: input.status, questions, updatedAt: this.now() }\n : thinContract({\n id: this.nextId(),\n sessionId: input.sessionId,\n sourceVersion: input.sourceVersion,\n revision: nextRevision(state.contract),\n goal: input.text.slice(0, 2000),\n evidence: input.evidence,\n readiness: input.status,\n now: this.now(),\n extra: { questions },\n })\n const hold = isBlockingKind(input.kind) || clarification.length > 0\n ? holdOf(input.sourceVersion, input.kind, input.claimed)\n : undefined\n await this.commitIfCurrent(input.sessionId, input.generation, {\n contract,\n clarification,\n pendingManual: false,\n lastHandledVersion: undefined,\n heldRequest: hold,\n projectId: state.projectId,\n })\n void input.inner\n }\n\n private async updateMode(mode: MoodMode, expectedRevision: number): Promise<MoodStatus> {\n return this.serialize(async () => {\n this.assertLive()\n if (expectedRevision !== this.settings.revision) coded('MOOD_STALE', '需求澄清设置已更新,请刷新后重试。')\n const proposed = this.snapshot()\n proposed.settings = { mode, revision: this.settings.revision + 1 }\n await this.persistProposed(proposed)\n this.commitState(proposed)\n return this.status()\n })\n }\n\n private async requestManual(sessionId: string): Promise<MoodStatus> {\n const state = this.ensure(sessionId)\n const generation = state.generation\n const held = state.heldRequest\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n pendingManual: true,\n lastHandledVersion: undefined,\n heldRequest: held,\n clarification: state.clarification,\n contract: state.contract,\n projectId: state.projectId,\n })\n if (!wrote) coded('MOOD_CANCELLED', '会话已切换,未执行手动分析。')\n if (held?.messages.length) await this.resumeExact(sessionId, held.messages)\n return this.status(sessionId)\n }\n\n private async requestRetry(sessionId: string): Promise<MoodStatus> {\n const state = this.ensure(sessionId)\n const held = state.heldRequest\n if (!held?.messages.length) coded('MOOD_NOT_FOUND', '没有可按原请求重试的内容。')\n const generation = state.generation\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n pendingManual: false,\n lastHandledVersion: undefined,\n heldRequest: held,\n clarification: state.clarification.map(item => (\n item.status === 'cancelled' || item.status === 'stale' ? { ...item, status: 'pending' as const, answer: undefined } : item\n )),\n contract: state.contract ? { ...state.contract, readiness: 'pending', updatedAt: this.now() } : state.contract,\n projectId: state.projectId,\n })\n if (!wrote) coded('MOOD_CANCELLED', '会话已切换,未重试。')\n await this.resumeExact(sessionId, held.messages)\n return this.status(sessionId)\n }\n\n private async resumeExact(sessionId: string, messages: unknown[]): Promise<void> {\n const resume = this.options.resumeHeld\n if (!resume) coded('MOOD_NO_RESUME', '当前 Host 不能按原请求恢复。')\n await resume(sessionId, messages)\n }\n\n private async editContract(\n sessionId: string,\n expectedRevision: number,\n patch: Partial<Pick<TaskContract, 'goal' | 'deliverables' | 'inScope' | 'outOfScope' | 'constraints' | 'acceptance' | 'assumptions' | 'questions'>>,\n ): Promise<MoodStatus> {\n const state = this.ensure(sessionId)\n const generation = state.generation\n const current = state.contract\n if (!current) coded('MOOD_NOT_FOUND', '还没有可修订的约定。')\n if (current.revision !== expectedRevision) coded('MOOD_STALE', '约定已更新,请刷新后重试。')\n const evidence = [\n ...current.evidence,\n { sessionId, seq: latestUserSeq(this.options.readEvents(sessionId) ?? []), kind: 'manual' as const, excerpt: excerptOf(patch.goal ?? '修订约定') },\n ]\n const contract: TaskContract = {\n ...current,\n ...patch,\n revision: current.revision + 1,\n readiness: 'user-confirmed',\n evidence,\n updatedAt: this.now(),\n }\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification: state.clarification.map(item => item.status === 'pending' ? { ...item, status: 'answered' as const, answer: '作者直接修订约定' } : item),\n pendingManual: false,\n lastHandledVersion: state.lastHandledVersion,\n heldRequest: undefined,\n projectId: state.projectId,\n })\n if (!wrote) coded('MOOD_CANCELLED', '会话已切换,未保存修订。')\n return this.status(sessionId)\n }\n\n private hostSessionId(sessionId: string | undefined, required: boolean): string | undefined {\n if (!sessionId) return undefined\n if (!this.options.liveSession) return sessionId\n const live = this.options.liveSession(sessionId)\n if (!live) return required ? undefined : sessionId\n return live.id != null ? String(live.id) : sessionId\n }\n\n private ensure(sessionId: string): InternalSession {\n const existing = this.sessions.get(sessionId)\n if (existing) return existing\n const created: InternalSession = { clarification: [], pendingManual: false, generation: 0 }\n this.sessions.set(sessionId, created)\n return created\n }\n\n private view(sessionId: string, row: InternalSession): MoodSessionView {\n return {\n sessionId,\n ...(row.projectId ? { projectId: row.projectId } : {}),\n ...(row.contract ? { contract: cloneContract(row.contract) } : {}),\n clarification: row.clarification.map(item => ({ ...item })),\n pendingManual: row.pendingManual,\n held: Boolean(row.heldRequest?.messages.length),\n }\n }\n\n private isBlocked(state: InternalSession): boolean {\n if (!state.heldRequest) return false\n const readiness = state.contract?.readiness\n return readiness === 'pending' || readiness === 'cancelled' || state.clarification.some(item => item.status === 'pending' || item.status === 'cancelled')\n }\n\n private async commitIfCurrent(sessionId: string, generation: number, patch: MoodStoredSession): Promise<boolean> {\n return this.serialize(async () => {\n if (!this.generationCurrent(sessionId, generation)) return false\n const proposed = this.snapshot()\n proposed.sessions[sessionId] = storedOf({ ...this.ensure(sessionId), ...patch })\n await this.persistProposed(proposed)\n if (!this.generationCurrent(sessionId, generation)) return false\n this.commitState(proposed)\n return true\n })\n }\n\n private supersedeIfNew(sessionId: string, sourceVersion: string): void {\n const state = this.ensure(sessionId)\n const previous = state.inflightVersion ?? state.heldRequest?.sourceVersion ?? state.contract?.sourceVersion\n if (!previous || previous === sourceVersion) return\n this.supersede(sessionId)\n }\n\n private supersede(sessionId: string): void {\n const state = this.ensure(sessionId)\n state.generation += 1\n state.work?.abort()\n state.work = undefined\n state.inflightVersion = undefined\n state.heldRequest = undefined\n state.lastHandledVersion = undefined\n if (state.contract && state.contract.readiness !== 'stale' && state.contract.readiness !== 'cancelled') {\n state.contract = { ...state.contract, readiness: 'stale', updatedAt: this.now() }\n }\n state.clarification = markClarification(state.clarification, 'stale')\n }\n\n private replaceWork(sessionId: string): AbortController {\n const state = this.ensure(sessionId)\n state.work?.abort()\n const work = new AbortController()\n state.work = work\n return work\n }\n\n private generationCurrent(sessionId: string, generation: number): boolean {\n if (!this.active) return false\n const state = this.sessions.get(sessionId)\n return Boolean(state && state.generation === generation)\n }\n\n private snapshot(): MoodPersistedState {\n const sessions: Record<string, MoodStoredSession> = {}\n for (const [sessionId, row] of this.sessions) sessions[sessionId] = storedOf(row)\n return cloneState({ settings: this.settings, sessions })\n }\n\n private commitState(proposed: MoodPersistedState): void {\n this.settings = proposed.settings\n const next = new Map<string, InternalSession>()\n for (const [sessionId, row] of Object.entries(proposed.sessions)) {\n const previous = this.sessions.get(sessionId)\n next.set(sessionId, {\n ...row,\n generation: previous?.generation ?? 0,\n work: previous?.work,\n inflightVersion: previous?.inflightVersion,\n })\n }\n this.sessions = next\n }\n\n private async persistProposed(proposed: MoodPersistedState): Promise<void> {\n this.assertLive()\n if (!this.options.store) {\n this.storageFailed = false\n return\n }\n try {\n await this.options.store.save(cloneState(proposed))\n this.storageFailed = false\n } catch (error) {\n this.storageFailed = true\n if (error && typeof error === 'object' && 'code' in error) throw error\n coded('MOOD_STORAGE', '需求澄清保存失败,已保留原内容。')\n }\n }\n\n private assertLive(): void {\n if (!this.active) coded('MOOD_DISABLED', '需求澄清已关闭。')\n }\n\n private serialize<T>(run: () => Promise<T>): Promise<T> {\n const task = this.pending.then(run, run)\n this.pending = task.then(() => {}, () => {})\n return task\n }\n\n private syncAi(): void {\n if (!this.active) {\n this.detachAi()\n return\n }\n if (this.ai) return\n const scope = this.options.activateAi?.()\n if (!scope) return\n this.ai = scope\n this.unregisterPurpose = scope.registerPurpose(analyzePurpose)\n }\n\n private detachAi(): void {\n this.unregisterPurpose?.()\n this.unregisterPurpose = undefined\n this.ai?.dispose()\n this.ai = undefined\n }\n}\n\nfunction isSettled(readiness: TaskContract['readiness'] | undefined): boolean {\n return readiness === 'user-confirmed' || readiness === 'clear-request' || readiness === 'disclosed-assumptions'\n}\n\nfunction nextRevision(contract: TaskContract | undefined): number {\n return (contract?.revision ?? 0) + 1\n}\n\nfunction holdOf(sourceVersion: string, kind: TriggerKind, messages: unknown[]): HeldRequest {\n const trigger = kind === 'risk' || kind === 'material' || kind === 'mild' || kind === 'clear' ? kind : 'material'\n return { sourceVersion, trigger, messages: structuredClone(messages) }\n}\n\nfunction storedOf(row: MoodStoredSession): MoodStoredSession {\n return {\n clarification: row.clarification,\n pendingManual: row.pendingManual,\n ...(row.contract ? { contract: row.contract } : {}),\n ...(row.lastHandledVersion !== undefined ? { lastHandledVersion: row.lastHandledVersion } : {}),\n ...(row.projectId ? { projectId: row.projectId } : {}),\n ...(row.heldRequest ? { heldRequest: row.heldRequest } : {}),\n }\n}\n\nfunction cloneState(state: MoodPersistedState): MoodPersistedState {\n return structuredClone(state)\n}\n\nfunction coded(code: string, message: string): never {\n throw Object.assign(new Error(message), { code })\n}\n\nfunction combineSignals(...signals: Array<AbortSignal | undefined>): AbortSignal {\n const live = signals.filter((item): item is AbortSignal => Boolean(item))\n if (live.length === 0) return new AbortController().signal\n if (live.length === 1) return live[0]!\n return AbortSignal.any(live)\n}\n","import { defineDomain, domainTable } from '@deepseek-ai/dsh-storage-domain'\nimport { z } from 'zod'\nimport { MAX_PROJECT_ID_CHARS, defaultSettings, type MoodSettings } from './contracts.ts'\nimport type { MoodPersistedState, MoodStoredSession, MoodStore } from './service.ts'\n\nconst evidenceSchema = z.object({\n sessionId: z.string().min(1).max(200),\n seq: z.number().int().nonnegative(),\n kind: z.enum(['user', 'tool', 'turn', 'manual']),\n excerpt: z.string().max(200).optional(),\n}).strict()\n\nconst contractSchema = z.object({\n id: z.string().min(1).max(120),\n sessionId: z.string().min(1).max(200),\n sourceVersion: z.string().min(1).max(400),\n revision: z.number().int().nonnegative(),\n goal: z.string().max(2000),\n deliverables: z.array(z.string().max(400)).max(16),\n inScope: z.array(z.string().max(400)).max(16),\n outOfScope: z.array(z.string().max(400)).max(16),\n constraints: z.array(z.string().max(400)).max(16),\n acceptance: z.array(z.string().max(400)).max(16),\n assumptions: z.array(z.string().max(400)).max(16),\n questions: z.array(z.string().max(400)).max(8),\n evidence: z.array(evidenceSchema).max(32),\n readiness: z.enum(['pending', 'clear-request', 'user-confirmed', 'disclosed-assumptions', 'cancelled', 'stale']),\n updatedAt: z.number().int().nonnegative(),\n}).strict()\n\nconst clarificationSchema = z.object({\n id: z.string().min(1).max(80),\n question: z.string().max(400),\n status: z.enum(['pending', 'answered', 'skipped', 'cancelled', 'stale']),\n answer: z.string().max(400).optional(),\n}).strict()\n\nconst heldRequestSchema = z.object({\n sourceVersion: z.string().min(1).max(400),\n trigger: z.enum(['material', 'risk', 'mild', 'clear']),\n messages: z.array(z.unknown()).max(32),\n}).strict()\n\nconst sessionSchema = z.object({\n contract: contractSchema.optional(),\n clarification: z.array(clarificationSchema).max(8),\n lastHandledVersion: z.string().max(400).optional(),\n pendingManual: z.boolean(),\n projectId: z.string().max(MAX_PROJECT_ID_CHARS).optional(),\n heldRequest: heldRequestSchema.optional(),\n}).strict()\n\nconst settingsSchema = z.object({\n revision: z.number().int().nonnegative(),\n mode: z.enum(['auto', 'manual', 'strict']),\n}).strict()\n\nexport const moodStateSchema = z.object({\n settings: settingsSchema,\n sessions: z.record(z.string().min(1).max(200), sessionSchema),\n}).strict()\n\nexport const moodDomain = defineDomain({\n name: 'dsh_editor_mood',\n version: 1,\n tables: {\n state: domainTable<string, MoodPersistedState>(moodStateSchema),\n },\n})\n\nexport type MoodDomainHandle = {\n table(name: 'state'): {\n get(key: string): unknown\n put(key: string, value: unknown): Promise<void>\n delete(key: string): Promise<boolean>\n entries(): IterableIterator<[string, unknown]>\n }\n close(): Promise<void>\n}\n\nexport function emptyMoodState(): MoodPersistedState {\n return { settings: defaultSettings(), sessions: {} }\n}\n\nexport function domainStore(domain: MoodDomainHandle): MoodStore {\n const table = domain.table('state')\n return {\n load(): MoodPersistedState {\n const row = table.get('global') as MoodPersistedState | undefined\n if (!row) return emptyMoodState()\n return {\n settings: { ...defaultSettings(), ...row.settings } as MoodSettings,\n sessions: { ...(row.sessions ?? {}) } as Record<string, MoodStoredSession>,\n }\n },\n async save(state) {\n await table.put('global', {\n settings: { ...state.settings },\n sessions: { ...state.sessions },\n } satisfies MoodPersistedState)\n },\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type { AiServices, RpcResult } from '@klarkxy/dsh-ai-services/contracts'\nimport { registerHostRpc, type HostRpcContext } from '@klarkxy/dsh-ai-services/host-rpc'\nimport {\n MOOD_PLUGIN, MOOD_RPC_CHANNEL, type AskUserQuestionAnswer, type AskUserRequest,\n} from './contracts.ts'\nimport { createMoodContextMessage } from './inject.ts'\nimport { isHumanUserMessage, type UserMessageLike } from './evidence.ts'\nimport { MoodService, type PreStepDecision, type PreStepPayload } from './service.ts'\nimport { domainStore, moodDomain, type MoodDomainHandle } from './storage.ts'\n\nexport const name = MOOD_PLUGIN\nexport const inject = ['aiServices', 'storageDomain', 'sessions', 'userQuestions', 'agents', 'connection', 'webServer'] as const\n\nexport { MoodService } from './service.ts'\nexport { createMoodContextMessage } from './inject.ts'\nexport { domainStore, moodDomain } from './storage.ts'\nexport { CHAT_EVENTS_SLOT, MOOD_AI_PLUGIN, MOOD_PLUGIN, MOOD_RPC_CHANNEL, defaultSettings, projectIdFromCwd } from './contracts.ts'\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context { aiMood: MoodService }\n}\n\nexport type LiveAgent = {\n id?: unknown\n steer?: (message: unknown) => void\n followup?: (message: unknown) => void\n}\n\nexport type AgentsRegistry = {\n get(id: unknown): LiveAgent | undefined\n}\n\ntype Host = Context & HostRpcContext & {\n storageDomain: { open: (spec: typeof moodDomain) => Promise<MoodDomainHandle> }\n aiServices: AiServices\n sessions: { get(id: unknown): { id?: unknown; header?: { cwd?: string }; meta?: { cwd?: string }; snapshotEvents(): readonly unknown[] } | undefined }\n userQuestions: { ask(input: AskUserRequest): Promise<AskUserQuestionAnswer> }\n agents: AgentsRegistry\n}\n\nexport async function apply(ctx: Context): Promise<void> {\n const host = ctx as Host\n if (!host.storageDomain || !host.aiServices || !host.sessions || !host.userQuestions || !host.agents) {\n throw new Error('dsh-mood requires Host aiServices, storageDomain, sessions, userQuestions, and agents')\n }\n const domain = await host.storageDomain.open(moodDomain)\n const service = new MoodService({\n store: domainStore(domain),\n readEvents: sessionId => readSessionEvents(host, sessionId),\n liveSession: sessionId => readLiveSession(host, sessionId),\n activateAi: () => host.aiServices.activate(MOOD_PLUGIN),\n askUser: request => host.userQuestions.ask(request),\n createInjectMessage: text => createMoodContextMessage(text),\n resumeHeld: async (sessionId, messages) => { resumeHeldOnHost(host.agents, sessionId, messages) },\n })\n ctx.provide('aiMood', service)\n ctx.effect(() => async () => { await service.dispose(); await domain.close() }, 'dsh-mood.dispose')\n ctx.effect(() => registerHostRpc(host, MOOD_RPC_CHANNEL, (endpoint, payload, signal): Promise<RpcResult> => (\n service.call(endpoint, payload, signal)\n )), 'dsh-mood.rpc')\n ctx.effect(() => {\n const offStep = listen(ctx, 'agent/pre-step', async (payload: PreStepPayload, next: () => Promise<PreStepDecision>) => (\n service.handlePreStep(payload, next)\n ))\n return () => { offStep?.() }\n }, 'dsh-mood.pre-step')\n}\n\nfunction readLiveSession(host: Host, sessionId: string) {\n return host.sessions.get(sessionId) ?? host.sessions.get(String(sessionId))\n}\n\nfunction readSessionEvents(host: Host, sessionId: string) {\n const session = readLiveSession(host, sessionId) as { snapshotEvents?: () => ReadonlyArray<{ seq: number; type: string; data?: unknown }> } | undefined\n return session?.snapshotEvents?.()\n}\n\n/** Bound invoke: native steer/followup call this.send on the live Agents.get instance. */\nexport function resumeHeldOnHost(agents: AgentsRegistry, sessionId: string, messages: unknown[]): void {\n const agent = agents.get(sessionId) ?? agents.get(String(sessionId))\n if (!agent) throw Object.assign(new Error('当前 Host 没有可恢复的会话。'), { code: 'MOOD_SESSION_NOT_FOUND' })\n const humans = messages.filter(message => isHumanUserMessage(message as UserMessageLike))\n if (!humans.length) throw Object.assign(new Error('没有可重试的原请求。'), { code: 'MOOD_NOT_FOUND' })\n if (typeof agent.steer === 'function') {\n for (const human of humans) agent.steer(human)\n return\n }\n if (typeof agent.followup === 'function') {\n for (const human of humans) agent.followup(human)\n return\n }\n throw Object.assign(new Error('当前会话不能按原请求重试。'), { code: 'MOOD_NO_RESUME' })\n}\n\nfunction listen(ctx: Context, name: string, handler: (...args: never[]) => unknown): (() => void) | undefined {\n const on = ctx.on as unknown as (event: string, listener: (...args: never[]) => unknown) => (() => void) | void\n const off = on.call(ctx, name, handler)\n return typeof off === 'function' ? off : undefined\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["asRecord","asString"],"sources":["../src/evidence.ts","../src/inject.ts","../src/analyze.ts","../src/trigger.ts","../src/questions.ts","../src/schema.ts","../src/service.ts","../src/storage.ts","../src/index.ts"],"sourcesContent":["import {\n CONTRACT_SECTION, MOOD_PLUGIN, MOOD_SOURCE_KIND, excerptOf, type EvidenceRef,\n} from './contracts.ts'\n\nexport interface ContentBlockLike { type?: string; text?: string }\nexport interface MessageSourceLike { kind?: string; plugin?: string; form?: string; sections?: Array<{ name?: string }> }\nexport interface UserMessageLike {\n id?: unknown\n role?: string\n content?: ContentBlockLike[]\n source?: MessageSourceLike\n}\nexport interface SessionEventLike {\n seq: number\n type: string\n data?: unknown\n}\n\nexport function textFromContent(content: unknown): string {\n if (typeof content === 'string') return content\n if (!Array.isArray(content)) return ''\n const parts: string[] = []\n for (const block of content) {\n if (!block || typeof block !== 'object') continue\n const row = block as ContentBlockLike\n if (row.type === 'text' && typeof row.text === 'string') parts.push(row.text)\n }\n return parts.join('\\n')\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nexport function messageSource(value: unknown): MessageSourceLike | undefined {\n const row = asRecord(value)\n const source = asRecord(row?.source) ?? asRecord(asRecord(row?.message)?.source)\n return source as MessageSourceLike | undefined\n}\n\nexport function isHumanUserMessage(message: UserMessageLike | undefined): boolean {\n return message?.source?.kind === 'user'\n}\n\nexport function isMoodMessage(message: UserMessageLike | undefined): boolean {\n if (message?.source?.kind !== MOOD_SOURCE_KIND || message.source.plugin !== MOOD_PLUGIN) return false\n if (message.source.form === 'snapshot') {\n return Boolean(message.source.sections?.some(section => section.name === CONTRACT_SECTION))\n }\n return true\n}\n\nexport function incomingAreAuxiliaryOnly(messages: readonly UserMessageLike[]): boolean {\n if (messages.length === 0) return true\n return messages.every(message => !isHumanUserMessage(message))\n}\n\nexport interface HumanTurn {\n id: string\n seq?: number\n text: string\n}\n\nexport function humanTextOf(message: UserMessageLike): string {\n return textFromContent(message.content)\n}\n\nfunction messageIdOf(value: unknown): string | undefined {\n if (typeof value === 'string' && value.length > 0) return value\n return undefined\n}\n\nexport function collectLogHumans(sessionId: string, events: readonly SessionEventLike[]): Array<HumanTurn & { evidence: EvidenceRef }> {\n const humans: Array<HumanTurn & { evidence: EvidenceRef }> = []\n for (const event of events) {\n if (event.type !== 'user/message') continue\n const source = messageSource(event.data)\n if (source?.kind !== 'user') continue\n const data = asRecord(event.data)\n const text = textFromContent(data?.content)\n const excerpt = excerptOf(text)\n if (!excerpt) continue\n const id = messageIdOf(data?.id) ?? `log:${event.seq}`\n humans.push({\n id,\n seq: event.seq,\n text,\n evidence: excerpt ? { sessionId, seq: event.seq, kind: 'user', excerpt } : { sessionId, seq: event.seq, kind: 'user' },\n })\n }\n return humans\n}\n\nexport function collectClaimedHumans(messages: readonly UserMessageLike[]): HumanTurn[] {\n const humans: HumanTurn[] = []\n for (const message of messages) {\n if (!isHumanUserMessage(message)) continue\n const id = messageIdOf(message.id)\n if (!id) continue\n const text = humanTextOf(message)\n if (!text.trim()) continue\n humans.push({ id, text })\n }\n return humans\n}\n\nexport function latestUserSeq(events: readonly SessionEventLike[]): number {\n let seq = 0\n for (const event of events) {\n if (event.type === 'user/message' && messageSource(event.data)?.kind === 'user') seq = event.seq\n }\n return seq\n}\n\n/** Immutable claimed user-message ids only. Previous turn seq is not this request. */\nexport function sourceVersionOf(humans: readonly HumanTurn[]): string {\n return humans.map(item => item.id).filter(Boolean).join('|')\n}\n\nexport function evidenceForRequest(\n sessionId: string,\n events: readonly SessionEventLike[],\n claimed: readonly HumanTurn[],\n): EvidenceRef[] {\n const ids = new Set(claimed.map(item => item.id))\n if (ids.size === 0) return []\n const refs: EvidenceRef[] = []\n for (const event of events) {\n if (event.type !== 'user/message') continue\n const data = asRecord(event.data)\n const id = messageIdOf(data?.id)\n if (!id || !ids.has(id)) continue\n if (messageSource(event.data)?.kind !== 'user') continue\n const excerpt = excerptOf(textFromContent(data?.content))\n refs.push(excerpt ? { sessionId, seq: event.seq, kind: 'user', excerpt } : { sessionId, seq: event.seq, kind: 'user' })\n }\n return refs\n}\n\nexport function latestHumanText(events: readonly SessionEventLike[], messages: readonly UserMessageLike[]): string {\n const claimed = collectClaimedHumans(messages)\n if (claimed.length) return claimed.at(-1)!.text\n return collectLogHumans('', events).at(-1)?.text ?? ''\n}\n","import { createUserMessage } from '@deepseek-ai/dsh-llm'\nimport {\n CONTRACT_SECTION, MOOD_PLUGIN, MOOD_SOURCE_KIND, readinessLabel, type ClarificationItem, type ProducerMessageSource, type TaskContract,\n} from './contracts.ts'\nimport { isMoodMessage, type UserMessageLike } from './evidence.ts'\n\nexport interface ContractMessageInput {\n source: ProducerMessageSource & {\n kind: typeof MOOD_SOURCE_KIND\n plugin: typeof MOOD_PLUGIN\n form: 'snapshot'\n sections: Array<{ name: string; text: string }>\n }\n content: Array<{ type: 'text'; text: string }>\n}\n\nexport function contractMessageInput(text: string): ContractMessageInput {\n return {\n source: {\n kind: MOOD_SOURCE_KIND,\n plugin: MOOD_PLUGIN,\n form: 'snapshot',\n sections: [{ name: CONTRACT_SECTION, text }],\n },\n content: [{ type: 'text', text }],\n }\n}\n\nexport function createMoodContextMessage(text: string): unknown {\n return createUserMessage(contractMessageInput(text))\n}\n\nexport function formatContract(contract: TaskContract, clarification: readonly ClarificationItem[] = []): string {\n const lines = [\n `【需求约定 · ${readinessLabel(contract.readiness)}】`,\n contract.goal ? `目标:${contract.goal}` : '',\n contract.deliverables.length ? `交付:${contract.deliverables.join(';')}` : '',\n contract.inScope.length ? `范围内:${contract.inScope.join(';')}` : '',\n contract.outOfScope.length ? `范围外:${contract.outOfScope.join(';')}` : '',\n contract.constraints.length ? `约束:${contract.constraints.join(';')}` : '',\n contract.acceptance.length ? `验收:${contract.acceptance.join(';')}` : '',\n contract.assumptions.length ? `假定:${contract.assumptions.join(';')}` : '',\n ]\n if (clarification.length) {\n lines.push('澄清:')\n for (const item of clarification) {\n const answer = item.answer ? ` → ${item.answer}` : ''\n lines.push(`- [${item.status}] ${item.question}${answer}`)\n }\n } else if (contract.questions.length) {\n lines.push(`待确认:${contract.questions.join(';')}`)\n }\n if (contract.evidence.length) {\n lines.push('证据:' + contract.evidence.map((item: { seq: number; excerpt?: string }) => `#${item.seq}${item.excerpt ? `「${item.excerpt}」` : ''}`).join(' '))\n }\n lines.push('本约定不能代替文件修改或发布审批。未确认前不要当作已授权。')\n return lines.filter(Boolean).join('\\n')\n}\n\nexport function mergeContractMessage(\n messages: readonly unknown[],\n extra: unknown,\n): unknown[] {\n const kept = messages.filter(message => !isMoodMessage(message as UserMessageLike))\n return [...kept, extra]\n}\n","import type { EvidenceRef, TaskContract } from './contracts.ts'\nimport { DEFAULT_QUESTION, MAX_QUESTIONS } from './contracts.ts'\nimport type { TriggerKind } from './trigger.ts'\n\nexport interface AnalysisDraft {\n goal: string\n deliverables: string[]\n inScope: string[]\n outOfScope: string[]\n constraints: string[]\n acceptance: string[]\n assumptions: string[]\n questions: string[]\n}\n\nfunction asString(value: unknown): string {\n return typeof value === 'string' ? value.trim() : ''\n}\n\nfunction asList(value: unknown, max = 16): string[] {\n if (!Array.isArray(value)) return []\n const items: string[] = []\n for (const entry of value) {\n const text = asString(entry)\n if (!text) continue\n items.push(text.slice(0, 400))\n if (items.length >= max) break\n }\n return items\n}\n\nexport function parseAnalysis(text: string): AnalysisDraft | undefined {\n const trimmed = text.trim()\n if (!trimmed) return undefined\n const fence = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n const raw = fence?.[1]?.trim() ?? trimmed\n const start = raw.indexOf('{')\n const end = raw.lastIndexOf('}')\n if (start < 0 || end <= start) return undefined\n try {\n const parsed: unknown = JSON.parse(raw.slice(start, end + 1))\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return undefined\n const row = parsed as Record<string, unknown>\n const goal = asString(row.goal).slice(0, 2000)\n const questions = asList(row.questions, MAX_QUESTIONS)\n return {\n goal,\n deliverables: asList(row.deliverables),\n inScope: asList(row.inScope),\n outOfScope: asList(row.outOfScope),\n constraints: asList(row.constraints),\n acceptance: asList(row.acceptance),\n assumptions: asList(row.assumptions),\n questions,\n }\n } catch {\n return undefined\n }\n}\n\nexport function boundQuestions(questions: readonly string[], kind: TriggerKind): string[] {\n const unique: string[] = []\n for (const question of questions) {\n const text = question.trim()\n if (!text) continue\n if (unique.includes(text)) continue\n unique.push(text.slice(0, 400))\n if (unique.length === MAX_QUESTIONS) return unique\n }\n if (unique.length === 0 && (kind === 'material' || kind === 'risk')) return [DEFAULT_QUESTION]\n return unique\n}\n\nexport const ANALYZE_SYSTEM = [\n '你在确认写作任务需求。只根据给定的真实用户原文归纳。',\n '不要编造未给出的文件、人物、字数或验收条件。',\n '不要把需求确认写成文件修改或发布授权。',\n '返回一个 JSON 对象,不要 Markdown。',\n '键:goal, deliverables, inScope, outOfScope, constraints, acceptance, assumptions, questions。',\n `questions 最多 ${MAX_QUESTIONS} 条,仅在存在实质含糊或风险时提出;原文已经可执行则 questions 为空数组。`,\n].join('\\n')\n\nexport function thinContract(input: {\n id: string\n sessionId: string\n sourceVersion: string\n revision: number\n goal: string\n evidence: EvidenceRef[]\n readiness: TaskContract['readiness']\n now: number\n extra?: Partial<Pick<TaskContract, 'deliverables' | 'inScope' | 'outOfScope' | 'constraints' | 'acceptance' | 'assumptions' | 'questions'>>\n}): TaskContract {\n return {\n id: input.id,\n sessionId: input.sessionId,\n sourceVersion: input.sourceVersion,\n revision: input.revision,\n goal: input.goal.slice(0, 2000),\n deliverables: input.extra?.deliverables ?? [],\n inScope: input.extra?.inScope ?? [],\n outOfScope: input.extra?.outOfScope ?? [],\n constraints: input.extra?.constraints ?? [],\n acceptance: input.extra?.acceptance ?? [],\n assumptions: input.extra?.assumptions ?? [],\n questions: input.extra?.questions ?? [],\n evidence: input.evidence,\n readiness: input.readiness,\n updatedAt: input.now,\n }\n}\n\nexport function contractFromDraft(input: {\n id: string\n sessionId: string\n sourceVersion: string\n revision: number\n goalFallback: string\n evidence: EvidenceRef[]\n draft: AnalysisDraft | undefined\n questions: string[]\n readiness: TaskContract['readiness']\n now: number\n}): TaskContract {\n const draft = input.draft\n return thinContract({\n id: input.id,\n sessionId: input.sessionId,\n sourceVersion: input.sourceVersion,\n revision: input.revision,\n goal: draft?.goal || input.goalFallback,\n evidence: input.evidence,\n readiness: input.readiness,\n now: input.now,\n extra: {\n deliverables: draft?.deliverables ?? [],\n inScope: draft?.inScope ?? [],\n outOfScope: draft?.outOfScope ?? [],\n constraints: draft?.constraints ?? [],\n acceptance: draft?.acceptance ?? [],\n assumptions: draft?.assumptions ?? [],\n questions: input.questions,\n },\n })\n}\n\nexport const analyzePurpose = {\n id: 'mood.analyze',\n label: '需求澄清',\n defaultTarget: { kind: 'role' as const, role: 'normal' as const },\n maxOutputTokens: 1024,\n timeoutMs: 60_000,\n}\n","export type TriggerKind = 'skip' | 'clear' | 'mild' | 'material' | 'risk'\nexport type MoodMode = 'auto' | 'manual' | 'strict'\n\nconst ACK = /^(好的?|嗯+|行|ok|okay|收到|谢谢[.。!!]?|thanks[.!]?)$/i\nconst CONTINUE = /^(继续|接着(?:做|写|改)?|go on|continue)$/i\nconst VAGUE = /帮我(?:看|改|写|弄)?一下|改一下|写一下|处理一下|优化一下|弄好|随便|看情况|你决定|都行|无所谓|或者就|怎么写都行|看着办|帮我改改|改改/\nconst RISK = /删除全部|全部删除|清空(?:全书|所有|全部)?|覆盖原文|覆盖所有|重写全|全部重写|并发布|发布到|永久删除|替换所有/\nconst PATH = /\\.[A-Za-z][A-Za-z0-9]{0,7}\\b|第[一二三四五六七八九十百0-9]+章|[A-Za-z]:\\\\|\\//\nconst BOUND = /不超过|不少于|至少|最多|保持|不要|仅|只|必须|字以内|<=|≥|\\d+\\s*(?:字|句|段|行)/\nconst NAMED = /[\\u4e00-\\u9fff]{2,6}(?:的)?(?:对白|对话|语气|出场)|“[^”]{2,40}”/\nconst EXPLAIN = /解释什么是|^什么是|explain\\s+what/i\nconst TRANSLATE = /翻译成|译成|translate\\s+.+\\s+into/i\nconst LOCAL_EDIT = /把第[一二三四五六七八九十百0-9]+[行句段]|修正拼写|重命名为|把错字|typo/i\n\nexport function classifyRequest(text: string, options: { hasConfirmedContract?: boolean } = {}): TriggerKind {\n const trimmed = text.replace(/\\s+/g, ' ').trim()\n if (!trimmed) return 'skip'\n if (ACK.test(trimmed)) return 'skip'\n if (CONTINUE.test(trimmed)) return options.hasConfirmedContract ? 'skip' : 'material'\n if (RISK.test(trimmed)) return 'risk'\n if (EXPLAIN.test(trimmed) || TRANSLATE.test(trimmed) || LOCAL_EDIT.test(trimmed)) return 'clear'\n if (VAGUE.test(trimmed)) return 'material'\n const specific = PATH.test(trimmed) || NAMED.test(trimmed)\n const bounded = BOUND.test(trimmed)\n if (specific && bounded && trimmed.length >= 16) return 'clear'\n if (specific || bounded) return 'mild'\n return 'clear'\n}\n\nexport function shouldAnalyze(kind: TriggerKind, mode: MoodMode, pendingManual: boolean): boolean {\n if (kind === 'skip') return false\n if (pendingManual) return true\n if (mode === 'manual') return false\n if (mode === 'strict') return true\n return kind === 'material' || kind === 'risk'\n}\n\nexport function shouldWriteClearContract(kind: TriggerKind, pendingManual: boolean, mode: MoodMode = 'auto'): boolean {\n return kind === 'clear' && !pendingManual && mode === 'auto'\n}\n\nexport function isBlockingKind(kind: TriggerKind): boolean {\n return kind === 'material' || kind === 'risk'\n}\n","import type {\n AskUserQuestionAnswer, AskUserQuestionItem, ClarificationItem, ClarificationStatus,\n} from './contracts.ts'\nimport { isBlockingKind, type TriggerKind } from './trigger.ts'\n\n/** Native option label; selecting it without custom text is not an answer. */\nexport const ASK_DETAIL_OPTION = '补充说明'\n\nexport function toAskItems(items: readonly ClarificationItem[]): AskUserQuestionItem[] {\n return items.filter(item => item.status === 'pending').map(item => ({\n id: item.id,\n header: '澄清',\n question: item.question,\n options: [\n { label: ASK_DETAIL_OPTION, description: '在自定义输入中写明范围、约束或验收标准' },\n ],\n }))\n}\n\nexport function pendingClarifications(questions: readonly string[]): ClarificationItem[] {\n return questions.map((question, index) => ({\n id: `q${index + 1}`,\n question,\n status: 'pending',\n }))\n}\n\nfunction answerText(item: { selected: string[]; custom?: string }): string {\n const selected = item.selected.map(entry => entry.trim()).filter(Boolean).filter(entry => entry !== ASK_DETAIL_OPTION)\n const custom = item.custom?.trim() ?? ''\n if (custom && selected.length) return `${selected.join(';')};${custom}`\n if (custom) return custom\n return selected.join(';')\n}\n\nexport function applyAnswers(\n items: readonly ClarificationItem[],\n answer: AskUserQuestionAnswer | undefined,\n): ClarificationItem[] {\n const byId = new Map((answer?.answers ?? []).map(entry => [entry.id, entry]))\n return items.map(item => {\n if (item.status !== 'pending') return item\n const entry = byId.get(item.id)\n if (!entry) return { ...item, status: 'skipped' as const }\n const text = answerText(entry)\n if (!text) return { ...item, status: 'skipped' as const }\n return { ...item, status: 'answered' as const, answer: text.slice(0, 400) }\n })\n}\n\nexport function markClarification(items: readonly ClarificationItem[], status: ClarificationStatus): ClarificationItem[] {\n return items.map(item => item.status === 'pending' ? { ...item, status } : item)\n}\n\nexport function readinessAfterAnswers(\n items: readonly ClarificationItem[],\n kind: TriggerKind = 'mild',\n): 'user-confirmed' | 'disclosed-assumptions' | 'pending' {\n if (items.some(item => item.status === 'pending')) return 'pending'\n if (items.length === 0) return 'user-confirmed'\n if (items.every(item => item.status === 'answered')) return 'user-confirmed'\n if (isBlockingKind(kind)) return 'pending'\n return 'disclosed-assumptions'\n}\n\nexport function answeredNotes(items: readonly ClarificationItem[]): string[] {\n return items.filter(item => item.status === 'answered' && item.answer).map(item => `${item.question}:${item.answer}`)\n}\n\nexport function isAskAborted(error: unknown): boolean {\n if (!error || typeof error !== 'object') return false\n const row = error as { name?: unknown; code?: unknown }\n if (row.code === 'ASK_ABORTED' || row.code === 'ASK_CANCELLED') return true\n const name = String(row.name ?? '')\n return name === 'AbortError' || name === 'TimeoutError'\n}\n\nexport function isAbortLike(error: unknown, signal?: AbortSignal): boolean {\n if (signal?.aborted) return true\n if (!error || typeof error !== 'object') return false\n const row = error as { name?: unknown; code?: unknown }\n const name = String(row.name ?? '')\n const code = String(row.code ?? '')\n return name === 'AbortError' || name === 'TimeoutError' || code === 'ABORT_ERR' || code === 'ABORTED' || isAskAborted(error)\n}\n","import type { MoodMode, TaskContract } from './contracts.ts'\nimport { isMoodMode, parseSessionId } from './contracts.ts'\n\nexport interface ModeUpdate {\n expectedRevision: number\n mode: MoodMode\n}\n\nexport interface ManualRequest {\n sessionId: string\n}\n\nexport interface ContractEdit {\n sessionId: string\n expectedRevision: number\n patch: Partial<Pick<TaskContract, 'goal' | 'deliverables' | 'inScope' | 'outOfScope' | 'constraints' | 'acceptance' | 'assumptions' | 'questions'>>\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nfunction asString(value: unknown, max: number): string | undefined {\n if (typeof value !== 'string') return undefined\n const text = value.trim()\n if (text.length > max) return undefined\n return text\n}\n\nfunction asStringList(value: unknown, maxItems: number, maxChars: number): string[] | undefined {\n if (!Array.isArray(value) || value.length > maxItems) return undefined\n const items: string[] = []\n for (const entry of value) {\n if (typeof entry !== 'string' || entry.length > maxChars) return undefined\n items.push(entry)\n }\n return items\n}\n\nexport function parseModeUpdate(payload: unknown): ModeUpdate | undefined {\n const row = asRecord(payload)\n if (!row) return undefined\n if (typeof row.expectedRevision !== 'number' || !Number.isInteger(row.expectedRevision) || row.expectedRevision < 0) return undefined\n if (!isMoodMode(row.mode)) return undefined\n return { expectedRevision: row.expectedRevision, mode: row.mode }\n}\n\nexport function parseManual(payload: unknown): ManualRequest | undefined {\n const sessionId = parseSessionId(payload)\n return sessionId ? { sessionId } : undefined\n}\n\nconst PATCH_KEYS = ['goal', 'deliverables', 'inScope', 'outOfScope', 'constraints', 'acceptance', 'assumptions', 'questions'] as const\n\nexport function parseEdit(payload: unknown): ContractEdit | undefined {\n const row = asRecord(payload)\n if (!row) return undefined\n const sessionId = parseSessionId(row)\n if (!sessionId) return undefined\n if (typeof row.expectedRevision !== 'number' || !Number.isInteger(row.expectedRevision) || row.expectedRevision < 0) return undefined\n const patchRow = asRecord(row.patch)\n if (!patchRow) return undefined\n const patch: ContractEdit['patch'] = {}\n for (const key of Object.keys(patchRow)) {\n if (!(PATCH_KEYS as readonly string[]).includes(key)) return undefined\n }\n if (patchRow.goal !== undefined) {\n const goal = asString(patchRow.goal, 2000)\n if (goal === undefined) return undefined\n patch.goal = goal\n }\n for (const key of ['deliverables', 'inScope', 'outOfScope', 'constraints', 'acceptance', 'assumptions', 'questions'] as const) {\n if (patchRow[key] === undefined) continue\n const list = asStringList(patchRow[key], 16, 400)\n if (!list) return undefined\n patch[key] = list\n }\n if (Object.keys(patch).length === 0) return undefined\n return { sessionId, expectedRevision: row.expectedRevision, patch }\n}\n","import { randomUUID } from 'node:crypto'\nimport type { AiFeatureScope, AuxiliaryResult, RpcResult, TaskContract } from '@klarkxy/dsh-ai-services/contracts'\nimport {\n MOOD_ANALYZE_PURPOSE, PROMPT_VERSION, SCHEMA_VERSION, cloneContract, defaultSettings, excerptOf, fail, ok,\n operationalSettings,\n parseSessionId, projectIdFromCwd, sessionIdOf, type AskUserRequest, type AskUserQuestionAnswer, type ClarificationItem,\n type HeldRequest, type MoodMode, type MoodSessionView, type MoodSettings, type MoodStatus,\n} from './contracts.ts'\nimport { ANALYZE_SYSTEM, analyzePurpose, boundQuestions, contractFromDraft, parseAnalysis, thinContract } from './analyze.ts'\nimport {\n collectClaimedHumans, evidenceForRequest, incomingAreAuxiliaryOnly, latestUserSeq, sourceVersionOf,\n type SessionEventLike, type UserMessageLike,\n} from './evidence.ts'\nimport { createMoodContextMessage, formatContract, mergeContractMessage } from './inject.ts'\nimport {\n answeredNotes, applyAnswers, isAbortLike, markClarification, pendingClarifications, readinessAfterAnswers, toAskItems,\n} from './questions.ts'\nimport { parseEdit, parseManual, parseModeUpdate } from './schema.ts'\nimport { classifyRequest, isBlockingKind, shouldAnalyze, shouldWriteClearContract, type TriggerKind } from './trigger.ts'\n\nexport interface MoodPersistedState {\n settings: MoodSettings\n sessions: Record<string, MoodStoredSession>\n}\n\nexport interface MoodStoredSession {\n contract?: TaskContract\n clarification: ClarificationItem[]\n lastHandledVersion?: string\n pendingManual: boolean\n projectId?: string\n heldRequest?: HeldRequest\n}\n\nexport interface MoodStore {\n load(): MoodPersistedState\n save(state: MoodPersistedState): Promise<void>\n}\n\nexport interface SessionLike {\n id?: unknown\n header?: { cwd?: string }\n meta?: { cwd?: string }\n}\n\nexport interface PreStepPayload {\n agent: { id?: unknown; session?: SessionLike }\n messages: UserMessageLike[]\n turn: number\n step: number\n signal: AbortSignal\n}\n\nexport type PreStepDecision = { kind: 'reject' } | { kind: 'enter'; messages: unknown[]; startsRequestSeries?: true }\n\nexport interface MoodServiceOptions {\n store?: MoodStore\n now?: () => number\n id?: () => string\n readEvents: (sessionId: string) => readonly SessionEventLike[] | undefined\n liveSession?: (sessionId: string) => SessionLike | undefined\n activateAi?: () => AiFeatureScope | undefined\n askUser?: (request: AskUserRequest) => Promise<AskUserQuestionAnswer>\n createInjectMessage?: (text: string) => unknown\n resumeHeld?: (sessionId: string, messages: unknown[]) => Promise<void>\n}\n\ntype InternalSession = MoodStoredSession & {\n generation: number\n work?: AbortController\n inflightVersion?: string\n}\n\nexport class MoodService {\n private settings: MoodSettings\n private sessions = new Map<string, InternalSession>()\n private storageFailed = false\n private active = true\n private ai?: AiFeatureScope\n private unregisterPurpose?: () => void\n private pending = Promise.resolve()\n private readonly now: () => number\n private readonly nextId: () => string\n\n constructor(private readonly options: MoodServiceOptions) {\n const loaded = cloneState(options.store?.load() ?? { settings: defaultSettings(), sessions: {} })\n this.settings = operationalSettings(loaded.settings)\n for (const [sessionId, row] of Object.entries(loaded.sessions)) {\n this.sessions.set(sessionId, {\n ...row,\n clarification: row.clarification ?? [],\n pendingManual: Boolean(row.pendingManual),\n generation: 0,\n })\n }\n this.now = options.now ?? Date.now\n this.nextId = options.id ?? randomUUID\n this.syncAi()\n }\n\n getContract(sessionId: string): TaskContract | undefined {\n const contract = this.sessions.get(sessionId)?.contract\n return contract ? cloneContract(contract) : undefined\n }\n\n status(sessionId?: string): MoodStatus {\n const status: MoodStatus = {\n settings: { ...this.settings },\n storageFailed: this.storageFailed,\n }\n if (!sessionId) return status\n const row = this.ensure(sessionId)\n status.session = this.view(sessionId, row)\n return status\n }\n\n isActive(): boolean {\n return this.active\n }\n\n async dispose(): Promise<void> {\n this.active = false\n for (const row of this.sessions.values()) {\n row.generation += 1\n row.work?.abort()\n row.work = undefined\n }\n this.detachAi()\n await this.pending\n }\n\n async call(endpoint: string, payload: unknown, signal: AbortSignal): Promise<RpcResult> {\n if (!this.active) return fail('MOOD_DISABLED', '需求澄清已关闭。')\n if (signal.aborted) return fail('MOOD_CANCELLED', '请求已取消。')\n try {\n if (endpoint === 'status') return ok(this.status(parseSessionId(payload)))\n if (endpoint === 'contract') {\n const sessionId = this.hostSessionId(parseSessionId(payload), false)\n if (!sessionId) return fail('MOOD_INVALID', '缺少会话。')\n return ok(this.getContract(sessionId) ?? null)\n }\n if (endpoint === 'mode') {\n const parsed = parseModeUpdate(payload)\n if (!parsed) return fail('MOOD_INVALID', '模式格式无效。')\n return ok(await this.updateMode(parsed.mode, parsed.expectedRevision))\n }\n if (endpoint === 'manual') {\n const parsed = parseManual(payload)\n if (!parsed) return fail('MOOD_INVALID', '缺少会话。')\n const sessionId = this.hostSessionId(parsed.sessionId, true)\n if (!sessionId) return fail('MOOD_SESSION_NOT_FOUND', '会话不在当前 Host。')\n return ok(await this.requestManual(sessionId))\n }\n if (endpoint === 'retry') {\n const parsed = parseManual(payload)\n if (!parsed) return fail('MOOD_INVALID', '缺少会话。')\n const sessionId = this.hostSessionId(parsed.sessionId, true)\n if (!sessionId) return fail('MOOD_SESSION_NOT_FOUND', '会话不在当前 Host。')\n return ok(await this.requestRetry(sessionId))\n }\n if (endpoint === 'edit') {\n const parsed = parseEdit(payload)\n if (!parsed) return fail('MOOD_INVALID', '修订格式无效。')\n const sessionId = this.hostSessionId(parsed.sessionId, true)\n if (!sessionId) return fail('MOOD_SESSION_NOT_FOUND', '会话不在当前 Host。')\n return ok(await this.editContract(sessionId, parsed.expectedRevision, parsed.patch))\n }\n return fail('MOOD_INVALID', '未知操作。')\n } catch (error) {\n const code = error && typeof error === 'object' && 'code' in error ? String((error as { code: unknown }).code) : 'MOOD_FAILED'\n return fail(code, error instanceof Error ? error.message : '需求澄清操作失败。')\n }\n }\n\n async handlePreStep(payload: PreStepPayload, next: () => Promise<PreStepDecision>): Promise<PreStepDecision> {\n const inner = await next()\n if (!this.active) return inner\n if (inner.kind !== 'enter') return inner\n payload.signal.throwIfAborted()\n const sessionId = sessionIdOf(payload.agent)\n if (!sessionId) return inner\n const claimedMessages = payload.messages\n const state = this.ensure(sessionId)\n state.projectId = projectIdFromCwd(payload.agent.session?.header?.cwd ?? payload.agent.session?.meta?.cwd)\n ?? projectIdFromCwd(this.options.liveSession?.(sessionId)?.header?.cwd ?? this.options.liveSession?.(sessionId)?.meta?.cwd)\n ?? state.projectId\n\n if (incomingAreAuxiliaryOnly(claimedMessages) && !state.pendingManual) {\n if (this.isBlocked(state)) return { kind: 'reject' }\n return this.enter(inner, state.contract, state.clarification)\n }\n\n const claimed = collectClaimedHumans(claimedMessages)\n const sourceVersion = sourceVersionOf(claimed)\n const events = this.options.readEvents(sessionId) ?? []\n const evidence = evidenceForRequest(sessionId, events, claimed)\n const text = claimed.at(-1)?.text ?? ''\n\n if (claimed.length) this.supersedeIfNew(sessionId, sourceVersion)\n\n const live = this.ensure(sessionId)\n if (live.lastHandledVersion === sourceVersion && !live.pendingManual && isSettled(live.contract?.readiness)) {\n return this.enter(inner, live.contract, live.clarification)\n }\n\n const kind = classifyRequest(text, { hasConfirmedContract: isSettled(live.contract?.readiness) })\n if (kind === 'skip' && !live.pendingManual) {\n return this.enter(inner, live.contract, live.clarification)\n }\n\n if (shouldWriteClearContract(kind, live.pendingManual, this.settings.mode)) {\n const generation = live.generation\n const contract = thinContract({\n id: this.nextId(),\n sessionId,\n sourceVersion,\n revision: nextRevision(live.contract),\n goal: text.slice(0, 2000),\n evidence,\n readiness: 'clear-request',\n now: this.now(),\n })\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification: [],\n lastHandledVersion: sourceVersion,\n pendingManual: false,\n heldRequest: undefined,\n projectId: live.projectId,\n })\n if (!wrote) return this.afterStale(inner)\n return this.enter(inner, contract, [])\n }\n\n if (!shouldAnalyze(kind, this.settings.mode, live.pendingManual)) {\n return inner\n }\n\n const generation = live.generation\n live.inflightVersion = sourceVersion\n const work = this.replaceWork(sessionId)\n const combined = combineSignals(payload.signal, work.signal, this.ai?.signal)\n let draft = undefined as ReturnType<typeof parseAnalysis>\n try {\n draft = await this.runAnalysis({ sessionId, sourceVersion, text, evidence, signal: combined, generation })\n } catch (error) {\n if (!this.generationCurrent(sessionId, generation)) return this.afterStale(inner)\n const status = isAbortLike(error, combined) ? 'cancelled' : 'pending'\n await this.blockUnresolved({\n sessionId, generation, sourceVersion, text, evidence, kind, claimed: claimedMessages, status, inner,\n })\n return { kind: 'reject' }\n }\n\n if (!this.generationCurrent(sessionId, generation)) return this.afterStale(inner)\n\n const questions = boundQuestions(draft?.questions ?? [], kind)\n const clarification = pendingClarifications(questions)\n let contract = contractFromDraft({\n id: this.nextId(),\n sessionId,\n sourceVersion,\n revision: nextRevision(this.ensure(sessionId).contract),\n goalFallback: text.slice(0, 2000),\n evidence,\n draft,\n questions,\n readiness: questions.length || isBlockingKind(kind) ? 'pending' : 'disclosed-assumptions',\n now: this.now(),\n })\n\n if (questions.length > 0) {\n const asked = await this.askOnce(payload.agent, clarification, combined)\n if (!this.generationCurrent(sessionId, generation)) return this.afterStale(inner)\n if (asked.kind === 'aborted' || asked.kind === 'failed') {\n const status = asked.kind === 'aborted' ? 'cancelled' : 'pending'\n await this.blockUnresolved({\n sessionId, generation, sourceVersion, text, evidence, kind, claimed: claimedMessages, status, inner,\n contract, clarification: asked.kind === 'aborted' ? markClarification(clarification, 'cancelled') : clarification,\n })\n return { kind: 'reject' }\n }\n const answered = applyAnswers(clarification, asked.answer)\n const readiness = readinessAfterAnswers(answered, kind)\n if (isBlockingKind(kind) && readiness !== 'user-confirmed') {\n contract = {\n ...contract,\n readiness: 'pending',\n assumptions: draft?.assumptions ?? contract.assumptions,\n constraints: [...contract.constraints, ...answeredNotes(answered)],\n questions: answered.filter(item => item.status !== 'answered').map(item => item.question),\n updatedAt: this.now(),\n }\n await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification: answered,\n pendingManual: false,\n lastHandledVersion: undefined,\n heldRequest: holdOf(sourceVersion, kind, claimedMessages),\n projectId: this.ensure(sessionId).projectId,\n })\n return { kind: 'reject' }\n }\n contract = {\n ...contract,\n readiness,\n assumptions: [\n ...contract.assumptions,\n ...(isBlockingKind(kind) ? [] : answered.filter(item => item.status === 'skipped').map(item => `未回答:${item.question}`)),\n ],\n constraints: [...contract.constraints, ...answeredNotes(answered)],\n questions: answered.filter(item => item.status !== 'answered').map(item => item.question),\n updatedAt: this.now(),\n }\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification: answered,\n lastHandledVersion: sourceVersion,\n pendingManual: false,\n heldRequest: undefined,\n projectId: this.ensure(sessionId).projectId,\n })\n if (!wrote) return this.afterStale(inner)\n return this.enter(inner, contract, answered)\n }\n\n if (isBlockingKind(kind) && contract.readiness === 'pending') {\n await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification,\n pendingManual: false,\n lastHandledVersion: undefined,\n heldRequest: holdOf(sourceVersion, kind, claimedMessages),\n projectId: this.ensure(sessionId).projectId,\n })\n return { kind: 'reject' }\n }\n\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification,\n lastHandledVersion: sourceVersion,\n pendingManual: false,\n heldRequest: undefined,\n projectId: this.ensure(sessionId).projectId,\n })\n if (!wrote) return this.afterStale(inner)\n return this.enter(inner, contract, clarification)\n }\n\n private async runAnalysis(input: {\n sessionId: string\n sourceVersion: string\n text: string\n evidence: TaskContract['evidence']\n signal: AbortSignal\n generation: number\n }): Promise<ReturnType<typeof parseAnalysis>> {\n const scope = this.ai\n if (!scope?.active) return undefined\n input.signal.throwIfAborted()\n const result: AuxiliaryResult = await scope.run({\n purpose: MOOD_ANALYZE_PURPOSE,\n sessionId: input.sessionId,\n sourceVersion: input.sourceVersion,\n promptVersion: PROMPT_VERSION,\n schemaVersion: SCHEMA_VERSION,\n system: ANALYZE_SYSTEM,\n input: JSON.stringify({\n text: input.text,\n evidence: input.evidence,\n }),\n signal: input.signal,\n priority: 'interactive',\n isCurrent: () => this.generationCurrent(input.sessionId, input.generation) && !input.signal.aborted,\n })\n if (result.receipt.status !== 'success') return undefined\n if (!this.generationCurrent(input.sessionId, input.generation)) return undefined\n return parseAnalysis(result.text)\n }\n\n private async askOnce(\n agent: unknown,\n clarification: ClarificationItem[],\n signal: AbortSignal,\n ): Promise<{ kind: 'answered'; answer: AskUserQuestionAnswer } | { kind: 'aborted' } | { kind: 'failed' }> {\n const ask = this.options.askUser\n const items = toAskItems(clarification)\n if (!items.length || !ask) return { kind: 'failed' }\n try {\n const answer = await ask({ agent, questions: items, signal })\n return { kind: 'answered', answer }\n } catch (error) {\n if (isAbortLike(error, signal)) return { kind: 'aborted' }\n return { kind: 'failed' }\n }\n }\n\n private afterStale(inner: Extract<PreStepDecision, { kind: 'enter' }>): PreStepDecision {\n if (!this.active) return inner\n return { kind: 'reject' }\n }\n\n private enter(\n decision: Extract<PreStepDecision, { kind: 'enter' }>,\n contract: TaskContract | undefined,\n clarification: readonly ClarificationItem[],\n ): PreStepDecision {\n if (!this.active || !contract) return decision\n if (contract.readiness === 'pending' || contract.readiness === 'cancelled' || contract.readiness === 'stale') {\n return decision\n }\n const text = formatContract(contract, clarification)\n const extra = this.options.createInjectMessage\n ? this.options.createInjectMessage(text)\n : createMoodContextMessage(text)\n return { ...decision, messages: mergeContractMessage(decision.messages ?? [], extra) }\n }\n\n private async blockUnresolved(input: {\n sessionId: string\n generation: number\n sourceVersion: string\n text: string\n evidence: TaskContract['evidence']\n kind: TriggerKind\n claimed: unknown[]\n status: 'pending' | 'cancelled' | 'stale'\n inner: Extract<PreStepDecision, { kind: 'enter' }>\n contract?: TaskContract\n clarification?: ClarificationItem[]\n }): Promise<void> {\n if (!this.generationCurrent(input.sessionId, input.generation)) return\n const state = this.ensure(input.sessionId)\n const questions = boundQuestions(input.contract?.questions ?? [], input.kind)\n const clarification = input.clarification ?? markClarification(\n pendingClarifications(questions),\n input.status === 'pending' ? 'pending' : input.status,\n )\n const contract = input.contract\n ? { ...input.contract, readiness: input.status, questions, updatedAt: this.now() }\n : thinContract({\n id: this.nextId(),\n sessionId: input.sessionId,\n sourceVersion: input.sourceVersion,\n revision: nextRevision(state.contract),\n goal: input.text.slice(0, 2000),\n evidence: input.evidence,\n readiness: input.status,\n now: this.now(),\n extra: { questions },\n })\n const hold = isBlockingKind(input.kind) || clarification.length > 0\n ? holdOf(input.sourceVersion, input.kind, input.claimed)\n : undefined\n await this.commitIfCurrent(input.sessionId, input.generation, {\n contract,\n clarification,\n pendingManual: false,\n lastHandledVersion: undefined,\n heldRequest: hold,\n projectId: state.projectId,\n })\n void input.inner\n }\n\n private async updateMode(_mode: MoodMode, expectedRevision: number): Promise<MoodStatus> {\n return this.serialize(async () => {\n this.assertLive()\n if (expectedRevision !== this.settings.revision) coded('MOOD_STALE', '需求澄清设置已更新,请刷新后重试。')\n const proposed = this.snapshot()\n proposed.settings = operationalSettings({ mode: 'auto', revision: this.settings.revision + 1 })\n await this.persistProposed(proposed)\n this.commitState(proposed)\n return this.status()\n })\n }\n\n private async requestManual(sessionId: string): Promise<MoodStatus> {\n const state = this.ensure(sessionId)\n const generation = state.generation\n const held = state.heldRequest\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n pendingManual: true,\n lastHandledVersion: undefined,\n heldRequest: held,\n clarification: state.clarification,\n contract: state.contract,\n projectId: state.projectId,\n })\n if (!wrote) coded('MOOD_CANCELLED', '会话已切换,未执行手动分析。')\n if (held?.messages.length) await this.resumeExact(sessionId, held.messages)\n return this.status(sessionId)\n }\n\n private async requestRetry(sessionId: string): Promise<MoodStatus> {\n const state = this.ensure(sessionId)\n const held = state.heldRequest\n if (!held?.messages.length) coded('MOOD_NOT_FOUND', '没有可按原请求重试的内容。')\n const generation = state.generation\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n pendingManual: false,\n lastHandledVersion: undefined,\n heldRequest: held,\n clarification: state.clarification.map(item => (\n item.status === 'cancelled' || item.status === 'stale' ? { ...item, status: 'pending' as const, answer: undefined } : item\n )),\n contract: state.contract ? { ...state.contract, readiness: 'pending', updatedAt: this.now() } : state.contract,\n projectId: state.projectId,\n })\n if (!wrote) coded('MOOD_CANCELLED', '会话已切换,未重试。')\n await this.resumeExact(sessionId, held.messages)\n return this.status(sessionId)\n }\n\n private async resumeExact(sessionId: string, messages: unknown[]): Promise<void> {\n const resume = this.options.resumeHeld\n if (!resume) coded('MOOD_NO_RESUME', '当前 Host 不能按原请求恢复。')\n await resume(sessionId, messages)\n }\n\n private async editContract(\n sessionId: string,\n expectedRevision: number,\n patch: Partial<Pick<TaskContract, 'goal' | 'deliverables' | 'inScope' | 'outOfScope' | 'constraints' | 'acceptance' | 'assumptions' | 'questions'>>,\n ): Promise<MoodStatus> {\n const state = this.ensure(sessionId)\n const generation = state.generation\n const current = state.contract\n if (!current) coded('MOOD_NOT_FOUND', '还没有可修订的约定。')\n if (current.revision !== expectedRevision) coded('MOOD_STALE', '约定已更新,请刷新后重试。')\n const evidence = [\n ...current.evidence,\n { sessionId, seq: latestUserSeq(this.options.readEvents(sessionId) ?? []), kind: 'manual' as const, excerpt: excerptOf(patch.goal ?? '修订约定') },\n ]\n const contract: TaskContract = {\n ...current,\n ...patch,\n revision: current.revision + 1,\n readiness: 'user-confirmed',\n evidence,\n updatedAt: this.now(),\n }\n const wrote = await this.commitIfCurrent(sessionId, generation, {\n contract,\n clarification: state.clarification.map(item => item.status === 'pending' ? { ...item, status: 'answered' as const, answer: '作者直接修订约定' } : item),\n pendingManual: false,\n lastHandledVersion: state.lastHandledVersion,\n heldRequest: undefined,\n projectId: state.projectId,\n })\n if (!wrote) coded('MOOD_CANCELLED', '会话已切换,未保存修订。')\n return this.status(sessionId)\n }\n\n private hostSessionId(sessionId: string | undefined, required: boolean): string | undefined {\n if (!sessionId) return undefined\n if (!this.options.liveSession) return sessionId\n const live = this.options.liveSession(sessionId)\n if (!live) return required ? undefined : sessionId\n return live.id != null ? String(live.id) : sessionId\n }\n\n private ensure(sessionId: string): InternalSession {\n const existing = this.sessions.get(sessionId)\n if (existing) return existing\n const created: InternalSession = { clarification: [], pendingManual: false, generation: 0 }\n this.sessions.set(sessionId, created)\n return created\n }\n\n private view(sessionId: string, row: InternalSession): MoodSessionView {\n return {\n sessionId,\n ...(row.projectId ? { projectId: row.projectId } : {}),\n ...(row.contract ? { contract: cloneContract(row.contract) } : {}),\n clarification: row.clarification.map(item => ({ ...item })),\n pendingManual: row.pendingManual,\n held: Boolean(row.heldRequest?.messages.length),\n }\n }\n\n private isBlocked(state: InternalSession): boolean {\n if (!state.heldRequest) return false\n const readiness = state.contract?.readiness\n return readiness === 'pending' || readiness === 'cancelled' || state.clarification.some(item => item.status === 'pending' || item.status === 'cancelled')\n }\n\n private async commitIfCurrent(sessionId: string, generation: number, patch: MoodStoredSession): Promise<boolean> {\n return this.serialize(async () => {\n if (!this.generationCurrent(sessionId, generation)) return false\n const proposed = this.snapshot()\n proposed.sessions[sessionId] = storedOf({ ...this.ensure(sessionId), ...patch })\n await this.persistProposed(proposed)\n if (!this.generationCurrent(sessionId, generation)) return false\n this.commitState(proposed)\n return true\n })\n }\n\n private supersedeIfNew(sessionId: string, sourceVersion: string): void {\n const state = this.ensure(sessionId)\n const previous = state.inflightVersion ?? state.heldRequest?.sourceVersion ?? state.contract?.sourceVersion\n if (!previous || previous === sourceVersion) return\n this.supersede(sessionId)\n }\n\n private supersede(sessionId: string): void {\n const state = this.ensure(sessionId)\n state.generation += 1\n state.work?.abort()\n state.work = undefined\n state.inflightVersion = undefined\n state.heldRequest = undefined\n state.lastHandledVersion = undefined\n if (state.contract && state.contract.readiness !== 'stale' && state.contract.readiness !== 'cancelled') {\n state.contract = { ...state.contract, readiness: 'stale', updatedAt: this.now() }\n }\n state.clarification = markClarification(state.clarification, 'stale')\n }\n\n private replaceWork(sessionId: string): AbortController {\n const state = this.ensure(sessionId)\n state.work?.abort()\n const work = new AbortController()\n state.work = work\n return work\n }\n\n private generationCurrent(sessionId: string, generation: number): boolean {\n if (!this.active) return false\n const state = this.sessions.get(sessionId)\n return Boolean(state && state.generation === generation)\n }\n\n private snapshot(): MoodPersistedState {\n const sessions: Record<string, MoodStoredSession> = {}\n for (const [sessionId, row] of this.sessions) sessions[sessionId] = storedOf(row)\n return cloneState({ settings: this.settings, sessions })\n }\n\n private commitState(proposed: MoodPersistedState): void {\n this.settings = proposed.settings\n const next = new Map<string, InternalSession>()\n for (const [sessionId, row] of Object.entries(proposed.sessions)) {\n const previous = this.sessions.get(sessionId)\n next.set(sessionId, {\n ...row,\n generation: previous?.generation ?? 0,\n work: previous?.work,\n inflightVersion: previous?.inflightVersion,\n })\n }\n this.sessions = next\n }\n\n private async persistProposed(proposed: MoodPersistedState): Promise<void> {\n this.assertLive()\n if (!this.options.store) {\n this.storageFailed = false\n return\n }\n try {\n await this.options.store.save(cloneState(proposed))\n this.storageFailed = false\n } catch (error) {\n this.storageFailed = true\n if (error && typeof error === 'object' && 'code' in error) throw error\n coded('MOOD_STORAGE', '需求澄清保存失败,已保留原内容。')\n }\n }\n\n private assertLive(): void {\n if (!this.active) coded('MOOD_DISABLED', '需求澄清已关闭。')\n }\n\n private serialize<T>(run: () => Promise<T>): Promise<T> {\n const task = this.pending.then(run, run)\n this.pending = task.then(() => {}, () => {})\n return task\n }\n\n private syncAi(): void {\n if (!this.active) {\n this.detachAi()\n return\n }\n if (this.ai) return\n const scope = this.options.activateAi?.()\n if (!scope) return\n this.ai = scope\n this.unregisterPurpose = scope.registerPurpose(analyzePurpose)\n }\n\n private detachAi(): void {\n this.unregisterPurpose?.()\n this.unregisterPurpose = undefined\n this.ai?.dispose()\n this.ai = undefined\n }\n}\n\nfunction isSettled(readiness: TaskContract['readiness'] | undefined): boolean {\n return readiness === 'user-confirmed' || readiness === 'clear-request' || readiness === 'disclosed-assumptions'\n}\n\nfunction nextRevision(contract: TaskContract | undefined): number {\n return (contract?.revision ?? 0) + 1\n}\n\nfunction holdOf(sourceVersion: string, kind: TriggerKind, messages: unknown[]): HeldRequest {\n const trigger = kind === 'risk' || kind === 'material' || kind === 'mild' || kind === 'clear' ? kind : 'material'\n return { sourceVersion, trigger, messages: structuredClone(messages) }\n}\n\nfunction storedOf(row: MoodStoredSession): MoodStoredSession {\n return {\n clarification: row.clarification,\n pendingManual: row.pendingManual,\n ...(row.contract ? { contract: row.contract } : {}),\n ...(row.lastHandledVersion !== undefined ? { lastHandledVersion: row.lastHandledVersion } : {}),\n ...(row.projectId ? { projectId: row.projectId } : {}),\n ...(row.heldRequest ? { heldRequest: row.heldRequest } : {}),\n }\n}\n\nfunction cloneState(state: MoodPersistedState): MoodPersistedState {\n return structuredClone(state)\n}\n\nfunction coded(code: string, message: string): never {\n throw Object.assign(new Error(message), { code })\n}\n\nfunction combineSignals(...signals: Array<AbortSignal | undefined>): AbortSignal {\n const live = signals.filter((item): item is AbortSignal => Boolean(item))\n if (live.length === 0) return new AbortController().signal\n if (live.length === 1) return live[0]!\n return AbortSignal.any(live)\n}\n","import { defineDomain, domainTable } from '@deepseek-ai/dsh-storage-domain'\nimport { z } from 'zod'\nimport { MAX_PROJECT_ID_CHARS, defaultSettings, type MoodSettings } from './contracts.ts'\nimport type { MoodPersistedState, MoodStoredSession, MoodStore } from './service.ts'\n\nconst evidenceSchema = z.object({\n sessionId: z.string().min(1).max(200),\n seq: z.number().int().nonnegative(),\n kind: z.enum(['user', 'tool', 'turn', 'manual']),\n excerpt: z.string().max(200).optional(),\n}).strict()\n\nconst contractSchema = z.object({\n id: z.string().min(1).max(120),\n sessionId: z.string().min(1).max(200),\n sourceVersion: z.string().min(1).max(400),\n revision: z.number().int().nonnegative(),\n goal: z.string().max(2000),\n deliverables: z.array(z.string().max(400)).max(16),\n inScope: z.array(z.string().max(400)).max(16),\n outOfScope: z.array(z.string().max(400)).max(16),\n constraints: z.array(z.string().max(400)).max(16),\n acceptance: z.array(z.string().max(400)).max(16),\n assumptions: z.array(z.string().max(400)).max(16),\n questions: z.array(z.string().max(400)).max(8),\n evidence: z.array(evidenceSchema).max(32),\n readiness: z.enum(['pending', 'clear-request', 'user-confirmed', 'disclosed-assumptions', 'cancelled', 'stale']),\n updatedAt: z.number().int().nonnegative(),\n}).strict()\n\nconst clarificationSchema = z.object({\n id: z.string().min(1).max(80),\n question: z.string().max(400),\n status: z.enum(['pending', 'answered', 'skipped', 'cancelled', 'stale']),\n answer: z.string().max(400).optional(),\n}).strict()\n\nconst heldRequestSchema = z.object({\n sourceVersion: z.string().min(1).max(400),\n trigger: z.enum(['material', 'risk', 'mild', 'clear']),\n messages: z.array(z.unknown()).max(32),\n}).strict()\n\nconst sessionSchema = z.object({\n contract: contractSchema.optional(),\n clarification: z.array(clarificationSchema).max(8),\n lastHandledVersion: z.string().max(400).optional(),\n pendingManual: z.boolean(),\n projectId: z.string().max(MAX_PROJECT_ID_CHARS).optional(),\n heldRequest: heldRequestSchema.optional(),\n}).strict()\n\nconst settingsSchema = z.object({\n revision: z.number().int().nonnegative(),\n mode: z.enum(['auto', 'manual', 'strict']),\n}).strict()\n\nexport const moodStateSchema = z.object({\n settings: settingsSchema,\n sessions: z.record(z.string().min(1).max(200), sessionSchema),\n}).strict()\n\nexport const moodDomain = defineDomain({\n name: 'dsh_editor_mood',\n version: 1,\n tables: {\n state: domainTable<string, MoodPersistedState>(moodStateSchema),\n },\n})\n\nexport type MoodDomainHandle = {\n table(name: 'state'): {\n get(key: string): unknown\n put(key: string, value: unknown): Promise<void>\n delete(key: string): Promise<boolean>\n entries(): IterableIterator<[string, unknown]>\n }\n close(): Promise<void>\n}\n\nexport function emptyMoodState(): MoodPersistedState {\n return { settings: defaultSettings(), sessions: {} }\n}\n\nexport function domainStore(domain: MoodDomainHandle): MoodStore {\n const table = domain.table('state')\n return {\n load(): MoodPersistedState {\n const row = table.get('global') as MoodPersistedState | undefined\n if (!row) return emptyMoodState()\n return {\n settings: { ...defaultSettings(), ...row.settings } as MoodSettings,\n sessions: { ...(row.sessions ?? {}) } as Record<string, MoodStoredSession>,\n }\n },\n async save(state) {\n await table.put('global', {\n settings: { ...state.settings },\n sessions: { ...state.sessions },\n } satisfies MoodPersistedState)\n },\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type { AiServices, RpcResult } from '@klarkxy/dsh-ai-services/contracts'\nimport { registerHostRpc, type HostRpcContext } from '@klarkxy/dsh-ai-services/host-rpc'\nimport {\n MOOD_PLUGIN, MOOD_RPC_CHANNEL, type AskUserQuestionAnswer, type AskUserRequest,\n} from './contracts.ts'\nimport { createMoodContextMessage } from './inject.ts'\nimport { isHumanUserMessage, type UserMessageLike } from './evidence.ts'\nimport { MoodService, type PreStepDecision, type PreStepPayload } from './service.ts'\nimport { domainStore, moodDomain, type MoodDomainHandle } from './storage.ts'\n\nexport const name = MOOD_PLUGIN\nexport const inject = ['aiServices', 'storageDomain', 'sessions', 'userQuestions', 'agents', 'connection', 'webServer'] as const\n\nexport { MoodService } from './service.ts'\nexport { createMoodContextMessage } from './inject.ts'\nexport { domainStore, moodDomain } from './storage.ts'\nexport { CHAT_EVENTS_SLOT, MOOD_AI_PLUGIN, MOOD_PLUGIN, MOOD_RPC_CHANNEL, defaultSettings, projectIdFromCwd } from './contracts.ts'\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context { aiMood: MoodService }\n}\n\nexport type LiveAgent = {\n id?: unknown\n steer?: (message: unknown) => void\n followup?: (message: unknown) => void\n}\n\nexport type AgentsRegistry = {\n get(id: unknown): LiveAgent | undefined\n}\n\ntype Host = Context & HostRpcContext & {\n storageDomain: { open: (spec: typeof moodDomain) => Promise<MoodDomainHandle> }\n aiServices: AiServices\n sessions: { get(id: unknown): { id?: unknown; header?: { cwd?: string }; meta?: { cwd?: string }; snapshotEvents(): readonly unknown[] } | undefined }\n userQuestions: { ask(input: AskUserRequest): Promise<AskUserQuestionAnswer> }\n agents: AgentsRegistry\n}\n\nexport async function apply(ctx: Context): Promise<void> {\n const host = ctx as Host\n if (!host.storageDomain || !host.aiServices || !host.sessions || !host.userQuestions || !host.agents) {\n throw new Error('dsh-mood requires Host aiServices, storageDomain, sessions, userQuestions, and agents')\n }\n const domain = await host.storageDomain.open(moodDomain)\n const service = new MoodService({\n store: domainStore(domain),\n readEvents: sessionId => readSessionEvents(host, sessionId),\n liveSession: sessionId => readLiveSession(host, sessionId),\n activateAi: () => host.aiServices.activate(MOOD_PLUGIN),\n askUser: request => host.userQuestions.ask(request),\n createInjectMessage: text => createMoodContextMessage(text),\n resumeHeld: async (sessionId, messages) => { resumeHeldOnHost(host.agents, sessionId, messages) },\n })\n ctx.provide('aiMood', service)\n ctx.effect(() => async () => { await service.dispose(); await domain.close() }, 'dsh-mood.dispose')\n ctx.effect(() => registerHostRpc(host, MOOD_RPC_CHANNEL, (endpoint, payload, signal): Promise<RpcResult> => (\n service.call(endpoint, payload, signal)\n )), 'dsh-mood.rpc')\n ctx.effect(() => {\n const offStep = listen(ctx, 'agent/pre-step', async (payload: PreStepPayload, next: () => Promise<PreStepDecision>) => (\n service.handlePreStep(payload, next)\n ))\n return () => { offStep?.() }\n }, 'dsh-mood.pre-step')\n}\n\nfunction readLiveSession(host: Host, sessionId: string) {\n return host.sessions.get(sessionId) ?? host.sessions.get(String(sessionId))\n}\n\nfunction readSessionEvents(host: Host, sessionId: string) {\n const session = readLiveSession(host, sessionId) as { snapshotEvents?: () => ReadonlyArray<{ seq: number; type: string; data?: unknown }> } | undefined\n return session?.snapshotEvents?.()\n}\n\n/** Bound invoke: native steer/followup call this.send on the live Agents.get instance. */\nexport function resumeHeldOnHost(agents: AgentsRegistry, sessionId: string, messages: unknown[]): void {\n const agent = agents.get(sessionId) ?? agents.get(String(sessionId))\n if (!agent) throw Object.assign(new Error('当前 Host 没有可恢复的会话。'), { code: 'MOOD_SESSION_NOT_FOUND' })\n const humans = messages.filter(message => isHumanUserMessage(message as UserMessageLike))\n if (!humans.length) throw Object.assign(new Error('没有可重试的原请求。'), { code: 'MOOD_NOT_FOUND' })\n if (typeof agent.steer === 'function') {\n for (const human of humans) agent.steer(human)\n return\n }\n if (typeof agent.followup === 'function') {\n for (const human of humans) agent.followup(human)\n return\n }\n throw Object.assign(new Error('当前会话不能按原请求重试。'), { code: 'MOOD_NO_RESUME' })\n}\n\nfunction listen(ctx: Context, name: string, handler: (...args: never[]) => unknown): (() => void) | undefined {\n const on = ctx.on as unknown as (event: string, listener: (...args: never[]) => unknown) => (() => void) | void\n const off = on.call(ctx, name, handler)\n return typeof off === 'function' ? off : undefined\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@klarkxy/dsh-mood",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Clarify ambiguous requests before agent execution in DeepSeek Harness.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
|
@@ -61,16 +61,16 @@
|
|
|
61
61
|
]
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@deepseek-ai/dsh-storage-domain": "0.1.7-
|
|
65
|
-
"@deepseek-ai/dsh-llm": "0.1.7-
|
|
64
|
+
"@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-llm": "0.1.7-rc.2",
|
|
66
66
|
"zod": "^4.1.5",
|
|
67
|
-
"@klarkxy/dsh-ai-services": "0.1.
|
|
67
|
+
"@klarkxy/dsh-ai-services": "0.1.3"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
70
|
+
"@deepseek-ai/cordis": "^4.0.4"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
73
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
74
74
|
"react": "^18.2.0",
|
|
75
75
|
"@types/react": "18.3.31"
|
|
76
76
|
},
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"registry": "https://registry.npmjs.org/"
|
|
98
98
|
},
|
|
99
99
|
"dshRelease": {
|
|
100
|
-
"contentHash": "sha256-
|
|
100
|
+
"contentHash": "sha256-c9d42e8b93f36a8345e1ef7a5f3a2e027cbe470680ea354e27f84e9017a44b76"
|
|
101
101
|
},
|
|
102
102
|
"scripts": {
|
|
103
103
|
"build": "tsdown && node ../../scripts/wrap-client.mjs @klarkxy/dsh-mood",
|