flavor-code 1.3.12 → 1.3.15

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.
@@ -0,0 +1,114 @@
1
+ import type { ModelRegistry } from "../models/registry.js";
2
+ import type { QuestionBridge } from "../tools/ask-user-question.js";
3
+ export interface ExplainNode {
4
+ id: string;
5
+ kind: string;
6
+ name: string;
7
+ qualifiedName: string;
8
+ filePath: string;
9
+ language: string;
10
+ startLine: number;
11
+ endLine: number;
12
+ signature?: string;
13
+ }
14
+ export interface ExplainGraph {
15
+ status(): Promise<{
16
+ available: boolean;
17
+ }>;
18
+ search(query: string, limit?: number): Promise<readonly ExplainNode[]>;
19
+ relations(id: string, hops?: number): Promise<{
20
+ origin?: ExplainNode;
21
+ callers: readonly ExplainNode[];
22
+ callees: readonly ExplainNode[];
23
+ }>;
24
+ }
25
+ export type ExplainTarget = {
26
+ kind: "resolved";
27
+ node: ExplainNode;
28
+ } | {
29
+ kind: "ambiguous";
30
+ candidates: readonly ExplainNode[];
31
+ } | {
32
+ kind: "not-found";
33
+ query: string;
34
+ };
35
+ /** A query that looks like a node id ('path/…#name') is tried as an exact
36
+ * graph lookup first; anything else goes through ranked name search. */
37
+ export declare function resolveExplainTarget(graph: ExplainGraph, query: string): Promise<ExplainTarget>;
38
+ /** Label shared by the picker options and the answer matching below. The
39
+ * graph node id is unique, so it doubles as an unambiguous picker label. */
40
+ export declare function explainCandidateLabel(candidate: ExplainNode): string;
41
+ export type ExplainSelection = {
42
+ kind: "picked";
43
+ node: ExplainNode;
44
+ } | {
45
+ kind: "typed";
46
+ query: string;
47
+ } | {
48
+ kind: "cancelled";
49
+ };
50
+ /** Interactive disambiguation: top-3 candidates (label = `name (filePath)`,
51
+ * description = kind + file:line) plus Cancel. The terminal question cards
52
+ * always append a free-text choice, so the user can type a more exact symbol
53
+ * instead; that raw text comes back as `typed` for the caller to re-resolve. */
54
+ export declare function selectExplainCandidate(candidates: readonly ExplainNode[], questions: QuestionBridge, signal: AbortSignal): Promise<ExplainSelection>;
55
+ export interface ExplainPromptInput {
56
+ anchor: ExplainNode;
57
+ anchorSource: string;
58
+ callers: readonly {
59
+ name: string;
60
+ filePath: string;
61
+ startLine: number;
62
+ }[];
63
+ callees: readonly {
64
+ name: string;
65
+ filePath: string;
66
+ startLine: number;
67
+ }[];
68
+ history: readonly {
69
+ date: string;
70
+ author: string;
71
+ subject: string;
72
+ }[];
73
+ focus?: string;
74
+ language: string;
75
+ }
76
+ /** Assemble the evidence bundle (source slice + relations + commit subjects)
77
+ * into a single prompt. The model must only see real code and real history,
78
+ * so the "why" section stays grounded and can say 不确定 instead of guessing. */
79
+ export declare function buildExplainPrompt(input: ExplainPromptInput): string;
80
+ export interface ExplainModelOptions {
81
+ registry: ModelRegistry;
82
+ /** Cheap model id provider; evaluated lazily so /model switches apply. */
83
+ modelId(): string;
84
+ }
85
+ /** One streaming completion from the cheap (subagent) model, mirroring
86
+ * src/git/insights.ts. Throws on stream errors or empty output; runExplain
87
+ * turns the throw into user-facing text. When `onText` is provided every
88
+ * streamed text delta is forwarded as it arrives, so callers can surface
89
+ * incremental (SSE-style) output instead of one buffered blob. */
90
+ export declare function explainWithModel(options: ExplainModelOptions, prompt: string, signal: AbortSignal, onText?: (chunk: string) => void): Promise<string>;
91
+ export interface ExplainDeps {
92
+ graph: ExplainGraph;
93
+ /** Read a workspace-relative file (production enforces workspace containment). */
94
+ readFile(path: string): Promise<string>;
95
+ history?(path: string, limit: number): Promise<readonly {
96
+ date: string;
97
+ author: string;
98
+ subject: string;
99
+ }[]>;
100
+ questions?: QuestionBridge;
101
+ registry: ModelRegistry;
102
+ modelId(): string;
103
+ language: string;
104
+ notify?(message: string): void;
105
+ /** Forwarded per streamed text delta. When present, runExplain emits the
106
+ * whole answer incrementally through it and returns an empty string on
107
+ * success (the caller must not re-print the answer as one notice). */
108
+ onText?(chunk: string): void;
109
+ }
110
+ /** Orchestrate one /explain turn: resolve the symbol (asking the user to pick
111
+ * on ambiguity), gather grounded evidence and stream a cheap-model answer.
112
+ * Every failure path returns user-facing text instead of throwing, matching
113
+ * the /review semantics in src/ui/session.ts. */
114
+ export declare function runExplain(deps: ExplainDeps, query: string | undefined, focus: string | undefined, signal: AbortSignal): Promise<string>;
package/dist/sdk/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  FlavorRpcServer,
5
5
  TraceRecordSchema,
6
6
  TraceRecorder
7
- } from "../chunk-EZNIDHFZ.js";
7
+ } from "../chunk-TQXNF337.js";
8
8
  import {
9
9
  AgentMessageQueue,
10
10
  DockerExecutionEnvironment,
@@ -13,7 +13,7 @@ import {
13
13
  WorkspaceCheckpointStore,
14
14
  buildDockerInvocation,
15
15
  createProductionRuntime
16
- } from "../chunk-QC5OYQTB.js";
16
+ } from "../chunk-WB4IJXFT.js";
17
17
  import "../chunk-JFKRX2KG.js";
18
18
  import "../chunk-RQTYHUMK.js";
19
19
  import "../chunk-S32JRDZK.js";
@@ -1,4 +1,4 @@
1
- export declare const MVP_COMMANDS: readonly ["model", "init", "config", "login", "logout", "permissions", "skills", "plugins", "hooks", "tasks", "finish", "compact", "clear", "help", "exit", "audit", "usage", "loop", "goal", "evolve", "mcp", "commit", "review", "ide", "memory", "remember", "forget", "forget-cold", "checkpoint", "tree", "rewind", "unrevert", "fork", "pals", "chat", "co-work", "tool"];
1
+ export declare const MVP_COMMANDS: readonly ["model", "init", "config", "login", "logout", "permissions", "skills", "plugins", "hooks", "tasks", "finish", "compact", "clear", "help", "exit", "audit", "usage", "loop", "goal", "evolve", "mcp", "commit", "review", "explain", "ide", "memory", "remember", "forget", "forget-cold", "checkpoint", "tree", "rewind", "unrevert", "fork", "pals", "chat", "co-work", "tool"];
2
2
  export declare const COMMAND_DESCRIPTIONS: Record<(typeof MVP_COMMANDS)[number], string>;
3
3
  export type PermissionCommandMode = PermissionMode;
4
4
  export type ModelRole = "main" | "subagent";
@@ -73,6 +73,10 @@ export type SlashCommand = {
73
73
  } | {
74
74
  name: "review";
75
75
  focus?: string;
76
+ } | {
77
+ name: "explain";
78
+ query?: string;
79
+ focus?: string;
76
80
  } | {
77
81
  name: "remember";
78
82
  type: MemoryType;
@@ -91,7 +95,7 @@ export type SlashCommand = {
91
95
  target: string;
92
96
  goal: string;
93
97
  } | CoWorkSlashCommand | {
94
- name: Exclude<(typeof MVP_COMMANDS)[number], "model" | "permissions" | "audit" | "loop" | "goal" | "evolve" | "commit" | "review" | "mcp" | "remember" | "forget" | "checkpoint" | "rewind" | "fork" | "pals" | "chat" | "co-work" | "tool">;
98
+ name: Exclude<(typeof MVP_COMMANDS)[number], "model" | "permissions" | "audit" | "loop" | "goal" | "evolve" | "commit" | "review" | "explain" | "mcp" | "remember" | "forget" | "checkpoint" | "rewind" | "fork" | "pals" | "chat" | "co-work" | "tool">;
95
99
  } | {
96
100
  name: "audit";
97
101
  toolFilter?: string | undefined;
@@ -133,6 +133,7 @@ export interface SessionServices {
133
133
  evolve(args: readonly string[]): string | Promise<string>;
134
134
  gitCommit?(hint: string | undefined, signal: AbortSignal): Promise<string>;
135
135
  gitReview?(focus: string | undefined, signal: AbortSignal): Promise<string>;
136
+ explain?(query: string | undefined, focus: string | undefined, signal: AbortSignal, onText?: (chunk: string) => void): Promise<string>;
136
137
  usage(): string | Promise<string>;
137
138
  cancelActiveTask(): void | Promise<void>;
138
139
  clearContext(): void | Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flavor-code",
3
- "version": "1.3.12",
3
+ "version": "1.3.15",
4
4
  "author": "YachuanWzh",
5
5
  "type": "module",
6
6
  "publishConfig": {