@monkey-mini-app/host 0.1.0
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/dist/index.d.ts +782 -0
- package/dist/index.js +3603 -0
- package/package.json +46 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,782 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
|
|
3
|
+
type AgentCwdType = "app" | "process" | "temp" | "custom";
|
|
4
|
+
type AgentCwdInput = {
|
|
5
|
+
cwdType?: AgentCwdType;
|
|
6
|
+
/** Absolute path; only for custom (or alone ⇒ implied custom). */
|
|
7
|
+
cwd?: string;
|
|
8
|
+
};
|
|
9
|
+
/** Subset of AppRuntime needed to resolve cwdType "app". */
|
|
10
|
+
type AgentCwdContext = {
|
|
11
|
+
appDir?: string;
|
|
12
|
+
};
|
|
13
|
+
declare function isAgentCwdType(value: unknown): value is AgentCwdType;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve an absolute enterable cwd for the agent session.
|
|
16
|
+
* When cwdType is "temp", creates a new directory under os.tmpdir().
|
|
17
|
+
*/
|
|
18
|
+
declare function resolveAgentCwd(input: AgentCwdInput, ctx?: AgentCwdContext): string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Shared / extensible options for ctx.llm and ctx.agent.
|
|
22
|
+
* Minimum known field set is explicit; hosts may intersect extra fields at the edges.
|
|
23
|
+
*/
|
|
24
|
+
/** JSON Schema document passed as `opts.schema` (soft-instruct + coerce). */
|
|
25
|
+
type JsonSchema = object;
|
|
26
|
+
/**
|
|
27
|
+
* Minimum shared options for model-backed calls (llm + agent).
|
|
28
|
+
* Open for declaration merging / intersection by host packages.
|
|
29
|
+
*/
|
|
30
|
+
interface ModelCallOptions {
|
|
31
|
+
provider?: string;
|
|
32
|
+
model?: string;
|
|
33
|
+
/** Extra system instruction (combined with schema instruction when both set). */
|
|
34
|
+
system?: string;
|
|
35
|
+
/** When set, host soft-instructs JSON-only output and coerces fences/preamble. */
|
|
36
|
+
schema?: JsonSchema;
|
|
37
|
+
maxTokens?: number;
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
}
|
|
40
|
+
/** Options for HostCapabilities.llm / ctx.llm. */
|
|
41
|
+
interface LlmRunOptions extends ModelCallOptions {
|
|
42
|
+
}
|
|
43
|
+
/** Subset used by JSON instruct / coerce helpers. */
|
|
44
|
+
type JsonInstructOptions = Pick<ModelCallOptions, "schema" | "system">;
|
|
45
|
+
/** Subset used by provider/model routing. */
|
|
46
|
+
type ModelRouteOptions = Pick<ModelCallOptions, "provider" | "model">;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Process events for ctx.agent — optional observation surface.
|
|
50
|
+
* Final answer remains Promise<string>; apps opt in via opts.onEvent.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Why a turn ended (from dsh session `turn/end.reason`).
|
|
55
|
+
* Kept loose so hosts can pass through new kinds without breaking apps.
|
|
56
|
+
*/
|
|
57
|
+
type AgentTurnEndReason = {
|
|
58
|
+
kind: string;
|
|
59
|
+
/** Nested details when kind is error / aborted / etc. */
|
|
60
|
+
error?: unknown;
|
|
61
|
+
reason?: unknown;
|
|
62
|
+
};
|
|
63
|
+
type AgentEvent = {
|
|
64
|
+
type: "status";
|
|
65
|
+
status: "running" | "idle";
|
|
66
|
+
} | {
|
|
67
|
+
type: "text-delta";
|
|
68
|
+
text: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: "tool";
|
|
71
|
+
phase: "start" | "end";
|
|
72
|
+
name: string;
|
|
73
|
+
args?: unknown;
|
|
74
|
+
result?: unknown;
|
|
75
|
+
} | {
|
|
76
|
+
type: "turn";
|
|
77
|
+
phase: "start";
|
|
78
|
+
turn: number;
|
|
79
|
+
} | {
|
|
80
|
+
type: "turn";
|
|
81
|
+
phase: "end";
|
|
82
|
+
turn: number;
|
|
83
|
+
reason?: AgentTurnEndReason;
|
|
84
|
+
} | {
|
|
85
|
+
type: "error";
|
|
86
|
+
message: string;
|
|
87
|
+
} | {
|
|
88
|
+
type: "done";
|
|
89
|
+
text: string;
|
|
90
|
+
};
|
|
91
|
+
type AgentEventHandler = (event: AgentEvent) => void;
|
|
92
|
+
/** Options for HostCapabilities.agent / ctx.agent (extends shared model-call fields). */
|
|
93
|
+
interface AgentRunOptions extends ModelCallOptions {
|
|
94
|
+
/**
|
|
95
|
+
* Soft cap on agent turns (host cancels after this many `turn` end events).
|
|
96
|
+
* dsh AgentOptions has no native maxIterations — enforced by the one-shot runner.
|
|
97
|
+
*/
|
|
98
|
+
maxIterations?: number;
|
|
99
|
+
/** Optional live projection of the agent run (does not change the string return). */
|
|
100
|
+
onEvent?: AgentEventHandler;
|
|
101
|
+
/**
|
|
102
|
+
* Working-directory mode for the agent session (default `"process"`).
|
|
103
|
+
* - app: current mini-app directory (from AppRuntime.appDir)
|
|
104
|
+
* - process: dsh process.cwd()
|
|
105
|
+
* - temp: fresh directory under os.tmpdir()
|
|
106
|
+
* - custom: requires `cwd` absolute path
|
|
107
|
+
*
|
|
108
|
+
* If `cwd` is set without cwdType, treated as custom.
|
|
109
|
+
* If `cwd` is set with cwdType other than custom → error.
|
|
110
|
+
*/
|
|
111
|
+
cwdType?: AgentCwdType;
|
|
112
|
+
/** Absolute path; only with cwdType "custom", or alone (implies custom). */
|
|
113
|
+
cwd?: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Call-level facts for a mini-app API invocation (no capability methods).
|
|
118
|
+
* Passed as the first argument to HostCapabilities.* — never merged into user opts.
|
|
119
|
+
*/
|
|
120
|
+
type AppCallContext = {
|
|
121
|
+
/** Reverse-DNS app id (e.g. com.example.todo). */
|
|
122
|
+
appId: string;
|
|
123
|
+
/** Absolute runtime/apps/<appId> directory (derived from appId). */
|
|
124
|
+
appDir: string;
|
|
125
|
+
/** Cancel signal for the current dashboard API call. */
|
|
126
|
+
signal?: AbortSignal;
|
|
127
|
+
/**
|
|
128
|
+
* Optional host.json llm route defaults — routing only, never written into opts.
|
|
129
|
+
*/
|
|
130
|
+
hostLlm?: {
|
|
131
|
+
provider?: string;
|
|
132
|
+
model?: string;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
/** Effective abort signal: user opts win when set, else call context signal. */
|
|
136
|
+
declare function effectiveSignal(optsSignal: AbortSignal | undefined, call: AppCallContext | undefined): AbortSignal | undefined;
|
|
137
|
+
|
|
138
|
+
type AppTheme = {
|
|
139
|
+
theme: string;
|
|
140
|
+
palette: string;
|
|
141
|
+
};
|
|
142
|
+
declare function readAppTheme(dir: string): AppTheme | null;
|
|
143
|
+
declare function writeAppTheme(dir: string, val: AppTheme | null): AppTheme | null;
|
|
144
|
+
|
|
145
|
+
declare const appIdBrand: unique symbol;
|
|
146
|
+
declare const absolutePathBrand: unique symbol;
|
|
147
|
+
type AppId = string & {
|
|
148
|
+
readonly [appIdBrand]: "AppId";
|
|
149
|
+
};
|
|
150
|
+
type AbsolutePath = string & {
|
|
151
|
+
readonly [absolutePathBrand]: "AbsolutePath";
|
|
152
|
+
};
|
|
153
|
+
declare function isAppId(value: string): value is AppId;
|
|
154
|
+
declare function asAppId(value: string): AppId;
|
|
155
|
+
declare function isAbsolutePath(value: string): value is AbsolutePath;
|
|
156
|
+
declare function asAbsolutePath(value: string): AbsolutePath;
|
|
157
|
+
declare function assertNever(value: never, message?: string): never;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Stateless host capabilities. First argument is always the call context;
|
|
161
|
+
* user opts (2nd/3rd) stay pristine — do not mutate them.
|
|
162
|
+
*/
|
|
163
|
+
interface HostCapabilities {
|
|
164
|
+
bash?(ctx: AppCallContext, command: string): Promise<{
|
|
165
|
+
stdout: string;
|
|
166
|
+
stderr: string;
|
|
167
|
+
exitCode: number;
|
|
168
|
+
}>;
|
|
169
|
+
llm?(ctx: AppCallContext, prompt: string, opts?: LlmRunOptions): Promise<string>;
|
|
170
|
+
/** Final answer is always a string; pass `opts.onEvent` for live process events. */
|
|
171
|
+
agent?(ctx: AppCallContext, goal: string, opts?: AgentRunOptions): Promise<string>;
|
|
172
|
+
tool?(ctx: AppCallContext, name: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
173
|
+
mcp?(ctx: AppCallContext, name: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
174
|
+
/** May later scope by app/call; pass ctx even if unused today. */
|
|
175
|
+
credentials?(ctx: AppCallContext): Record<string, string>;
|
|
176
|
+
/** May later scope by app/call; pass ctx even if unused today. */
|
|
177
|
+
config?(ctx: AppCallContext): Record<string, unknown>;
|
|
178
|
+
listTools?(ctx: AppCallContext): unknown[];
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Author-facing methods (no leading ctx — bound by bindCapsToContext).
|
|
182
|
+
* `credentials` / `config` are methods here; AppsManager exposes them as `ctx.*` properties.
|
|
183
|
+
*/
|
|
184
|
+
type BoundHostCapabilities = {
|
|
185
|
+
bash(command: string): Promise<{
|
|
186
|
+
stdout: string;
|
|
187
|
+
stderr: string;
|
|
188
|
+
exitCode: number;
|
|
189
|
+
}>;
|
|
190
|
+
llm(prompt: string, opts?: LlmRunOptions): Promise<string>;
|
|
191
|
+
agent(goal: string, opts?: AgentRunOptions): Promise<string>;
|
|
192
|
+
tool(name: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
193
|
+
mcp(name: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
194
|
+
credentials(): Record<string, string>;
|
|
195
|
+
config(): Record<string, unknown>;
|
|
196
|
+
listTools(): unknown[];
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* Bind caps.*(ctx, …) onto author-facing methods.
|
|
200
|
+
* Keep this list next to HostCapabilities so new tools are not forgotten.
|
|
201
|
+
*/
|
|
202
|
+
declare function bindCapsToContext(ctx: AppCallContext, caps: HostCapabilities): BoundHostCapabilities;
|
|
203
|
+
|
|
204
|
+
/** Owns all path composition under a validated absolute runtime root. */
|
|
205
|
+
declare class WorkspacePaths {
|
|
206
|
+
static readonly Rel: {
|
|
207
|
+
readonly apps: "apps";
|
|
208
|
+
readonly hostConfig: "host.json";
|
|
209
|
+
readonly ui: "ui.tsx";
|
|
210
|
+
readonly api: "main.api.ts";
|
|
211
|
+
readonly manifest: "manifest.json";
|
|
212
|
+
readonly storage: "storage";
|
|
213
|
+
readonly uiCache: ".ui-cache";
|
|
214
|
+
};
|
|
215
|
+
readonly root: AbsolutePath;
|
|
216
|
+
constructor(root: AbsolutePath);
|
|
217
|
+
appsDir(): AbsolutePath;
|
|
218
|
+
appDir(id: AppId): AbsolutePath;
|
|
219
|
+
hostConfigFile(): AbsolutePath;
|
|
220
|
+
uiCacheDir(): AbsolutePath;
|
|
221
|
+
appFile(id: AppId, rel: string): AbsolutePath;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
declare const THEME_IDS: readonly ["light", "dark"];
|
|
225
|
+
type ThemeId = (typeof THEME_IDS)[number];
|
|
226
|
+
declare const PALETTE_IDS: readonly ["default", "tokyo", "forest", "matcha", "yellow", "zoro", "hokage", "slate"];
|
|
227
|
+
type PaletteId = (typeof PALETTE_IDS)[number];
|
|
228
|
+
declare const LOCALE_IDS: readonly ["zh-CN", "en"];
|
|
229
|
+
type LocaleId = (typeof LOCALE_IDS)[number];
|
|
230
|
+
type LlmConfig = {
|
|
231
|
+
provider: string;
|
|
232
|
+
model: string;
|
|
233
|
+
};
|
|
234
|
+
type HostConfig = {
|
|
235
|
+
runtimeRoot: AbsolutePath;
|
|
236
|
+
hostPort: number;
|
|
237
|
+
theme: ThemeId;
|
|
238
|
+
/** Builtin {@link PaletteId} or a custom theme id from runtime themes/. */
|
|
239
|
+
palette: string;
|
|
240
|
+
locale: LocaleId;
|
|
241
|
+
chatLanguage: LocaleId;
|
|
242
|
+
llm: LlmConfig | null;
|
|
243
|
+
};
|
|
244
|
+
type HostConfigSeed = {
|
|
245
|
+
runtimeRoot: string;
|
|
246
|
+
hostPort: number;
|
|
247
|
+
theme: ThemeId;
|
|
248
|
+
palette: string;
|
|
249
|
+
locale: LocaleId;
|
|
250
|
+
chatLanguage: LocaleId;
|
|
251
|
+
llm: LlmConfig | null;
|
|
252
|
+
};
|
|
253
|
+
type HostConfigInitInput = {
|
|
254
|
+
runtimeRoot?: string;
|
|
255
|
+
hostPort?: number;
|
|
256
|
+
theme?: string;
|
|
257
|
+
palette?: string;
|
|
258
|
+
locale?: string;
|
|
259
|
+
chatLanguage?: string;
|
|
260
|
+
llm?: {
|
|
261
|
+
provider?: string;
|
|
262
|
+
model?: string;
|
|
263
|
+
} | null;
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
type UiBuildFile = {
|
|
267
|
+
name: string;
|
|
268
|
+
contents: Uint8Array;
|
|
269
|
+
};
|
|
270
|
+
type UiCompileOptions = {
|
|
271
|
+
locale: LocaleId;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* Locate @monkey-mini-app/ui dist.
|
|
275
|
+
* When host is bundled into dsh/lib, `import.meta.url` is the plugin bundle —
|
|
276
|
+
* resolve from several bases + monorepo-relative fallbacks.
|
|
277
|
+
*/
|
|
278
|
+
declare function resolveUiDistDir(): string;
|
|
279
|
+
/** Bundles a mini-app ui.tsx into self-contained ESM (entry.js + chunks). */
|
|
280
|
+
declare class UiCompiler {
|
|
281
|
+
private readonly paths;
|
|
282
|
+
private readonly buildCache;
|
|
283
|
+
constructor(paths: WorkspacePaths);
|
|
284
|
+
invalidate(appDir: string): void;
|
|
285
|
+
cacheSize(): number;
|
|
286
|
+
compile(appDir: string, options: UiCompileOptions): Promise<UiBuildFile[]>;
|
|
287
|
+
private cacheKey;
|
|
288
|
+
private cacheSig;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
type GitAuthor = {
|
|
292
|
+
name: string;
|
|
293
|
+
email: string;
|
|
294
|
+
};
|
|
295
|
+
type Commit = {
|
|
296
|
+
id: string;
|
|
297
|
+
time: string;
|
|
298
|
+
message: string;
|
|
299
|
+
};
|
|
300
|
+
type FileStat = {
|
|
301
|
+
path: string;
|
|
302
|
+
add: number;
|
|
303
|
+
del: number;
|
|
304
|
+
};
|
|
305
|
+
type CommitNode = {
|
|
306
|
+
id: string;
|
|
307
|
+
parentIds: string[];
|
|
308
|
+
message: string;
|
|
309
|
+
time: string;
|
|
310
|
+
};
|
|
311
|
+
type CommitTree = {
|
|
312
|
+
head: string;
|
|
313
|
+
nodes: CommitNode[];
|
|
314
|
+
tips: {
|
|
315
|
+
name: string;
|
|
316
|
+
commitId: string;
|
|
317
|
+
}[];
|
|
318
|
+
};
|
|
319
|
+
/** isomorphic-git only. Read + write history for an app directory. */
|
|
320
|
+
declare class GitHistory {
|
|
321
|
+
private readonly commitCountCache;
|
|
322
|
+
private invalidateCount;
|
|
323
|
+
init(dir: string): Promise<void>;
|
|
324
|
+
commit(dir: string, message: string, opts?: {
|
|
325
|
+
author?: GitAuthor;
|
|
326
|
+
}): Promise<{
|
|
327
|
+
commitId: string;
|
|
328
|
+
}>;
|
|
329
|
+
/**
|
|
330
|
+
* True when worktree or index differs from HEAD.
|
|
331
|
+
* Content-hashes tracked files that statusMatrix marks clean — isomorphic-git
|
|
332
|
+
* can miss same-size / same-mtime edits (see stageAll comment).
|
|
333
|
+
*/
|
|
334
|
+
isDirty(dir: string): Promise<boolean>;
|
|
335
|
+
listCommits(dir: string, opts?: {
|
|
336
|
+
limit?: number;
|
|
337
|
+
}): Promise<CommitTree>;
|
|
338
|
+
revert(dir: string, commitId: string, opts?: {
|
|
339
|
+
message?: string;
|
|
340
|
+
}): Promise<{
|
|
341
|
+
commitId: string;
|
|
342
|
+
}>;
|
|
343
|
+
resetTo(dir: string, commitId: string, opts?: {
|
|
344
|
+
createBackupRef?: boolean;
|
|
345
|
+
}): Promise<{
|
|
346
|
+
backupRef?: string;
|
|
347
|
+
}>;
|
|
348
|
+
commitCount(dir: string): Promise<number>;
|
|
349
|
+
log(dir: string, limit: number): Promise<Commit[]>;
|
|
350
|
+
fileStats(dir: string, id: string): Promise<FileStat[]>;
|
|
351
|
+
filePreview(dir: string, id: string, filepath: string, maxLines?: number): Promise<string>;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
interface FuzzyMatchResult {
|
|
355
|
+
/** Whether a match was found */
|
|
356
|
+
found: boolean;
|
|
357
|
+
/** The index where the match starts (in the content that should be used for replacement) */
|
|
358
|
+
index: number;
|
|
359
|
+
/** Length of the matched text */
|
|
360
|
+
matchLength: number;
|
|
361
|
+
/** Whether fuzzy matching was used (false = exact match) */
|
|
362
|
+
usedFuzzyMatch: boolean;
|
|
363
|
+
/**
|
|
364
|
+
* The content to use for replacement operations.
|
|
365
|
+
* When exact match: original content. When fuzzy match: normalized content.
|
|
366
|
+
*/
|
|
367
|
+
contentForReplacement: string;
|
|
368
|
+
}
|
|
369
|
+
interface Edit {
|
|
370
|
+
oldText: string;
|
|
371
|
+
newText: string;
|
|
372
|
+
}
|
|
373
|
+
interface AppliedEditsResult {
|
|
374
|
+
baseContent: string;
|
|
375
|
+
newContent: string;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Find oldText in content, trying exact match first, then fuzzy match.
|
|
379
|
+
* When fuzzy matching is used, the returned contentForReplacement is the
|
|
380
|
+
* fuzzy-normalized version of the content (trailing whitespace stripped,
|
|
381
|
+
* Unicode quotes/dashes normalized to ASCII).
|
|
382
|
+
*/
|
|
383
|
+
declare function fuzzyFindText(content: string, oldText: string): FuzzyMatchResult;
|
|
384
|
+
/**
|
|
385
|
+
* Apply one or more exact-text replacements to LF-normalized content.
|
|
386
|
+
*
|
|
387
|
+
* All edits are matched against the same original content. Replacements are
|
|
388
|
+
* then applied in reverse order so offsets remain stable. If any edit needs
|
|
389
|
+
* fuzzy matching, the operation runs in fuzzy-normalized content space and then
|
|
390
|
+
* overlays those line-level changes onto the original content so unchanged line
|
|
391
|
+
* blocks keep their original bytes.
|
|
392
|
+
*/
|
|
393
|
+
declare function applyEditsToNormalizedContent(normalizedContent: string, edits: Edit[], path: string): AppliedEditsResult;
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Mini-app source file CUD helpers (list/read/write/edit/delete).
|
|
397
|
+
* Edit semantics come from ./edit-diff.ts (Pi MIT port).
|
|
398
|
+
*/
|
|
399
|
+
|
|
400
|
+
type ListedFile = {
|
|
401
|
+
path: string;
|
|
402
|
+
size: number;
|
|
403
|
+
};
|
|
404
|
+
/** 1-indexed inclusive line window. Omit both → whole file. */
|
|
405
|
+
type ReadFileRange = {
|
|
406
|
+
startLine?: number;
|
|
407
|
+
endLine?: number;
|
|
408
|
+
/**
|
|
409
|
+
* Prefix each returned line with `N|` (1-indexed absolute line numbers).
|
|
410
|
+
* Default false — raw text is better for copying into mini_app_edit oldText.
|
|
411
|
+
*/
|
|
412
|
+
numbered?: boolean;
|
|
413
|
+
};
|
|
414
|
+
type ReadFileResult = {
|
|
415
|
+
path: string;
|
|
416
|
+
/** Sliced file text (raw, or numbered when numbered:true). */
|
|
417
|
+
content: string;
|
|
418
|
+
bytes: number;
|
|
419
|
+
totalLines: number;
|
|
420
|
+
/** Actual 1-indexed inclusive window returned. */
|
|
421
|
+
startLine: number;
|
|
422
|
+
endLine: number;
|
|
423
|
+
/** True when a safety cap truncated the response (caller should page with startLine). */
|
|
424
|
+
truncated?: boolean;
|
|
425
|
+
};
|
|
426
|
+
type MutateFileResult = {
|
|
427
|
+
path: string;
|
|
428
|
+
bytes: number;
|
|
429
|
+
diff?: string;
|
|
430
|
+
created?: boolean;
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
type HttpRequest = {
|
|
434
|
+
url: string;
|
|
435
|
+
method?: string;
|
|
436
|
+
headers?: Record<string, string>;
|
|
437
|
+
query?: Record<string, string | number | boolean | null | undefined>;
|
|
438
|
+
body?: unknown;
|
|
439
|
+
timeout?: number;
|
|
440
|
+
signal?: AbortSignal;
|
|
441
|
+
};
|
|
442
|
+
type HttpResponse = {
|
|
443
|
+
ok: boolean;
|
|
444
|
+
status: number;
|
|
445
|
+
headers: Record<string, string>;
|
|
446
|
+
text: string;
|
|
447
|
+
json: unknown | null;
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
type AppItem = {
|
|
451
|
+
id: AppId;
|
|
452
|
+
name: string;
|
|
453
|
+
description: string;
|
|
454
|
+
version: string;
|
|
455
|
+
acronym: string;
|
|
456
|
+
commits: number;
|
|
457
|
+
};
|
|
458
|
+
type AppStorage = {
|
|
459
|
+
get(key: string): Promise<unknown>;
|
|
460
|
+
set(key: string, value: unknown): Promise<void>;
|
|
461
|
+
delete(key: string): Promise<void>;
|
|
462
|
+
clear(): Promise<void>;
|
|
463
|
+
table(name: string): AppStorage;
|
|
464
|
+
};
|
|
465
|
+
type AppContext = {
|
|
466
|
+
/** Reverse-DNS id of the running mini-app. */
|
|
467
|
+
appId: string;
|
|
468
|
+
/** Absolute runtime/apps/<appId> directory (derived from appId). */
|
|
469
|
+
appDir: string;
|
|
470
|
+
storage: AppStorage;
|
|
471
|
+
state: Record<string, unknown>;
|
|
472
|
+
credentials: Record<string, string>;
|
|
473
|
+
log(...a: unknown[]): void;
|
|
474
|
+
push(method: string, params?: unknown): void;
|
|
475
|
+
mcp(name: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
476
|
+
tool(name: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
477
|
+
listTools(): unknown[];
|
|
478
|
+
llm(prompt: string, opts?: LlmRunOptions): Promise<string>;
|
|
479
|
+
agent(goal: string, opts?: AgentRunOptions): Promise<string>;
|
|
480
|
+
bash(command: string): Promise<{
|
|
481
|
+
stdout: string;
|
|
482
|
+
stderr: string;
|
|
483
|
+
exitCode: number;
|
|
484
|
+
}>;
|
|
485
|
+
http(url: string | HttpRequest, opts?: Omit<HttpRequest, "url">): Promise<HttpResponse>;
|
|
486
|
+
system: {
|
|
487
|
+
metrics(): Promise<Record<string, unknown>>;
|
|
488
|
+
};
|
|
489
|
+
config: Record<string, unknown>;
|
|
490
|
+
/** Cancel signal for the current dashboard API call. */
|
|
491
|
+
signal?: AbortSignal;
|
|
492
|
+
};
|
|
493
|
+
type DashboardMethod = (ctx: AppContext, args: unknown) => unknown | Promise<unknown>;
|
|
494
|
+
type DashboardDef = {
|
|
495
|
+
name: string;
|
|
496
|
+
description: string;
|
|
497
|
+
api: Record<string, DashboardMethod>;
|
|
498
|
+
state?: Record<string, unknown>;
|
|
499
|
+
};
|
|
500
|
+
type AfterMutateOptions = {
|
|
501
|
+
commitMessage: string;
|
|
502
|
+
/** Default true. Pass false to skip auto-commit. */
|
|
503
|
+
commit?: boolean;
|
|
504
|
+
};
|
|
505
|
+
type AfterMutateResult = {
|
|
506
|
+
committed: {
|
|
507
|
+
commitId: string;
|
|
508
|
+
message: string;
|
|
509
|
+
} | null;
|
|
510
|
+
};
|
|
511
|
+
type ReloadResult = {
|
|
512
|
+
ok: boolean;
|
|
513
|
+
errors: string[];
|
|
514
|
+
path: string;
|
|
515
|
+
compiled?: {
|
|
516
|
+
api: boolean;
|
|
517
|
+
ui: boolean;
|
|
518
|
+
};
|
|
519
|
+
committed?: {
|
|
520
|
+
commitId: string;
|
|
521
|
+
message: string;
|
|
522
|
+
} | null;
|
|
523
|
+
};
|
|
524
|
+
/** Loads, registers, and executes mini-apps under WorkspacePaths.appsDir(). */
|
|
525
|
+
declare class AppsManager {
|
|
526
|
+
private readonly paths;
|
|
527
|
+
private readonly capabilities;
|
|
528
|
+
private readonly git;
|
|
529
|
+
private readonly config;
|
|
530
|
+
private readonly dashboardCache;
|
|
531
|
+
private uiCompiler;
|
|
532
|
+
constructor(paths: WorkspacePaths, capabilities: HostCapabilities, git: GitHistory, config: HostConfig);
|
|
533
|
+
/** Wire UI compiler for invalidate + reload (createHost calls this). */
|
|
534
|
+
setUiCompiler(compiler: UiCompiler): void;
|
|
535
|
+
dirOf(appId: string): AbsolutePath;
|
|
536
|
+
list(): Promise<AppItem[]>;
|
|
537
|
+
get(appId: string): Promise<AppItem | null>;
|
|
538
|
+
register(appId: string, files: Record<string, string>): Promise<AppItem>;
|
|
539
|
+
listFiles(appId: string): Promise<ListedFile[]>;
|
|
540
|
+
readFile(appId: string, relPath: string, range?: ReadFileRange): Promise<ReadFileResult>;
|
|
541
|
+
writeFile(appId: string, relPath: string, content: string, opts?: {
|
|
542
|
+
commit?: boolean;
|
|
543
|
+
}): Promise<MutateFileResult & AfterMutateResult>;
|
|
544
|
+
editFile(appId: string, relPath: string, edits: Edit[], opts?: {
|
|
545
|
+
commit?: boolean;
|
|
546
|
+
}): Promise<MutateFileResult & AfterMutateResult>;
|
|
547
|
+
deleteFile(appId: string, relPath: string, opts?: {
|
|
548
|
+
commit?: boolean;
|
|
549
|
+
}): Promise<{
|
|
550
|
+
path: string;
|
|
551
|
+
} & AfterMutateResult>;
|
|
552
|
+
/**
|
|
553
|
+
* Validate + sync-compile api/ui. On success, auto-commit if the worktree is dirty.
|
|
554
|
+
* Replaces the old lightweight mini_app_validate tool.
|
|
555
|
+
*/
|
|
556
|
+
reload(appId: string): Promise<ReloadResult>;
|
|
557
|
+
afterMutate(appDir: string, opts: AfterMutateOptions): Promise<AfterMutateResult>;
|
|
558
|
+
remove(appId: string): Promise<void>;
|
|
559
|
+
load(appId: string): {
|
|
560
|
+
def: DashboardDef;
|
|
561
|
+
ctx: AppContext;
|
|
562
|
+
};
|
|
563
|
+
call(appId: string, method: string, args?: unknown, signal?: AbortSignal): Promise<unknown>;
|
|
564
|
+
invalidate(appDir: string): void;
|
|
565
|
+
private readAppItem;
|
|
566
|
+
private dashboardMtime;
|
|
567
|
+
private loadMainApi;
|
|
568
|
+
private loadAppFile;
|
|
569
|
+
private buildCtx;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
type AppManifest = {
|
|
573
|
+
id: AppId;
|
|
574
|
+
name: string;
|
|
575
|
+
version: string;
|
|
576
|
+
entry: string;
|
|
577
|
+
description?: string;
|
|
578
|
+
permissions: string[];
|
|
579
|
+
acronym?: string;
|
|
580
|
+
theme?: {
|
|
581
|
+
followsHost?: boolean;
|
|
582
|
+
};
|
|
583
|
+
};
|
|
584
|
+
/** Parse and validate a mini-app manifest.json. */
|
|
585
|
+
declare function parseManifest(raw: string): AppManifest;
|
|
586
|
+
/** Two-letter badge: manifest acronym wins, else first two alphanumeric of name. */
|
|
587
|
+
declare function acronymOf(name: string, manifestAcronym?: string): string;
|
|
588
|
+
|
|
589
|
+
type StorageTableInfo = {
|
|
590
|
+
name: string;
|
|
591
|
+
size: number;
|
|
592
|
+
updatedAt: string;
|
|
593
|
+
};
|
|
594
|
+
/** Enumerate `*.json` tables under an app storage dir (newest first). */
|
|
595
|
+
declare function listStorageTables(dir: string): StorageTableInfo[];
|
|
596
|
+
/** Basename-only join + `.json` — blocks path traversal. */
|
|
597
|
+
declare function storageTablePath(dir: string, table: string): string;
|
|
598
|
+
declare function readJsonFile(fp: string, fallback?: unknown): unknown;
|
|
599
|
+
|
|
600
|
+
/** Install/init: apply DEFAULT_HOST_CONFIG_SEED, then parse. */
|
|
601
|
+
declare function bootstrapHostConfig(input: HostConfigInitInput): HostConfig;
|
|
602
|
+
|
|
603
|
+
/** Bootstrap-only defaults. Runtime load/parse must not read this module. */
|
|
604
|
+
declare const DEFAULT_HOST_CONFIG_SEED: HostConfigSeed;
|
|
605
|
+
|
|
606
|
+
/** Read host.json from WorkspacePaths. Fail loud; no defaults. */
|
|
607
|
+
declare function loadHostConfig(paths: WorkspacePaths): HostConfig;
|
|
608
|
+
|
|
609
|
+
/** Validate a complete host config. Does not apply defaults. */
|
|
610
|
+
declare function parseHostConfig(raw: unknown): HostConfig;
|
|
611
|
+
|
|
612
|
+
/** Persist a complete HostConfig to host.json (pretty-printed). */
|
|
613
|
+
declare function writeHostConfig(paths: WorkspacePaths, config: HostConfig): void;
|
|
614
|
+
|
|
615
|
+
/** Host → browser events (SSE). Agent-agnostic; tools emit, HttpGateway fans out. */
|
|
616
|
+
type HostEvent = {
|
|
617
|
+
type: "app:open";
|
|
618
|
+
appId: string;
|
|
619
|
+
title?: string;
|
|
620
|
+
};
|
|
621
|
+
type HostEventListener = (event: HostEvent) => void;
|
|
622
|
+
declare class HostEventBus {
|
|
623
|
+
private readonly listeners;
|
|
624
|
+
private seq;
|
|
625
|
+
subscribe(listener: HostEventListener): () => void;
|
|
626
|
+
emit(event: HostEvent): void;
|
|
627
|
+
/** Monotonic id for SSE `id:` fields. */
|
|
628
|
+
nextId(): number;
|
|
629
|
+
}
|
|
630
|
+
declare function formatSse(event: HostEvent, id: number): string;
|
|
631
|
+
|
|
632
|
+
/** Custom palette row for GET /api/palettes (builtins stay in panel). */
|
|
633
|
+
type CustomThemePalette = {
|
|
634
|
+
id: string;
|
|
635
|
+
label: string;
|
|
636
|
+
swatch: string;
|
|
637
|
+
custom: true;
|
|
638
|
+
/** Opaque token bags; panel maps them when applying. */
|
|
639
|
+
tokens?: {
|
|
640
|
+
light: Record<string, string>;
|
|
641
|
+
dark: Record<string, string>;
|
|
642
|
+
};
|
|
643
|
+
};
|
|
644
|
+
/**
|
|
645
|
+
* ThemeResource — host consumes; the shell (dsh) implements.
|
|
646
|
+
* Parallel to HostCapabilities / HostLifecycle (not a bare CSS string callback).
|
|
647
|
+
*/
|
|
648
|
+
interface ThemeResource {
|
|
649
|
+
/** Full CSS injected into the iframe runner `<style>` (builtin + custom blocks). */
|
|
650
|
+
runnerCss(): string;
|
|
651
|
+
/** Optional custom themes for `/api/palettes`. Default empty. */
|
|
652
|
+
listCustomPalettes?(): CustomThemePalette[] | Promise<CustomThemePalette[]>;
|
|
653
|
+
}
|
|
654
|
+
/** Empty resource used when the shell does not supply themes. */
|
|
655
|
+
declare const EMPTY_THEME_RESOURCE: ThemeResource;
|
|
656
|
+
|
|
657
|
+
/** Localhost HTTP surface. Calls AppsManager / UiCompiler — never ToolFacade. */
|
|
658
|
+
declare class HttpGateway {
|
|
659
|
+
private readonly apps;
|
|
660
|
+
private readonly config;
|
|
661
|
+
private readonly paths;
|
|
662
|
+
private readonly compiler;
|
|
663
|
+
private readonly git;
|
|
664
|
+
private readonly themes;
|
|
665
|
+
private readonly events?;
|
|
666
|
+
private readonly onHostPortChanged?;
|
|
667
|
+
readonly app: Hono;
|
|
668
|
+
private server;
|
|
669
|
+
private boundPort;
|
|
670
|
+
constructor(apps: AppsManager, config: HostConfig, paths: WorkspacePaths, compiler: UiCompiler, git: GitHistory, themes?: ThemeResource, events?: HostEventBus | undefined, onHostPortChanged?: ((port: number) => void) | undefined);
|
|
671
|
+
get port(): number;
|
|
672
|
+
listen(port: number): Promise<number>;
|
|
673
|
+
close(): Promise<void>;
|
|
674
|
+
private buildApp;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
type ToolDefinition = {
|
|
678
|
+
name: string;
|
|
679
|
+
description: string;
|
|
680
|
+
inputSchema: Record<string, unknown>;
|
|
681
|
+
execute: (args: Record<string, unknown>, signal?: AbortSignal) => Promise<unknown>;
|
|
682
|
+
};
|
|
683
|
+
/** Host chat tools: `mini_app_list`, `mini_app_read`, … and `mini_app_list_ctx_tools`. */
|
|
684
|
+
declare function isMiniAppToolName(name: string): boolean;
|
|
685
|
+
/** Agent-facing mini_app_* tools. Execute calls AppsManager / GitHistory — never HTTP. */
|
|
686
|
+
declare class ToolFacade {
|
|
687
|
+
private readonly apps;
|
|
688
|
+
private readonly git;
|
|
689
|
+
private readonly paths;
|
|
690
|
+
private readonly events?;
|
|
691
|
+
constructor(apps: AppsManager, git: GitHistory, paths: WorkspacePaths, events?: HostEventBus | undefined);
|
|
692
|
+
definitions(): ToolDefinition[];
|
|
693
|
+
invoke(name: string, args?: Record<string, unknown>, signal?: AbortSignal): Promise<unknown>;
|
|
694
|
+
private handleGet;
|
|
695
|
+
private handleReload;
|
|
696
|
+
private handleRegister;
|
|
697
|
+
private handleListFiles;
|
|
698
|
+
private handleRead;
|
|
699
|
+
private handleEdit;
|
|
700
|
+
private handleWrite;
|
|
701
|
+
private handleDelete;
|
|
702
|
+
private handleOpen;
|
|
703
|
+
private handleCall;
|
|
704
|
+
private handleHistoryCommit;
|
|
705
|
+
private handleHistoryList;
|
|
706
|
+
private handleHistoryReset;
|
|
707
|
+
private handleHistoryRevert;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
711
|
+
/** Domain managers passed to `attach`. HTTP and tools both call these. */
|
|
712
|
+
type HostServices = {
|
|
713
|
+
apps: AppsManager;
|
|
714
|
+
git: GitHistory;
|
|
715
|
+
tools: ToolFacade;
|
|
716
|
+
paths: WorkspacePaths;
|
|
717
|
+
config: HostConfig;
|
|
718
|
+
};
|
|
719
|
+
/** Host calls these; the agent plugin implements. */
|
|
720
|
+
interface HostLifecycle {
|
|
721
|
+
attach(ctx: unknown, services: HostServices): void | Promise<void>;
|
|
722
|
+
detach?(): void | Promise<void>;
|
|
723
|
+
onHostPortChanged?(port: number): void;
|
|
724
|
+
log?(level: LogLevel, message: string, meta?: unknown): void;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/** Agent-agnostic host. `apply` = attach + listen on the Hono HttpGateway. */
|
|
728
|
+
declare class Host {
|
|
729
|
+
private readonly capabilities;
|
|
730
|
+
private readonly lifecycle;
|
|
731
|
+
private readonly paths;
|
|
732
|
+
private readonly config;
|
|
733
|
+
private readonly services;
|
|
734
|
+
private readonly http;
|
|
735
|
+
private boundPort;
|
|
736
|
+
private attached;
|
|
737
|
+
private active;
|
|
738
|
+
constructor(capabilities: HostCapabilities, lifecycle: HostLifecycle, paths: WorkspacePaths, config: HostConfig, services: HostServices, http: HttpGateway);
|
|
739
|
+
get port(): number;
|
|
740
|
+
apply(ctx?: unknown): Promise<{
|
|
741
|
+
port: number;
|
|
742
|
+
}>;
|
|
743
|
+
start(): Promise<{
|
|
744
|
+
port: number;
|
|
745
|
+
}>;
|
|
746
|
+
stop(): Promise<void>;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/** Assemble a Host. `options.config` must already be parsed (`parseHostConfig` / bootstrap). */
|
|
750
|
+
declare function createHost(capabilities: HostCapabilities, lifecycle: HostLifecycle, options: {
|
|
751
|
+
config: HostConfig;
|
|
752
|
+
/** Theme resource port — shell implements; host only consumes the interface. */
|
|
753
|
+
themes?: ThemeResource;
|
|
754
|
+
}): Host;
|
|
755
|
+
|
|
756
|
+
declare class HostError extends Error {
|
|
757
|
+
readonly code: string;
|
|
758
|
+
constructor(code: string, message: string, options?: {
|
|
759
|
+
cause?: unknown;
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
declare class HostConfigError extends HostError {
|
|
763
|
+
constructor(message: string, options?: {
|
|
764
|
+
code?: string;
|
|
765
|
+
cause?: unknown;
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/** Iframe entry HTML for a compiled mini-app UI bundle. */
|
|
770
|
+
declare function appRunnerHtml(appId: string, themeCss?: string): string;
|
|
771
|
+
|
|
772
|
+
type I18nParams = Record<string, string | number>;
|
|
773
|
+
type HostI18n = {
|
|
774
|
+
readonly locale: LocaleId;
|
|
775
|
+
t(key: string, params?: I18nParams): string;
|
|
776
|
+
};
|
|
777
|
+
/** i18next helper bound to `locale`. Missing keys throw outside production. */
|
|
778
|
+
declare function createHostI18n(locale: LocaleId): HostI18n;
|
|
779
|
+
|
|
780
|
+
declare const packageName = "@monkey-mini-app/host";
|
|
781
|
+
|
|
782
|
+
export { type AbsolutePath, type AfterMutateOptions, type AfterMutateResult, type AgentCwdContext, type AgentCwdInput, type AgentCwdType, type AgentEvent, type AgentEventHandler, type AgentRunOptions, type AgentTurnEndReason, type AppCallContext, type AppContext, type AppId, type AppItem, type AppManifest, type AppStorage, type AppTheme, AppsManager, type BoundHostCapabilities, type Commit, type CommitNode, type CommitTree, type CustomThemePalette, DEFAULT_HOST_CONFIG_SEED, type DashboardDef, type DashboardMethod, EMPTY_THEME_RESOURCE, type Edit, type FileStat, type GitAuthor, GitHistory, Host, type HostCapabilities, type HostConfig, HostConfigError, type HostConfigInitInput, type HostConfigSeed, HostError, type HostEvent, HostEventBus, type HostEventListener, type HostI18n, type HostLifecycle, type HostServices, HttpGateway, type I18nParams, type JsonInstructOptions, type JsonSchema, LOCALE_IDS, type LlmConfig, type LlmRunOptions, type LocaleId, type LogLevel, type ModelCallOptions, type ModelRouteOptions, PALETTE_IDS, type PaletteId, type ReloadResult, type StorageTableInfo, THEME_IDS, type ThemeId, type ThemeResource, type ToolDefinition, ToolFacade, type UiBuildFile, type UiCompileOptions, UiCompiler, WorkspacePaths, acronymOf, appRunnerHtml, applyEditsToNormalizedContent, asAbsolutePath, asAppId, assertNever, bindCapsToContext, bootstrapHostConfig, createHost, createHostI18n, effectiveSignal, formatSse, fuzzyFindText, isAbsolutePath, isAgentCwdType, isAppId, isMiniAppToolName, listStorageTables, loadHostConfig, packageName, parseHostConfig, parseManifest, readAppTheme, readJsonFile, resolveAgentCwd, resolveUiDistDir, storageTablePath, writeAppTheme, writeHostConfig };
|