@apitap/core 1.8.1 → 1.9.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.
@@ -0,0 +1,410 @@
1
+ // src/skill/github.ts
2
+ import { execFileSync as _execFileSync } from 'node:child_process';
3
+ import { resolveAndValidateUrl as _resolveAndValidateUrl } from './ssrf.js';
4
+ // ─── Token resolution ─────────────────────────────────────────────────────────
5
+ // Indirection so tests can inject a fake without patching non-configurable
6
+ // built-in module exports.
7
+ let _execFileSyncImpl = _execFileSync;
8
+ /**
9
+ * Override the execFileSync implementation — for testing only.
10
+ * Returns the previous implementation so callers can restore it.
11
+ */
12
+ export function _setExecFileSync(impl) {
13
+ const prev = _execFileSyncImpl;
14
+ _execFileSyncImpl = impl;
15
+ return prev;
16
+ }
17
+ let cachedToken; // undefined = not yet resolved
18
+ /** Reset token cache — for testing only. */
19
+ export function resetTokenCache() {
20
+ cachedToken = undefined;
21
+ }
22
+ /**
23
+ * Resolve a GitHub token. Tries gh CLI first, then GITHUB_TOKEN env var.
24
+ * Caches the result (even null) for the session.
25
+ */
26
+ export async function resolveGitHubToken() {
27
+ if (cachedToken !== undefined)
28
+ return cachedToken;
29
+ try {
30
+ cachedToken = _execFileSyncImpl('gh', ['auth', 'token'], { timeout: 2000 })
31
+ .toString()
32
+ .trim();
33
+ if (!cachedToken) {
34
+ // gh returned empty output — treat as failure
35
+ throw new Error('empty token');
36
+ }
37
+ }
38
+ catch {
39
+ cachedToken = process.env.GITHUB_TOKEN ?? null;
40
+ }
41
+ if (cachedToken === null) {
42
+ console.error("Warning: No GitHub token found — rate limited to 60 req/hr. " +
43
+ "Run 'gh auth login' or set GITHUB_TOKEN.");
44
+ }
45
+ return cachedToken;
46
+ }
47
+ const MAX_RESPONSE_SIZE = 10 * 1024 * 1024; // 10 MB
48
+ /**
49
+ * Fetch a GitHub API path and return parsed JSON plus rate-limit metadata.
50
+ * Throws with a descriptive message on HTTP errors and size overruns.
51
+ */
52
+ export async function githubFetch(path, token) {
53
+ const url = `https://api.github.com${path}`;
54
+ const headers = {
55
+ Accept: 'application/vnd.github+json',
56
+ 'User-Agent': 'apitap-import',
57
+ };
58
+ if (token) {
59
+ headers['Authorization'] = `Bearer ${token}`;
60
+ }
61
+ const response = await fetch(url, {
62
+ headers,
63
+ signal: AbortSignal.timeout(30_000),
64
+ });
65
+ // Parse rate limit before checking status (available even on error responses).
66
+ const rateLimit = {
67
+ remaining: parseInt(response.headers.get('x-ratelimit-remaining') ?? '0', 10),
68
+ limit: parseInt(response.headers.get('x-ratelimit-limit') ?? '0', 10),
69
+ resetAt: new Date(parseInt(response.headers.get('x-ratelimit-reset') ?? '0', 10) * 1000),
70
+ };
71
+ if (!response.ok) {
72
+ if (response.status === 403 && rateLimit.remaining === 0) {
73
+ const err = new Error(`GitHub API rate limit exhausted. Resets at ${rateLimit.resetAt.toLocaleTimeString()}.` +
74
+ ` Run 'gh auth login' for higher limits.`);
75
+ err.status = 403;
76
+ throw err;
77
+ }
78
+ if (response.status === 429) {
79
+ const retryAfter = response.headers.get('retry-after');
80
+ const waitMsg = retryAfter ? ` Retry after ${retryAfter}s.` : '';
81
+ const err = new Error(`GitHub secondary rate limit hit.${waitMsg}`);
82
+ err.status = 429;
83
+ err.retryAfter = retryAfter ? parseInt(retryAfter, 10) : undefined;
84
+ throw err;
85
+ }
86
+ const err = new Error(`GitHub API ${response.status} ${response.statusText} for ${path}`);
87
+ err.status = response.status;
88
+ throw err;
89
+ }
90
+ // Size check via Content-Length header (fast path, avoids reading body).
91
+ const contentLength = response.headers.get('content-length');
92
+ if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {
93
+ throw new Error(`GitHub API response too large: ${contentLength} bytes (limit: ${MAX_RESPONSE_SIZE})`);
94
+ }
95
+ const text = await response.text();
96
+ if (text.length > MAX_RESPONSE_SIZE) {
97
+ throw new Error(`GitHub API response body too large: ${text.length} bytes (limit: ${MAX_RESPONSE_SIZE})`);
98
+ }
99
+ return { data: JSON.parse(text), rateLimit };
100
+ }
101
+ // ─── Template domain normalizer ───────────────────────────────────────────────
102
+ /**
103
+ * Strips leading `{var}.` template segments from a domain name.
104
+ * e.g. "{region}.api.example.com" → "api.example.com"
105
+ */
106
+ export function normalizeTemplatedDomain(domain) {
107
+ let d = domain;
108
+ while (d.startsWith('{')) {
109
+ const next = d.replace(/^\{[^}]+\}\./, '');
110
+ if (next === d)
111
+ break; // malformed template — stop
112
+ d = next;
113
+ }
114
+ return d;
115
+ }
116
+ /**
117
+ * Pre-process spec's server URLs to normalize templated domains.
118
+ * Mutates the spec object in place — intentional, called before convertOpenAPISpec() consumes it.
119
+ */
120
+ export function normalizeSpecServerUrls(spec) {
121
+ if (!spec.servers)
122
+ return;
123
+ for (const server of spec.servers) {
124
+ if (!server.url || !server.url.includes('{'))
125
+ continue;
126
+ try {
127
+ const url = new URL(server.url);
128
+ url.hostname = normalizeTemplatedDomain(url.hostname);
129
+ server.url = url.toString();
130
+ }
131
+ catch {
132
+ // URL with leading template like https://{region}.sentry.io fails new URL()
133
+ const match = server.url.match(/^(https?:\/\/)([^/]+)(.*)/);
134
+ if (match) {
135
+ const normalized = normalizeTemplatedDomain(match[2]);
136
+ server.url = match[1] + normalized + match[3];
137
+ }
138
+ }
139
+ }
140
+ }
141
+ /** Repos not pushed to in 3 years are considered stale. */
142
+ const STALE_THRESHOLD_MS = 3 * 365 * 24 * 60 * 60 * 1000;
143
+ /**
144
+ * Run results through the metadata filter pipeline.
145
+ * Skips forks, archived repos, stale repos (>3 years, unless includeStale),
146
+ * and repos below the minStars threshold.
147
+ */
148
+ export function filterResults(results, options) {
149
+ const passed = [];
150
+ const skips = [];
151
+ for (const result of results) {
152
+ if (result.isFork) {
153
+ skips.push({ repo: result.repoFullName, reason: 'fork' });
154
+ continue;
155
+ }
156
+ if (result.isArchived) {
157
+ skips.push({ repo: result.repoFullName, reason: 'archived' });
158
+ continue;
159
+ }
160
+ if (!options.includeStale) {
161
+ const pushedMs = new Date(result.pushedAt).getTime();
162
+ if (Date.now() - pushedMs > STALE_THRESHOLD_MS) {
163
+ const pushedDate = new Date(result.pushedAt).toISOString().slice(0, 10);
164
+ skips.push({ repo: result.repoFullName, reason: `stale, last push ${pushedDate}` });
165
+ continue;
166
+ }
167
+ }
168
+ if (options.minStars !== undefined && result.stars < options.minStars) {
169
+ skips.push({ repo: result.repoFullName, reason: `${result.stars} stars, below --min-stars ${options.minStars}` });
170
+ continue;
171
+ }
172
+ passed.push(result);
173
+ }
174
+ return { passed, skips };
175
+ }
176
+ // ─── Org Scan — Code Search ───────────────────────────────────────────────────
177
+ export const SPEC_FILENAMES = ['openapi.json', 'openapi.yaml', 'swagger.json', 'swagger.yaml'];
178
+ /**
179
+ * Uses GitHub's Code Search API to find OpenAPI spec files across an org's repos.
180
+ * Queries run sequentially — GitHub's code search has a secondary rate limit of
181
+ * 30 req/min (authenticated). Parallel fan-out risks immediate 403.
182
+ */
183
+ export async function searchOrgSpecs(org, token) {
184
+ const allItems = [];
185
+ const seen = new Set();
186
+ // Sequential queries — GitHub's code search has a secondary rate limit
187
+ // of 30 req/min (authenticated). Parallel fan-out risks immediate 403.
188
+ for (const filename of SPEC_FILENAMES) {
189
+ const q = encodeURIComponent(`filename:${filename} org:${org}`);
190
+ let response;
191
+ try {
192
+ response = await githubFetch(`/search/code?q=${q}&per_page=100`, token);
193
+ }
194
+ catch (err) {
195
+ if (err.status === 422) {
196
+ throw new Error(`GitHub org '${org}' not found.`);
197
+ }
198
+ throw err;
199
+ }
200
+ for (const item of response.data.items ?? []) {
201
+ const htmlUrl = item.html_url;
202
+ if (seen.has(htmlUrl))
203
+ continue;
204
+ seen.add(htmlUrl);
205
+ const repo = item.repository;
206
+ allItems.push({
207
+ owner: repo.owner?.login ?? org,
208
+ repo: repo.name,
209
+ repoFullName: repo.full_name,
210
+ filePath: item.path,
211
+ htmlUrl,
212
+ specUrl: `https://raw.githubusercontent.com/${repo.full_name}/${repo.default_branch ?? 'main'}/${item.path}`,
213
+ stars: repo.stargazers_count ?? 0,
214
+ isFork: repo.fork ?? false,
215
+ isArchived: repo.archived ?? false,
216
+ pushedAt: repo.pushed_at ?? '',
217
+ description: repo.description ?? '',
218
+ });
219
+ }
220
+ }
221
+ // Rank: stars desc, then path depth asc (shallower = more likely canonical)
222
+ allItems.sort((a, b) => {
223
+ if (b.stars !== a.stars)
224
+ return b.stars - a.stars;
225
+ const depthA = a.filePath.split('/').length;
226
+ const depthB = b.filePath.split('/').length;
227
+ return depthA - depthB;
228
+ });
229
+ return allItems;
230
+ }
231
+ // ─── Topic Search — Repo Discovery + Spec Probing ─────────────────────────────
232
+ export const CANONICAL_TOPICS = ['openapi-specification', 'openapi', 'openapi3', 'swagger-api'];
233
+ const PROBE_DIRS = ['', 'api', 'spec', 'docs'];
234
+ async function probeForSpecs(owner, repo, token) {
235
+ const found = [];
236
+ for (const dir of PROBE_DIRS) {
237
+ const contentsPath = dir
238
+ ? `/repos/${owner}/${repo}/contents/${dir}`
239
+ : `/repos/${owner}/${repo}/contents`;
240
+ try {
241
+ const { data } = await githubFetch(contentsPath, token);
242
+ if (!Array.isArray(data))
243
+ continue;
244
+ for (const entry of data) {
245
+ if (SPEC_FILENAMES.includes(entry.name)) {
246
+ found.push({
247
+ path: entry.path,
248
+ htmlUrl: entry.html_url,
249
+ });
250
+ }
251
+ }
252
+ }
253
+ catch {
254
+ // Directory doesn't exist or 404 — continue to next
255
+ continue;
256
+ }
257
+ // If we found specs in this dir, don't probe deeper
258
+ if (found.length > 0)
259
+ break;
260
+ }
261
+ return found;
262
+ }
263
+ export async function searchTopicSpecs(topics, token, options) {
264
+ // Fan out topic queries in parallel — repository search has more
265
+ // generous secondary rate limits than code search.
266
+ const responses = await Promise.all(topics.map(topic => githubFetch(`/search/repositories?q=${encodeURIComponent(`topic:${topic}`)}&sort=stars&order=desc&per_page=100`, token)));
267
+ // Dedup by full_name
268
+ const seen = new Set();
269
+ const repos = [];
270
+ for (const { data } of responses) {
271
+ for (const item of data.items ?? []) {
272
+ if (seen.has(item.full_name))
273
+ continue;
274
+ seen.add(item.full_name);
275
+ if (item.stargazers_count < options.minStars)
276
+ continue;
277
+ if (options.query) {
278
+ const q = options.query.toLowerCase();
279
+ const name = (item.name ?? '').toLowerCase();
280
+ const desc = (item.description ?? '').toLowerCase();
281
+ if (!name.includes(q) && !desc.includes(q))
282
+ continue;
283
+ }
284
+ repos.push({
285
+ owner: item.owner?.login,
286
+ repo: item.name,
287
+ fullName: item.full_name,
288
+ stars: item.stargazers_count ?? 0,
289
+ isFork: item.fork ?? false,
290
+ isArchived: item.archived ?? false,
291
+ pushedAt: item.pushed_at ?? '',
292
+ description: item.description ?? '',
293
+ defaultBranch: item.default_branch ?? 'main',
294
+ });
295
+ }
296
+ }
297
+ // Probe each repo for spec files
298
+ const results = [];
299
+ for (const repo of repos) {
300
+ const specs = await probeForSpecs(repo.owner, repo.repo, token);
301
+ for (const spec of specs) {
302
+ results.push({
303
+ owner: repo.owner,
304
+ repo: repo.repo,
305
+ repoFullName: repo.fullName,
306
+ filePath: spec.path,
307
+ htmlUrl: spec.htmlUrl,
308
+ specUrl: `https://raw.githubusercontent.com/${repo.fullName}/${repo.defaultBranch}/${spec.path}`,
309
+ stars: repo.stars,
310
+ isFork: repo.isFork,
311
+ isArchived: repo.isArchived,
312
+ pushedAt: repo.pushedAt,
313
+ description: repo.description,
314
+ });
315
+ }
316
+ }
317
+ // Sort by stars desc
318
+ results.sort((a, b) => b.stars - a.stars);
319
+ return results;
320
+ }
321
+ // ─── Spec content predicates ──────────────────────────────────────────────────
322
+ /**
323
+ * Returns true if the spec has a usable server URL —
324
+ * either OpenAPI 3.x `servers[0].url` or Swagger 2.0 `host`.
325
+ */
326
+ export function hasServerUrl(spec) {
327
+ if (spec.host)
328
+ return true;
329
+ if (Array.isArray(spec.servers) && spec.servers.length > 0 && spec.servers[0].url) {
330
+ return true;
331
+ }
332
+ return false;
333
+ }
334
+ // ─── SSRF DI hook ─────────────────────────────────────────────────────────────
335
+ // Indirection so tests can inject a fake resolveAndValidateUrl without network.
336
+ let _resolveAndValidateUrlImpl = _resolveAndValidateUrl;
337
+ /**
338
+ * Override the resolveAndValidateUrl implementation — for testing only.
339
+ * Returns the previous implementation so callers can restore it.
340
+ */
341
+ export function _setResolveAndValidateUrl(impl) {
342
+ const prev = _resolveAndValidateUrlImpl;
343
+ _resolveAndValidateUrlImpl = impl;
344
+ return prev;
345
+ }
346
+ // ─── Spec content fetching ────────────────────────────────────────────────────
347
+ const MAX_SPEC_SIZE = 10 * 1024 * 1024; // 10 MB
348
+ /**
349
+ * Fetch an OpenAPI spec from raw.githubusercontent.com.
350
+ * Uses direct fetch() — does NOT use githubFetch() since this is a different host.
351
+ * raw.githubusercontent.com requests do not count against the GitHub API rate limit.
352
+ * Auth token is sent to raw.githubusercontent.com (GitHub-controlled domain) for private repo support.
353
+ */
354
+ export async function fetchGitHubSpec(specUrl, token) {
355
+ const ssrf = await _resolveAndValidateUrlImpl(specUrl);
356
+ if (!ssrf.safe) {
357
+ throw new Error(`SSRF check failed for spec URL ${specUrl}: ${ssrf.reason}`);
358
+ }
359
+ const headers = { 'User-Agent': 'apitap-import' };
360
+ if (token) {
361
+ headers['Authorization'] = `Bearer ${token}`;
362
+ }
363
+ const response = await fetch(specUrl, {
364
+ headers,
365
+ signal: AbortSignal.timeout(30_000),
366
+ });
367
+ if (!response.ok) {
368
+ throw new Error(`HTTP ${response.status} ${response.statusText} for ${specUrl}`);
369
+ }
370
+ const contentLength = response.headers.get('content-length');
371
+ if (contentLength && parseInt(contentLength, 10) > MAX_SPEC_SIZE) {
372
+ throw new Error(`Spec too large: ${contentLength} bytes (limit: ${MAX_SPEC_SIZE})`);
373
+ }
374
+ const text = await response.text();
375
+ if (text.length > MAX_SPEC_SIZE) {
376
+ throw new Error(`Spec body too large: ${text.length} bytes`);
377
+ }
378
+ // Try JSON first, then YAML
379
+ try {
380
+ return JSON.parse(text);
381
+ }
382
+ catch {
383
+ const yaml = await import('js-yaml');
384
+ const parsed = yaml.load(text);
385
+ if (typeof parsed !== 'object' || parsed === null) {
386
+ throw new Error(`Invalid JSON/YAML from ${specUrl}`);
387
+ }
388
+ return parsed;
389
+ }
390
+ }
391
+ /** Placeholder domains that indicate a spec is not pointing at a real API. */
392
+ const PLACEHOLDER_HOSTS = ['localhost', '127.0.0.1', 'example.com', 'petstore.swagger.io'];
393
+ /**
394
+ * Returns true if the spec's server URL points at localhost, a loopback address,
395
+ * or a well-known placeholder domain (example.com, petstore.swagger.io).
396
+ */
397
+ export function isLocalhostSpec(spec) {
398
+ const urls = [];
399
+ if (spec.host) {
400
+ urls.push(spec.host);
401
+ }
402
+ if (Array.isArray(spec.servers)) {
403
+ for (const server of spec.servers) {
404
+ if (server.url)
405
+ urls.push(server.url);
406
+ }
407
+ }
408
+ return urls.some(u => PLACEHOLDER_HOSTS.some(ph => u.includes(ph)));
409
+ }
410
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/skill/github.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,OAAO,EAAE,YAAY,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAE5E,iFAAiF;AAEjF,2EAA2E;AAC3E,2BAA2B;AAC3B,IAAI,iBAAiB,GAAyB,aAAa,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA0B;IACzD,MAAM,IAAI,GAAG,iBAAiB,CAAC;IAC/B,iBAAiB,GAAG,IAAI,CAAC;IACzB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,IAAI,WAAsC,CAAC,CAAC,+BAA+B;AAE3E,4CAA4C;AAC5C,MAAM,UAAU,eAAe;IAC7B,WAAW,GAAG,SAAS,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC;IAElD,IAAI,CAAC;QACH,WAAW,GAAG,iBAAiB,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;aACxE,QAAQ,EAAE;aACV,IAAI,EAAE,CAAC;QACV,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,8CAA8C;YAC9C,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC;IACjD,CAAC;IAED,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CACX,8DAA8D;YAC9D,0CAA0C,CAC3C,CAAC;IACJ,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAUD,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AAEpD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,KAAoB;IAEpB,MAAM,GAAG,GAAG,yBAAyB,IAAI,EAAE,CAAC;IAC5C,MAAM,OAAO,GAA2B;QACtC,MAAM,EAAE,6BAA6B;QACrC,YAAY,EAAE,eAAe;KAC9B,CAAC;IACF,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,OAAO;QACP,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,MAAM,SAAS,GAAc;QAC3B,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QAC7E,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACrE,OAAO,EAAE,IAAI,IAAI,CACf,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CACtE;KACF,CAAC;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YACzD,MAAM,GAAG,GAAG,IAAI,KAAK,CACnB,8CAA8C,SAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG;gBACrF,yCAAyC,CAC5C,CAAC;YACD,GAAW,CAAC,MAAM,GAAG,GAAG,CAAC;YAC1B,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACvD,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,gBAAgB,UAAU,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,mCAAmC,OAAO,EAAE,CAAC,CAAC;YACnE,GAAW,CAAC,MAAM,GAAG,GAAG,CAAC;YACzB,GAAW,CAAC,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5E,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,KAAK,CACnB,cAAc,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,QAAQ,IAAI,EAAE,CACnE,CAAC;QACD,GAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QACtC,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,yEAAyE;IACzE,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC7D,IAAI,aAAa,IAAI,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,GAAG,iBAAiB,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CACb,kCAAkC,aAAa,kBAAkB,iBAAiB,GAAG,CACtF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,uCAAuC,IAAI,CAAC,MAAM,kBAAkB,iBAAiB,GAAG,CACzF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC;AAC/C,CAAC;AAED,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAc;IACrD,IAAI,CAAC,GAAG,MAAM,CAAC;IACf,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC3C,IAAI,IAAI,KAAK,CAAC;YAAE,MAAM,CAAC,4BAA4B;QACnD,CAAC,GAAG,IAAI,CAAC;IACX,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAyB;IAC/D,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO;IAC1B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACvD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChC,GAAG,CAAC,QAAQ,GAAG,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACtD,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,4EAA4E;YAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC5D,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,UAAU,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtD,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAkCD,2DAA2D;AAC3D,MAAM,kBAAkB,GAAG,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEzD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,OAA2B,EAC3B,OAAsB;IAEtB,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,MAAM,KAAK,GAA4C,EAAE,CAAC;IAE1D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1D,SAAS;QACX,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YAC9D,SAAS;QACX,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;YACrD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,GAAG,kBAAkB,EAAE,CAAC;gBAC/C,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACxE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,oBAAoB,UAAU,EAAE,EAAE,CAAC,CAAC;gBACpF,SAAS;YACX,CAAC;QACH,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,6BAA6B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAClH,SAAS;QACX,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,iFAAiF;AAEjF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;AAE/F;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,KAAoB;IAEpB,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,uEAAuE;IACvE,uEAAuE;IACvE,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,kBAAkB,CAAC,YAAY,QAAQ,QAAQ,GAAG,EAAE,CAAC,CAAC;QAChE,IAAI,QAAQ,CAAC;QACb,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,WAAW,CAAC,kBAAkB,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,eAAe,GAAG,cAAc,CAAC,CAAC;YACpD,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YAC7C,MAAM,OAAO,GAAW,IAAI,CAAC,QAAQ,CAAC;YACtC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,SAAS;YAChC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAElB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;YAC7B,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,GAAG;gBAC/B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,YAAY,EAAE,IAAI,CAAC,SAAS;gBAC5B,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,OAAO;gBACP,OAAO,EAAE,qCAAqC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,cAAc,IAAI,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE;gBAC5G,KAAK,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC;gBACjC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK;gBAC1B,UAAU,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;gBAClC,QAAQ,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;gBAC9B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;aACpC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;YAAE,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QAClD,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QAC5C,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QAC5C,OAAO,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,iFAAiF;AAEjF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,uBAAuB,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;AAEhG,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE/C,KAAK,UAAU,aAAa,CAC1B,KAAa,EACb,IAAY,EACZ,KAAoB;IAEpB,MAAM,KAAK,GAA6C,EAAE,CAAC;IAE3D,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,YAAY,GAAG,GAAG;YACtB,CAAC,CAAC,UAAU,KAAK,IAAI,IAAI,aAAa,GAAG,EAAE;YAC3C,CAAC,CAAC,UAAU,KAAK,IAAI,IAAI,WAAW,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;YACxD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;gBAAE,SAAS;YAEnC,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;gBACzB,IAAI,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxC,KAAK,CAAC,IAAI,CAAC;wBACT,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,OAAO,EAAE,KAAK,CAAC,QAAQ;qBACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;YACpD,SAAS;QACX,CAAC;QAED,oDAAoD;QACpD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM;IAC9B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAgB,EAChB,KAAoB,EACpB,OAA6C;IAE7C,iEAAiE;IACjE,mDAAmD;IACnD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CACjB,WAAW,CACT,0BAA0B,kBAAkB,CAAC,SAAS,KAAK,EAAE,CAAC,qCAAqC,EACnG,KAAK,CACN,CACF,CACF,CAAC;IAEF,qBAAqB;IACrB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,KAAK,GAAgL,EAAE,CAAC;IAE9L,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YACpC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBAAE,SAAS;YACvC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEzB,IAAI,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,QAAQ;gBAAE,SAAS;YAEvD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClB,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC7C,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;gBACpD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAAE,SAAS;YACvD,CAAC;YAED,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK;gBACxB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,SAAS;gBACxB,KAAK,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC;gBACjC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK;gBAC1B,UAAU,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;gBAClC,QAAQ,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;gBAC9B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,aAAa,EAAE,IAAI,CAAC,cAAc,IAAI,MAAM;aAC7C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,YAAY,EAAE,IAAI,CAAC,QAAQ;gBAC3B,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO,EAAE,qCAAqC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,EAAE;gBAChG,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAE1C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAyB;IACpD,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iFAAiF;AAEjF,gFAAgF;AAChF,IAAI,0BAA0B,GAAkC,sBAAsB,CAAC;AAEvF;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,IAAmC;IAEnC,MAAM,IAAI,GAAG,0BAA0B,CAAC;IACxC,0BAA0B,GAAG,IAAI,CAAC;IAClC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iFAAiF;AAEjF,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AAEhD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,KAAoB;IAEpB,MAAM,IAAI,GAAG,MAAM,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,OAAO,GAA2B,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC;IAC1E,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE;QACpC,OAAO;QACP,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,QAAQ,OAAO,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC7D,IAAI,aAAa,IAAI,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,mBAAmB,aAAa,kBAAkB,aAAa,GAAG,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC;IAC/D,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwB,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,0BAA0B,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,MAA6B,CAAC;IACvC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,iBAAiB,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;AAE3F;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAyB;IACvD,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,GAAG;gBAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CACnB,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAC7C,CAAC;AACJ,CAAC"}
@@ -31,10 +31,12 @@ function sortKeysDeep(value) {
31
31
  * Sign a skill file. Returns a new object with signature and provenance: 'self'.
32
32
  */
33
33
  export function signSkillFile(skill, key) {
34
- const payload = canonicalize(skill);
34
+ const signedAt = new Date().toISOString();
35
+ const payload = canonicalize({ ...skill, signedAt });
35
36
  const signature = hmacSign(payload, key);
36
37
  return {
37
38
  ...skill,
39
+ signedAt,
38
40
  provenance: 'self',
39
41
  signature,
40
42
  };
@@ -44,9 +46,10 @@ export function signSkillFile(skill, key) {
44
46
  * Use 'self' for captured files, 'imported-signed' for import-only files.
45
47
  */
46
48
  export function signSkillFileAs(skill, key, provenance) {
47
- const payload = canonicalize(skill);
49
+ const signedAt = new Date().toISOString();
50
+ const payload = canonicalize({ ...skill, signedAt });
48
51
  const signature = hmacSign(payload, key);
49
- return { ...skill, provenance, signature };
52
+ return { ...skill, signedAt, provenance, signature };
50
53
  }
51
54
  /**
52
55
  * Verify a skill file's signature.
@@ -1 +1 @@
1
- {"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/skill/signing.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGzD;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAgB;IAC3C,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAC9D,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACvE,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAgB,EAAE,GAAW;IACzD,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACzC,OAAO;QACL,GAAG,KAAK;QACR,UAAU,EAAE,MAAM;QAClB,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAgB,EAChB,GAAW,EACX,UAAsC;IAEtC,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACzC,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAgB,EAAE,GAAW;IAC3D,IAAI,CAAC,KAAK,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACpC,OAAO,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AACnD,CAAC"}
1
+ {"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/skill/signing.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGzD;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAgB;IAC3C,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAC9D,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACvE,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAgB,EAAE,GAAW;IACzD,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAe,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACzC,OAAO;QACL,GAAG,KAAK;QACR,QAAQ;QACR,UAAU,EAAE,MAAM;QAClB,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAgB,EAChB,GAAW,EACX,UAAsC;IAEtC,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAe,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACzC,OAAO,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAgB,EAAE,GAAW;IAC3D,IAAI,CAAC,KAAK,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACpC,OAAO,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AACnD,CAAC"}
@@ -9,6 +9,7 @@ const BASE_GITIGNORE = `# ApiTap — prevent accidental credential commits
9
9
  auth.enc
10
10
  *.key
11
11
  `;
12
+ const MAX_SIGNATURE_AGE_DAYS = 180;
12
13
  function skillPath(domain, skillsDir) {
13
14
  if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(domain)) {
14
15
  throw new Error(`Invalid domain: ${domain}`);
@@ -96,6 +97,17 @@ export async function readSkillFile(domain, skillsDir = DEFAULT_SKILLS_DIR, opti
96
97
  if (!verified) {
97
98
  throw new Error(`Skill file signature verification failed for ${domain} — file may be tampered`);
98
99
  }
100
+ if (skill.signedAt) {
101
+ const signedAtMs = Date.parse(skill.signedAt);
102
+ if (!Number.isNaN(signedAtMs)) {
103
+ const ageMs = Date.now() - signedAtMs;
104
+ const maxAgeMs = MAX_SIGNATURE_AGE_DAYS * 24 * 60 * 60 * 1000;
105
+ if (ageMs > maxAgeMs) {
106
+ throw new Error(`Skill file signature is stale for ${domain} (signed ${skill.signedAt}). ` +
107
+ `Re-capture or re-import to refresh signature.`);
108
+ }
109
+ }
110
+ }
99
111
  }
100
112
  }
101
113
  return skill;
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/skill/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/skill/store.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -138,6 +138,8 @@ export interface SkillFile {
138
138
  version: string;
139
139
  domain: string;
140
140
  capturedAt: string;
141
+ /** Signature timestamp (ISO) used for anti-replay staleness checks */
142
+ signedAt?: string;
141
143
  baseUrl: string;
142
144
  endpoints: SkillEndpoint[];
143
145
  metadata: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apitap/core",
3
- "version": "1.8.1",
3
+ "version": "1.9.0",
4
4
  "description": "Intercept web API traffic during browsing. Generate portable skill files so AI agents can call APIs directly instead of scraping.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",