@aiworkbench/vibe-ide 0.0.3 → 0.0.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/dist/core/boot.d.ts +3 -0
- package/dist/core/boot.d.ts.map +1 -1
- package/dist/core/bridge-shim.d.ts +1 -1
- package/dist/core/bridge-shim.d.ts.map +1 -1
- package/dist/core/filesystem.d.ts +72 -1
- package/dist/core/filesystem.d.ts.map +1 -1
- package/dist/core/local-snapshot-cache.d.ts +72 -0
- package/dist/core/local-snapshot-cache.d.ts.map +1 -0
- package/dist/core/path-policy.d.ts +77 -0
- package/dist/core/path-policy.d.ts.map +1 -0
- package/dist/core/preview-channel.d.ts +2 -2
- package/dist/core/process-registry.d.ts +71 -0
- package/dist/core/process-registry.d.ts.map +1 -0
- package/dist/core/process.d.ts +5 -0
- package/dist/core/process.d.ts.map +1 -1
- package/dist/core/write-skills.d.ts +18 -0
- package/dist/core/write-skills.d.ts.map +1 -0
- package/dist/ide-theme.css +46 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11368 -5115
- package/dist/mcp/mcp-adapter.d.ts +5 -6
- package/dist/mcp/mcp-adapter.d.ts.map +1 -1
- package/dist/power-user.d.ts +13 -0
- package/dist/power-user.d.ts.map +1 -0
- package/dist/power-user.js +4554 -0
- package/dist/prompts/core-rules.d.ts +20 -0
- package/dist/prompts/core-rules.d.ts.map +1 -0
- package/dist/prompts/skills.d.ts +36 -0
- package/dist/prompts/skills.d.ts.map +1 -0
- package/dist/prompts/skills.generated.d.ts +17 -0
- package/dist/prompts/skills.generated.d.ts.map +1 -0
- package/dist/react/code-editor.d.ts +18 -0
- package/dist/react/code-editor.d.ts.map +1 -0
- package/dist/react/file-explorer.d.ts +17 -0
- package/dist/react/file-explorer.d.ts.map +1 -0
- package/dist/react/provider.d.ts.map +1 -1
- package/dist/react/terminal-view.d.ts +19 -0
- package/dist/react/terminal-view.d.ts.map +1 -0
- package/dist/react/use-autosave.d.ts +46 -0
- package/dist/react/use-autosave.d.ts.map +1 -0
- package/dist/react/vibe-ide-bridge-relay.d.ts.map +1 -1
- package/dist/react/vibe-ide-layout.d.ts +4 -0
- package/dist/react/vibe-ide-layout.d.ts.map +1 -1
- package/dist/react/vibe-ide-preview-pane.d.ts.map +1 -1
- package/dist/react/vibe-ide-toolbar.d.ts +2 -1
- package/dist/react/vibe-ide-toolbar.d.ts.map +1 -1
- package/dist/server.js +7 -0
- package/dist/templates/generated.d.ts +16 -12
- package/dist/templates/generated.d.ts.map +1 -1
- package/dist/templates/react-template.generated.d.ts +12 -0
- package/dist/templates/react-template.generated.d.ts.map +1 -0
- package/dist/types.d.ts +80 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +15 -2
package/dist/core/boot.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ import type { VibeIdeBootOptions } from "../types";
|
|
|
9
9
|
export declare class WebContainerTabBlockedError extends Error {
|
|
10
10
|
constructor();
|
|
11
11
|
}
|
|
12
|
+
export declare class WebContainerBootTimeoutError extends Error {
|
|
13
|
+
constructor();
|
|
14
|
+
}
|
|
12
15
|
export declare function bootWebContainer(options?: VibeIdeBootOptions): Promise<WebContainer>;
|
|
13
16
|
export declare function teardownWebContainer(): void;
|
|
14
17
|
export declare function getWebContainer(): WebContainer | null;
|
package/dist/core/boot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../src/core/boot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../src/core/boot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsCnD,qBAAa,2BAA4B,SAAQ,KAAK;;CAOrD;AAED,qBAAa,4BAA6B,SAAQ,KAAK;;CAOtD;AAqCD,wBAAsB,gBAAgB,CACpC,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAwGvB;AAED,wBAAgB,oBAAoB,SAcnC;AAED,wBAAgB,eAAe,wBAE9B"}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* implementing the full Bridge API client-side inside the preview iframe. It
|
|
6
6
|
* communicates with the host via a MessagePort received through `vibe:init`.
|
|
7
7
|
*/
|
|
8
|
-
export declare const BRIDGE_DEV_SHIM_SOURCE = "\n(async function() {\n function waitForBridgeInit() {\n return new Promise((resolve) => {\n window.addEventListener('message', (e) => {\n if (e.data?.type === 'vibe:init') {\n resolve({ port: e.ports[0], previewSessionId: e.data.previewSessionId, bootstrap: e.data.bootstrap });\n }\n });\n });\n }\n\n const { port, previewSessionId, bootstrap } = await waitForBridgeInit();\n const effectivePermissions = new Set(Array.isArray(bootstrap?.effectivePermissions) ? bootstrap.effectivePermissions : []);\n let currentBootstrap = bootstrap || {};\n\n
|
|
8
|
+
export declare const BRIDGE_DEV_SHIM_SOURCE = "\n(async function() {\n function waitForBridgeInit() {\n return new Promise((resolve) => {\n window.addEventListener('message', (e) => {\n if (e.data?.type === 'vibe:init') {\n resolve({ port: e.ports[0], previewSessionId: e.data.previewSessionId, bootstrap: e.data.bootstrap });\n }\n });\n });\n }\n\n const { port, previewSessionId, bootstrap } = await waitForBridgeInit();\n const effectivePermissions = new Set(Array.isArray(bootstrap?.effectivePermissions) ? bootstrap.effectivePermissions : []);\n let currentBootstrap = bootstrap || {};\n\n function sendOneWay(capability, method, args) {\n port.postMessage({ id: crypto.randomUUID(), previewSessionId, capability, method, args });\n }\n\n function sendRequest(capability, method, args) {\n const id = crypto.randomUUID();\n return new Promise((resolve, reject) => {\n const handler = (e) => {\n if (e.data.id === id) {\n port.removeEventListener('message', handler);\n if (e.data.error) reject(new Error(e.data.error));\n else resolve(e.data.result);\n }\n };\n port.addEventListener('message', handler);\n port.start();\n port.postMessage({ id, previewSessionId, capability, method, args });\n });\n }\n\n function sendStream(capability, method, args, onChunk) {\n const id = crypto.randomUUID();\n let isDone = false;\n let stopEventRegistration = () => {};\n\n const promise = new Promise((resolve, reject) => {\n const handler = (e) => {\n if (e.data.id === id) {\n if (e.data.error) {\n port.removeEventListener('message', handler);\n reject(new Error(e.data.error));\n } else if (e.data.chunk !== undefined) {\n onChunk(e.data.chunk);\n } else if (e.data.subscribed) {\n resolve({ subscriptionId: id, unsubscribe: stopEventRegistration });\n } else if (e.data.done || e.data.result !== undefined) {\n port.removeEventListener('message', handler);\n isDone = true;\n resolve(e.data.result);\n }\n }\n };\n port.addEventListener('message', handler);\n port.start();\n port.postMessage({ id, previewSessionId, capability, method, args });\n \n stopEventRegistration = () => {\n if (!isDone) {\n port.removeEventListener('message', handler);\n port.postMessage({\n id: crypto.randomUUID(),\n previewSessionId,\n capability,\n method: 'unsubscribe',\n args: [id],\n });\n }\n };\n });\n \n return { promise, unsubscribe: stopEventRegistration };\n }\n\n /* \u2500\u2500 Capability factories \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Each factory returns the namespace object for a single capability.\n * Only capabilities present in effectivePermissions are assigned to the\n * bridge object, so unpermitted ones remain undefined and optional\n * chaining (e.g. bridge.auth?.getUser()) short-circuits safely.\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n const capabilityFactories = {\n auth: () => ({\n getUser: () => {\n if (!currentBootstrap.user) {\n throw new Error('auth.getUser() is unavailable in this preview');\n }\n return currentBootstrap.user;\n },\n getToken: async () => { throw new Error(\"auth.getToken() is unavailable in dev preview\"); }\n }),\n theme: () => ({\n current: () => currentBootstrap.theme\n }),\n toast: () => ({\n show: (msg, opts) => sendOneWay('toast', 'show', [msg, opts])\n }),\n api: () => ({\n fetch: async (ep, opts) => {\n const res = await sendRequest('api', 'fetch', [ep, opts]);\n return new Response(res.body, { status: res.status, statusText: res.statusText, headers: res.headers });\n }\n }),\n storage: () => ({\n get: (key) => sendRequest('storage', 'get', [key]),\n set: (key, val) => sendRequest('storage', 'set', [key, val]),\n remove: (key) => sendRequest('storage', 'remove', [key]),\n keys: () => sendRequest('storage', 'keys', [])\n }),\n navigation: () => ({\n navigate: (path) => sendOneWay('navigation', 'navigate', [path])\n }),\n events: () => ({\n emit: (evt, data) => sendOneWay('events', 'emit', [evt, data]),\n on: (evt, cb) => {\n const stream = sendStream('events', 'on', [evt], (chunk) => {\n cb(chunk);\n });\n return stream.unsubscribe;\n },\n once: (evt, cb) => {\n let unsub = () => {};\n const wrappedCb = (chunk) => { unsub(); cb(chunk); };\n const stream = sendStream('events', 'once', [evt], wrappedCb);\n unsub = stream.unsubscribe;\n return unsub;\n }\n }),\n chat: () => ({\n send: function(serverUrl, parts, options) {\n const payload = {\n serverUrl,\n parts,\n options: options ? {\n contextId: options.contextId,\n messageId: options.messageId,\n metadata: options.metadata,\n } : undefined,\n };\n let buffer = [];\n let error = null;\n let done = false;\n let resolvers = [];\n const stream = sendStream('chat', 'send', [payload], (chunk) => {\n buffer.push(chunk);\n if (resolvers.length > 0) resolvers.shift()();\n });\n\n stream.promise.then((res) => {\n done = true;\n if (resolvers.length > 0) resolvers.shift()();\n }).catch(err => {\n error = err;\n done = true;\n if (resolvers.length > 0) resolvers.shift()();\n });\n const iterator = (async function*() {\n while (true) {\n if (buffer.length > 0) yield buffer.shift();\n else if (error) throw error;\n else if (done) break;\n else await new Promise(r => resolvers.push(r));\n }\n })();\n\n return {\n [Symbol.asyncIterator]: () => iterator,\n abort: () => stream.unsubscribe(),\n };\n }\n })\n };\n\n /* \u2500\u2500 Build bridge object from permitted capabilities only \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n function buildBridge() {\n const bridge = {};\n for (const cap of effectivePermissions) {\n if (capabilityFactories[cap]) {\n bridge[cap] = capabilityFactories[cap]();\n }\n }\n return bridge;\n }\n\n window.__VIBE_BRIDGE_DEV__ = buildBridge();\n\n /* \u2500\u2500 Handle runtime permission changes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n window.addEventListener('message', (e) => {\n if (e.data?.type === 'vibe:permissions') {\n effectivePermissions.clear();\n const nextPermissions = Array.isArray(e.data.effectivePermissions) ? e.data.effectivePermissions : [];\n nextPermissions.forEach((capability) => effectivePermissions.add(capability));\n currentBootstrap = e.data.bootstrap || currentBootstrap;\n window.__VIBE_BRIDGE_DEV__ = buildBridge();\n }\n });\n\n window.dispatchEvent(new Event(\"vibe-bridge-ready\"));\n})();\n";
|
|
9
9
|
//# sourceMappingURL=bridge-shim.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-shim.d.ts","sourceRoot":"","sources":["../../src/core/bridge-shim.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"bridge-shim.d.ts","sourceRoot":"","sources":["../../src/core/bridge-shim.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,sBAAsB,66PA8MlC,CAAC"}
|
|
@@ -1,12 +1,71 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WebContainer filesystem helpers: read, write, serialize, and batched writes.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Phase 2 additions:
|
|
5
|
+
* - Canonical snapshot serializer with sorted entries and binary-safe encoding
|
|
6
|
+
* - Structure-only tree walker (no file content reads)
|
|
7
|
+
* - Size caps (file count, total bytes, per-file bytes)
|
|
8
|
+
* - All path/secret logic delegated to path-policy.ts
|
|
5
9
|
*/
|
|
6
10
|
import type { WebContainer, FileSystemTree } from "@webcontainer/api";
|
|
11
|
+
export { isSecretPath } from "./path-policy";
|
|
12
|
+
/** A file entry in a canonical snapshot — path-sorted, binary-safe. */
|
|
13
|
+
export interface CanonicalFileEntry {
|
|
14
|
+
/** Normalized absolute path (e.g. "/src/App.tsx") */
|
|
15
|
+
path: string;
|
|
16
|
+
/** File contents as a string (UTF-8 text files) */
|
|
17
|
+
content: string;
|
|
18
|
+
/** Byte size of content */
|
|
19
|
+
byteSize: number;
|
|
20
|
+
}
|
|
21
|
+
/** Result of creating a canonical snapshot. */
|
|
22
|
+
export interface CanonicalSnapshot {
|
|
23
|
+
/** Sorted file entries. */
|
|
24
|
+
files: CanonicalFileEntry[];
|
|
25
|
+
/** Total file count. */
|
|
26
|
+
fileCount: number;
|
|
27
|
+
/** Total uncompressed byte size. */
|
|
28
|
+
totalBytes: number;
|
|
29
|
+
/** SHA-256 hash of the canonical representation. */
|
|
30
|
+
treeHash: string;
|
|
31
|
+
}
|
|
32
|
+
/** A lightweight directory entry for the file explorer (no content). */
|
|
33
|
+
export interface TreeEntry {
|
|
34
|
+
name: string;
|
|
35
|
+
path: string;
|
|
36
|
+
type: "file" | "directory";
|
|
37
|
+
children?: TreeEntry[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Walk the WebContainer filesystem and return a tree structure without
|
|
41
|
+
* reading file contents. Used for file explorer display and agent context
|
|
42
|
+
* summaries where only the directory layout matters.
|
|
43
|
+
*
|
|
44
|
+
* Entries within each directory are sorted alphabetically (dirs first, then files).
|
|
45
|
+
*/
|
|
46
|
+
export declare function readTreeStructure(instance: WebContainer, basePath?: string, options?: {
|
|
47
|
+
exclude?: string[];
|
|
48
|
+
}): Promise<TreeEntry[]>;
|
|
7
49
|
export declare function readFileTree(instance: WebContainer, basePath?: string, options?: {
|
|
8
50
|
exclude?: string[];
|
|
9
51
|
}): Promise<FileSystemTree>;
|
|
52
|
+
/**
|
|
53
|
+
* Create a canonical, deterministic snapshot of the project files.
|
|
54
|
+
*
|
|
55
|
+
* - Paths are normalized and sorted lexicographically
|
|
56
|
+
* - Secret files and excluded dirs are filtered out
|
|
57
|
+
* - File count, total bytes, and per-file size are validated against caps
|
|
58
|
+
* - A SHA-256 tree hash is computed from the canonical representation
|
|
59
|
+
*
|
|
60
|
+
* @throws Error if snapshot exceeds caps
|
|
61
|
+
*/
|
|
62
|
+
export declare function createCanonicalSnapshot(instance: WebContainer, options?: {
|
|
63
|
+
exclude?: string[];
|
|
64
|
+
}): Promise<CanonicalSnapshot>;
|
|
65
|
+
/**
|
|
66
|
+
* Convert a canonical snapshot back to a FileSystemTree for mounting.
|
|
67
|
+
*/
|
|
68
|
+
export declare function snapshotToFileSystemTree(snapshot: CanonicalSnapshot): FileSystemTree;
|
|
10
69
|
export declare function serializeProject(instance: WebContainer): Promise<{
|
|
11
70
|
path: string;
|
|
12
71
|
content: string;
|
|
@@ -23,9 +82,21 @@ export declare class WriteCoalescer {
|
|
|
23
82
|
dirty: boolean;
|
|
24
83
|
private maxBufferSize;
|
|
25
84
|
private currentBufferSize;
|
|
85
|
+
private onFlush?;
|
|
86
|
+
/** Listeners notified when a file is written (path). */
|
|
87
|
+
private writeListeners;
|
|
88
|
+
/** Listeners notified when a file/dir is deleted (path). */
|
|
89
|
+
private deleteListeners;
|
|
26
90
|
constructor(instance: WebContainer, options?: {
|
|
27
91
|
maxBufferSize?: number;
|
|
92
|
+
onFlush?: () => void;
|
|
28
93
|
});
|
|
94
|
+
/** Subscribe to file write events. Returns unsubscribe function. */
|
|
95
|
+
onWrite(listener: (path: string) => void): () => void;
|
|
96
|
+
/** Subscribe to file/directory delete events. Returns unsubscribe function. */
|
|
97
|
+
onDelete(listener: (path: string) => void): () => void;
|
|
98
|
+
/** Notify listeners that a file or directory was deleted. */
|
|
99
|
+
notifyDelete(path: string): void;
|
|
29
100
|
enqueue(path: string, content: string): void;
|
|
30
101
|
write(path: string, content: string): void;
|
|
31
102
|
private scheduleFlush;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/core/filesystem.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/core/filesystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IndexedDB local snapshot cache for draft persistence.
|
|
3
|
+
*
|
|
4
|
+
* Stores canonical snapshots locally for fast recovery on page reload or
|
|
5
|
+
* crash. Completely separate from preview bridge storage/localStorage.
|
|
6
|
+
*
|
|
7
|
+
* Schema: one object store keyed by draftId, holding:
|
|
8
|
+
* - tree: FileSystemTree (serializable JSON)
|
|
9
|
+
* - treeHash: SHA-256 of canonical representation
|
|
10
|
+
* - installFingerprint: for install-skip checks
|
|
11
|
+
* - chatHistory: sanitized/capped conversation
|
|
12
|
+
* - savedAt: epoch ms timestamp
|
|
13
|
+
* - revisionId: last known server revision
|
|
14
|
+
*
|
|
15
|
+
* Eviction: snapshots older than 7 days are cleaned up on open.
|
|
16
|
+
*/
|
|
17
|
+
import type { FileSystemTree } from "@webcontainer/api";
|
|
18
|
+
import type { DraftSnapshotMeta } from "../types";
|
|
19
|
+
export interface LocalSnapshotRecord {
|
|
20
|
+
/** Primary key — the draftId */
|
|
21
|
+
draftId: string;
|
|
22
|
+
/** The file system tree (JSON-serializable) */
|
|
23
|
+
tree: FileSystemTree;
|
|
24
|
+
/** SHA-256 of the canonical snapshot */
|
|
25
|
+
treeHash?: string;
|
|
26
|
+
/** Install fingerprint for skip checks */
|
|
27
|
+
installFingerprint?: string;
|
|
28
|
+
/** Server revision (last known) */
|
|
29
|
+
revisionId?: string;
|
|
30
|
+
/** Sanitized chat history */
|
|
31
|
+
chatHistory?: unknown[];
|
|
32
|
+
/** When this snapshot was saved (epoch ms) */
|
|
33
|
+
savedAt: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Save a local snapshot for the given draft. Overwrites any existing entry.
|
|
37
|
+
*/
|
|
38
|
+
export declare function saveLocalSnapshot(draftId: string, tree: FileSystemTree, meta: DraftSnapshotMeta): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Load a local snapshot for the given draft, or null if none exists.
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadLocalSnapshot(draftId: string): Promise<LocalSnapshotRecord | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Delete the local snapshot for a draft.
|
|
45
|
+
*/
|
|
46
|
+
export declare function deleteLocalSnapshot(draftId: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a local snapshot exists that is newer than the given timestamp.
|
|
49
|
+
* `remoteSavedAt` can be an ISO 8601 string or epoch ms number.
|
|
50
|
+
*/
|
|
51
|
+
export declare function hasNewerLocalSnapshot(draftId: string, remoteSavedAt: string | number): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Get the savedAt timestamp for a local snapshot, or null.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getLocalSnapshotTimestamp(draftId: string): Promise<number | null>;
|
|
56
|
+
/**
|
|
57
|
+
* List all local draft IDs with their metadata (no tree data).
|
|
58
|
+
*/
|
|
59
|
+
export declare function listLocalSnapshots(): Promise<Array<{
|
|
60
|
+
draftId: string;
|
|
61
|
+
savedAt: number;
|
|
62
|
+
treeHash?: string;
|
|
63
|
+
}>>;
|
|
64
|
+
/**
|
|
65
|
+
* Manually trigger eviction (e.g. when storage quota is tight).
|
|
66
|
+
*/
|
|
67
|
+
export declare function evictStaleLocalSnapshots(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Clear all local snapshots. Use with caution (e.g. user-initiated reset).
|
|
70
|
+
*/
|
|
71
|
+
export declare function clearAllLocalSnapshots(): Promise<void>;
|
|
72
|
+
//# sourceMappingURL=local-snapshot-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-snapshot-cache.d.ts","sourceRoot":"","sources":["../../src/core/local-snapshot-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAelD,MAAM,WAAW,mBAAmB;IAClC,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,IAAI,EAAE,cAAc,CAAC;IACrB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;CACjB;AAmED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAGrC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAExE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,GAAG,MAAM,GAC7B,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CACjD,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAC/D,CAkBA;AAgCD;;GAEG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG9D;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5D"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared path normalization, secret classifier, and validation policy.
|
|
3
|
+
*
|
|
4
|
+
* This is the single source of truth for:
|
|
5
|
+
* - Path normalization (backslash → slash, null-byte rejection, traversal blocking)
|
|
6
|
+
* - Secret file detection (env files, keys, credentials, certificates)
|
|
7
|
+
* - Excluded directory lists (node_modules, .vite, dist, etc.)
|
|
8
|
+
* - File/snapshot size caps
|
|
9
|
+
* - Approval-required path checks for MCP tools
|
|
10
|
+
*
|
|
11
|
+
* Used by: filesystem.ts, mcp-adapter.ts, code-editor, file-explorer,
|
|
12
|
+
* draft API validation, and hydration.
|
|
13
|
+
*/
|
|
14
|
+
/** Directories excluded from tree reads, snapshots, and explorer display. */
|
|
15
|
+
export declare const EXCLUDED_DIRS: Set<string>;
|
|
16
|
+
/** Maximum number of files allowed in a snapshot. */
|
|
17
|
+
export declare const MAX_SNAPSHOT_FILES = 2000;
|
|
18
|
+
/** Maximum uncompressed snapshot size in bytes (50 MB). */
|
|
19
|
+
export declare const MAX_SNAPSHOT_BYTES: number;
|
|
20
|
+
/** Maximum single file size in bytes (5 MB). */
|
|
21
|
+
export declare const MAX_FILE_BYTES: number;
|
|
22
|
+
/** Large-file threshold for code editor (500 KB). Files above this open read-only. */
|
|
23
|
+
export declare const LARGE_FILE_THRESHOLD: number;
|
|
24
|
+
/**
|
|
25
|
+
* Normalize a path for security comparisons. Converts backslashes to forward
|
|
26
|
+
* slashes, trims whitespace, and ensures a leading `/`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function normalizePath(path: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Extract the basename (last segment) from a normalized path.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getBasename(path: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Validate and normalize a relative path from user/agent input.
|
|
35
|
+
*
|
|
36
|
+
* - Rejects empty paths, null bytes, absolute paths, and `..` traversal.
|
|
37
|
+
* - Returns a normalized absolute path (leading `/`).
|
|
38
|
+
*
|
|
39
|
+
* @throws Error on invalid paths
|
|
40
|
+
*/
|
|
41
|
+
export declare function validateAndNormalizePath(path: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Check whether a file path matches any known secret/credential pattern.
|
|
44
|
+
*
|
|
45
|
+
* @param path - Normalized absolute path (e.g. `/src/.env.local`)
|
|
46
|
+
*/
|
|
47
|
+
export declare function isSecretPath(path: string): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Validate a path for security: normalize + check secret rules.
|
|
50
|
+
* Used by MCP adapter, editor actions, and file explorer mutations.
|
|
51
|
+
*
|
|
52
|
+
* @param path - Relative path from user/agent input
|
|
53
|
+
* @returns Normalized absolute path
|
|
54
|
+
* @throws Error if path is invalid or targets a secret file
|
|
55
|
+
*/
|
|
56
|
+
export declare function sanitizePath(path: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a directory entry name should be excluded from tree walks.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isExcludedDir(name: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Check if a path segment belongs to an excluded directory.
|
|
63
|
+
*/
|
|
64
|
+
export declare function pathContainsExcludedDir(path: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Determine if a normalized path requires user approval before modification.
|
|
67
|
+
*/
|
|
68
|
+
export declare function pathRequiresApproval(path: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Check if npm args contain a blocked flag. Returns the flag if found, null otherwise.
|
|
71
|
+
*/
|
|
72
|
+
export declare function getBlockedNpmFlag(args: string[]): string | null;
|
|
73
|
+
/**
|
|
74
|
+
* Check if npm args contain shell composition characters.
|
|
75
|
+
*/
|
|
76
|
+
export declare function hasShellCompositionChars(args: string[]): boolean;
|
|
77
|
+
//# sourceMappingURL=path-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-policy.d.ts","sourceRoot":"","sources":["../../src/core/path-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,6EAA6E;AAC7E,eAAO,MAAM,aAAa,aAMxB,CAAC;AAuBH,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,2DAA2D;AAC3D,eAAO,MAAM,kBAAkB,QAAmB,CAAC;AAEnD,gDAAgD;AAChD,eAAO,MAAM,cAAc,QAAkB,CAAC;AAE9C,sFAAsF;AACtF,eAAO,MAAM,oBAAoB,QAAa,CAAC;AAM/C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA2B7D;AAMD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjD;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG7D;AA6CD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAe1D;AAkBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAgB/D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAEhE"}
|
|
@@ -41,16 +41,16 @@ export declare const BridgeResponseSchema: z.ZodObject<{
|
|
|
41
41
|
}, "strip", z.ZodTypeAny, {
|
|
42
42
|
id: string;
|
|
43
43
|
error?: string | undefined;
|
|
44
|
+
done?: boolean | undefined;
|
|
44
45
|
result?: unknown;
|
|
45
46
|
chunk?: unknown;
|
|
46
|
-
done?: boolean | undefined;
|
|
47
47
|
subscribed?: boolean | undefined;
|
|
48
48
|
}, {
|
|
49
49
|
id: string;
|
|
50
50
|
error?: string | undefined;
|
|
51
|
+
done?: boolean | undefined;
|
|
51
52
|
result?: unknown;
|
|
52
53
|
chunk?: unknown;
|
|
53
|
-
done?: boolean | undefined;
|
|
54
54
|
subscribed?: boolean | undefined;
|
|
55
55
|
}>;
|
|
56
56
|
export type BridgeResponse = z.infer<typeof BridgeResponseSchema>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyed process registry for the WebContainer IDE.
|
|
3
|
+
*
|
|
4
|
+
* Manages named process slots (install, dev-server, user-command) so that:
|
|
5
|
+
* - Duplicate launches of the same key are blocked
|
|
6
|
+
* - All process stdout/stderr is multiplexed into registered listeners
|
|
7
|
+
* - Terminal views can subscribe/unsubscribe to the output stream
|
|
8
|
+
* - Processes can be killed by key
|
|
9
|
+
*
|
|
10
|
+
* This module does NOT depend on React — it is a plain TypeScript service
|
|
11
|
+
* consumed by both the provider and terminal view.
|
|
12
|
+
*/
|
|
13
|
+
import type { WebContainer } from "@webcontainer/api";
|
|
14
|
+
/** Well-known process keys. Arbitrary string keys are also allowed. */
|
|
15
|
+
export type ProcessKey = "install" | "dev-server" | "user-command" | (string & {});
|
|
16
|
+
export interface ProcessEntry {
|
|
17
|
+
key: ProcessKey;
|
|
18
|
+
command: string;
|
|
19
|
+
args: string[];
|
|
20
|
+
/** Resolves with the exit code when the process ends. */
|
|
21
|
+
exitCode: Promise<number>;
|
|
22
|
+
/** Kill the process. */
|
|
23
|
+
kill: () => void;
|
|
24
|
+
/** Timestamp when the process was spawned. */
|
|
25
|
+
startedAt: number;
|
|
26
|
+
}
|
|
27
|
+
export type OutputListener = (key: ProcessKey, chunk: string) => void;
|
|
28
|
+
export type ProcessEventListener = (key: ProcessKey, entry: ProcessEntry | null) => void;
|
|
29
|
+
export declare class ProcessRegistry {
|
|
30
|
+
private processes;
|
|
31
|
+
private outputListeners;
|
|
32
|
+
private processEventListeners;
|
|
33
|
+
private instance;
|
|
34
|
+
constructor(instance: WebContainer);
|
|
35
|
+
/** Check if a process is currently running under the given key. */
|
|
36
|
+
isRunning(key: ProcessKey): boolean;
|
|
37
|
+
/** Get the entry for a running process, or null. */
|
|
38
|
+
get(key: ProcessKey): ProcessEntry | null;
|
|
39
|
+
/** Get all currently running process entries. */
|
|
40
|
+
getAll(): ProcessEntry[];
|
|
41
|
+
/**
|
|
42
|
+
* Spawn a process under a keyed slot. If the key is already occupied,
|
|
43
|
+
* throws an error instead of spawning a duplicate.
|
|
44
|
+
*
|
|
45
|
+
* @param key - Unique slot key (e.g. "dev-server")
|
|
46
|
+
* @param command - Command to run (e.g. "npm")
|
|
47
|
+
* @param args - Arguments (e.g. ["run", "dev"])
|
|
48
|
+
* @param options.timeout - Kill after this many ms (0 = no timeout)
|
|
49
|
+
* @param options.maxOutput - Kill if output exceeds this many bytes (default 2MB)
|
|
50
|
+
* @returns The process entry
|
|
51
|
+
*/
|
|
52
|
+
spawn(key: ProcessKey, command: string, args: string[], options?: {
|
|
53
|
+
timeout?: number;
|
|
54
|
+
maxOutput?: number;
|
|
55
|
+
}): Promise<ProcessEntry>;
|
|
56
|
+
/** Kill a process by key. No-op if not running. */
|
|
57
|
+
kill(key: ProcessKey): void;
|
|
58
|
+
/** Kill all running processes. */
|
|
59
|
+
killAll(): void;
|
|
60
|
+
/** Subscribe to multiplexed output from all processes. */
|
|
61
|
+
onOutput(listener: OutputListener): () => void;
|
|
62
|
+
/** Subscribe to process start/stop events. */
|
|
63
|
+
onProcessEvent(listener: ProcessEventListener): () => void;
|
|
64
|
+
/** Write arbitrary text to the output stream (e.g. for system messages). */
|
|
65
|
+
writeSystemMessage(message: string): void;
|
|
66
|
+
private emitOutput;
|
|
67
|
+
private emitProcessEvent;
|
|
68
|
+
/** Tear down the registry. Kills all processes and clears listeners. */
|
|
69
|
+
destroy(): void;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=process-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-registry.d.ts","sourceRoot":"","sources":["../../src/core/process-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAMtD,uEAAuE;AACvE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,cAAc,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEnF,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,UAAU,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,wBAAwB;IACxB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AACtE,MAAM,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,KAAK,IAAI,CAAC;AAMzF,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,qBAAqB,CAAmC;IAChE,OAAO,CAAC,QAAQ,CAAe;gBAEnB,QAAQ,EAAE,YAAY;IAQlC,mEAAmE;IACnE,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAInC,oDAAoD;IACpD,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI;IAIzC,iDAAiD;IACjD,MAAM,IAAI,YAAY,EAAE;IAQxB;;;;;;;;;;OAUG;IACG,KAAK,CACT,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GACjD,OAAO,CAAC,YAAY,CAAC;IA2GxB,mDAAmD;IACnD,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAO3B,kCAAkC;IAClC,OAAO,IAAI,IAAI;IAUf,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI;IAO9C,8CAA8C;IAC9C,cAAc,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAO1D,4EAA4E;IAC5E,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQzC,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,gBAAgB;IAUxB,wEAAwE;IACxE,OAAO,IAAI,IAAI;CAKhB"}
|
package/dist/core/process.d.ts
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* WebContainer process spawning with output buffering and timeout control.
|
|
3
3
|
*/
|
|
4
4
|
import type { WebContainer } from "@webcontainer/api";
|
|
5
|
+
export declare class DevServerStartupError extends Error {
|
|
6
|
+
output: string;
|
|
7
|
+
constructor(message: string, output: string);
|
|
8
|
+
}
|
|
5
9
|
export interface ProcessResult {
|
|
6
10
|
exitCode: Promise<number>;
|
|
7
11
|
kill: () => void;
|
|
@@ -12,6 +16,7 @@ export declare function spawnWithOutput(instance: WebContainer, command: string,
|
|
|
12
16
|
}): Promise<ProcessResult>;
|
|
13
17
|
export declare function spawnDevServer(instance: WebContainer, options?: {
|
|
14
18
|
onOutput?: (chunk: string) => void;
|
|
19
|
+
timeout?: number;
|
|
15
20
|
}): Promise<{
|
|
16
21
|
url: Promise<string>;
|
|
17
22
|
kill: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/core/process.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,OAAO,CAAC,aAAa,CAAC,CA2ExB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,YAAY,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE;;;;
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/core/process.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,MAAM,EAAE,MAAM,CAAC;gBAEH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,OAAO,CAAC,aAAa,CAAC,CA2ExB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,YAAY,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;;;;GAoEnE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Writes the pre-rendered skill files to .vibe/skills/ in the WebContainer.
|
|
3
|
+
*
|
|
4
|
+
* Called during the boot sequence, after the template is mounted. The skills
|
|
5
|
+
* are markdown reference guides that the Direct LLM agent can load on demand
|
|
6
|
+
* via the read_file tool.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import type { WebContainer } from "@webcontainer/api";
|
|
11
|
+
/**
|
|
12
|
+
* Write all skill files to `.vibe/skills/` in the given WebContainer.
|
|
13
|
+
*
|
|
14
|
+
* This is safe to call multiple times — files are overwritten if they exist.
|
|
15
|
+
* The `.vibe/` directory is excluded from project snapshots by path policy.
|
|
16
|
+
*/
|
|
17
|
+
export declare function writeSkillFiles(instance: WebContainer): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=write-skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-skills.d.ts","sourceRoot":"","sources":["../../src/core/write-skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3E"}
|
package/dist/ide-theme.css
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
/* Accent — tertiary gold/amber from design tokens */
|
|
25
25
|
--ide-accent: oklch(0.8544 0.1746 90.88);
|
|
26
|
-
--ide-accent-soft: rgba(234, 179, 8, 0.
|
|
26
|
+
--ide-accent-soft: rgba(234, 179, 8, 0.1);
|
|
27
27
|
--ide-accent-hover: oklch(0.9 0.16 90.88);
|
|
28
28
|
--ide-accent-muted: oklch(0.7 0.14 90.88);
|
|
29
29
|
|
|
@@ -229,6 +229,21 @@
|
|
|
229
229
|
border-color: var(--ide-accent);
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
+
/* ── Starter Prompt Pill ────────────────────────────────── */
|
|
233
|
+
.ide-starter-prompt {
|
|
234
|
+
background: var(--ide-surface);
|
|
235
|
+
color: var(--ide-text-secondary);
|
|
236
|
+
border: 1px solid var(--ide-border);
|
|
237
|
+
transition-property: color, border-color, transform;
|
|
238
|
+
transition-duration: 150ms;
|
|
239
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.ide-starter-prompt:hover {
|
|
243
|
+
border-color: var(--ide-accent);
|
|
244
|
+
color: var(--ide-accent);
|
|
245
|
+
}
|
|
246
|
+
|
|
232
247
|
/* ── Reduce motion ─────────────────────────────────────── */
|
|
233
248
|
@media (prefers-reduced-motion: reduce) {
|
|
234
249
|
.ide-spinner {
|
|
@@ -246,3 +261,33 @@
|
|
|
246
261
|
transition-duration: 0ms;
|
|
247
262
|
}
|
|
248
263
|
}
|
|
264
|
+
|
|
265
|
+
/* Fix Tailwind conflicting with Monaco Editor */
|
|
266
|
+
.monaco-editor textarea.inputarea {
|
|
267
|
+
resize: none !important;
|
|
268
|
+
border: none !important;
|
|
269
|
+
outline: none !important;
|
|
270
|
+
box-shadow: none !important;
|
|
271
|
+
background: transparent !important;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* Fix Tailwind conflicting with xterm.js helper textarea */
|
|
275
|
+
.xterm-helper-textarea {
|
|
276
|
+
position: absolute !important;
|
|
277
|
+
opacity: 0 !important;
|
|
278
|
+
left: -9999em !important;
|
|
279
|
+
top: 0 !important;
|
|
280
|
+
width: 0 !important;
|
|
281
|
+
height: 0 !important;
|
|
282
|
+
z-index: -5 !important;
|
|
283
|
+
overflow: hidden !important;
|
|
284
|
+
resize: none !important;
|
|
285
|
+
border: none !important;
|
|
286
|
+
outline: none !important;
|
|
287
|
+
box-shadow: none !important;
|
|
288
|
+
padding: 0 !important;
|
|
289
|
+
}
|
|
290
|
+
.monaco-editor .slider {
|
|
291
|
+
border: none !important;
|
|
292
|
+
outline: none !important;
|
|
293
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,19 +5,25 @@
|
|
|
5
5
|
* consumers need: types, core runtime, MCP layer, template generation,
|
|
6
6
|
* and React components/hooks.
|
|
7
7
|
*/
|
|
8
|
-
export type { TemplateId, TemplateVars, RightPaneTab, UnifiedMessageStatus, UnifiedConnectionStatus, UnifiedArtifact, UnifiedStatusUpdate, UnifiedToolInvocation, UnifiedMessage, VibeIdeChatAdapter, VibeIdePreviewPolicy, VibeIdePersistenceAdapter, VibeIdeApprovalAdapter, WebContainerMcpAdapterOptions, VibeIdeBootOptions, VibeIdeProviderProps, VibeIdeSplitLayoutProps, VibeIdeContextValue, } from "./types";
|
|
8
|
+
export type { TemplateId, TemplateVars, RightPaneTab, UnifiedMessageStatus, UnifiedConnectionStatus, UnifiedArtifact, UnifiedStatusUpdate, UnifiedToolInvocation, UnifiedAttachment, UnifiedMessage, VibeIdeChatAdapter, VibeIdePreviewPolicy, VibeIdePersistenceAdapter, DraftSnapshotMeta, VibeIdeApprovalAdapter, WebContainerMcpAdapterOptions, VibeIdeBootOptions, VibeIdeProviderProps, VibeIdeSplitLayoutProps, VibeIdeContextValue, } from "./types";
|
|
9
9
|
export { bootWebContainer, teardownWebContainer, getWebContainer, WebContainerTabBlockedError, } from "./core/boot";
|
|
10
|
-
export { readFileTree, serializeProject, writeFileTree, WriteCoalescer, } from "./core/filesystem";
|
|
10
|
+
export { readFileTree, readTreeStructure, serializeProject, createCanonicalSnapshot, snapshotToFileSystemTree, writeFileTree, WriteCoalescer, type CanonicalFileEntry, type CanonicalSnapshot, type TreeEntry, } from "./core/filesystem";
|
|
11
11
|
export { spawnWithOutput, spawnDevServer, type ProcessResult, } from "./core/process";
|
|
12
|
+
export { ProcessRegistry, type ProcessKey, type ProcessEntry, type OutputListener, type ProcessEventListener, } from "./core/process-registry";
|
|
13
|
+
export { normalizePath, getBasename, validateAndNormalizePath, isSecretPath, sanitizePath, isExcludedDir, pathContainsExcludedDir, pathRequiresApproval, getBlockedNpmFlag, hasShellCompositionChars, EXCLUDED_DIRS, MAX_SNAPSHOT_FILES, MAX_SNAPSHOT_BYTES, MAX_FILE_BYTES, LARGE_FILE_THRESHOLD, } from "./core/path-policy";
|
|
12
14
|
export { installDependencies, computeInstallFingerprint, } from "./core/install";
|
|
15
|
+
export { saveLocalSnapshot, loadLocalSnapshot, deleteLocalSnapshot, hasNewerLocalSnapshot, getLocalSnapshotTimestamp, listLocalSnapshots, evictStaleLocalSnapshots, clearAllLocalSnapshots, type LocalSnapshotRecord, } from "./core/local-snapshot-cache";
|
|
13
16
|
export { createPreviewChannel, createRequestHandler, BridgeCapabilitySchema, BridgeRequestSchema, BridgeResponseSchema, type IframeRef, type BridgeCapability, type BridgeRequest, type BridgeResponse, type StreamingContext, type CapabilityHandler, } from "./core/preview-channel";
|
|
14
17
|
export { BRIDGE_DEV_SHIM_SOURCE } from "./core/bridge-shim";
|
|
15
18
|
export { injectDevShim } from "./core/inject-shim";
|
|
16
19
|
export { webContainerToolArgumentSchemas, WebContainerToolSchema, webContainerToolsDefinition, type WebContainerToolCall, } from "./mcp/mcp-tools";
|
|
17
20
|
export { WebContainerMcpAdapter, createWebContainerMcpAdapter, } from "./mcp/mcp-adapter";
|
|
18
21
|
export { getVibeIdeTemplateTree } from "./templates/generated";
|
|
22
|
+
export { generateCoreRules } from "./prompts/core-rules";
|
|
23
|
+
export { getSkillFiles, getSkillsMeta, getSkillContent, type SkillFileEntry, type SkillMeta, type SkillEntry, } from "./prompts/skills";
|
|
19
24
|
export { VibeIdeProvider } from "./react/provider";
|
|
20
25
|
export { useVibeIde } from "./react/use-vibe-ide";
|
|
26
|
+
export { useAutosave, type AutosaveState, type UseAutosaveOptions, type RemoteSaveStatus } from "./react/use-autosave";
|
|
21
27
|
export { VibeIdeSplitLayout } from "./react/vibe-ide-layout";
|
|
22
28
|
export { VibeIdePreviewPane } from "./react/vibe-ide-preview-pane";
|
|
23
29
|
export { VibeIdeToolbar } from "./react/vibe-ide-toolbar";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,YAAY,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,6BAA6B,EAC7B,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAMjB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,eAAe,EACf,cAAc,EACd,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMnD,OAAO,EACL,+BAA+B,EAC/B,sBAAsB,EACtB,2BAA2B,EAC3B,KAAK,oBAAoB,GAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAM/D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|