@skillsmith/core 0.5.3 → 0.5.5
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/CHANGELOG.md +14 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/activation/ActivationManager.d.ts +7 -0
- package/dist/src/activation/ActivationManager.d.ts.map +1 -1
- package/dist/src/activation/ActivationManager.js +13 -4
- package/dist/src/activation/ActivationManager.js.map +1 -1
- package/dist/src/analysis/adapters/python.d.ts +16 -11
- package/dist/src/analysis/adapters/python.d.ts.map +1 -1
- package/dist/src/analysis/adapters/python.js +46 -61
- package/dist/src/analysis/adapters/python.js.map +1 -1
- package/dist/src/analysis/router.test.d.ts +2 -0
- package/dist/src/analysis/router.test.d.ts.map +1 -0
- package/dist/src/analysis/router.test.js +411 -0
- package/dist/src/analysis/router.test.js.map +1 -0
- package/dist/src/analysis/tree-sitter/manager.d.ts.map +1 -1
- package/dist/src/analysis/tree-sitter/manager.js +12 -5
- package/dist/src/analysis/tree-sitter/manager.js.map +1 -1
- package/dist/src/analysis/tree-sitter/pythonExtractor.d.ts +45 -0
- package/dist/src/analysis/tree-sitter/pythonExtractor.d.ts.map +1 -0
- package/dist/src/analysis/tree-sitter/pythonExtractor.js +264 -0
- package/dist/src/analysis/tree-sitter/pythonExtractor.js.map +1 -0
- package/dist/src/analysis/tree-sitter/pythonExtractor.test.d.ts +12 -0
- package/dist/src/analysis/tree-sitter/pythonExtractor.test.d.ts.map +1 -0
- package/dist/src/analysis/tree-sitter/pythonExtractor.test.js +74 -0
- package/dist/src/analysis/tree-sitter/pythonExtractor.test.js.map +1 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.d.ts +93 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.d.ts.map +1 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.hardening.test.d.ts +22 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.hardening.test.d.ts.map +1 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.hardening.test.js +229 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.hardening.test.js.map +1 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.js +287 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.js.map +1 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.test.d.ts +17 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.test.d.ts.map +1 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.test.js +142 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.test.js.map +1 -0
- package/dist/src/analysis/tree-sitter/queries/python.d.ts +43 -0
- package/dist/src/analysis/tree-sitter/queries/python.d.ts.map +1 -0
- package/dist/src/analysis/tree-sitter/queries/python.js +88 -0
- package/dist/src/analysis/tree-sitter/queries/python.js.map +1 -0
- package/dist/src/analysis/tree-sitter/queryExtractionMatchesOrExceedsRegex.test.d.ts +13 -0
- package/dist/src/analysis/tree-sitter/queryExtractionMatchesOrExceedsRegex.test.d.ts.map +1 -0
- package/dist/src/analysis/tree-sitter/queryExtractionMatchesOrExceedsRegex.test.js +174 -0
- package/dist/src/analysis/tree-sitter/queryExtractionMatchesOrExceedsRegex.test.js.map +1 -0
- package/dist/src/analytics/ROIDashboardService.csv.d.ts +11 -0
- package/dist/src/analytics/ROIDashboardService.csv.d.ts.map +1 -0
- package/dist/src/analytics/ROIDashboardService.csv.js +43 -0
- package/dist/src/analytics/ROIDashboardService.csv.js.map +1 -0
- package/dist/src/analytics/ROIDashboardService.d.ts +64 -3
- package/dist/src/analytics/ROIDashboardService.d.ts.map +1 -1
- package/dist/src/analytics/ROIDashboardService.js +116 -45
- package/dist/src/analytics/ROIDashboardService.js.map +1 -1
- package/dist/src/api/client.d.ts +4 -66
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.events.d.ts.map +1 -1
- package/dist/src/api/client.events.js +10 -1
- package/dist/src/api/client.events.js.map +1 -1
- package/dist/src/api/client.js +40 -66
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/client.token-refresh.d.ts +3 -0
- package/dist/src/api/client.token-refresh.d.ts.map +1 -0
- package/dist/src/api/client.token-refresh.js +19 -0
- package/dist/src/api/client.token-refresh.js.map +1 -0
- package/dist/src/api/client.token-refresh.test.d.ts +2 -0
- package/dist/src/api/client.token-refresh.test.d.ts.map +1 -0
- package/dist/src/api/client.token-refresh.test.js +73 -0
- package/dist/src/api/client.token-refresh.test.js.map +1 -0
- package/dist/src/api/client.types.d.ts +2 -0
- package/dist/src/api/client.types.d.ts.map +1 -1
- package/dist/src/api/index.d.ts +1 -1
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js +1 -1
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/schemas.d.ts +60 -60
- package/dist/src/api/schemas.d.ts.map +1 -1
- package/dist/src/benchmarks/incrementalParseBenchmark.d.ts +18 -0
- package/dist/src/benchmarks/incrementalParseBenchmark.d.ts.map +1 -0
- package/dist/src/benchmarks/incrementalParseBenchmark.js +121 -0
- package/dist/src/benchmarks/incrementalParseBenchmark.js.map +1 -0
- package/dist/src/billing/GDPRComplianceService.test.d.ts +2 -0
- package/dist/src/billing/GDPRComplianceService.test.d.ts.map +1 -0
- package/dist/src/billing/GDPRComplianceService.test.js +405 -0
- package/dist/src/billing/GDPRComplianceService.test.js.map +1 -0
- package/dist/src/config/index.d.ts +4 -0
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/index.js +6 -0
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/token-credentials.d.ts +13 -0
- package/dist/src/config/token-credentials.d.ts.map +1 -0
- package/dist/src/config/token-credentials.js +126 -0
- package/dist/src/config/token-credentials.js.map +1 -0
- package/dist/src/config/token-credentials.test.d.ts +10 -0
- package/dist/src/config/token-credentials.test.d.ts.map +1 -0
- package/dist/src/config/token-credentials.test.js +91 -0
- package/dist/src/config/token-credentials.test.js.map +1 -0
- package/dist/src/index.d.ts +7 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/indexer/SkillParser.coverage.test.d.ts +10 -0
- package/dist/src/indexer/SkillParser.coverage.test.d.ts.map +1 -0
- package/dist/src/indexer/SkillParser.coverage.test.js +76 -0
- package/dist/src/indexer/SkillParser.coverage.test.js.map +1 -0
- package/dist/src/indexer/SkillParser.test.d.ts +2 -0
- package/dist/src/indexer/SkillParser.test.d.ts.map +1 -0
- package/dist/src/indexer/SkillParser.test.js +375 -0
- package/dist/src/indexer/SkillParser.test.js.map +1 -0
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js +34 -5
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js.map +1 -1
- package/dist/src/scripts/github-import/blocklist.d.ts +65 -0
- package/dist/src/scripts/github-import/blocklist.d.ts.map +1 -0
- package/dist/src/scripts/github-import/blocklist.js +124 -0
- package/dist/src/scripts/github-import/blocklist.js.map +1 -0
- package/dist/src/scripts/github-import/index.d.ts +1 -0
- package/dist/src/scripts/github-import/index.d.ts.map +1 -1
- package/dist/src/scripts/github-import/index.js +3 -0
- package/dist/src/scripts/github-import/index.js.map +1 -1
- package/dist/src/scripts/github-import/signal-of-intent.d.ts +87 -0
- package/dist/src/scripts/github-import/signal-of-intent.d.ts.map +1 -0
- package/dist/src/scripts/github-import/signal-of-intent.js +213 -0
- package/dist/src/scripts/github-import/signal-of-intent.js.map +1 -0
- package/dist/src/scripts/github-import/types.d.ts +22 -0
- package/dist/src/scripts/github-import/types.d.ts.map +1 -1
- package/dist/src/scripts/github-import/types.js.map +1 -1
- package/dist/src/scripts/import-github-skills.js +73 -3
- package/dist/src/scripts/import-github-skills.js.map +1 -1
- package/dist/src/scripts/skill-scanner/allowlist.d.ts +38 -0
- package/dist/src/scripts/skill-scanner/allowlist.d.ts.map +1 -0
- package/dist/src/scripts/skill-scanner/allowlist.js +178 -0
- package/dist/src/scripts/skill-scanner/allowlist.js.map +1 -0
- package/dist/src/scripts/skill-scanner/scanner.d.ts +10 -2
- package/dist/src/scripts/skill-scanner/scanner.d.ts.map +1 -1
- package/dist/src/scripts/skill-scanner/scanner.js +15 -3
- package/dist/src/scripts/skill-scanner/scanner.js.map +1 -1
- package/dist/src/scripts/skill-scanner/trust-scorer.d.ts +20 -6
- package/dist/src/scripts/skill-scanner/trust-scorer.d.ts.map +1 -1
- package/dist/src/scripts/skill-scanner/trust-scorer.js +28 -9
- package/dist/src/scripts/skill-scanner/trust-scorer.js.map +1 -1
- package/dist/src/scripts/skill-scanner/types.d.ts +50 -0
- package/dist/src/scripts/skill-scanner/types.d.ts.map +1 -1
- package/dist/src/scripts/validation/types.d.ts +14 -24
- package/dist/src/scripts/validation/types.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.d.ts +18 -0
- package/dist/src/security/scanner/SecurityScanner.helpers.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.js +54 -6
- package/dist/src/security/scanner/SecurityScanner.helpers.js.map +1 -1
- package/dist/src/security/scanner/patterns.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.js +45 -5
- package/dist/src/security/scanner/patterns.js.map +1 -1
- package/dist/src/services/skill-config-schema.d.ts +4 -36
- package/dist/src/services/skill-config-schema.d.ts.map +1 -1
- package/dist/src/sources/LocalFilesystemAdapter.d.ts +104 -10
- package/dist/src/sources/LocalFilesystemAdapter.d.ts.map +1 -1
- package/dist/src/sources/LocalFilesystemAdapter.helpers.d.ts +92 -0
- package/dist/src/sources/LocalFilesystemAdapter.helpers.d.ts.map +1 -0
- package/dist/src/sources/LocalFilesystemAdapter.helpers.js +157 -0
- package/dist/src/sources/LocalFilesystemAdapter.helpers.js.map +1 -0
- package/dist/src/sources/LocalFilesystemAdapter.js +218 -159
- package/dist/src/sources/LocalFilesystemAdapter.js.map +1 -1
- package/dist/src/sources/LocalFilesystemAdapter.scan.d.ts +78 -0
- package/dist/src/sources/LocalFilesystemAdapter.scan.d.ts.map +1 -0
- package/dist/src/sources/LocalFilesystemAdapter.scan.js +118 -0
- package/dist/src/sources/LocalFilesystemAdapter.scan.js.map +1 -0
- package/dist/src/sources/index.d.ts +1 -1
- package/dist/src/sources/index.d.ts.map +1 -1
- package/dist/src/sources/index.js.map +1 -1
- package/dist/src/sources/types.d.ts +28 -0
- package/dist/src/sources/types.d.ts.map +1 -1
- package/dist/src/telemetry/tracer-imports.d.ts +13 -0
- package/dist/src/telemetry/tracer-imports.d.ts.map +1 -0
- package/dist/src/telemetry/tracer-imports.js +26 -0
- package/dist/src/telemetry/tracer-imports.js.map +1 -0
- package/dist/src/telemetry/tracer.d.ts.map +1 -1
- package/dist/src/telemetry/tracer.js +18 -21
- package/dist/src/telemetry/tracer.js.map +1 -1
- package/dist/src/utils/rate-limit.d.ts +39 -0
- package/dist/src/utils/rate-limit.d.ts.map +1 -0
- package/dist/src/utils/rate-limit.js +48 -0
- package/dist/src/utils/rate-limit.js.map +1 -0
- package/dist/src/utils/rate-limit.test.d.ts +11 -0
- package/dist/src/utils/rate-limit.test.d.ts.map +1 -0
- package/dist/src/utils/rate-limit.test.js +86 -0
- package/dist/src/utils/rate-limit.test.js.map +1 -0
- package/dist/src/webhooks/WebhookDeadLetterRepository.d.ts +178 -0
- package/dist/src/webhooks/WebhookDeadLetterRepository.d.ts.map +1 -0
- package/dist/src/webhooks/WebhookDeadLetterRepository.js +196 -0
- package/dist/src/webhooks/WebhookDeadLetterRepository.js.map +1 -0
- package/dist/src/webhooks/WebhookQueue.d.ts +1 -0
- package/dist/src/webhooks/WebhookQueue.d.ts.map +1 -1
- package/dist/src/webhooks/WebhookQueue.js +19 -0
- package/dist/src/webhooks/WebhookQueue.js.map +1 -1
- package/dist/src/webhooks/WebhookQueue.types.d.ts +11 -0
- package/dist/src/webhooks/WebhookQueue.types.d.ts.map +1 -1
- package/dist/src/webhooks/index.d.ts +1 -0
- package/dist/src/webhooks/index.d.ts.map +1 -1
- package/dist/src/webhooks/index.js +2 -0
- package/dist/src/webhooks/index.js.map +1 -1
- package/dist/src/webhooks/webhook-schemas.d.ts +117 -1212
- package/dist/src/webhooks/webhook-schemas.d.ts.map +1 -1
- package/dist/tests/ActivationManager.test.d.ts +13 -0
- package/dist/tests/ActivationManager.test.d.ts.map +1 -0
- package/dist/tests/ActivationManager.test.js +218 -0
- package/dist/tests/ActivationManager.test.js.map +1 -0
- package/dist/tests/LocalFilesystemAdapter.coverage.test.d.ts +13 -0
- package/dist/tests/LocalFilesystemAdapter.coverage.test.d.ts.map +1 -0
- package/dist/tests/LocalFilesystemAdapter.coverage.test.js +314 -0
- package/dist/tests/LocalFilesystemAdapter.coverage.test.js.map +1 -0
- package/dist/tests/LocalFilesystemAdapter.security.test.d.ts +18 -0
- package/dist/tests/LocalFilesystemAdapter.security.test.d.ts.map +1 -0
- package/dist/tests/LocalFilesystemAdapter.security.test.js +344 -0
- package/dist/tests/LocalFilesystemAdapter.security.test.js.map +1 -0
- package/dist/tests/LocalFilesystemAdapter.test.d.ts +12 -0
- package/dist/tests/LocalFilesystemAdapter.test.d.ts.map +1 -0
- package/dist/tests/LocalFilesystemAdapter.test.js +301 -0
- package/dist/tests/LocalFilesystemAdapter.test.js.map +1 -0
- package/dist/tests/ROIDashboardService.coverage.test.d.ts +9 -0
- package/dist/tests/ROIDashboardService.coverage.test.d.ts.map +1 -0
- package/dist/tests/ROIDashboardService.coverage.test.js +118 -0
- package/dist/tests/ROIDashboardService.coverage.test.js.map +1 -0
- package/dist/tests/ROIDashboardService.test.js +87 -0
- package/dist/tests/ROIDashboardService.test.js.map +1 -1
- package/dist/tests/ScraperAdapters.gitlab-coverage.test.d.ts +14 -0
- package/dist/tests/ScraperAdapters.gitlab-coverage.test.d.ts.map +1 -0
- package/dist/tests/ScraperAdapters.gitlab-coverage.test.js +169 -0
- package/dist/tests/ScraperAdapters.gitlab-coverage.test.js.map +1 -0
- package/dist/tests/ScraperAdapters.test.d.ts +5 -1
- package/dist/tests/ScraperAdapters.test.d.ts.map +1 -1
- package/dist/tests/ScraperAdapters.test.js +6 -336
- package/dist/tests/ScraperAdapters.test.js.map +1 -1
- package/dist/tests/WebhookDeadLetterRepository.test.d.ts +2 -0
- package/dist/tests/WebhookDeadLetterRepository.test.d.ts.map +1 -0
- package/dist/tests/WebhookDeadLetterRepository.test.js +333 -0
- package/dist/tests/WebhookDeadLetterRepository.test.js.map +1 -0
- package/dist/tests/WebhookHandler.test.js +93 -1
- package/dist/tests/WebhookHandler.test.js.map +1 -1
- package/dist/tests/WebhookQueue.coverage.test.d.ts +19 -0
- package/dist/tests/WebhookQueue.coverage.test.d.ts.map +1 -0
- package/dist/tests/WebhookQueue.coverage.test.js +190 -0
- package/dist/tests/WebhookQueue.coverage.test.js.map +1 -0
- package/dist/tests/api/client.events.test.d.ts +10 -0
- package/dist/tests/api/client.events.test.d.ts.map +1 -0
- package/dist/tests/api/client.events.test.js +85 -0
- package/dist/tests/api/client.events.test.js.map +1 -0
- package/dist/tests/billing/GDPRCompliance.test.d.ts +2 -2
- package/dist/tests/billing/GDPRCompliance.test.js +221 -36
- package/dist/tests/billing/GDPRCompliance.test.js.map +1 -1
- package/dist/tests/github-import/blocklist.test.d.ts +15 -0
- package/dist/tests/github-import/blocklist.test.d.ts.map +1 -0
- package/dist/tests/github-import/blocklist.test.js +182 -0
- package/dist/tests/github-import/blocklist.test.js.map +1 -0
- package/dist/tests/github-import/signal-of-intent.test.d.ts +15 -0
- package/dist/tests/github-import/signal-of-intent.test.d.ts.map +1 -0
- package/dist/tests/github-import/signal-of-intent.test.js +171 -0
- package/dist/tests/github-import/signal-of-intent.test.js.map +1 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts +12 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.js +15 -3
- package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
- package/dist/tests/security/scanner-wave2-fixtures.test.d.ts +12 -0
- package/dist/tests/security/scanner-wave2-fixtures.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-wave2-fixtures.test.js +173 -0
- package/dist/tests/security/scanner-wave2-fixtures.test.js.map +1 -0
- package/dist/tests/security.test.js +1 -0
- package/dist/tests/security.test.js.map +1 -1
- package/dist/tests/skill-scanner/allowlist.test.d.ts +16 -0
- package/dist/tests/skill-scanner/allowlist.test.d.ts.map +1 -0
- package/dist/tests/skill-scanner/allowlist.test.js +332 -0
- package/dist/tests/skill-scanner/allowlist.test.js.map +1 -0
- package/dist/tests/telemetry.test.js +126 -0
- package/dist/tests/telemetry.test.js.map +1 -1
- package/dist/tests/webhooks/WebhookDeadLetterRepository.test.d.ts +10 -0
- package/dist/tests/webhooks/WebhookDeadLetterRepository.test.d.ts.map +1 -0
- package/dist/tests/webhooks/WebhookDeadLetterRepository.test.js +109 -0
- package/dist/tests/webhooks/WebhookDeadLetterRepository.test.js.map +1 -0
- package/package.json +8 -3
|
@@ -1,20 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Local Filesystem Source Adapter (SMI-591)
|
|
2
|
+
* Local Filesystem Source Adapter (SMI-591, SMI-4287, SMI-4319, SMI-4320)
|
|
3
3
|
*
|
|
4
4
|
* Scans local directories for SKILL.md files.
|
|
5
5
|
* Useful for local development and testing.
|
|
6
|
+
*
|
|
7
|
+
* SMI-4287 hardening:
|
|
8
|
+
* - Symlink targets are resolved via `fs.realpath` and checked against the
|
|
9
|
+
* adapter's `rootDir`. Targets outside root are skipped with a
|
|
10
|
+
* `symlink-escape` warning (unless `allowSymlinksOutsideRoot` is `true`).
|
|
11
|
+
* - Permission (EACCES/EPERM), not-found (ENOENT), and loop (ELOOP) errors
|
|
12
|
+
* are surfaced as `AdapterError` entries on `SourceSearchResult.warnings`
|
|
13
|
+
* instead of throwing, so siblings continue to be scanned.
|
|
14
|
+
* - All `fs.*` calls route through the typed `safeFs` helpers; the historic
|
|
15
|
+
* bare `try/catch` for EACCES in `scanDirectory` is removed.
|
|
16
|
+
*
|
|
17
|
+
* SMI-4319 hardening:
|
|
18
|
+
* - `runScan` allocates a fresh `visitedRealpaths: Set<string>` per
|
|
19
|
+
* invocation so mutually-recursive / self-looping directory symlinks are
|
|
20
|
+
* detected and skipped with a `loop` warning instead of silently wasting
|
|
21
|
+
* `maxDepth` traversals.
|
|
22
|
+
*
|
|
23
|
+
* SMI-4320 hardening:
|
|
24
|
+
* - `resolveSkillPath` is now async and routes through `resolveSafeRealpath`
|
|
25
|
+
* (byte-wise `startsWith(rootReal + sep)` on realpath outputs — no
|
|
26
|
+
* platform lowercasing). Direct-access methods (`getRepository`,
|
|
27
|
+
* `fetchSkillContent`, `skillExists`) inherit containment instead of
|
|
28
|
+
* relying solely on lexical `validatePath`. This closes the scan-to-fetch
|
|
29
|
+
* TOCTOU window where an indexed-then-swapped symlink previously escaped
|
|
30
|
+
* containment. `allowSymlinksOutsideRoot` is honoured at every realpath
|
|
31
|
+
* callsite. Residual TOCTOU between `resolveSkillPath` and the subsequent
|
|
32
|
+
* `fs.readFile` is documented; closing it requires fd-based I/O and is
|
|
33
|
+
* tracked as a separate follow-up.
|
|
6
34
|
*/
|
|
7
35
|
import { BaseSourceAdapter } from './BaseSourceAdapter.js';
|
|
8
36
|
import { createHash } from 'crypto';
|
|
9
|
-
import {
|
|
10
|
-
import { join, basename, dirname, relative, resolve } from 'path';
|
|
37
|
+
import { basename, dirname, resolve, join } from 'path';
|
|
11
38
|
import { createLogger } from '../utils/logger.js';
|
|
12
39
|
import { validatePath, safePatternMatch } from '../validation/index.js';
|
|
40
|
+
import { safeFs, resolveSafeRealpath } from './LocalFilesystemAdapter.helpers.js';
|
|
41
|
+
import { scanDirectoryRecursive, } from './LocalFilesystemAdapter.scan.js';
|
|
13
42
|
const log = createLogger('LocalFilesystemAdapter');
|
|
14
|
-
/**
|
|
15
|
-
* Default skill file names to search for
|
|
16
|
-
*/
|
|
17
|
-
const SKILL_FILE_NAMES = ['SKILL.md', 'skill.md'];
|
|
18
43
|
/**
|
|
19
44
|
* Local Filesystem Source Adapter
|
|
20
45
|
*
|
|
@@ -33,6 +58,9 @@ const SKILL_FILE_NAMES = ['SKILL.md', 'skill.md'];
|
|
|
33
58
|
*
|
|
34
59
|
* await adapter.initialize()
|
|
35
60
|
* const result = await adapter.search({})
|
|
61
|
+
* for (const warning of result.warnings ?? []) {
|
|
62
|
+
* console.warn(`[${warning.code}] ${warning.message}`)
|
|
63
|
+
* }
|
|
36
64
|
* ```
|
|
37
65
|
*/
|
|
38
66
|
export class LocalFilesystemAdapter extends BaseSourceAdapter {
|
|
@@ -40,140 +68,167 @@ export class LocalFilesystemAdapter extends BaseSourceAdapter {
|
|
|
40
68
|
maxDepth;
|
|
41
69
|
excludePatterns;
|
|
42
70
|
followSymlinks;
|
|
71
|
+
allowSymlinksOutsideRoot;
|
|
43
72
|
discoveredSkills = [];
|
|
73
|
+
/**
|
|
74
|
+
* Warnings accumulated during the most recent scan. Consumed and cleared
|
|
75
|
+
* by `search()` so each caller sees only the warnings from that call's
|
|
76
|
+
* underlying scan.
|
|
77
|
+
*/
|
|
78
|
+
scanWarnings = [];
|
|
44
79
|
constructor(config) {
|
|
45
80
|
super(config);
|
|
46
81
|
this.rootDir = config.rootDir;
|
|
47
82
|
this.maxDepth = config.maxDepth ?? 5;
|
|
48
83
|
this.excludePatterns = config.excludePatterns ?? ['node_modules', '.git', '.svn', 'dist'];
|
|
49
84
|
this.followSymlinks = config.followSymlinks ?? false;
|
|
85
|
+
this.allowSymlinksOutsideRoot = config.allowSymlinksOutsideRoot ?? false;
|
|
50
86
|
}
|
|
51
87
|
/**
|
|
52
88
|
* Initialize by scanning the filesystem
|
|
53
89
|
*/
|
|
54
90
|
async doInitialize() {
|
|
55
|
-
|
|
91
|
+
this.scanWarnings = [];
|
|
92
|
+
await this.runScan();
|
|
56
93
|
}
|
|
57
94
|
/**
|
|
58
|
-
* Check if root directory exists and is accessible
|
|
95
|
+
* Check if root directory exists and is accessible.
|
|
96
|
+
*
|
|
97
|
+
* SMI-4287: routes `fs.stat(rootDir)` through `safeFs` so the raw Node
|
|
98
|
+
* error is translated to a typed `AdapterError` message.
|
|
59
99
|
*/
|
|
60
100
|
async doHealthCheck() {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
healthy: stats.isDirectory(),
|
|
65
|
-
error: stats.isDirectory() ? undefined : 'Root path is not a directory',
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
101
|
+
const statResult = await safeFs.stat(this.rootDir);
|
|
102
|
+
if (!statResult.ok) {
|
|
69
103
|
return {
|
|
70
104
|
healthy: false,
|
|
71
|
-
error: error
|
|
105
|
+
error: statResult.error.message,
|
|
72
106
|
};
|
|
73
107
|
}
|
|
108
|
+
return {
|
|
109
|
+
healthy: statResult.value.isDirectory(),
|
|
110
|
+
error: statResult.value.isDirectory() ? undefined : 'Root path is not a directory',
|
|
111
|
+
};
|
|
74
112
|
}
|
|
75
113
|
/**
|
|
76
|
-
* Search for skills in the scanned directories
|
|
114
|
+
* Search for skills in the scanned directories.
|
|
115
|
+
*
|
|
116
|
+
* SMI-4287: `warnings` collects non-fatal `AdapterError` entries from the
|
|
117
|
+
* scan (symlink escapes, permission denials, loops). An empty array is
|
|
118
|
+
* returned as `undefined` to keep the field strictly optional.
|
|
77
119
|
*/
|
|
78
120
|
async search(options = {}) {
|
|
79
|
-
// Re-scan if needed
|
|
80
121
|
if (this.discoveredSkills.length === 0) {
|
|
81
|
-
|
|
122
|
+
this.scanWarnings = [];
|
|
123
|
+
await this.runScan();
|
|
82
124
|
}
|
|
83
125
|
let filtered = [...this.discoveredSkills];
|
|
84
|
-
// Filter by query (search in path/directory name)
|
|
85
126
|
if (options.query) {
|
|
86
127
|
const query = options.query.toLowerCase();
|
|
87
128
|
filtered = filtered.filter((skill) => skill.relativePath.toLowerCase().includes(query) ||
|
|
88
129
|
skill.directory.toLowerCase().includes(query));
|
|
89
130
|
}
|
|
90
|
-
// Apply limit
|
|
91
131
|
const limit = options.limit ?? 100;
|
|
92
132
|
const limitedResults = filtered.slice(0, limit);
|
|
93
|
-
|
|
94
|
-
const repositories =
|
|
133
|
+
const repositoriesWithWarnings = await Promise.all(limitedResults.map((skill) => this.skillToRepository(skill)));
|
|
134
|
+
const repositories = repositoriesWithWarnings.map((r) => r.repo);
|
|
135
|
+
const repoWarnings = repositoriesWithWarnings.flatMap((r) => r.warnings);
|
|
136
|
+
const allWarnings = [...this.scanWarnings, ...repoWarnings];
|
|
95
137
|
return {
|
|
96
138
|
repositories,
|
|
97
139
|
totalCount: filtered.length,
|
|
98
140
|
hasMore: filtered.length > limit,
|
|
141
|
+
warnings: allWarnings.length > 0 ? allWarnings : undefined,
|
|
99
142
|
};
|
|
100
143
|
}
|
|
101
144
|
/**
|
|
102
|
-
* Get repository info for a skill location
|
|
145
|
+
* Get repository info for a skill location.
|
|
146
|
+
*
|
|
147
|
+
* SMI-4287: `fs.stat` is routed through `safeFs`; permission errors are
|
|
148
|
+
* converted to typed Error messages instead of raw Node throws.
|
|
103
149
|
*/
|
|
104
150
|
async getRepository(location) {
|
|
105
|
-
const skillPath = this.resolveSkillPath(location);
|
|
151
|
+
const skillPath = await this.resolveSkillPath(location);
|
|
106
152
|
const skill = this.discoveredSkills.find((s) => s.path === skillPath);
|
|
107
153
|
if (skill) {
|
|
108
|
-
|
|
154
|
+
const { repo } = await this.skillToRepository(skill);
|
|
155
|
+
return repo;
|
|
109
156
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
id: this.generateId(skillPath),
|
|
115
|
-
name: basename(dirname(skillPath)),
|
|
116
|
-
url: `file://${skillPath}`,
|
|
117
|
-
description: null,
|
|
118
|
-
owner: 'local',
|
|
119
|
-
defaultBranch: 'main',
|
|
120
|
-
stars: 0,
|
|
121
|
-
forks: 0,
|
|
122
|
-
topics: ['local'],
|
|
123
|
-
updatedAt: stats.mtime.toISOString(),
|
|
124
|
-
createdAt: stats.ctime.toISOString(),
|
|
125
|
-
license: null,
|
|
126
|
-
metadata: {
|
|
127
|
-
sourceType: 'local',
|
|
128
|
-
path: skillPath,
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
throw new Error(`Skill not found at ${skillPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
157
|
+
const statResult = await safeFs.stat(skillPath);
|
|
158
|
+
if (!statResult.ok) {
|
|
159
|
+
throw new Error(`Skill not found at ${skillPath}: ${statResult.error.message}`);
|
|
134
160
|
}
|
|
161
|
+
const stats = statResult.value;
|
|
162
|
+
return {
|
|
163
|
+
id: this.generateId(skillPath),
|
|
164
|
+
name: basename(dirname(skillPath)),
|
|
165
|
+
url: `file://${skillPath}`,
|
|
166
|
+
description: null,
|
|
167
|
+
owner: 'local',
|
|
168
|
+
defaultBranch: 'main',
|
|
169
|
+
stars: 0,
|
|
170
|
+
forks: 0,
|
|
171
|
+
topics: ['local'],
|
|
172
|
+
updatedAt: stats.mtime.toISOString(),
|
|
173
|
+
createdAt: stats.ctime.toISOString(),
|
|
174
|
+
license: null,
|
|
175
|
+
metadata: {
|
|
176
|
+
sourceType: 'local',
|
|
177
|
+
path: skillPath,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
135
180
|
}
|
|
136
181
|
/**
|
|
137
|
-
* Fetch skill content from local file
|
|
182
|
+
* Fetch skill content from local file.
|
|
183
|
+
*
|
|
184
|
+
* SMI-4287: both `fs.readFile` and `fs.stat` route through `safeFs`, so
|
|
185
|
+
* permission errors (EACCES/EPERM) raise typed Errors with path context
|
|
186
|
+
* instead of raw Node errors.
|
|
138
187
|
*/
|
|
139
188
|
async fetchSkillContent(location) {
|
|
140
|
-
const skillPath = this.resolveSkillPath(location);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const sha = this.generateSha(rawContent);
|
|
145
|
-
return {
|
|
146
|
-
rawContent,
|
|
147
|
-
sha,
|
|
148
|
-
location,
|
|
149
|
-
filePath: skillPath,
|
|
150
|
-
encoding: 'utf-8',
|
|
151
|
-
lastModified: stats.mtime.toISOString(),
|
|
152
|
-
};
|
|
189
|
+
const skillPath = await this.resolveSkillPath(location);
|
|
190
|
+
const contentResult = await safeFs.readFile(skillPath);
|
|
191
|
+
if (!contentResult.ok) {
|
|
192
|
+
throw new Error(`Failed to read skill file at ${skillPath}: ${contentResult.error.message}`);
|
|
153
193
|
}
|
|
154
|
-
|
|
155
|
-
|
|
194
|
+
const statResult = await safeFs.stat(skillPath);
|
|
195
|
+
if (!statResult.ok) {
|
|
196
|
+
throw new Error(`Failed to stat skill file at ${skillPath}: ${statResult.error.message}`);
|
|
156
197
|
}
|
|
198
|
+
const rawContent = contentResult.value;
|
|
199
|
+
const stats = statResult.value;
|
|
200
|
+
const sha = this.generateSha(rawContent);
|
|
201
|
+
return {
|
|
202
|
+
rawContent,
|
|
203
|
+
sha,
|
|
204
|
+
location,
|
|
205
|
+
filePath: skillPath,
|
|
206
|
+
encoding: 'utf-8',
|
|
207
|
+
lastModified: stats.mtime.toISOString(),
|
|
208
|
+
};
|
|
157
209
|
}
|
|
158
210
|
/**
|
|
159
211
|
* Check if skill exists at location
|
|
160
212
|
*/
|
|
161
213
|
async skillExists(location) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
214
|
+
// SMI-720 contract: lexical path-traversal attempts throw
|
|
215
|
+
// `ValidationError('Path traversal detected: ...')` from `resolveSkillPath`
|
|
216
|
+
// — callers (and the SMI-720 test suite) rely on this. Only absence on
|
|
217
|
+
// disk should return `false`; traversal attempts surface as exceptions.
|
|
218
|
+
const skillPath = await this.resolveSkillPath(location);
|
|
219
|
+
const statResult = await safeFs.stat(skillPath);
|
|
220
|
+
return statResult.ok;
|
|
170
221
|
}
|
|
171
222
|
/**
|
|
172
|
-
* Rescan the filesystem for new skills
|
|
223
|
+
* Rescan the filesystem for new skills.
|
|
224
|
+
*
|
|
225
|
+
* Returns the count of discovered skills. Warnings from the rescan are
|
|
226
|
+
* available via the next call to `search()`.
|
|
173
227
|
*/
|
|
174
228
|
async rescan() {
|
|
175
229
|
this.discoveredSkills = [];
|
|
176
|
-
|
|
230
|
+
this.scanWarnings = [];
|
|
231
|
+
await this.runScan();
|
|
177
232
|
return this.discoveredSkills.length;
|
|
178
233
|
}
|
|
179
234
|
/**
|
|
@@ -183,59 +238,27 @@ export class LocalFilesystemAdapter extends BaseSourceAdapter {
|
|
|
183
238
|
return this.discoveredSkills.length;
|
|
184
239
|
}
|
|
185
240
|
/**
|
|
186
|
-
*
|
|
241
|
+
* Run the recursive scan starting at `rootDir`. Delegates to the extracted
|
|
242
|
+
* `scanDirectoryRecursive` helper (see `LocalFilesystemAdapter.scan.ts`).
|
|
243
|
+
*
|
|
244
|
+
* SMI-4319: allocates a fresh `visitedRealpaths` set per invocation so
|
|
245
|
+
* back-to-back scans don't share state. Sibling directories within a
|
|
246
|
+
* single scan share the set (they're in the same call tree), so
|
|
247
|
+
* cross-linked loops (A↔B) are caught even when the loop isn't on the
|
|
248
|
+
* descent path from `rootDir`.
|
|
187
249
|
*/
|
|
188
|
-
async
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
let isFile = entry.isFile();
|
|
201
|
-
if (entry.isSymbolicLink()) {
|
|
202
|
-
if (!this.followSymlinks)
|
|
203
|
-
continue;
|
|
204
|
-
try {
|
|
205
|
-
const stats = await fs.stat(fullPath);
|
|
206
|
-
isDirectory = stats.isDirectory();
|
|
207
|
-
isFile = stats.isFile();
|
|
208
|
-
}
|
|
209
|
-
catch {
|
|
210
|
-
continue; // Skip broken symlinks
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
// Check for skill files
|
|
214
|
-
if (isFile && SKILL_FILE_NAMES.includes(entry.name)) {
|
|
215
|
-
const stats = await fs.stat(fullPath);
|
|
216
|
-
this.discoveredSkills.push({
|
|
217
|
-
path: fullPath,
|
|
218
|
-
relativePath: relative(this.rootDir, fullPath),
|
|
219
|
-
directory: dirname(fullPath),
|
|
220
|
-
stats: {
|
|
221
|
-
size: stats.size,
|
|
222
|
-
mtime: stats.mtime,
|
|
223
|
-
ctime: stats.ctime,
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
// Recurse into directories
|
|
228
|
-
if (isDirectory) {
|
|
229
|
-
await this.scanDirectory(fullPath, depth + 1);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
catch (error) {
|
|
234
|
-
// Ignore permission errors and continue scanning
|
|
235
|
-
if (error.code !== 'EACCES') {
|
|
236
|
-
log.warn(`Error scanning directory ${dirPath}: ${error}`);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
250
|
+
async runScan() {
|
|
251
|
+
await scanDirectoryRecursive(this.rootDir, 0, {
|
|
252
|
+
rootDir: this.rootDir,
|
|
253
|
+
maxDepth: this.maxDepth,
|
|
254
|
+
followSymlinks: this.followSymlinks,
|
|
255
|
+
allowSymlinksOutsideRoot: this.allowSymlinksOutsideRoot,
|
|
256
|
+
isExcluded: (name) => this.isExcluded(name),
|
|
257
|
+
discovered: this.discoveredSkills,
|
|
258
|
+
warnings: this.scanWarnings,
|
|
259
|
+
visitedRealpaths: new Set(),
|
|
260
|
+
log,
|
|
261
|
+
});
|
|
239
262
|
}
|
|
240
263
|
/**
|
|
241
264
|
* Check if a path/name should be excluded (SMI-722, SMI-726)
|
|
@@ -246,9 +269,22 @@ export class LocalFilesystemAdapter extends BaseSourceAdapter {
|
|
|
246
269
|
}
|
|
247
270
|
/**
|
|
248
271
|
* Resolve a skill location to a full filesystem path
|
|
249
|
-
*
|
|
272
|
+
* (SMI-720, SMI-726, SMI-4287, SMI-4320).
|
|
273
|
+
*
|
|
274
|
+
* Two-stage containment: (1) lexical `validatePath` fast-fails
|
|
275
|
+
* `../`-style traversal (SMI-720 contract — callers assert the
|
|
276
|
+
* "Path traversal detected" message), then (2) `resolveSafeRealpath`
|
|
277
|
+
* enforces realpath byte-wise containment so symlinks can't escape
|
|
278
|
+
* `rootDir` even when the lexical path is clean. Honours the SMI-4287
|
|
279
|
+
* `allowSymlinksOutsideRoot` opt-in.
|
|
280
|
+
*
|
|
281
|
+
* Not-found behaviour: realpath ENOENT falls back to the lexically
|
|
282
|
+
* resolved path so downstream `stat` / `readFile` produce the canonical
|
|
283
|
+
* caller-visible error. TOCTOU caveat: the window between this resolve
|
|
284
|
+
* and the caller's subsequent read remains open; closing it requires
|
|
285
|
+
* fd-based I/O and is tracked separately.
|
|
250
286
|
*/
|
|
251
|
-
resolveSkillPath(location) {
|
|
287
|
+
async resolveSkillPath(location) {
|
|
252
288
|
let resolvedPath;
|
|
253
289
|
if (location.path?.startsWith('/')) {
|
|
254
290
|
resolvedPath = location.path;
|
|
@@ -265,53 +301,76 @@ export class LocalFilesystemAdapter extends BaseSourceAdapter {
|
|
|
265
301
|
else {
|
|
266
302
|
throw new Error('Invalid location: must specify path or repo');
|
|
267
303
|
}
|
|
268
|
-
//
|
|
304
|
+
// Lexical fast-fail (SMI-720 contract — callers test for
|
|
305
|
+
// "Path traversal detected" on obvious traversal attempts).
|
|
269
306
|
validatePath(resolvedPath, this.rootDir);
|
|
270
|
-
|
|
307
|
+
const absolutePath = resolve(resolvedPath);
|
|
308
|
+
// SMI-4320: realpath-based containment. Honours SMI-4287 opt-in.
|
|
309
|
+
const realResult = await resolveSafeRealpath(absolutePath, this.rootDir, {
|
|
310
|
+
allowSymlinksOutsideRoot: this.allowSymlinksOutsideRoot,
|
|
311
|
+
});
|
|
312
|
+
if (realResult.ok) {
|
|
313
|
+
return realResult.value;
|
|
314
|
+
}
|
|
315
|
+
// `not-found` is expected for skillExists / fetchSkillContent on paths
|
|
316
|
+
// that the caller hasn't verified exist. Fall back to the lexically
|
|
317
|
+
// resolved path so downstream `stat` / `readFile` produce the canonical
|
|
318
|
+
// error message callers already depend on.
|
|
319
|
+
if (realResult.error.code === 'not-found') {
|
|
320
|
+
return absolutePath;
|
|
321
|
+
}
|
|
322
|
+
// `symlink-escape`, `loop`, `permission`, `io` all throw — the caller
|
|
323
|
+
// asked for a path that either escapes root or can't be validated.
|
|
324
|
+
throw new Error(`Path rejected by realpath containment: ${realResult.error.message}`);
|
|
271
325
|
}
|
|
272
326
|
/**
|
|
273
|
-
* Convert discovered skill to SourceRepository
|
|
327
|
+
* Convert discovered skill to SourceRepository.
|
|
328
|
+
*
|
|
329
|
+
* Returns both the repository and any warnings encountered while reading
|
|
330
|
+
* the file (typically permission errors on SKILL.md after discovery).
|
|
274
331
|
*/
|
|
275
332
|
async skillToRepository(skill) {
|
|
276
333
|
const dirName = basename(skill.directory);
|
|
277
|
-
|
|
334
|
+
const warnings = [];
|
|
278
335
|
let description = null;
|
|
279
336
|
let name = dirName;
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
337
|
+
const contentResult = await safeFs.readFile(skill.path);
|
|
338
|
+
if (contentResult.ok) {
|
|
339
|
+
const content = contentResult.value;
|
|
283
340
|
const nameMatch = content.match(/^---[\s\S]*?name:\s*["']?([^"'\n]+)["']?/m);
|
|
284
341
|
if (nameMatch) {
|
|
285
342
|
name = nameMatch[1].trim();
|
|
286
343
|
}
|
|
287
|
-
// Try to extract description from frontmatter
|
|
288
344
|
const descMatch = content.match(/^---[\s\S]*?description:\s*["']?([^"'\n]+)["']?/m);
|
|
289
345
|
if (descMatch) {
|
|
290
346
|
description = descMatch[1].trim();
|
|
291
347
|
}
|
|
292
348
|
}
|
|
293
|
-
|
|
294
|
-
|
|
349
|
+
else {
|
|
350
|
+
warnings.push(contentResult.error);
|
|
295
351
|
}
|
|
296
352
|
return {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
353
|
+
repo: {
|
|
354
|
+
id: this.generateId(skill.path),
|
|
355
|
+
name,
|
|
356
|
+
url: `file://${skill.path}`,
|
|
357
|
+
description,
|
|
358
|
+
owner: 'local',
|
|
359
|
+
defaultBranch: 'main',
|
|
360
|
+
stars: 0,
|
|
361
|
+
forks: 0,
|
|
362
|
+
topics: ['local'],
|
|
363
|
+
updatedAt: skill.stats.mtime.toISOString(),
|
|
364
|
+
createdAt: skill.stats.ctime.toISOString(),
|
|
365
|
+
license: null,
|
|
366
|
+
metadata: {
|
|
367
|
+
sourceType: 'local',
|
|
368
|
+
path: skill.path,
|
|
369
|
+
relativePath: skill.relativePath,
|
|
370
|
+
size: skill.stats.size,
|
|
371
|
+
},
|
|
314
372
|
},
|
|
373
|
+
warnings,
|
|
315
374
|
};
|
|
316
375
|
}
|
|
317
376
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalFilesystemAdapter.js","sourceRoot":"","sources":["../../../src/sources/LocalFilesystemAdapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"LocalFilesystemAdapter.js","sourceRoot":"","sources":["../../../src/sources/LocalFilesystemAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LocalFilesystemAdapter scan loop (SMI-4287, SMI-4319)
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `LocalFilesystemAdapter.ts` to keep the main adapter file
|
|
5
|
+
* under the 500-line governance ceiling. Pure function of its inputs — no
|
|
6
|
+
* shared instance state other than the `warnings` sink.
|
|
7
|
+
*
|
|
8
|
+
* SMI-4319: tracks visited directory realpaths in a per-scan `Set<string>`
|
|
9
|
+
* so mutually-recursive symlinks (A→B, B→A) are detected and skipped with a
|
|
10
|
+
* `loop` warning. Each `scanDirectoryRecursive` invocation checks the set
|
|
11
|
+
* BEFORE recursing; the set is keyed on the raw realpath (no
|
|
12
|
+
* `normaliseForFs`) so legitimate case-sensitive distinctions are preserved.
|
|
13
|
+
* Loop detection runs regardless of `allowSymlinksOutsideRoot` — loops are a
|
|
14
|
+
* correctness issue (infinite work), not a security issue.
|
|
15
|
+
*/
|
|
16
|
+
import type { AdapterError } from './types.js';
|
|
17
|
+
import type { createLogger } from '../utils/logger.js';
|
|
18
|
+
/**
|
|
19
|
+
* File names that identify a skill definition.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SKILL_FILE_NAMES: string[];
|
|
22
|
+
/**
|
|
23
|
+
* Shape shared with `LocalFilesystemAdapter.DiscoveredSkill`.
|
|
24
|
+
*/
|
|
25
|
+
export interface DiscoveredSkillRecord {
|
|
26
|
+
path: string;
|
|
27
|
+
relativePath: string;
|
|
28
|
+
directory: string;
|
|
29
|
+
stats: {
|
|
30
|
+
size: number;
|
|
31
|
+
mtime: Date;
|
|
32
|
+
ctime: Date;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Configuration consumed by the scan loop.
|
|
37
|
+
*/
|
|
38
|
+
export interface ScanDirectoryOptions {
|
|
39
|
+
/** Root directory (used for relative path calculations). */
|
|
40
|
+
rootDir: string;
|
|
41
|
+
/** Maximum recursion depth. */
|
|
42
|
+
maxDepth: number;
|
|
43
|
+
/** If false, symlinks are skipped entirely. */
|
|
44
|
+
followSymlinks: boolean;
|
|
45
|
+
/** If true, skip the symlink-containment check. */
|
|
46
|
+
allowSymlinksOutsideRoot: boolean;
|
|
47
|
+
/** Predicate for name-based exclusion. */
|
|
48
|
+
isExcluded: (name: string) => boolean;
|
|
49
|
+
/** Destination array for discovered skills (mutated in place). */
|
|
50
|
+
discovered: DiscoveredSkillRecord[];
|
|
51
|
+
/** Destination array for non-fatal errors (mutated in place). */
|
|
52
|
+
warnings: AdapterError[];
|
|
53
|
+
/**
|
|
54
|
+
* Visited directory realpaths for this scan (SMI-4319). Mutated in place.
|
|
55
|
+
* Keyed on the raw realpath string (no platform lowercasing). Must be a
|
|
56
|
+
* fresh `Set` per `runScan` invocation so back-to-back scans don't share
|
|
57
|
+
* state.
|
|
58
|
+
*/
|
|
59
|
+
visitedRealpaths: Set<string>;
|
|
60
|
+
/** Logger instance from the parent adapter. */
|
|
61
|
+
log: ReturnType<typeof createLogger>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Recursively scan `dirPath` for `SKILL.md` files, populating
|
|
65
|
+
* `options.discovered` and `options.warnings` in place.
|
|
66
|
+
*
|
|
67
|
+
* SMI-4287: all filesystem access routes through `safeFs`. Per-entry errors
|
|
68
|
+
* are recorded on `warnings` and the scan continues for siblings.
|
|
69
|
+
*
|
|
70
|
+
* SMI-4319: before descending, realpath `dirPath` and check
|
|
71
|
+
* `options.visitedRealpaths` for a prior visit. On hit, push a `loop` warning
|
|
72
|
+
* and return — prevents A↔B / self-loop directory symlinks from wasting
|
|
73
|
+
* `maxDepth` traversals and surfacing the same SKILL.md under multiple
|
|
74
|
+
* lexical paths. Realpath errors (permission, ENOENT, ELOOP on the dir
|
|
75
|
+
* itself) are recorded and the subtree is skipped.
|
|
76
|
+
*/
|
|
77
|
+
export declare function scanDirectoryRecursive(dirPath: string, depth: number, options: ScanDirectoryOptions): Promise<void>;
|
|
78
|
+
//# sourceMappingURL=LocalFilesystemAdapter.scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalFilesystemAdapter.scan.d.ts","sourceRoot":"","sources":["../../../src/sources/LocalFilesystemAdapter.scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD;;GAEG;AACH,eAAO,MAAM,gBAAgB,UAA2B,CAAA;AAExD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,IAAI,CAAA;QACX,KAAK,EAAE,IAAI,CAAA;KACZ,CAAA;CACF;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAA;IACf,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,+CAA+C;IAC/C,cAAc,EAAE,OAAO,CAAA;IACvB,mDAAmD;IACnD,wBAAwB,EAAE,OAAO,CAAA;IACjC,0CAA0C;IAC1C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;IACrC,kEAAkE;IAClE,UAAU,EAAE,qBAAqB,EAAE,CAAA;IACnC,iEAAiE;IACjE,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB;;;;;OAKG;IACH,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC7B,+CAA+C;IAC/C,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;CACrC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAuFf"}
|