Merge remote-tracking branch 'origin/master' into feat/plan-mode
17 master merges (GUI host/web stack, compact header, dshweb, fast local hooks, windows coverage skips, worktree runtime). Conflicts: - packages/ui/user-interaction/src/index.ts: master extracted the question types to types.ts; took the re-export and grafted our detail field (the plan-review payload) into the extracted AskUserQuestionItem. - generated catalogs regenerated over both sides. The module graph crossed mermaid's default 500-edge render guard with the GUI packages plus our plan-mode edges; raised maxEdges in verify-mermaid (a secure config settable only at initialize). Note: the remote branch also renamed packages/mode -> packages/plan (PR #512 plan-mode-simplification, fast-forwarded before this merge).
This commit is contained in:
@@ -102,10 +102,10 @@ async function tick(): Promise<void> {
|
||||
async function setup(options: TuiHarnessOptions = {}) {
|
||||
const terminal = new FakeTerminal()
|
||||
const exit = vi.fn()
|
||||
const result = await createTuiTestHarness(terminal, exit, {
|
||||
...options,
|
||||
cwd: options.cwd === undefined ? process.cwd() : options.cwd,
|
||||
})
|
||||
// Let the harness default cwd ('/workspace') stand: a checkout-dependent
|
||||
// process.cwd() longer than the 88-column fake terminal pushes the footer
|
||||
// token counters off-screen and fails their assertions by location.
|
||||
const result = await createTuiTestHarness(terminal, exit, options)
|
||||
await tick()
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -15,12 +15,17 @@
|
||||
"types": "./lib/types/invariant.d.ts",
|
||||
"default": "./lib/invariant.js"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./lib/types/types.d.ts",
|
||||
"default": "./lib/types/types.js"
|
||||
},
|
||||
"./src/*": "./src/*",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"lib/index.js",
|
||||
"lib/invariant.js",
|
||||
"lib/types/**/*.js",
|
||||
"lib/types/**/*.d.ts",
|
||||
"lib/types/**/*.d.ts.map",
|
||||
"src"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { Context, Service } from 'cordis'
|
||||
import z from 'schemastery'
|
||||
import type { Branded } from '@deepseek-ai/dsh-brand'
|
||||
import type { Agent } from '@deepseek-ai/dsh-agent'
|
||||
import type { CallId } from '@deepseek-ai/dsh-llm'
|
||||
import { scopeTarget } from '@deepseek-ai/dsh-scope'
|
||||
@@ -69,26 +68,11 @@ declare module '@deepseek-ai/dsh-session' {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pairs one `approval/asked` audit event with its `approval/decided`.
|
||||
* Service-issued (one fresh id per {@link ApprovalService.request} call).
|
||||
*/
|
||||
export type ApprovalRequestId = Branded<'ApprovalRequestId'>
|
||||
import { ApprovalRequestId } from './types.ts'
|
||||
import type { ApprovalOutcome } from './types.ts'
|
||||
|
||||
/**
|
||||
* Brand a string as an {@link ApprovalRequestId}.
|
||||
* @param id - the raw id string to brand.
|
||||
* @returns the same string carrying the brand.
|
||||
*/
|
||||
export function ApprovalRequestId(id: string): ApprovalRequestId {
|
||||
return id as ApprovalRequestId
|
||||
}
|
||||
|
||||
/**
|
||||
* Closed approval outcomes: a one-shot grant, explicit rejection, withdrawn
|
||||
* request, or unavailable answerer. Callers fail closed on `unavailable`.
|
||||
*/
|
||||
export type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable'
|
||||
export { ApprovalRequestId } from './types.ts'
|
||||
export type { ApprovalOutcome } from './types.ts'
|
||||
|
||||
/** Every {@link ApprovalOutcome}, for runtime normalization of answerer returns. */
|
||||
const OUTCOMES: readonly ApprovalOutcome[] = ['allowed-once', 'rejected', 'cancelled', 'unavailable']
|
||||
|
||||
29
packages/ui/user-approval/src/types.ts
Normal file
29
packages/ui/user-approval/src/types.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Wire-safe approval identifiers and outcome vocabulary, free of
|
||||
* cordis/service imports so browser type chains (apiproxy api → client) can
|
||||
* consume them without loading this package's Context augmentation.
|
||||
* @module @deepseek-ai/dsh-user-approval/types
|
||||
*/
|
||||
|
||||
import type { Branded } from '@deepseek-ai/dsh-brand'
|
||||
|
||||
/**
|
||||
* Pairs one `approval/asked` audit event with its `approval/decided`.
|
||||
* Service-issued (one fresh id per {@link ApprovalService.request} call).
|
||||
*/
|
||||
export type ApprovalRequestId = Branded<'ApprovalRequestId'>
|
||||
|
||||
/**
|
||||
* Brand a string as an {@link ApprovalRequestId}.
|
||||
* @param id - the raw id string to brand.
|
||||
* @returns the same string carrying the brand.
|
||||
*/
|
||||
export function ApprovalRequestId(id: string): ApprovalRequestId {
|
||||
return id as ApprovalRequestId
|
||||
}
|
||||
|
||||
/**
|
||||
* Closed approval outcomes: a one-shot grant, explicit rejection, withdrawn
|
||||
* request, or unavailable answerer. Callers fail closed on `unavailable`.
|
||||
*/
|
||||
export type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable'
|
||||
30
packages/ui/user-approval/tsdown.config.ts
Normal file
30
packages/ui/user-approval/tsdown.config.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { defineConfig } from 'tsdown'
|
||||
|
||||
/**
|
||||
* Build index and the invariant companion as separate single-entry bundles.
|
||||
* Both entries import src/types.ts (the browser-safe subpath), so a
|
||||
* multi-entry build emits a shared chunk the package's exact `files`
|
||||
* whitelist omits; separate builds inline it.
|
||||
*/
|
||||
export default defineConfig([
|
||||
{
|
||||
entry: ['lib/types/index.js'],
|
||||
outDir: 'lib',
|
||||
format: ['esm'],
|
||||
platform: 'node',
|
||||
target: 'es2024',
|
||||
fixedExtension: false,
|
||||
dts: false,
|
||||
clean: false,
|
||||
},
|
||||
{
|
||||
entry: ['lib/types/invariant.js'],
|
||||
outDir: 'lib',
|
||||
format: ['esm'],
|
||||
platform: 'node',
|
||||
target: 'es2024',
|
||||
fixedExtension: false,
|
||||
dts: false,
|
||||
clean: false,
|
||||
},
|
||||
])
|
||||
@@ -15,12 +15,17 @@
|
||||
"types": "./lib/types/invariant.d.ts",
|
||||
"default": "./lib/invariant.js"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./lib/types/types.d.ts",
|
||||
"default": "./lib/types/types.js"
|
||||
},
|
||||
"./src/*": "./src/*",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"lib/index.js",
|
||||
"lib/invariant.js",
|
||||
"lib/types/**/*.js",
|
||||
"lib/types/**/*.d.ts",
|
||||
"lib/types/**/*.d.ts.map",
|
||||
"src"
|
||||
|
||||
@@ -17,29 +17,11 @@ declare module 'cordis' {
|
||||
}
|
||||
}
|
||||
|
||||
/** One selectable answer offered to the user. */
|
||||
export interface AskUserQuestionOption {
|
||||
/** User-facing label. */
|
||||
label: string
|
||||
/** Optional extra context rendered by capable UIs. */
|
||||
description?: string
|
||||
}
|
||||
import type { AskUserQuestionAnswer, AskUserQuestionItem } from './types.ts'
|
||||
|
||||
/** One question in a user-interaction request. */
|
||||
export interface AskUserQuestionItem {
|
||||
/** Stable caller-provided question id, echoed in the answer. */
|
||||
id: string
|
||||
/** The question to display. */
|
||||
question: string
|
||||
/** Optional supporting detail rendered with the question but kept out of option labels. */
|
||||
detail?: string
|
||||
/** Optional short heading/group label. */
|
||||
header?: string
|
||||
/** Optional choices the UI can render as a menu. */
|
||||
options?: AskUserQuestionOption[]
|
||||
/** Whether more than one option may be selected. Defaults to single-select. */
|
||||
multiSelect?: boolean
|
||||
}
|
||||
export type {
|
||||
AskUserQuestionAnswer, AskUserQuestionAnswerItem, AskUserQuestionItem, AskUserQuestionOption,
|
||||
} from './types.ts'
|
||||
|
||||
/** Request for a human answer. */
|
||||
export interface AskUserQuestionRequest {
|
||||
@@ -51,22 +33,6 @@ export interface AskUserQuestionRequest {
|
||||
signal?: AbortSignal
|
||||
}
|
||||
|
||||
/** Answer to one question. */
|
||||
export interface AskUserQuestionAnswerItem {
|
||||
/** The answered question id. */
|
||||
id: string
|
||||
/** Selected option labels. Empty when the answer is purely custom text. */
|
||||
selected: string[]
|
||||
/** Optional free-text "Other" answer. */
|
||||
custom?: string
|
||||
}
|
||||
|
||||
/** The human's answer. */
|
||||
export interface AskUserQuestionAnswer {
|
||||
/** Structured answers keyed by question id. */
|
||||
answers: AskUserQuestionAnswerItem[]
|
||||
}
|
||||
|
||||
/** UI-side provider for user questions. */
|
||||
export interface UserInteractionProvider {
|
||||
ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>
|
||||
|
||||
46
packages/ui/user-interaction/src/types.ts
Normal file
46
packages/ui/user-interaction/src/types.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Wire-safe question/answer shapes, free of cordis/service imports so browser
|
||||
* type chains (apiproxy api → client) can consume them without loading this
|
||||
* package's Context augmentation.
|
||||
* @module @deepseek-ai/dsh-user-interaction/types
|
||||
*/
|
||||
|
||||
/** One selectable answer offered to the user. */
|
||||
export interface AskUserQuestionOption {
|
||||
/** User-facing label. */
|
||||
label: string
|
||||
/** Optional extra context rendered by capable UIs. */
|
||||
description?: string
|
||||
}
|
||||
|
||||
/** One question in a user-interaction request. */
|
||||
export interface AskUserQuestionItem {
|
||||
/** Stable caller-provided question id, echoed in the answer. */
|
||||
id: string
|
||||
/** The question to display. */
|
||||
question: string
|
||||
/** Optional supporting detail rendered with the question but kept out of option labels. */
|
||||
detail?: string
|
||||
/** Optional short heading/group label. */
|
||||
header?: string
|
||||
/** Optional choices the UI can render as a menu. */
|
||||
options?: AskUserQuestionOption[]
|
||||
/** Whether more than one option may be selected. Defaults to single-select. */
|
||||
multiSelect?: boolean
|
||||
}
|
||||
|
||||
/** Answer to one question. */
|
||||
export interface AskUserQuestionAnswerItem {
|
||||
/** The answered question id. */
|
||||
id: string
|
||||
/** Selected option labels. Empty when the answer is purely custom text. */
|
||||
selected: string[]
|
||||
/** Optional free-text "Other" answer. */
|
||||
custom?: string
|
||||
}
|
||||
|
||||
/** The human's answer. */
|
||||
export interface AskUserQuestionAnswer {
|
||||
/** Structured answers keyed by question id. */
|
||||
answers: AskUserQuestionAnswerItem[]
|
||||
}
|
||||
Reference in New Issue
Block a user