lua-cli 3.15.1 → 3.15.3
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/api/skills.api.service.d.ts +8 -0
- package/dist/api/skills.api.service.d.ts.map +1 -1
- package/dist/api/skills.api.service.js +8 -0
- package/dist/api/skills.api.service.js.map +1 -1
- package/dist/cli/command-definitions.d.ts.map +1 -1
- package/dist/cli/command-definitions.js +8 -0
- package/dist/cli/command-definitions.js.map +1 -1
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +13 -6
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/push.d.ts +12 -0
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +125 -8
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/source.d.ts.map +1 -1
- package/dist/commands/source.js +17 -7
- package/dist/commands/source.js.map +1 -1
- package/dist/compiler/plugins/agent.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/agent.plugin.js +2 -0
- package/dist/compiler/plugins/agent.plugin.js.map +1 -1
- package/dist/compiler/utils/common.d.ts +3 -19
- package/dist/compiler/utils/common.d.ts.map +1 -1
- package/dist/compiler/utils/common.js +8 -47
- package/dist/compiler/utils/common.js.map +1 -1
- package/dist/interfaces/backup.d.ts +6 -132
- package/dist/interfaces/backup.d.ts.map +1 -1
- package/dist/interfaces/backup.js +3 -4
- package/dist/interfaces/backup.js.map +1 -1
- package/dist/utils/backup-helpers.d.ts +6 -58
- package/dist/utils/backup-helpers.d.ts.map +1 -1
- package/dist/utils/backup-helpers.js +35 -158
- package/dist/utils/backup-helpers.js.map +1 -1
- package/dist/utils/build-manifest-from-disk.d.ts +3 -12
- package/dist/utils/build-manifest-from-disk.d.ts.map +1 -1
- package/dist/utils/build-manifest-from-disk.js +10 -100
- package/dist/utils/build-manifest-from-disk.js.map +1 -1
- package/node_modules/@lua/shared-source-sync/dist/index.d.mts +424 -0
- package/node_modules/@lua/shared-source-sync/dist/index.d.ts +424 -0
- package/node_modules/@lua/shared-source-sync/dist/index.js +536 -0
- package/node_modules/@lua/shared-source-sync/dist/index.mjs +491 -0
- package/node_modules/@lua/shared-source-sync/package.json +26 -0
- package/node_modules/@lua/shared-source-sync/src/archive.ts +98 -0
- package/node_modules/@lua/shared-source-sync/src/filter.ts +72 -0
- package/node_modules/@lua/shared-source-sync/src/hash.ts +40 -0
- package/node_modules/@lua/shared-source-sync/src/http.ts +132 -0
- package/node_modules/@lua/shared-source-sync/src/index.ts +56 -0
- package/node_modules/@lua/shared-source-sync/src/pull.ts +50 -0
- package/node_modules/@lua/shared-source-sync/src/push.ts +94 -0
- package/node_modules/@lua/shared-source-sync/src/restore.ts +83 -0
- package/node_modules/@lua/shared-source-sync/src/skill-source.ts +55 -0
- package/node_modules/@lua/shared-source-sync/src/transfer.ts +92 -0
- package/node_modules/@lua/shared-source-sync/src/types.ts +88 -0
- package/node_modules/@lua/shared-source-sync/src/walk.ts +91 -0
- package/node_modules/@lua/shared-source-sync/tests/archive.test.ts +108 -0
- package/node_modules/@lua/shared-source-sync/tests/hash.test.ts +40 -0
- package/node_modules/@lua/shared-source-sync/tests/http.test.ts +77 -0
- package/node_modules/@lua/shared-source-sync/tests/push.test.ts +162 -0
- package/node_modules/@lua/shared-source-sync/tests/walk.test.ts +84 -0
- package/node_modules/@lua/shared-source-sync/tsconfig.json +12 -0
- package/node_modules/@lua/shared-source-sync/tsup.config.ts +9 -0
- package/node_modules/@lua/shared-source-sync/vitest.config.ts +8 -0
- package/node_modules/@lua/shared-types/dist/index.d.mts +27 -0
- package/node_modules/@lua/shared-types/dist/index.d.ts +27 -0
- package/node_modules/@lua/shared-types/src/agent-config.types.ts +14 -0
- package/node_modules/@lua/shared-types/src/chat-stream.types.ts +7 -0
- package/node_modules/@lua/shared-types/src/model-registry.ts +6 -0
- package/package.json +3 -1
- package/template/package.json +1 -1
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types for the agent project backup feature.
|
|
3
|
+
*
|
|
4
|
+
* These mirror `packages/lua-cli/src/interfaces/backup.ts` byte-for-byte so the
|
|
5
|
+
* CLI and any server-side caller speak the same protocol against the existing
|
|
6
|
+
* `/developer/agents/:agentId/backup/*` endpoints on lua-api.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* A single file entry in the backup manifest. Carries no content — content is
|
|
10
|
+
* stored as a blob in S3 under `backups/blobs/<hash>` and dereferenced at
|
|
11
|
+
* restore time.
|
|
12
|
+
*/
|
|
13
|
+
interface BackupFileRef {
|
|
14
|
+
/**
|
|
15
|
+
* Path used both as identifier and as on-disk restore location.
|
|
16
|
+
* - In-project: relative to the agent's project root (e.g. `src/index.ts`).
|
|
17
|
+
* - External (monorepo cross-root): relative to the workspace root; restored
|
|
18
|
+
* under `.lua/external/<relativePath>` (see BAC-69).
|
|
19
|
+
*/
|
|
20
|
+
relativePath: string;
|
|
21
|
+
/** Truncated SHA-256 (16 hex chars) of the file's raw bytes. Used as the S3 key. */
|
|
22
|
+
hash: string;
|
|
23
|
+
/** Original (uncompressed) byte size. */
|
|
24
|
+
size: number;
|
|
25
|
+
/** Coarse classification for telemetry and UI grouping. */
|
|
26
|
+
type: 'source' | 'config' | 'other';
|
|
27
|
+
/** Defaults to in-project when absent. Cross-root files set this `true`. */
|
|
28
|
+
external?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Body of `POST /developer/agents/:agentId/backup/check-blobs`. */
|
|
31
|
+
interface CheckBlobsRequest {
|
|
32
|
+
hashes: string[];
|
|
33
|
+
}
|
|
34
|
+
/** Response shape from `check-blobs`. */
|
|
35
|
+
interface CheckBlobsResponse {
|
|
36
|
+
missing: string[];
|
|
37
|
+
existing: string[];
|
|
38
|
+
results: Record<string, boolean>;
|
|
39
|
+
}
|
|
40
|
+
/** Body of `POST /developer/agents/:agentId/backup/blob-upload-urls` and `.../blob-urls`. */
|
|
41
|
+
interface GetBlobUrlsRequest {
|
|
42
|
+
hashes: string[];
|
|
43
|
+
}
|
|
44
|
+
/** Response shape: `{ urls: { <hash>: <presignedUrl> }, expiresIn: <seconds> }`. */
|
|
45
|
+
interface GetBlobUrlsResponse {
|
|
46
|
+
urls: Record<string, string>;
|
|
47
|
+
expiresIn: number;
|
|
48
|
+
}
|
|
49
|
+
/** Body of `POST /developer/agents/:agentId/backup/manifest`. */
|
|
50
|
+
interface SaveManifestRequest {
|
|
51
|
+
projectHash: string;
|
|
52
|
+
files: BackupFileRef[];
|
|
53
|
+
version?: string;
|
|
54
|
+
createdBy?: string;
|
|
55
|
+
orgId?: string;
|
|
56
|
+
triggeredBy?: string;
|
|
57
|
+
}
|
|
58
|
+
/** Metadata returned by `GET /developer/agents/:agentId/backup`. */
|
|
59
|
+
interface BackupMetadata {
|
|
60
|
+
agentId: string;
|
|
61
|
+
orgId: string;
|
|
62
|
+
projectHash: string;
|
|
63
|
+
fileCount: number;
|
|
64
|
+
totalSize: number;
|
|
65
|
+
version?: string;
|
|
66
|
+
createdBy: string;
|
|
67
|
+
createdAt: string;
|
|
68
|
+
/** Monotonic manifest version assigned by the V2 server path. */
|
|
69
|
+
activeVersion?: number;
|
|
70
|
+
}
|
|
71
|
+
/** Full response from `GET /developer/agents/:agentId/backup/manifest`. */
|
|
72
|
+
interface BackupManifest extends BackupMetadata {
|
|
73
|
+
files: BackupFileRef[];
|
|
74
|
+
}
|
|
75
|
+
/** Response from `GET /developer/agents/:agentId/backup/check/:hash`. */
|
|
76
|
+
interface BackupExistsResponse {
|
|
77
|
+
exists: boolean;
|
|
78
|
+
currentHash?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Hashing primitives.
|
|
83
|
+
*
|
|
84
|
+
* Wire-format note: the rest of the Lua platform (compiler, CLI cache, server
|
|
85
|
+
* blob keys) uses the FIRST 16 HEX CHARS of SHA-256 as the file hash. This
|
|
86
|
+
* truncation is part of the protocol — full 64-char digests would be
|
|
87
|
+
* incompatible with the existing S3 layout and dedup. `hashContentTruncated`
|
|
88
|
+
* is the canonical helper; callers should not roll their own.
|
|
89
|
+
*/
|
|
90
|
+
/** Default truncation length used across the Lua platform. */
|
|
91
|
+
declare const FILE_HASH_LENGTH = 16;
|
|
92
|
+
/** Hash file content with the canonical 16-char truncated SHA-256. */
|
|
93
|
+
declare function hashContentTruncated(content: string | Buffer): string;
|
|
94
|
+
/** Full-length SHA-256 hex; used only for the combined project hash. */
|
|
95
|
+
declare function sha256Hex(content: string | Buffer): string;
|
|
96
|
+
/**
|
|
97
|
+
* Deterministic project hash: full-length SHA-256 over the sorted list of
|
|
98
|
+
* per-file hashes joined by `|`. Matches `calculateProjectHash` in
|
|
99
|
+
* `packages/lua-cli/src/utils/backup-helpers.ts` byte-for-byte so cross-tool
|
|
100
|
+
* pushes do not produce spurious drift.
|
|
101
|
+
*/
|
|
102
|
+
declare function combineFileHashes(files: {
|
|
103
|
+
relativePath: string;
|
|
104
|
+
hash: string;
|
|
105
|
+
}[]): string;
|
|
106
|
+
|
|
107
|
+
declare const DEFAULT_MAX_FILE_BYTES: number;
|
|
108
|
+
declare function shouldSkipDirectory(name: string): boolean;
|
|
109
|
+
declare function shouldSkipFile(filePathOrName: string): boolean;
|
|
110
|
+
declare function classifyFile(relPath: string): 'source' | 'config' | 'other';
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Walk an agent workspace from disk and produce a fresh manifest. Used by
|
|
114
|
+
* both the CLI (via `buildManifestFromDisk`) and server-side callers
|
|
115
|
+
* (`SourceSyncService`).
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
interface WalkOptions {
|
|
119
|
+
/** Per-file size cap. Files larger than this are skipped (default 256KB). */
|
|
120
|
+
maxFileBytes?: number;
|
|
121
|
+
}
|
|
122
|
+
interface WalkResult {
|
|
123
|
+
/** Sorted file references suitable for a backup manifest. */
|
|
124
|
+
files: BackupFileRef[];
|
|
125
|
+
/** Deterministic combined hash over the file set. */
|
|
126
|
+
projectHash: string;
|
|
127
|
+
/** Sum of original file sizes. */
|
|
128
|
+
totalSize: number;
|
|
129
|
+
/**
|
|
130
|
+
* Raw file content keyed by truncated hash. Caller uses this for the upload
|
|
131
|
+
* step instead of re-reading from disk. First-write-wins on collision so
|
|
132
|
+
* dedup is honored.
|
|
133
|
+
*/
|
|
134
|
+
contentByHash: Map<string, Buffer>;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Walk `rootDir` and return a stable workspace snapshot. 16-char truncated
|
|
138
|
+
* SHA-256 hashes; path separators normalized to `/` for OS-independent
|
|
139
|
+
* manifest round-trip.
|
|
140
|
+
*/
|
|
141
|
+
declare function walkWorkspace(rootDir: string, opts?: WalkOptions): WalkResult;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* HTTP client for the `/developer/agents/:agentId/backup/*` endpoints on lua-api.
|
|
145
|
+
*
|
|
146
|
+
* Authentication is opaque to this module — the caller injects an
|
|
147
|
+
* `Authorization` header value. lua-cli uses a Bearer API key; server-side
|
|
148
|
+
* callers (`lua-claude-builder`) use a scoped service token.
|
|
149
|
+
*
|
|
150
|
+
* Errors surface as `BackupHttpError` instances with status code attached so
|
|
151
|
+
* the caller can distinguish auth (`401/403`) from transport vs CAS-conflict
|
|
152
|
+
* (`409`) failures.
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
/** Minimal `fetch` contract — Node 18+, browser, or a test stub. */
|
|
156
|
+
type FetchLike = typeof fetch;
|
|
157
|
+
declare class BackupHttpError extends Error {
|
|
158
|
+
readonly status: number;
|
|
159
|
+
readonly endpoint: string;
|
|
160
|
+
readonly body?: string;
|
|
161
|
+
constructor(message: string, status: number, endpoint: string, body?: string);
|
|
162
|
+
}
|
|
163
|
+
interface BackupHttpClientOptions {
|
|
164
|
+
/** Base URL for lua-api (e.g. `https://api.heylua.ai`). No trailing slash. */
|
|
165
|
+
baseUrl: string;
|
|
166
|
+
/** Full `Authorization` header value, e.g. `Bearer <apiKey>`. */
|
|
167
|
+
authHeader: string;
|
|
168
|
+
/** Target agent id. Embedded into every path. */
|
|
169
|
+
agentId: string;
|
|
170
|
+
/** Override the global `fetch` (tests inject a mock). */
|
|
171
|
+
fetch?: FetchLike;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Thin wrapper around the backup endpoints. All methods return the parsed
|
|
175
|
+
* JSON body on `2xx` and throw `BackupHttpError` otherwise — by design this
|
|
176
|
+
* pushes branching (e.g. "no backup yet → 404") into the caller, where the
|
|
177
|
+
* intent is clearer than a discriminated success/error wrapper.
|
|
178
|
+
*/
|
|
179
|
+
declare class BackupHttpClient {
|
|
180
|
+
private readonly options;
|
|
181
|
+
private readonly fetchFn;
|
|
182
|
+
constructor(options: BackupHttpClientOptions);
|
|
183
|
+
private url;
|
|
184
|
+
private json;
|
|
185
|
+
/** `POST /backup/check-blobs` — returns existing vs missing partition. */
|
|
186
|
+
checkBlobsExist(hashes: string[]): Promise<CheckBlobsResponse>;
|
|
187
|
+
/** `POST /backup/blob-upload-urls` — presigned S3 PUT URLs. */
|
|
188
|
+
getBlobUploadUrls(hashes: string[]): Promise<GetBlobUrlsResponse>;
|
|
189
|
+
/** `POST /backup/blob-urls` — presigned S3 GET URLs (for restore). */
|
|
190
|
+
getBlobUrls(hashes: string[]): Promise<GetBlobUrlsResponse>;
|
|
191
|
+
/** `POST /backup/manifest` — final step in a push; returns server metadata. */
|
|
192
|
+
saveManifest(data: SaveManifestRequest): Promise<BackupMetadata>;
|
|
193
|
+
/** `GET /backup` — metadata only, no file list. */
|
|
194
|
+
getMetadata(): Promise<BackupMetadata>;
|
|
195
|
+
/** `GET /backup/manifest` — metadata + file list. */
|
|
196
|
+
getManifest(): Promise<BackupManifest>;
|
|
197
|
+
/** `GET /backup/check/:hash` — fast freshness probe. */
|
|
198
|
+
checkBackupExists(hash: string): Promise<BackupExistsResponse>;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* S3 transfer primitives: gzip-compressed blob upload and download.
|
|
203
|
+
*
|
|
204
|
+
* Content is always gzipped before upload (matches the CLI convention) and
|
|
205
|
+
* decompressed transparently on download (magic-byte sniff with raw fallback
|
|
206
|
+
* for legacy/uncompressed blobs that may still exist).
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* PUT each blob to its presigned URL. Caller supplies a map of `hash → URL`
|
|
211
|
+
* (from `BackupHttpClient.getBlobUploadUrls`) plus a map of `hash → content`.
|
|
212
|
+
* Returns the count of blobs that landed in S3.
|
|
213
|
+
*/
|
|
214
|
+
declare function uploadBlobs(opts: {
|
|
215
|
+
uploadUrls: Record<string, string>;
|
|
216
|
+
contentByHash: Map<string, Buffer>;
|
|
217
|
+
fetch?: FetchLike;
|
|
218
|
+
concurrency?: number;
|
|
219
|
+
}): Promise<number>;
|
|
220
|
+
/**
|
|
221
|
+
* GET each blob from its presigned URL and return `hash → buffer`. Detects
|
|
222
|
+
* gzip via magic bytes (1f 8b) and gracefully falls back to the raw response
|
|
223
|
+
* body for any legacy uncompressed blobs.
|
|
224
|
+
*/
|
|
225
|
+
declare function downloadBlobs(opts: {
|
|
226
|
+
urls: Record<string, string>;
|
|
227
|
+
fetch?: FetchLike;
|
|
228
|
+
concurrency?: number;
|
|
229
|
+
}): Promise<Map<string, Buffer>>;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Restore primitives: write a downloaded blob map back to disk.
|
|
233
|
+
*
|
|
234
|
+
* Mirrors `restoreProjectFromBackup` + `resolveBackupFileTarget` in
|
|
235
|
+
* `packages/lua-cli/src/utils/backup-helpers.ts`. The sandbox rule for
|
|
236
|
+
* `external: true` entries is preserved: they land under
|
|
237
|
+
* `<targetDir>/.lua/external/<workspaceRelativePath>` rather than being
|
|
238
|
+
* written back to their original workspace location.
|
|
239
|
+
*/
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Compute the disk path where a manifest entry should land during restore.
|
|
243
|
+
*
|
|
244
|
+
* Throws if the result would escape `targetDir` — a malicious manifest with
|
|
245
|
+
* `../` segments must not be allowed to overwrite arbitrary files.
|
|
246
|
+
*/
|
|
247
|
+
declare function resolveBackupFileTarget(file: BackupFileRef, targetDir: string): string;
|
|
248
|
+
interface RestoreOptions {
|
|
249
|
+
/** Overwrite existing files. Defaults to `false` — collision-safe. */
|
|
250
|
+
overwrite?: boolean;
|
|
251
|
+
}
|
|
252
|
+
interface RestoreResult {
|
|
253
|
+
filesWritten: number;
|
|
254
|
+
filesUnchanged: number;
|
|
255
|
+
filesSkipped: number;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Materialize a manifest's files into `targetDir`. Skips writes when the
|
|
259
|
+
* on-disk bytes already match the blob (so callers can distinguish "9 files
|
|
260
|
+
* restored" from "9 files matched, 0 written") and respects `overwrite=false`
|
|
261
|
+
* to avoid clobbering edits the user hasn't yet pushed.
|
|
262
|
+
*/
|
|
263
|
+
declare function restoreFromBlobs(manifest: BackupManifest, blobs: Map<string, Buffer>, targetDir: string, opts?: RestoreOptions): RestoreResult;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* High-level "push the contents of `workspaceDir` to the per-agent backup".
|
|
267
|
+
*
|
|
268
|
+
* This is the algorithm shared between `lua-cli`'s `lua push backup` and the
|
|
269
|
+
* `lua-claude-builder` `SourceSyncService`. Pure (no console output, no
|
|
270
|
+
* filesystem mutation outside of reading `workspaceDir`, no telemetry — the
|
|
271
|
+
* caller layers those concerns on top).
|
|
272
|
+
*/
|
|
273
|
+
|
|
274
|
+
interface PushAgentBackupOptions {
|
|
275
|
+
/** HTTP client config — the helper constructs the client internally. */
|
|
276
|
+
http: BackupHttpClientOptions;
|
|
277
|
+
/** Workspace root. Walked recursively with the standard skip rules. */
|
|
278
|
+
workspaceDir: string;
|
|
279
|
+
/** Org id (forwarded to the saveManifest body so the server can skip a lookup). */
|
|
280
|
+
orgId: string;
|
|
281
|
+
/** Semver of the deployed primitive when known. */
|
|
282
|
+
version?: string;
|
|
283
|
+
/** Audit label, e.g. `'admin-tool-builder'` or `'manual lua push backup'`. */
|
|
284
|
+
triggeredBy?: string;
|
|
285
|
+
/** Provenance label for the manifest record. Defaults to `'cli'` to match historical behavior. */
|
|
286
|
+
createdBy?: string;
|
|
287
|
+
/** Tuning knobs for the walk. */
|
|
288
|
+
walkOptions?: WalkOptions;
|
|
289
|
+
/** Tuning knob for the parallel S3 PUTs. */
|
|
290
|
+
concurrency?: number;
|
|
291
|
+
}
|
|
292
|
+
interface PushAgentBackupResult {
|
|
293
|
+
/** Combined project hash that was pushed. */
|
|
294
|
+
projectHash: string;
|
|
295
|
+
/** Number of files described by the manifest (post-dedupe by path). */
|
|
296
|
+
fileCount: number;
|
|
297
|
+
/** Number of blobs the helper actually PUT to S3 (deduped against existing). */
|
|
298
|
+
filesUploaded: number;
|
|
299
|
+
/** Server-assigned monotonic version, when the V2 manifest path returned one. */
|
|
300
|
+
activeVersion?: number;
|
|
301
|
+
/** Full server metadata response for the saveManifest call. */
|
|
302
|
+
metadata: BackupMetadata;
|
|
303
|
+
/** The manifest file refs in the order they were sent. */
|
|
304
|
+
files: BackupFileRef[];
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Walk the workspace, upload missing blobs, save the manifest, return the
|
|
308
|
+
* server's response. Throws on any non-2xx — callers decide how to react.
|
|
309
|
+
*
|
|
310
|
+
* Idempotent by design: the algorithm is content-addressed, so re-running the
|
|
311
|
+
* push for the same workspace state is a no-op aside from the manifest write
|
|
312
|
+
* (which the server treats as either equal-to-current or a new version).
|
|
313
|
+
*/
|
|
314
|
+
declare function pushAgentBackup(opts: PushAgentBackupOptions): Promise<PushAgentBackupResult>;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* High-level "pull the per-agent backup into `targetDir`".
|
|
318
|
+
*
|
|
319
|
+
* Counterpart to `pushAgentBackup`. Today only the CLI calls this; the
|
|
320
|
+
* shared package exposes it so future server-side features (e.g. "rehydrate
|
|
321
|
+
* Builder workspace from the latest CLI push") can reuse the same logic.
|
|
322
|
+
*/
|
|
323
|
+
|
|
324
|
+
interface PullAgentBackupOptions {
|
|
325
|
+
http: BackupHttpClientOptions;
|
|
326
|
+
/** Destination on disk. Will be created if necessary. */
|
|
327
|
+
targetDir: string;
|
|
328
|
+
/** Restore options (overwrite policy). */
|
|
329
|
+
restore?: RestoreOptions;
|
|
330
|
+
/** Tuning knob for the parallel S3 GETs. */
|
|
331
|
+
concurrency?: number;
|
|
332
|
+
}
|
|
333
|
+
interface PullAgentBackupResult extends RestoreResult {
|
|
334
|
+
manifest: BackupManifest;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Fetch the manifest, download every referenced blob, write to disk. Returns
|
|
338
|
+
* the manifest plus a tally of write/no-op/skip outcomes.
|
|
339
|
+
*
|
|
340
|
+
* Errors propagate — a missing backup throws `BackupHttpError` (404). Callers
|
|
341
|
+
* decide whether that warrants a friendly "no source yet" message or a hard
|
|
342
|
+
* failure.
|
|
343
|
+
*/
|
|
344
|
+
declare function pullAgentBackup(opts: PullAgentBackupOptions): Promise<PullAgentBackupResult>;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Workspace ↔ archive serialization. Wire format:
|
|
348
|
+
* gzip(JSON.stringify({ [relPath]: contents })) → base64.
|
|
349
|
+
* Spec: docs/superpowers/specs/2026-05-02-canonical-tool-source-design.md.
|
|
350
|
+
*
|
|
351
|
+
* A JSON map is used (vs tar) so neither the CLI bundle nor the
|
|
352
|
+
* lua-claude-builder runtime needs a tar dependency. The format is symmetric
|
|
353
|
+
* across both, so encode/decode go through these helpers — never inline.
|
|
354
|
+
*/
|
|
355
|
+
declare const ARCHIVE_SCHEMA_VERSION = 1;
|
|
356
|
+
/**
|
|
357
|
+
* Encode a workspace directory tree into a base64-gzip JSON map. Returns
|
|
358
|
+
* `null` if the workspace doesn't exist or is empty.
|
|
359
|
+
*/
|
|
360
|
+
declare function encodeWorkspaceArchive(workspaceDir: string): string | null;
|
|
361
|
+
/**
|
|
362
|
+
* Decode a base64-gzip JSON map back to a `{ relPath: content }` object.
|
|
363
|
+
* Throws on malformed payloads — callers should treat that as a corrupt
|
|
364
|
+
* canonical record and surface clearly rather than silently writing nothing.
|
|
365
|
+
*/
|
|
366
|
+
declare function decodeWorkspaceArchive(archive: string, schemaVersion?: number): Record<string, string>;
|
|
367
|
+
/**
|
|
368
|
+
* Write the contents of a decoded archive into `workspaceDir`. Existing files
|
|
369
|
+
* are overwritten — caller is responsible for save-pending-changes prompts.
|
|
370
|
+
* Defense-in-depth: any `relPath` containing `..` is rejected.
|
|
371
|
+
*/
|
|
372
|
+
declare function writeArchiveToWorkspace(workspaceDir: string, files: Record<string, string>): void;
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Wire types for the per-skill canonical source store.
|
|
376
|
+
* Spec: docs/superpowers/specs/2026-05-02-canonical-tool-source-design.md.
|
|
377
|
+
*
|
|
378
|
+
* Driven by both the admin-tool-builder's CanonicalSourceClient (internal
|
|
379
|
+
* lua-agents URI, no auth) and lua-cli's SkillApi (developer-facing lua-api
|
|
380
|
+
* endpoint, Bearer auth). Transport differs; the wire shapes are shared.
|
|
381
|
+
*/
|
|
382
|
+
declare const SKILL_SOURCE_EDITORS: readonly ["builder", "cli", "engineer", "system"];
|
|
383
|
+
type SkillSourceEditor = (typeof SKILL_SOURCE_EDITORS)[number];
|
|
384
|
+
/** Per-tool entry returned by `GET /skills/.../source`. */
|
|
385
|
+
interface SkillSourceTool {
|
|
386
|
+
name: string;
|
|
387
|
+
entryFile: string | null;
|
|
388
|
+
source: string | null;
|
|
389
|
+
lastEditedBy: SkillSourceEditor | null;
|
|
390
|
+
lastEditedAt: string | Date | null;
|
|
391
|
+
}
|
|
392
|
+
/** Response from `GET /skills/.../source` (lua-agents internal) / `GET /developer/skills/.../source` (lua-api). */
|
|
393
|
+
interface FetchedSkillSource {
|
|
394
|
+
skillId: string;
|
|
395
|
+
version: string;
|
|
396
|
+
sourceArchive: string | null;
|
|
397
|
+
archiveSchemaVersion: number | null;
|
|
398
|
+
tools: SkillSourceTool[];
|
|
399
|
+
}
|
|
400
|
+
/** Per-tool entry accepted by `PUT /skills/.../version/.../source`. */
|
|
401
|
+
interface AttachSkillSourceTool {
|
|
402
|
+
name: string;
|
|
403
|
+
source?: string;
|
|
404
|
+
entryFile?: string;
|
|
405
|
+
lastEditedBy?: SkillSourceEditor;
|
|
406
|
+
}
|
|
407
|
+
/** Body of `PUT /skills/.../version/.../source`. */
|
|
408
|
+
interface AttachSkillSourcePayload {
|
|
409
|
+
sourceArchive?: string;
|
|
410
|
+
archiveSchemaVersion?: number;
|
|
411
|
+
tools?: AttachSkillSourceTool[];
|
|
412
|
+
/**
|
|
413
|
+
* CAS gate: if supplied and not matching the skill's current
|
|
414
|
+
* `activeVersionId` on the server, the write is rejected with 409.
|
|
415
|
+
*/
|
|
416
|
+
expectedActiveVersionId?: string;
|
|
417
|
+
}
|
|
418
|
+
/** Successful response shape from `PUT /skills/.../version/.../source`. */
|
|
419
|
+
interface AttachSkillSourceResponse {
|
|
420
|
+
ok: true;
|
|
421
|
+
version: string;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
export { ARCHIVE_SCHEMA_VERSION, type AttachSkillSourcePayload, type AttachSkillSourceResponse, type AttachSkillSourceTool, type BackupExistsResponse, type BackupFileRef, BackupHttpClient, type BackupHttpClientOptions, BackupHttpError, type BackupManifest, type BackupMetadata, type CheckBlobsRequest, type CheckBlobsResponse, DEFAULT_MAX_FILE_BYTES, FILE_HASH_LENGTH, type FetchLike, type FetchedSkillSource, type GetBlobUrlsRequest, type GetBlobUrlsResponse, type PullAgentBackupOptions, type PullAgentBackupResult, type PushAgentBackupOptions, type PushAgentBackupResult, type RestoreOptions, type RestoreResult, SKILL_SOURCE_EDITORS, type SaveManifestRequest, type SkillSourceEditor, type SkillSourceTool, type WalkOptions, type WalkResult, classifyFile, combineFileHashes, decodeWorkspaceArchive, downloadBlobs, encodeWorkspaceArchive, hashContentTruncated, pullAgentBackup, pushAgentBackup, resolveBackupFileTarget, restoreFromBlobs, sha256Hex, shouldSkipDirectory, shouldSkipFile, uploadBlobs, walkWorkspace, writeArchiveToWorkspace };
|