@xfey/tutti 0.1.125 → 0.1.127

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.
Files changed (52) hide show
  1. package/README.md +2 -0
  2. package/dist/chat-assistant/diagnostics.d.ts +4 -1
  3. package/dist/chat-assistant/index.js +15 -6
  4. package/dist/chat-assistant/language-context.d.ts +8 -0
  5. package/dist/chat-assistant/language-context.js +41 -0
  6. package/dist/collaboration-state/communication-language.d.ts +31 -0
  7. package/dist/collaboration-state/communication-language.js +36 -0
  8. package/dist/collaboration-state/task-compile-context.js +9 -0
  9. package/dist/communication-language/index.d.ts +75 -0
  10. package/dist/communication-language/index.js +122 -0
  11. package/dist/communication-language/live-smoke-cli.d.ts +2 -0
  12. package/dist/communication-language/live-smoke-cli.js +368 -0
  13. package/dist/communication-language/prompt.d.ts +22 -0
  14. package/dist/communication-language/prompt.js +73 -0
  15. package/dist/control-plane/communication-language.d.ts +33 -0
  16. package/dist/control-plane/communication-language.js +72 -0
  17. package/dist/control-plane/context-sync.js +7 -0
  18. package/dist/control-plane/follow-up-output.js +25 -4
  19. package/dist/control-plane/follow-up-start.js +17 -0
  20. package/dist/control-plane/project-brief-refresh.js +10 -1
  21. package/dist/control-plane/project-context-bootstrap.d.ts +2 -0
  22. package/dist/control-plane/project-context-bootstrap.js +8 -0
  23. package/dist/control-plane/reference-summary-refresh.js +7 -0
  24. package/dist/control-plane/run-start.js +14 -6
  25. package/dist/control-plane/scratchpad-refresh-start.d.ts +1 -0
  26. package/dist/control-plane/scratchpad-refresh-start.js +13 -0
  27. package/dist/control-plane/scratchpad-refresh.d.ts +2 -0
  28. package/dist/control-plane/scratchpad-refresh.js +40 -26
  29. package/dist/control-plane/task-compile-continuation.js +14 -1
  30. package/dist/control-plane/task-compile-output.js +38 -14
  31. package/dist/control-plane/task-compile-start.d.ts +1 -0
  32. package/dist/control-plane/task-compile-start.js +22 -1
  33. package/dist/control-plane/types.d.ts +2 -0
  34. package/dist/control-plane/workflows/openai.js +48 -28
  35. package/dist/control-plane/workflows/types.d.ts +18 -13
  36. package/dist/prompt-templates/index.d.ts +1 -1
  37. package/dist/prompt-templates/index.js +2 -0
  38. package/dist/run-pipeline/task-run-invocation.js +12 -9
  39. package/migrations/0023_communication_language.sql +14 -0
  40. package/package.json +1 -1
  41. package/prompts/README.md +1 -0
  42. package/prompts/chat-assistant.md +1 -1
  43. package/prompts/communication-language-result.md +27 -0
  44. package/prompts/communication-language.md +50 -0
  45. package/prompts/procedures/follow-up-check.md +1 -1
  46. package/prompts/procedures/scratchpad-refresh.md +2 -2
  47. package/prompts/procedures/task-compile.md +1 -1
  48. package/prompts/prompt-flow-map.md +2 -0
  49. package/web/assets/{homepage-motion-scene-Ctt45F9o.js → homepage-motion-scene-DyEmWwvt.js} +1 -1
  50. package/web/assets/{index-BJpTcX_E.js → index-By3idT4U.js} +2 -2
  51. package/web/assets/{index-DTuz8Hb5.css → index-DSBjOZmJ.css} +1 -1
  52. package/web/index.html +2 -2
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # server
2
2
 
3
+ 当前源码的[协作输出语言](../../docs/system/communication-language.md)由 Host 统一处理:migration `0023`、共享 prompt、Scratchpad/workflow/task 语言继承。通过 Host npm 包交付,需更新项目 Host 才会生效,不依赖 Web 或飞书端新增设置;对照模型的引用语言误判作为已知项保留,不宣称所有模型均稳定通过。
4
+
3
5
  ## 作用
4
6
 
5
7
  `apps/server` 是 Tutti 的项目 host service,也是机器级 Local Console 的进程入口。
@@ -1,9 +1,12 @@
1
1
  import type { ProviderInvocationProgress } from "../providers/invocation-progress.js";
2
+ import type { languageDiagnosticFields } from "../communication-language/index.js";
2
3
  export type ChatAssistantLogger = {
3
4
  info: (fields: Record<string, unknown>, message: string) => void;
4
5
  warn: (fields: Record<string, unknown>, message: string) => void;
5
6
  };
6
- type ChatAssistantProgress = ProviderInvocationProgress | {
7
+ type ChatAssistantProgress = ProviderInvocationProgress | ({
8
+ stage: "language_context";
9
+ } & ReturnType<typeof languageDiagnosticFields>) | {
7
10
  stage: "queued" | "inspection_wait" | "model_requested" | "reply_persisted" | "failed" | "skipped";
8
11
  reason_code?: "queue_full" | "stopping" | "context_unavailable" | "answer_failed" | "reply_failed";
9
12
  reference_source_count?: number;
@@ -1,6 +1,8 @@
1
1
  import { createChatAssistantDiagnostics } from "./diagnostics.js";
2
2
  import { createClarificationRoundAgentMessage, createMainChatAgentMessage, readClarificationRoundMessagesWindow, readClarificationRoundProjection, readMainChatMessageWindow, readMainChatMessagesBeforeCursor, readMessageProjectionById, } from "../collaboration-state/index.js";
3
- import { renderPromptTemplate } from "../prompt-templates/index.js";
3
+ import { renderLanguageAwarePrompt } from "../communication-language/prompt.js";
4
+ import { languageDiagnosticFields } from "../communication-language/index.js";
5
+ import { chatLanguageContext } from "./language-context.js";
4
6
  import { withHostStoreTransaction, } from "../store/index.js";
5
7
  import { messageTextForModel, messageTextForTuttiMention, } from "../collaboration-state/message-context.js";
6
8
  import { externalReferenceMessageContext } from "../reference-access/message-context.js";
@@ -241,18 +243,25 @@ export class ReadOnlyChatAssistant {
241
243
  }
242
244
  return this.buildMainChatContext(triggerMessage);
243
245
  }
244
- renderPrompt(triggerMessage) {
246
+ renderPrompt(triggerMessage, report) {
245
247
  const context = this.buildContext(triggerMessage);
246
248
  if (context === null) {
247
249
  return null;
248
250
  }
249
- return renderPromptTemplate({
251
+ const language = chatLanguageContext(this.options.store.db, triggerMessage, {
252
+ mainChat: CHAT_ASSISTANT_CONTEXT_MESSAGE_LIMIT,
253
+ round: CHAT_ASSISTANT_ROUND_MESSAGE_LIMIT,
254
+ });
255
+ report({ stage: "language_context", ...languageDiagnosticFields(language) });
256
+ return renderLanguageAwarePrompt({
250
257
  templateKey: "chat.assistant",
251
- ...(this.options.promptsRoot === undefined ? {} : { promptsRoot: this.options.promptsRoot }),
258
+ ...(this.options.promptsRoot === undefined
259
+ ? {}
260
+ : { promptsRoot: this.options.promptsRoot }),
252
261
  variables: {
253
262
  assistant_context_json: context,
254
263
  },
255
- });
264
+ }, language);
256
265
  }
257
266
  appendMainChatAssistantMessage(triggerMessage, body, refs) {
258
267
  let afterCommit;
@@ -342,7 +351,7 @@ export class ReadOnlyChatAssistant {
342
351
  try {
343
352
  report({ stage: "inspection_wait" });
344
353
  await this.options.waitForInspectionAvailability?.();
345
- const prompt = this.renderPrompt(triggerMessage);
354
+ const prompt = this.renderPrompt(triggerMessage, report);
346
355
  if (prompt === null) {
347
356
  report({ stage: "skipped", reason_code: "context_unavailable" });
348
357
  return;
@@ -0,0 +1,8 @@
1
+ import type { MessageProjection } from "@tutti/shared/schemas/api";
2
+ import type { SqliteDatabase } from "../store/index.js";
3
+ /** Same compact scope as Q&A, never boundary-after main chat for a round. */
4
+ export declare function chatLanguageContext(db: SqliteDatabase, trigger: MessageProjection, limits: {
5
+ mainChat: number;
6
+ round: number;
7
+ }): import("../communication-language/index.js").CommunicationLanguageContext;
8
+ //# sourceMappingURL=language-context.d.ts.map
@@ -0,0 +1,41 @@
1
+ import { readActiveClarificationProjection, readClarificationRoundMessagesWindow, readMainChatMessageWindow, readTaskProjection, } from "../collaboration-state/index.js";
2
+ import { readCommunicationLanguage } from "../collaboration-state/communication-language.js";
3
+ import { createLanguageContext, messageLanguageEvidence } from "../communication-language/index.js";
4
+ /** Same compact scope as Q&A, never boundary-after main chat for a round. */
5
+ export function chatLanguageContext(db, trigger, limits) {
6
+ let inherited = readCommunicationLanguage(db);
7
+ let messages;
8
+ if (trigger.scope.kind === "main_chat") {
9
+ messages = readMainChatMessageWindow(db, { limit: limits.mainChat }).items;
10
+ }
11
+ else {
12
+ messages =
13
+ readClarificationRoundMessagesWindow(db, trigger.scope.clarification_round_ref, {
14
+ anchor: "start",
15
+ limit: limits.round,
16
+ })?.items ?? [];
17
+ const active = readActiveClarificationProjection(db);
18
+ // A task/compile round must not inherit a newer project-wide language choice.
19
+ inherited = null;
20
+ if (active.state === "active" && active.round.id === trigger.scope.clarification_round_ref) {
21
+ const owner = active.thread.owner;
22
+ const task = owner.kind === "task" ? readTaskProjection(db, owner.task_id) : null;
23
+ const workflowRef = owner.kind === "task_compile" ? owner.workflow_ref : task?.created_from_workflow_ref;
24
+ inherited =
25
+ (task === null ? null : readCommunicationLanguage(db, { kind: "task", ref: task.id })) ??
26
+ (workflowRef === undefined
27
+ ? null
28
+ : readCommunicationLanguage(db, { kind: "workflow", ref: workflowRef }));
29
+ }
30
+ }
31
+ return createLanguageContext({
32
+ scope: "reply",
33
+ inherited,
34
+ messages: [
35
+ ...messages.filter((message) => message.created_at < trigger.created_at ||
36
+ (message.created_at === trigger.created_at && message.id < trigger.id)),
37
+ trigger,
38
+ ].map(messageLanguageEvidence),
39
+ });
40
+ }
41
+ //# sourceMappingURL=language-context.js.map
@@ -0,0 +1,31 @@
1
+ import type { SqliteDatabase } from "../store/index.js";
2
+ import { type LanguageDecision, type LanguagePreference } from "../communication-language/index.js";
3
+ export type LanguageOwner = {
4
+ kind: "project" | "scratchpad" | "workflow" | "task";
5
+ ref: string;
6
+ };
7
+ export type StoredCommunicationLanguage = LanguagePreference & {
8
+ basis: LanguageDecision["basis"];
9
+ activity_ref: string | null;
10
+ source_message_id: string | null;
11
+ source_created_at: string | null;
12
+ };
13
+ export declare function readCommunicationLanguage(db: SqliteDatabase, owner?: LanguageOwner): StoredCommunicationLanguage | null;
14
+ export declare function writeCommunicationLanguage(db: SqliteDatabase, input: {
15
+ owner: LanguageOwner;
16
+ language: LanguagePreference & {
17
+ basis: LanguageDecision["basis"];
18
+ };
19
+ activityRef?: string;
20
+ sourceCursor?: {
21
+ message_id: string;
22
+ created_at: string;
23
+ };
24
+ now: () => Date;
25
+ }): void;
26
+ export declare function copyCommunicationLanguage(db: SqliteDatabase, input: {
27
+ from: LanguageOwner;
28
+ to: LanguageOwner;
29
+ now: () => Date;
30
+ }): void;
31
+ //# sourceMappingURL=communication-language.d.ts.map
@@ -0,0 +1,36 @@
1
+ import { COMMUNICATION_LANGUAGE_POLICY_VERSION, isLanguagePreference, } from "../communication-language/index.js";
2
+ export function readCommunicationLanguage(db, owner = { kind: "project", ref: "current" }) {
3
+ const row = db
4
+ .prepare(`SELECT locale, preference, basis, activity_ref, source_message_id, source_created_at
5
+ FROM communication_language_state WHERE owner_kind = ? AND owner_ref = ?`)
6
+ .get(owner.kind, owner.ref);
7
+ if (row === undefined)
8
+ return null;
9
+ if (!isLanguagePreference(row))
10
+ throw new Error("communication_language_state_invalid");
11
+ return row;
12
+ }
13
+ export function writeCommunicationLanguage(db, input) {
14
+ if (!isLanguagePreference(input.language))
15
+ throw new Error("communication_language_state_invalid");
16
+ db.prepare(`INSERT INTO communication_language_state
17
+ (owner_kind, owner_ref, locale, preference, basis, policy_version, activity_ref,
18
+ source_message_id, source_created_at, updated_at)
19
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
20
+ ON CONFLICT(owner_kind, owner_ref) DO UPDATE SET
21
+ locale = excluded.locale, preference = excluded.preference, basis = excluded.basis,
22
+ policy_version = excluded.policy_version, activity_ref = excluded.activity_ref,
23
+ source_message_id = excluded.source_message_id, source_created_at = excluded.source_created_at,
24
+ updated_at = excluded.updated_at
25
+ WHERE excluded.owner_kind != 'project' OR
26
+ communication_language_state.source_created_at IS NULL OR
27
+ (excluded.source_created_at, excluded.source_message_id) >
28
+ (communication_language_state.source_created_at, communication_language_state.source_message_id)`).run(input.owner.kind, input.owner.ref, input.language.locale, input.language.preference, input.language.basis, COMMUNICATION_LANGUAGE_POLICY_VERSION, input.activityRef ?? null, input.sourceCursor?.message_id ?? null, input.sourceCursor?.created_at ?? null, input.now().toISOString());
29
+ }
30
+ export function copyCommunicationLanguage(db, input) {
31
+ const language = readCommunicationLanguage(db, input.from);
32
+ if (language === null)
33
+ return;
34
+ writeCommunicationLanguage(db, { owner: input.to, language, now: input.now });
35
+ }
36
+ //# sourceMappingURL=communication-language.js.map
@@ -1,5 +1,6 @@
1
1
  import { withHostStoreTransaction } from "../store/index.js";
2
2
  import { readScratchpadProjection } from "./scratchpad.js";
3
+ import { readCommunicationLanguage, copyCommunicationLanguage } from "./communication-language.js";
3
4
  import { readScratchpadSourceState } from "./scratchpad-source-state.js";
4
5
  import { nowIso, stringifyJson } from "./serialization.js";
5
6
  function cursorIsAfter(left, right) {
@@ -206,6 +207,14 @@ export function captureTaskCompileContext(db, input) {
206
207
  if (scratchpad.state !== "ready" || scratchpad.updated_at === undefined) {
207
208
  throw new Error("A ready Scratchpad is required to capture Task Compile Context");
208
209
  }
210
+ const language = readCommunicationLanguage(tx, { kind: "scratchpad", ref: "current" });
211
+ if (language !== null && language.activity_ref === scratchpad.updated_by_activity_ref) {
212
+ copyCommunicationLanguage(tx, {
213
+ from: { kind: "scratchpad", ref: "current" },
214
+ to: { kind: "workflow", ref: input.workflow_ref },
215
+ now: input.now ?? (() => new Date()),
216
+ });
217
+ }
209
218
  const sourceState = readScratchpadSourceState(tx);
210
219
  const submission = readPendingTaskCompileSubmission(tx, input.workflow_ref);
211
220
  const sources = readCurrentScratchpadSourceRefs(tx, submission?.source_window.through);
@@ -0,0 +1,75 @@
1
+ import type { MessageProjection } from "@tutti/shared/schemas/api";
2
+ export declare const COMMUNICATION_LANGUAGE_POLICY_VERSION = 1;
3
+ export type LanguagePreference = {
4
+ locale: string;
5
+ preference: "auto" | "fixed";
6
+ };
7
+ export type LanguageDecision = LanguagePreference & {
8
+ basis: "discussion" | "explicit" | "inherited" | "default";
9
+ evidence_index: number | null;
10
+ };
11
+ export type LanguageEvidenceMessage = {
12
+ role: "human" | "tutti" | "operator" | "system";
13
+ text: string;
14
+ };
15
+ export declare function messageLanguageEvidence(message: MessageProjection): LanguageEvidenceMessage;
16
+ export type CommunicationLanguageContext = {
17
+ policy_version: 1;
18
+ scope: "scratchpad" | "reply" | "workflow" | "summary" | "documents";
19
+ inherited: LanguagePreference | null;
20
+ pinned: boolean;
21
+ evidence: Array<{
22
+ role: "human" | "operator";
23
+ text: string;
24
+ }>;
25
+ };
26
+ export declare function isLanguagePreference(value: unknown): value is LanguagePreference;
27
+ export declare function isLanguageDecision(value: unknown): value is LanguageDecision;
28
+ /** A language sample, not task context. The original message is never rewritten. */
29
+ export declare function authoredLanguageSample(text: string): string;
30
+ export declare function createLanguageContext(input: {
31
+ scope: CommunicationLanguageContext["scope"];
32
+ inherited?: LanguagePreference | null;
33
+ pinned?: boolean;
34
+ messages?: readonly LanguageEvidenceMessage[];
35
+ }): CommunicationLanguageContext;
36
+ export declare function languageDecisionMatchesContext(decision: unknown, context: CommunicationLanguageContext): decision is LanguageDecision;
37
+ export declare function languageDiagnosticFields(context: CommunicationLanguageContext): {
38
+ language_policy_version: 1;
39
+ language_scope: "scratchpad" | "summary" | "workflow" | "reply" | "documents";
40
+ language_locale: string;
41
+ language_pinned: boolean;
42
+ language_evidence_count: number;
43
+ };
44
+ export type LanguageAwareOutput = {
45
+ communication_language?: LanguageDecision;
46
+ };
47
+ export declare const LANGUAGE_DECISION_SCHEMA: {
48
+ readonly type: "object";
49
+ readonly additionalProperties: false;
50
+ readonly required: readonly ["locale", "preference", "basis", "evidence_index"];
51
+ readonly properties: {
52
+ readonly locale: {
53
+ readonly type: "string";
54
+ readonly pattern: string;
55
+ };
56
+ readonly preference: {
57
+ readonly type: "string";
58
+ readonly enum: readonly ["auto", "fixed"];
59
+ };
60
+ readonly basis: {
61
+ readonly type: "string";
62
+ readonly enum: readonly ["discussion", "explicit", "inherited", "default"];
63
+ };
64
+ readonly evidence_index: {
65
+ readonly anyOf: readonly [{
66
+ readonly type: "integer";
67
+ readonly minimum: 0;
68
+ readonly maximum: 11;
69
+ }, {
70
+ readonly type: "null";
71
+ }];
72
+ };
73
+ };
74
+ };
75
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,122 @@
1
+ export const COMMUNICATION_LANGUAGE_POLICY_VERSION = 1;
2
+ export function messageLanguageEvidence(message) {
3
+ const feedback = message.refs?.artifact_feedback;
4
+ return {
5
+ role: message.author.kind === "human"
6
+ ? "human"
7
+ : message.refs?.development_operator === true
8
+ ? "operator"
9
+ : "system",
10
+ text: message.refs?.reference_file !== undefined
11
+ ? ""
12
+ : feedback === undefined
13
+ ? message.body
14
+ : [feedback.summary, ...feedback.annotations.map((entry) => entry.comment)]
15
+ .filter(Boolean)
16
+ .join("\n"),
17
+ };
18
+ }
19
+ const BASES = new Set(["discussion", "explicit", "inherited", "default"]);
20
+ const LOCALE_PATTERN = /^[a-z]{2,3}(?:-[A-Z][a-z]{3})?(?:-[A-Z]{2}|-\d{3})?$/u;
21
+ export function isLanguagePreference(value) {
22
+ if (typeof value !== "object" || value === null)
23
+ return false;
24
+ const entry = value;
25
+ if (entry.preference !== "auto" && entry.preference !== "fixed")
26
+ return false;
27
+ if (typeof entry.locale !== "string" || !LOCALE_PATTERN.test(entry.locale))
28
+ return false;
29
+ try {
30
+ return Intl.getCanonicalLocales(entry.locale)[0] === entry.locale && entry.locale !== "und";
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ export function isLanguageDecision(value) {
37
+ if (!isLanguagePreference(value))
38
+ return false;
39
+ const entry = value;
40
+ return (BASES.has(entry.basis ?? "") &&
41
+ (entry.evidence_index === null ||
42
+ (Number.isSafeInteger(entry.evidence_index) && (entry.evidence_index ?? -1) >= 0)) &&
43
+ Object.keys(value).every((key) => ["locale", "preference", "basis", "evidence_index"].includes(key)));
44
+ }
45
+ /** A language sample, not task context. The original message is never rewritten. */
46
+ export function authoredLanguageSample(text) {
47
+ const sample = text
48
+ .replace(/```[^]*?```|~~~[^]*?~~~/gu, " ")
49
+ .replace(/^(?: {0,3}>| {4}|\t).*$/gmu, " ")
50
+ .replace(/`[^`]*`/gu, " ")
51
+ .replace(/!\[[^\]]*\]\([^)]*\)/gu, " ")
52
+ .replace(/\[([^\]]+)\]\([^)]*\)/gu, "$1")
53
+ .replace(/https?:\/\/\S+|@tutti\b/giu, " ")
54
+ .replace(/\s+/gu, " ")
55
+ .trim();
56
+ return sample.length <= 800 ? sample : `${sample.slice(0, 398)} … ${sample.slice(-399)}`;
57
+ }
58
+ export function createLanguageContext(input) {
59
+ const evidence = (input.messages ?? []).flatMap((message) => {
60
+ if (message.role !== "human" && message.role !== "operator")
61
+ return [];
62
+ const text = authoredLanguageSample(message.text);
63
+ return /\p{L}/u.test(text) ? [{ role: message.role, text }] : [];
64
+ });
65
+ // Prefer humans. Operator-only tests can infer locally but cannot update project memory.
66
+ const selected = input.scope !== "reply" && evidence.some((entry) => entry.role === "human")
67
+ ? evidence.filter((entry) => entry.role === "human")
68
+ : evidence;
69
+ return {
70
+ policy_version: COMMUNICATION_LANGUAGE_POLICY_VERSION,
71
+ scope: input.scope,
72
+ inherited: input.inherited == null
73
+ ? null
74
+ : { locale: input.inherited.locale, preference: input.inherited.preference },
75
+ pinned: input.pinned ?? false,
76
+ evidence: selected.slice(-12),
77
+ };
78
+ }
79
+ export function languageDecisionMatchesContext(decision, context) {
80
+ if (!isLanguageDecision(decision))
81
+ return false;
82
+ if (decision.basis === "inherited") {
83
+ return (decision.evidence_index === null &&
84
+ decision.locale === context.inherited?.locale &&
85
+ decision.preference === context.inherited.preference);
86
+ }
87
+ if (decision.basis === "default") {
88
+ return (decision.evidence_index === null &&
89
+ context.inherited === null &&
90
+ decision.locale === "en" &&
91
+ decision.preference === "auto");
92
+ }
93
+ if (decision.evidence_index === null || !context.evidence[decision.evidence_index])
94
+ return false;
95
+ if (context.scope === "summary" || context.scope === "documents")
96
+ return false;
97
+ if (decision.basis === "discussion") {
98
+ return (!context.pinned && context.inherited?.preference !== "fixed" && decision.preference === "auto");
99
+ }
100
+ return true;
101
+ }
102
+ export function languageDiagnosticFields(context) {
103
+ return {
104
+ language_policy_version: context.policy_version,
105
+ language_scope: context.scope,
106
+ language_locale: context.inherited?.locale ?? "undetermined",
107
+ language_pinned: context.pinned,
108
+ language_evidence_count: context.evidence.length,
109
+ };
110
+ }
111
+ export const LANGUAGE_DECISION_SCHEMA = {
112
+ type: "object",
113
+ additionalProperties: false,
114
+ required: ["locale", "preference", "basis", "evidence_index"],
115
+ properties: {
116
+ locale: { type: "string", pattern: LOCALE_PATTERN.source },
117
+ preference: { type: "string", enum: ["auto", "fixed"] },
118
+ basis: { type: "string", enum: ["discussion", "explicit", "inherited", "default"] },
119
+ evidence_index: { anyOf: [{ type: "integer", minimum: 0, maximum: 11 }, { type: "null" }] },
120
+ },
121
+ };
122
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=live-smoke-cli.d.ts.map