@feiyoug/skill-lab 0.0.0 → 0.0.2
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/README.md +73 -0
- package/esm/analyzer/astgrep/client.d.ts +20 -8
- package/esm/analyzer/astgrep/client.d.ts.map +1 -1
- package/esm/analyzer/astgrep/client.js +58 -31
- package/esm/analyzer/config/default.d.ts +8 -0
- package/esm/analyzer/config/default.d.ts.map +1 -0
- package/esm/analyzer/config/default.js +91 -0
- package/esm/analyzer/config/helpers.d.ts +8 -0
- package/esm/analyzer/config/helpers.d.ts.map +1 -0
- package/esm/analyzer/config/helpers.js +72 -0
- package/esm/analyzer/config/mod.d.ts +4 -0
- package/esm/analyzer/config/mod.d.ts.map +1 -0
- package/esm/analyzer/config/mod.js +3 -0
- package/esm/analyzer/config/types.d.ts +58 -0
- package/esm/analyzer/config/types.d.ts.map +1 -0
- package/esm/analyzer/{config.js → config/types.js} +0 -28
- package/esm/analyzer/logging.d.ts +3 -0
- package/esm/analyzer/logging.d.ts.map +1 -0
- package/esm/analyzer/logging.js +6 -0
- package/esm/analyzer/mod.d.ts +12 -5
- package/esm/analyzer/mod.d.ts.map +1 -1
- package/esm/analyzer/mod.js +25 -12
- package/esm/analyzer/result.d.ts +35 -0
- package/esm/analyzer/result.d.ts.map +1 -0
- package/esm/analyzer/result.js +311 -0
- package/esm/analyzer/rules/bash/commands/mod.d.ts +1 -0
- package/esm/analyzer/rules/bash/commands/mod.d.ts.map +1 -1
- package/esm/analyzer/rules/bash/commands/mod.js +3 -0
- package/esm/analyzer/rules/bash/commands/pip.d.ts +3 -0
- package/esm/analyzer/rules/bash/commands/pip.d.ts.map +1 -0
- package/esm/analyzer/rules/bash/commands/pip.js +14 -0
- package/esm/analyzer/rules/bash/extractFileRefs.d.ts +1 -1
- package/esm/analyzer/rules/bash/extractFileRefs.d.ts.map +1 -1
- package/esm/analyzer/rules/bash/extractFileRefs.js +2 -2
- package/esm/analyzer/rules/bash/inline-command-classifier.d.ts +1 -1
- package/esm/analyzer/rules/bash/inline-command-classifier.d.ts.map +1 -1
- package/esm/analyzer/rules/bash/inline-command-classifier.js +4 -4
- package/esm/analyzer/rules/javascript/extractFileRefs.d.ts +3 -4
- package/esm/analyzer/rules/javascript/extractFileRefs.d.ts.map +1 -1
- package/esm/analyzer/rules/javascript/extractFileRefs.js +3 -4
- package/esm/analyzer/rules/markdown/extractCodeBlocks.d.ts.map +1 -1
- package/esm/analyzer/rules/markdown/extractCodeBlocks.js +6 -3
- package/esm/analyzer/rules/markdown/extractFileRefs.d.ts.map +1 -1
- package/esm/analyzer/rules/markdown/extractFileRefs.js +2 -0
- package/esm/analyzer/rules/python/extractFileRefs.d.ts +1 -1
- package/esm/analyzer/rules/python/extractFileRefs.d.ts.map +1 -1
- package/esm/analyzer/rules/python/extractFileRefs.js +2 -2
- package/esm/analyzer/steps/001-discovery/discover-files.d.ts +4 -0
- package/esm/analyzer/steps/001-discovery/discover-files.d.ts.map +1 -1
- package/esm/analyzer/steps/001-discovery/discover-files.js +18 -2
- package/esm/analyzer/steps/001-discovery/mod.d.ts.map +1 -1
- package/esm/analyzer/steps/001-discovery/mod.js +39 -9
- package/esm/analyzer/steps/002-permissions/mod.d.ts.map +1 -1
- package/esm/analyzer/steps/002-permissions/mod.js +156 -73
- package/esm/analyzer/steps/002-permissions/scan-file.d.ts +1 -1
- package/esm/analyzer/steps/002-permissions/scan-file.d.ts.map +1 -1
- package/esm/analyzer/steps/002-permissions/scan-file.js +40 -5
- package/esm/analyzer/steps/002-permissions/seed-frontmatter.js +2 -2
- package/esm/analyzer/steps/003-risks/dep-risks.d.ts +3 -0
- package/esm/analyzer/steps/003-risks/dep-risks.d.ts.map +1 -0
- package/esm/analyzer/steps/003-risks/dep-risks.js +74 -0
- package/esm/analyzer/steps/003-risks/helpers.d.ts +1 -0
- package/esm/analyzer/steps/003-risks/helpers.d.ts.map +1 -1
- package/esm/analyzer/steps/003-risks/helpers.js +1 -0
- package/esm/analyzer/steps/003-risks/mod.d.ts +3 -2
- package/esm/analyzer/steps/003-risks/mod.d.ts.map +1 -1
- package/esm/analyzer/steps/003-risks/mod.js +41 -4
- package/esm/analyzer/steps/003-risks/policy.d.ts +7 -0
- package/esm/analyzer/steps/003-risks/policy.d.ts.map +1 -0
- package/esm/analyzer/steps/003-risks/policy.js +23 -0
- package/esm/analyzer/steps/003-risks/rule-mapped.d.ts +2 -2
- package/esm/analyzer/steps/003-risks/rule-mapped.d.ts.map +1 -1
- package/esm/analyzer/steps/003-risks/rule-mapped.js +83 -2
- package/esm/analyzer/steps/003-risks/scoring.d.ts +9 -1
- package/esm/analyzer/steps/003-risks/scoring.d.ts.map +1 -1
- package/esm/analyzer/steps/003-risks/scoring.js +55 -42
- package/esm/analyzer/treesitter/client.d.ts +31 -0
- package/esm/analyzer/treesitter/client.d.ts.map +1 -0
- package/esm/analyzer/{treesiter → treesitter}/client.js +43 -39
- package/esm/analyzer/treesitter/registry.d.ts +73 -0
- package/esm/analyzer/treesitter/registry.d.ts.map +1 -0
- package/esm/analyzer/treesitter/registry.js +165 -0
- package/esm/analyzer/types.d.ts +14 -28
- package/esm/analyzer/types.d.ts.map +1 -1
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/deps.d.ts +3 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/deps.d.ts.map +1 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/deps.js +3 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/mod.d.ts +93 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/mod.js +297 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/multi.d.ts +84 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/multi.d.ts.map +1 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/multi.js +268 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/time.d.ts +18 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/time.d.ts.map +1 -0
- package/esm/deps/jsr.io/@deno-library/progress/1.5.1/time.js +45 -0
- package/esm/deps/jsr.io/@std/fmt/1.0.3/colors.d.ts +700 -0
- package/esm/deps/jsr.io/@std/fmt/1.0.3/colors.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/fmt/1.0.3/colors.js +903 -0
- package/esm/deps/jsr.io/@std/io/0.225.0/types.d.ts +146 -0
- package/esm/deps/jsr.io/@std/io/0.225.0/types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/io/0.225.0/types.js +15 -0
- package/esm/deps/jsr.io/@std/io/0.225.0/write_all.d.ts +51 -0
- package/esm/deps/jsr.io/@std/io/0.225.0/write_all.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/io/0.225.0/write_all.js +61 -0
- package/esm/shared/deep_merge.d.ts +12 -0
- package/esm/shared/deep_merge.d.ts.map +1 -0
- package/esm/shared/deep_merge.js +49 -0
- package/esm/shared/mod.d.ts +1 -0
- package/esm/shared/mod.d.ts.map +1 -1
- package/esm/shared/mod.js +1 -0
- package/esm/shared/types/filetypes.d.ts +2 -2
- package/esm/shared/types/filetypes.d.ts.map +1 -1
- package/esm/shared/types/permissions.d.ts +1 -1
- package/esm/shared/types/permissions.d.ts.map +1 -1
- package/esm/shared/types/risks.d.ts +4 -1
- package/esm/shared/types/risks.d.ts.map +1 -1
- package/esm/skillreader/types.d.ts +2 -2
- package/esm/skillreader/types.d.ts.map +1 -1
- package/esm/skillreader/types.js +2 -2
- package/package.json +1 -1
- package/script/analyzer/astgrep/client.d.ts +20 -8
- package/script/analyzer/astgrep/client.d.ts.map +1 -1
- package/script/analyzer/astgrep/client.js +58 -64
- package/script/analyzer/config/default.d.ts +8 -0
- package/script/analyzer/config/default.d.ts.map +1 -0
- package/script/analyzer/config/default.js +94 -0
- package/script/analyzer/config/helpers.d.ts +8 -0
- package/script/analyzer/config/helpers.d.ts.map +1 -0
- package/script/analyzer/config/helpers.js +76 -0
- package/script/analyzer/config/mod.d.ts +4 -0
- package/script/analyzer/config/mod.d.ts.map +1 -0
- package/script/analyzer/config/mod.js +21 -0
- package/script/analyzer/config/types.d.ts +58 -0
- package/script/analyzer/config/types.d.ts.map +1 -0
- package/script/analyzer/{config.js → config/types.js} +1 -29
- package/script/analyzer/logging.d.ts +3 -0
- package/script/analyzer/logging.d.ts.map +1 -0
- package/script/analyzer/logging.js +9 -0
- package/script/analyzer/mod.d.ts +12 -5
- package/script/analyzer/mod.d.ts.map +1 -1
- package/script/analyzer/mod.js +35 -20
- package/script/analyzer/result.d.ts +35 -0
- package/script/analyzer/result.d.ts.map +1 -0
- package/script/analyzer/result.js +315 -0
- package/script/analyzer/rules/bash/commands/mod.d.ts +1 -0
- package/script/analyzer/rules/bash/commands/mod.d.ts.map +1 -1
- package/script/analyzer/rules/bash/commands/mod.js +3 -0
- package/script/analyzer/rules/bash/commands/pip.d.ts +3 -0
- package/script/analyzer/rules/bash/commands/pip.d.ts.map +1 -0
- package/script/analyzer/rules/bash/commands/pip.js +17 -0
- package/script/analyzer/rules/bash/extractFileRefs.d.ts +1 -1
- package/script/analyzer/rules/bash/extractFileRefs.d.ts.map +1 -1
- package/script/analyzer/rules/bash/extractFileRefs.js +2 -2
- package/script/analyzer/rules/bash/inline-command-classifier.d.ts +1 -1
- package/script/analyzer/rules/bash/inline-command-classifier.d.ts.map +1 -1
- package/script/analyzer/rules/bash/inline-command-classifier.js +4 -4
- package/script/analyzer/rules/javascript/extractFileRefs.d.ts +3 -4
- package/script/analyzer/rules/javascript/extractFileRefs.d.ts.map +1 -1
- package/script/analyzer/rules/javascript/extractFileRefs.js +3 -4
- package/script/analyzer/rules/markdown/extractCodeBlocks.d.ts.map +1 -1
- package/script/analyzer/rules/markdown/extractCodeBlocks.js +6 -3
- package/script/analyzer/rules/markdown/extractFileRefs.d.ts.map +1 -1
- package/script/analyzer/rules/markdown/extractFileRefs.js +2 -0
- package/script/analyzer/rules/python/extractFileRefs.d.ts +1 -1
- package/script/analyzer/rules/python/extractFileRefs.d.ts.map +1 -1
- package/script/analyzer/rules/python/extractFileRefs.js +2 -2
- package/script/analyzer/steps/001-discovery/discover-files.d.ts +4 -0
- package/script/analyzer/steps/001-discovery/discover-files.d.ts.map +1 -1
- package/script/analyzer/steps/001-discovery/discover-files.js +18 -2
- package/script/analyzer/steps/001-discovery/mod.d.ts.map +1 -1
- package/script/analyzer/steps/001-discovery/mod.js +77 -11
- package/script/analyzer/steps/002-permissions/mod.d.ts.map +1 -1
- package/script/analyzer/steps/002-permissions/mod.js +194 -75
- package/script/analyzer/steps/002-permissions/scan-file.d.ts +1 -1
- package/script/analyzer/steps/002-permissions/scan-file.d.ts.map +1 -1
- package/script/analyzer/steps/002-permissions/scan-file.js +40 -5
- package/script/analyzer/steps/002-permissions/seed-frontmatter.js +3 -3
- package/script/analyzer/steps/003-risks/dep-risks.d.ts +3 -0
- package/script/analyzer/steps/003-risks/dep-risks.d.ts.map +1 -0
- package/script/analyzer/steps/003-risks/dep-risks.js +77 -0
- package/script/analyzer/steps/003-risks/helpers.d.ts +1 -0
- package/script/analyzer/steps/003-risks/helpers.d.ts.map +1 -1
- package/script/analyzer/steps/003-risks/helpers.js +1 -0
- package/script/analyzer/steps/003-risks/mod.d.ts +3 -2
- package/script/analyzer/steps/003-risks/mod.d.ts.map +1 -1
- package/script/analyzer/steps/003-risks/mod.js +77 -4
- package/script/analyzer/steps/003-risks/policy.d.ts +7 -0
- package/script/analyzer/steps/003-risks/policy.d.ts.map +1 -0
- package/script/analyzer/steps/003-risks/policy.js +29 -0
- package/script/analyzer/steps/003-risks/rule-mapped.d.ts +2 -2
- package/script/analyzer/steps/003-risks/rule-mapped.d.ts.map +1 -1
- package/script/analyzer/steps/003-risks/rule-mapped.js +83 -2
- package/script/analyzer/steps/003-risks/scoring.d.ts +9 -1
- package/script/analyzer/steps/003-risks/scoring.d.ts.map +1 -1
- package/script/analyzer/steps/003-risks/scoring.js +55 -42
- package/script/analyzer/treesitter/client.d.ts +31 -0
- package/script/analyzer/treesitter/client.d.ts.map +1 -0
- package/script/analyzer/treesitter/client.js +136 -0
- package/script/analyzer/treesitter/registry.d.ts +73 -0
- package/script/analyzer/treesitter/registry.d.ts.map +1 -0
- package/script/analyzer/treesitter/registry.js +206 -0
- package/script/analyzer/types.d.ts +14 -28
- package/script/analyzer/types.d.ts.map +1 -1
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/deps.d.ts +3 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/deps.d.ts.map +1 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/deps.js +10 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/mod.d.ts +93 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/mod.d.ts.map +1 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/mod.js +334 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/multi.d.ts +84 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/multi.d.ts.map +1 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/multi.js +305 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/time.d.ts +18 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/time.d.ts.map +1 -0
- package/script/deps/jsr.io/@deno-library/progress/1.5.1/time.js +48 -0
- package/script/deps/jsr.io/@std/fmt/1.0.3/colors.d.ts +700 -0
- package/script/deps/jsr.io/@std/fmt/1.0.3/colors.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/fmt/1.0.3/colors.js +986 -0
- package/script/deps/jsr.io/@std/io/0.225.0/types.d.ts +146 -0
- package/script/deps/jsr.io/@std/io/0.225.0/types.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/io/0.225.0/types.js +18 -0
- package/script/deps/jsr.io/@std/io/0.225.0/write_all.d.ts +51 -0
- package/script/deps/jsr.io/@std/io/0.225.0/write_all.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/io/0.225.0/write_all.js +65 -0
- package/script/shared/deep_merge.d.ts +12 -0
- package/script/shared/deep_merge.d.ts.map +1 -0
- package/script/shared/deep_merge.js +53 -0
- package/script/shared/mod.d.ts +1 -0
- package/script/shared/mod.d.ts.map +1 -1
- package/script/shared/mod.js +1 -0
- package/script/shared/types/filetypes.d.ts +2 -2
- package/script/shared/types/filetypes.d.ts.map +1 -1
- package/script/shared/types/permissions.d.ts +1 -1
- package/script/shared/types/permissions.d.ts.map +1 -1
- package/script/shared/types/risks.d.ts +4 -1
- package/script/shared/types/risks.d.ts.map +1 -1
- package/script/skillreader/types.d.ts +2 -2
- package/script/skillreader/types.d.ts.map +1 -1
- package/script/skillreader/types.js +2 -2
- package/src/_dnt.polyfills.ts +27 -0
- package/src/_dnt.shims.ts +64 -0
- package/src/analyzer/astgrep/client.ts +184 -0
- package/src/analyzer/astgrep/mod.ts +2 -0
- package/src/analyzer/config/default.ts +98 -0
- package/src/analyzer/config/helpers.ts +107 -0
- package/src/analyzer/config/mod.ts +3 -0
- package/src/analyzer/config/types.ts +103 -0
- package/src/analyzer/logging.ts +8 -0
- package/src/analyzer/mod.ts +118 -0
- package/src/analyzer/result.ts +393 -0
- package/src/analyzer/rules/bash/astTypes.ts +5 -0
- package/src/analyzer/rules/bash/commands/bd.ts +23 -0
- package/src/analyzer/rules/bash/commands/cron.ts +21 -0
- package/src/analyzer/rules/bash/commands/docker.ts +37 -0
- package/src/analyzer/rules/bash/commands/eval.ts +52 -0
- package/src/analyzer/rules/bash/commands/generic.ts +16 -0
- package/src/analyzer/rules/bash/commands/gh.ts +21 -0
- package/src/analyzer/rules/bash/commands/git.ts +28 -0
- package/src/analyzer/rules/bash/commands/mod.ts +38 -0
- package/src/analyzer/rules/bash/commands/node.ts +64 -0
- package/src/analyzer/rules/bash/commands/openspec.ts +16 -0
- package/src/analyzer/rules/bash/commands/pip.ts +16 -0
- package/src/analyzer/rules/bash/commands/sudo.ts +21 -0
- package/src/analyzer/rules/bash/destructive.ts +28 -0
- package/src/analyzer/rules/bash/extractFileRefs.ts +101 -0
- package/src/analyzer/rules/bash/filesystem.ts +50 -0
- package/src/analyzer/rules/bash/injection.ts +21 -0
- package/src/analyzer/rules/bash/inline-command-classifier.ts +94 -0
- package/src/analyzer/rules/bash/mod.ts +23 -0
- package/src/analyzer/rules/bash/network.ts +64 -0
- package/src/analyzer/rules/bash/secret-detection.ts +43 -0
- package/src/analyzer/rules/javascript/astTypes.ts +8 -0
- package/src/analyzer/rules/javascript/extractFileRefs.ts +131 -0
- package/src/analyzer/rules/javascript/filesystem.ts +28 -0
- package/src/analyzer/rules/javascript/injection.ts +21 -0
- package/src/analyzer/rules/javascript/mod.ts +26 -0
- package/src/analyzer/rules/javascript/network.ts +27 -0
- package/src/analyzer/rules/javascript/secret-detection.ts +68 -0
- package/src/analyzer/rules/javascript/subprocess.ts +16 -0
- package/src/analyzer/rules/markdown/astTypes.ts +35 -0
- package/src/analyzer/rules/markdown/extractCodeBlocks.ts +101 -0
- package/src/analyzer/rules/markdown/extractFileRefs.ts +179 -0
- package/src/analyzer/rules/markdown/mod.ts +12 -0
- package/src/analyzer/rules/mod.ts +77 -0
- package/src/analyzer/rules/python/astTypes.ts +9 -0
- package/src/analyzer/rules/python/extractFileRefs.ts +92 -0
- package/src/analyzer/rules/python/mod.ts +15 -0
- package/src/analyzer/rules/python/network.ts +26 -0
- package/src/analyzer/rules/python/secret-detection.ts +30 -0
- package/src/analyzer/rules/shared/file-refs.ts +38 -0
- package/src/analyzer/rules/shared/network-evaluators.ts +107 -0
- package/src/analyzer/rules/shared/prompt-injection.ts +48 -0
- package/src/analyzer/rules/shared/secret-evaluators.ts +13 -0
- package/src/analyzer/rules/text/mod.ts +12 -0
- package/src/analyzer/rules/typescript/mod.ts +7 -0
- package/src/analyzer/steps/001-discovery/discover-files.ts +211 -0
- package/src/analyzer/steps/001-discovery/filter-files.ts +72 -0
- package/src/analyzer/steps/001-discovery/mod.ts +103 -0
- package/src/analyzer/steps/002-permissions/mod.ts +329 -0
- package/src/analyzer/steps/002-permissions/scan-file.ts +258 -0
- package/src/analyzer/steps/002-permissions/seed-frontmatter.ts +66 -0
- package/src/analyzer/steps/002-permissions/synthesize.ts +42 -0
- package/src/analyzer/steps/003-risks/dep-risks.ts +89 -0
- package/src/analyzer/steps/003-risks/helpers.ts +41 -0
- package/src/analyzer/steps/003-risks/mod.ts +86 -0
- package/src/analyzer/steps/003-risks/policy.ts +38 -0
- package/src/analyzer/steps/003-risks/rule-mapped.ts +206 -0
- package/src/analyzer/steps/003-risks/scoring.ts +117 -0
- package/src/analyzer/steps/mod.ts +3 -0
- package/src/analyzer/treesitter/client.ts +120 -0
- package/src/analyzer/treesitter/registry.ts +198 -0
- package/src/analyzer/types.ts +78 -0
- package/src/analyzer/utils/code-block-path.ts +33 -0
- package/src/analyzer/utils/id-generator.ts +59 -0
- package/src/analyzer/utils/secret-validator.ts +29 -0
- package/src/analyzer/utils/url-parser.ts +25 -0
- package/src/deps/jsr.io/@deno-library/progress/1.5.1/deps.ts +3 -0
- package/src/deps/jsr.io/@deno-library/progress/1.5.1/mod.ts +265 -0
- package/src/deps/jsr.io/@deno-library/progress/1.5.1/multi.ts +250 -0
- package/src/deps/jsr.io/@deno-library/progress/1.5.1/time.ts +69 -0
- package/src/deps/jsr.io/@std/fmt/1.0.3/colors.ts +1004 -0
- package/src/deps/jsr.io/@std/internal/1.0.12/_os.ts +15 -0
- package/src/deps/jsr.io/@std/internal/1.0.12/os.ts +7 -0
- package/src/deps/jsr.io/@std/io/0.225.0/types.ts +157 -0
- package/src/deps/jsr.io/@std/io/0.225.0/write_all.ts +65 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/assert_path.ts +10 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/basename.ts +53 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/common.ts +26 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/constants.ts +49 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/dirname.ts +9 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/format.ts +25 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/from_file_url.ts +12 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/glob_to_reg_exp.ts +295 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/normalize.ts +9 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/normalize_string.ts +74 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/relative.ts +10 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/strip_trailing_separators.ts +25 -0
- package/src/deps/jsr.io/@std/path/1.1.4/_common/to_file_url.ts +17 -0
- package/src/deps/jsr.io/@std/path/1.1.4/basename.ts +37 -0
- package/src/deps/jsr.io/@std/path/1.1.4/common.ts +35 -0
- package/src/deps/jsr.io/@std/path/1.1.4/constants.ts +18 -0
- package/src/deps/jsr.io/@std/path/1.1.4/dirname.ts +30 -0
- package/src/deps/jsr.io/@std/path/1.1.4/extname.ts +29 -0
- package/src/deps/jsr.io/@std/path/1.1.4/format.ts +30 -0
- package/src/deps/jsr.io/@std/path/1.1.4/from_file_url.ts +30 -0
- package/src/deps/jsr.io/@std/path/1.1.4/glob_to_regexp.ts +94 -0
- package/src/deps/jsr.io/@std/path/1.1.4/is_absolute.ts +30 -0
- package/src/deps/jsr.io/@std/path/1.1.4/is_glob.ts +49 -0
- package/src/deps/jsr.io/@std/path/1.1.4/join.ts +31 -0
- package/src/deps/jsr.io/@std/path/1.1.4/join_globs.ts +42 -0
- package/src/deps/jsr.io/@std/path/1.1.4/mod.ts +217 -0
- package/src/deps/jsr.io/@std/path/1.1.4/normalize.ts +33 -0
- package/src/deps/jsr.io/@std/path/1.1.4/normalize_glob.ts +45 -0
- package/src/deps/jsr.io/@std/path/1.1.4/parse.ts +44 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/_util.ts +10 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/basename.ts +62 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/constants.ts +15 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/dirname.ts +72 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/extname.ts +96 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/format.ts +31 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/from_file_url.ts +25 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/glob_to_regexp.ts +94 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/is_absolute.ts +25 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/join.ts +46 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/join_globs.ts +45 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/normalize.ts +63 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/normalize_glob.ts +43 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/parse.ts +121 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/relative.ts +103 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/resolve.ts +71 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/to_file_url.ts +32 -0
- package/src/deps/jsr.io/@std/path/1.1.4/posix/to_namespaced_path.ts +21 -0
- package/src/deps/jsr.io/@std/path/1.1.4/relative.ts +32 -0
- package/src/deps/jsr.io/@std/path/1.1.4/resolve.ts +32 -0
- package/src/deps/jsr.io/@std/path/1.1.4/to_file_url.ts +30 -0
- package/src/deps/jsr.io/@std/path/1.1.4/to_namespaced_path.ts +31 -0
- package/src/deps/jsr.io/@std/path/1.1.4/types.ts +40 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/_util.ts +28 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/basename.ts +54 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/constants.ts +15 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/dirname.ts +118 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/extname.ts +90 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/format.ts +31 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/from_file_url.ts +34 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/glob_to_regexp.ts +92 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/is_absolute.ts +40 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/join.ts +78 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/join_globs.ts +46 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/normalize.ts +136 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/normalize_glob.ts +43 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/parse.ts +184 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/relative.ts +128 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/resolve.ts +178 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/to_file_url.ts +38 -0
- package/src/deps/jsr.io/@std/path/1.1.4/windows/to_namespaced_path.ts +60 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_chars.ts +55 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_dumper_state.ts +841 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_loader_state.ts +1780 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_schema.ts +183 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/binary.ts +127 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/bool.ts +37 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/float.ts +112 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/int.ts +174 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/map.ts +17 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/merge.ts +13 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/nil.ts +27 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/omap.ts +30 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/pairs.ts +22 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/regexp.ts +33 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/seq.ts +13 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/set.ts +17 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/str.ts +12 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/timestamp.ts +101 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type/undefined.ts +23 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_type.ts +49 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/_utils.ts +16 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/mod.ts +54 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/parse.ts +128 -0
- package/src/deps/jsr.io/@std/yaml/1.0.11/stringify.ts +118 -0
- package/src/shared/deep_merge.ts +73 -0
- package/src/shared/mod.ts +2 -0
- package/src/shared/types/filetypes.ts +101 -0
- package/src/shared/types/findings.ts +7 -0
- package/src/shared/types/mod.ts +6 -0
- package/src/shared/types/permissions.ts +17 -0
- package/src/shared/types/references.ts +62 -0
- package/src/shared/types/risks.ts +72 -0
- package/src/shared/types/syntaxNode.ts +7 -0
- package/src/skillreader/cloudStorage/mod.ts +170 -0
- package/src/skillreader/factory.ts +71 -0
- package/src/skillreader/fs/git.ts +153 -0
- package/src/skillreader/fs/mod.ts +84 -0
- package/src/skillreader/github/base.ts +162 -0
- package/src/skillreader/github/githubApi.ts +40 -0
- package/src/skillreader/github/githubRaw.ts +24 -0
- package/src/skillreader/github/mod.ts +45 -0
- package/src/skillreader/github/utils.ts +40 -0
- package/src/skillreader/manifest.ts +67 -0
- package/src/skillreader/mod.ts +26 -0
- package/src/skillreader/types.ts +150 -0
- package/src/skillreader/utils/frontmatter-parser.ts +72 -0
- package/src/skillreader/utils/http-range.ts +38 -0
- package/src/skillreader/utils/mod.ts +12 -0
- package/esm/analyzer/astgrep/registry.d.ts +0 -18
- package/esm/analyzer/astgrep/registry.d.ts.map +0 -1
- package/esm/analyzer/astgrep/registry.js +0 -71
- package/esm/analyzer/config.d.ts +0 -27
- package/esm/analyzer/config.d.ts.map +0 -1
- package/esm/analyzer/steps/003-risks/output.d.ts +0 -3
- package/esm/analyzer/steps/003-risks/output.d.ts.map +0 -1
- package/esm/analyzer/steps/003-risks/output.js +0 -16
- package/esm/analyzer/treesiter/client.d.ts +0 -26
- package/esm/analyzer/treesiter/client.d.ts.map +0 -1
- package/script/analyzer/astgrep/registry.d.ts +0 -18
- package/script/analyzer/astgrep/registry.d.ts.map +0 -1
- package/script/analyzer/astgrep/registry.js +0 -109
- package/script/analyzer/config.d.ts +0 -27
- package/script/analyzer/config.d.ts.map +0 -1
- package/script/analyzer/steps/003-risks/output.d.ts +0 -3
- package/script/analyzer/steps/003-risks/output.d.ts.map +0 -1
- package/script/analyzer/steps/003-risks/output.js +0 -19
- package/script/analyzer/treesiter/client.d.ts +0 -26
- package/script/analyzer/treesiter/client.d.ts.map +0 -1
- package/script/analyzer/treesiter/client.js +0 -165
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import * as dntShim from "../../_dnt.shims.js";
|
|
2
|
+
import { getFileType } from "../../shared/mod.js";
|
|
3
|
+
import { parseSkillManifest } from "../manifest.js";
|
|
4
|
+
import type { SkillFile } from "../types.js";
|
|
5
|
+
import { SkillReader } from "../types.js";
|
|
6
|
+
import { isProbablyText } from "../utils/mod.js";
|
|
7
|
+
|
|
8
|
+
type LocalGitSkillReaderOptions = {
|
|
9
|
+
repoRoot: string;
|
|
10
|
+
gitRef: string;
|
|
11
|
+
subDir?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type GitEntry = {
|
|
15
|
+
fullPath: string;
|
|
16
|
+
relativePath: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export class LocalGitSkillReader extends SkillReader {
|
|
20
|
+
private readonly repoRoot: string;
|
|
21
|
+
private readonly gitRef: string;
|
|
22
|
+
private readonly subDir: string;
|
|
23
|
+
|
|
24
|
+
constructor(options: LocalGitSkillReaderOptions) {
|
|
25
|
+
super();
|
|
26
|
+
this.repoRoot = options.repoRoot;
|
|
27
|
+
this.gitRef = options.gitRef;
|
|
28
|
+
this.subDir = options.subDir?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async retrieveFiles(dir?: string): Promise<SkillFile[]> {
|
|
32
|
+
const entries = await this.listEntries(dir);
|
|
33
|
+
return entries.map((entry) => ({
|
|
34
|
+
path: entry.relativePath,
|
|
35
|
+
contentType: getFileType(entry.relativePath),
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async readTextFile(path: string): Promise<string | null> {
|
|
40
|
+
if (getFileType(path) === "binary") return null;
|
|
41
|
+
const stream = await this.readFile(path);
|
|
42
|
+
if (!stream) return null;
|
|
43
|
+
const bytes = new Uint8Array(await new Response(stream).arrayBuffer());
|
|
44
|
+
if (!isProbablyText(bytes)) return null;
|
|
45
|
+
return new TextDecoder().decode(bytes);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async readFile(path: string): Promise<ReadableStream<Uint8Array> | null> {
|
|
49
|
+
const fullPath = this.joinWithSubDir(path);
|
|
50
|
+
const result = await runGit(this.repoRoot, ["show", `${this.gitRef}:${fullPath}`]);
|
|
51
|
+
if (result.code !== 0) return null;
|
|
52
|
+
return new Response(new Uint8Array(result.stdout)).body;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async readManifest() {
|
|
56
|
+
try {
|
|
57
|
+
const text = await this.readTextFile("manifest.json");
|
|
58
|
+
if (!text) return null;
|
|
59
|
+
return parseSkillManifest(text);
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async validateRepositoryRef(): Promise<void> {
|
|
66
|
+
const result = await runGit(this.repoRoot, ["rev-parse", "--verify", this.gitRef]);
|
|
67
|
+
if (result.code !== 0) {
|
|
68
|
+
throw new Error(`Git reference not found: ${this.gitRef}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private async listEntries(dir?: string): Promise<GitEntry[]> {
|
|
73
|
+
const scoped = this.joinWithSubDir(dir);
|
|
74
|
+
const args = ["ls-tree", "-r", "--name-only", this.gitRef];
|
|
75
|
+
if (scoped) {
|
|
76
|
+
args.push("--", scoped);
|
|
77
|
+
}
|
|
78
|
+
const result = await runGit(this.repoRoot, args);
|
|
79
|
+
if (result.code !== 0) {
|
|
80
|
+
throw new Error(`Failed to list files for git reference: ${this.gitRef}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const files = new TextDecoder().decode(result.stdout)
|
|
84
|
+
.split("\n")
|
|
85
|
+
.map((line) => line.trim())
|
|
86
|
+
.filter(Boolean);
|
|
87
|
+
|
|
88
|
+
const rootPrefix = this.joinWithSubDir(dir);
|
|
89
|
+
return files
|
|
90
|
+
.map((fullPath) => {
|
|
91
|
+
const relativePath = rootPrefix
|
|
92
|
+
? fullPath.startsWith(`${rootPrefix}/`)
|
|
93
|
+
? fullPath.slice(rootPrefix.length + 1)
|
|
94
|
+
: ""
|
|
95
|
+
: fullPath;
|
|
96
|
+
return { fullPath, relativePath };
|
|
97
|
+
})
|
|
98
|
+
.filter((entry) => entry.relativePath.length > 0);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private joinWithSubDir(path?: string): string {
|
|
102
|
+
const cleaned = path?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
103
|
+
return [this.subDir, cleaned].filter(Boolean).join("/");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function runGit(repoRoot: string, args: string[]) {
|
|
108
|
+
const denoRuntime = dntShim.Deno as unknown as {
|
|
109
|
+
Command?: new (
|
|
110
|
+
command: string,
|
|
111
|
+
options: {
|
|
112
|
+
args: string[];
|
|
113
|
+
stdout: "piped";
|
|
114
|
+
stderr: "piped";
|
|
115
|
+
},
|
|
116
|
+
) => { output: () => Promise<{ code: number; stdout: Uint8Array; stderr: Uint8Array }> };
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
if (denoRuntime.Command) {
|
|
120
|
+
return await new denoRuntime.Command("git", {
|
|
121
|
+
args: ["-C", repoRoot, ...args],
|
|
122
|
+
stdout: "piped",
|
|
123
|
+
stderr: "piped",
|
|
124
|
+
}).output();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const { spawnSync } = await import("node:child_process");
|
|
128
|
+
const output = spawnSync("git", ["-C", repoRoot, ...args], {
|
|
129
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
code: output.status ?? 1,
|
|
134
|
+
stdout: output.stdout ? new Uint8Array(output.stdout) : new Uint8Array(),
|
|
135
|
+
stderr: output.stderr ? new Uint8Array(output.stderr) : new Uint8Array(),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export async function ensureGitRepoRoot(path: string): Promise<void> {
|
|
140
|
+
const result = await runGit(path, ["rev-parse", "--show-toplevel"]);
|
|
141
|
+
if (result.code !== 0) {
|
|
142
|
+
throw new Error("Local path is not a git repository root");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const topLevel = new TextDecoder().decode(result.stdout).trim();
|
|
146
|
+
const canonicalPath = await dntShim.Deno.realPath(path);
|
|
147
|
+
const canonicalTopLevel = await dntShim.Deno.realPath(topLevel);
|
|
148
|
+
if (canonicalPath !== canonicalTopLevel) {
|
|
149
|
+
throw new Error(
|
|
150
|
+
"When --gitRef is used with local sources, path must point to the git repository root",
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as dntShim from "../../_dnt.shims.js";
|
|
2
|
+
import { join, relative } from "../../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
3
|
+
import { isProbablyText } from "../utils/mod.js";
|
|
4
|
+
import type { SkillFile } from "../types.js";
|
|
5
|
+
import { SkillReader } from "../types.js";
|
|
6
|
+
import { parseSkillManifest } from "../manifest.js";
|
|
7
|
+
import { getFileType } from "../../shared/mod.js";
|
|
8
|
+
|
|
9
|
+
export type LocalFsSkillReaderOptions = {
|
|
10
|
+
root: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export class LocalFsSkillReader extends SkillReader {
|
|
14
|
+
private root: string;
|
|
15
|
+
|
|
16
|
+
constructor(options: LocalFsSkillReaderOptions) {
|
|
17
|
+
super();
|
|
18
|
+
this.root = options.root;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async retrieveFiles(dir?: string): Promise<SkillFile[]> {
|
|
22
|
+
const base = dir ? join(this.root, dir) : this.root;
|
|
23
|
+
const files: SkillFile[] = [];
|
|
24
|
+
|
|
25
|
+
for await (const entry of this.walkDir(base)) {
|
|
26
|
+
if (!entry.isFile) continue;
|
|
27
|
+
const relPath = relative(this.root, entry.path);
|
|
28
|
+
files.push({
|
|
29
|
+
path: relPath.replace(/\\/g, "/"),
|
|
30
|
+
size: entry.size,
|
|
31
|
+
contentType: getFileType(relPath),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return files;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async readTextFile(path: string): Promise<string | null> {
|
|
39
|
+
const fullPath = join(this.root, path);
|
|
40
|
+
const contentType = getFileType(path);
|
|
41
|
+
if (contentType === "binary") return null;
|
|
42
|
+
try {
|
|
43
|
+
const data = await dntShim.Deno.readFile(fullPath);
|
|
44
|
+
if (!isProbablyText(data)) return null;
|
|
45
|
+
return new TextDecoder().decode(data);
|
|
46
|
+
} catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async readFile(path: string): Promise<ReadableStream<Uint8Array> | null> {
|
|
52
|
+
const fullPath = join(this.root, path);
|
|
53
|
+
try {
|
|
54
|
+
const file = await dntShim.Deno.open(fullPath, { read: true });
|
|
55
|
+
return file.readable;
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async readManifest() {
|
|
62
|
+
const manifestPath = join(this.root, "manifest.json");
|
|
63
|
+
try {
|
|
64
|
+
const text = await dntShim.Deno.readTextFile(manifestPath);
|
|
65
|
+
return parseSkillManifest(text);
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private async *walkDir(
|
|
72
|
+
dir: string,
|
|
73
|
+
): AsyncGenerator<{ path: string; size: number; isFile: boolean }> {
|
|
74
|
+
for await (const entry of dntShim.Deno.readDir(dir)) {
|
|
75
|
+
const fullPath = join(dir, entry.name);
|
|
76
|
+
if (entry.isDirectory) {
|
|
77
|
+
yield* this.walkDir(fullPath);
|
|
78
|
+
} else if (entry.isFile) {
|
|
79
|
+
const stat = await dntShim.Deno.stat(fullPath);
|
|
80
|
+
yield { path: fullPath, size: stat.size, isFile: true };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { isProbablyText } from "../utils/mod.js";
|
|
2
|
+
import type { SkillFile } from "../types.js";
|
|
3
|
+
import { SkillReader } from "../types.js";
|
|
4
|
+
import { parseSkillManifest } from "../manifest.js";
|
|
5
|
+
import {
|
|
6
|
+
buildGitHubHeaders,
|
|
7
|
+
buildPrefix,
|
|
8
|
+
normalizeRelativePath,
|
|
9
|
+
parseGitHubRepo,
|
|
10
|
+
} from "./utils.js";
|
|
11
|
+
import { getFileType } from "../../shared/mod.js";
|
|
12
|
+
|
|
13
|
+
export type GitHubTreeEntry = {
|
|
14
|
+
path: string;
|
|
15
|
+
type: string;
|
|
16
|
+
sha: string;
|
|
17
|
+
size?: number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type AbstractGitHubSkillReaderOptions = {
|
|
21
|
+
repoUrl: string;
|
|
22
|
+
gitRef?: string;
|
|
23
|
+
dir?: string;
|
|
24
|
+
token?: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export abstract class AbstractGitHubSkillReader extends SkillReader {
|
|
28
|
+
protected owner: string;
|
|
29
|
+
protected repo: string;
|
|
30
|
+
protected dir: string;
|
|
31
|
+
protected token?: string;
|
|
32
|
+
|
|
33
|
+
private requestedGitRef?: string;
|
|
34
|
+
private resolvedGitRef?: string;
|
|
35
|
+
private treeEntries: Map<string, GitHubTreeEntry> | null = null;
|
|
36
|
+
|
|
37
|
+
constructor(options: AbstractGitHubSkillReaderOptions) {
|
|
38
|
+
super();
|
|
39
|
+
const parsed = parseGitHubRepo(options.repoUrl);
|
|
40
|
+
if (!parsed) throw new Error("Unsupported repo URL");
|
|
41
|
+
this.owner = parsed.owner;
|
|
42
|
+
this.repo = parsed.repo;
|
|
43
|
+
this.requestedGitRef = options.gitRef;
|
|
44
|
+
this.dir = options.dir?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
45
|
+
this.token = options.token;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async retrieveFiles(dir?: string): Promise<SkillFile[]> {
|
|
49
|
+
const entries = await this.getTreeEntries();
|
|
50
|
+
const prefix = buildPrefix(this.dir, dir);
|
|
51
|
+
const files: SkillFile[] = [];
|
|
52
|
+
|
|
53
|
+
for (const entry of entries.values()) {
|
|
54
|
+
if (entry.type !== "blob") continue;
|
|
55
|
+
if (prefix && !entry.path.startsWith(prefix)) continue;
|
|
56
|
+
const relativePath = normalizeRelativePath(prefix, entry.path);
|
|
57
|
+
if (!relativePath) continue;
|
|
58
|
+
files.push({
|
|
59
|
+
path: relativePath,
|
|
60
|
+
size: entry.size,
|
|
61
|
+
contentType: getFileType(relativePath),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return files;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async readTextFile(path: string): Promise<string | null> {
|
|
69
|
+
if (getFileType(path) === "binary") return null;
|
|
70
|
+
const stream = await this.readFile(path);
|
|
71
|
+
if (!stream) return null;
|
|
72
|
+
const buffer = new Uint8Array(await new Response(stream).arrayBuffer());
|
|
73
|
+
if (!isProbablyText(buffer)) return null;
|
|
74
|
+
return new TextDecoder().decode(buffer);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async readFile(path: string): Promise<ReadableStream<Uint8Array> | null> {
|
|
78
|
+
const entry = await this.findEntry(path);
|
|
79
|
+
if (!entry) return null;
|
|
80
|
+
return this.readFileFromEntry(entry);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async readManifest() {
|
|
84
|
+
try {
|
|
85
|
+
const text = await this.readTextFile("manifest.json");
|
|
86
|
+
if (!text) return null;
|
|
87
|
+
return parseSkillManifest(text);
|
|
88
|
+
} catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected abstract readFileFromEntry(
|
|
94
|
+
entry: GitHubTreeEntry,
|
|
95
|
+
): Promise<ReadableStream<Uint8Array> | null>;
|
|
96
|
+
|
|
97
|
+
protected buildHeaders(): Record<string, string> {
|
|
98
|
+
return buildGitHubHeaders(this.token);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected async resolveGitRef(): Promise<string> {
|
|
102
|
+
if (this.resolvedGitRef) return this.resolvedGitRef;
|
|
103
|
+
if (this.requestedGitRef) {
|
|
104
|
+
this.resolvedGitRef = this.requestedGitRef;
|
|
105
|
+
return this.resolvedGitRef;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const response = await fetch(
|
|
109
|
+
`https://api.github.com/repos/${this.owner}/${this.repo}`,
|
|
110
|
+
{ headers: this.buildHeaders() },
|
|
111
|
+
);
|
|
112
|
+
if (!response.ok) {
|
|
113
|
+
throw new Error(`GitHub repository fetch failed: ${response.status}`);
|
|
114
|
+
}
|
|
115
|
+
const repoData = await response.json() as { default_branch?: string };
|
|
116
|
+
if (!repoData.default_branch) {
|
|
117
|
+
throw new Error("GitHub repository metadata missing default branch");
|
|
118
|
+
}
|
|
119
|
+
this.resolvedGitRef = repoData.default_branch;
|
|
120
|
+
return this.resolvedGitRef;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
protected async getTreeEntries(): Promise<Map<string, GitHubTreeEntry>> {
|
|
124
|
+
if (this.treeEntries) return this.treeEntries;
|
|
125
|
+
|
|
126
|
+
const gitRef = await this.resolveGitRef();
|
|
127
|
+
const headers = this.buildHeaders();
|
|
128
|
+
const commitResponse = await fetch(
|
|
129
|
+
`https://api.github.com/repos/${this.owner}/${this.repo}/commits/${gitRef}`,
|
|
130
|
+
{ headers },
|
|
131
|
+
);
|
|
132
|
+
if (!commitResponse.ok) {
|
|
133
|
+
throw new Error(`GitHub commit fetch failed: ${commitResponse.status}`);
|
|
134
|
+
}
|
|
135
|
+
const commitData = await commitResponse.json() as {
|
|
136
|
+
commit?: { tree?: { sha?: string } };
|
|
137
|
+
};
|
|
138
|
+
const treeSha = commitData?.commit?.tree?.sha;
|
|
139
|
+
if (!treeSha) throw new Error("Missing tree SHA");
|
|
140
|
+
|
|
141
|
+
const treeResponse = await fetch(
|
|
142
|
+
`https://api.github.com/repos/${this.owner}/${this.repo}/git/trees/${treeSha}?recursive=1`,
|
|
143
|
+
{ headers },
|
|
144
|
+
);
|
|
145
|
+
if (!treeResponse.ok) {
|
|
146
|
+
throw new Error(`GitHub tree fetch failed: ${treeResponse.status}`);
|
|
147
|
+
}
|
|
148
|
+
const treeData = await treeResponse.json() as { tree?: GitHubTreeEntry[] };
|
|
149
|
+
const entries = new Map<string, GitHubTreeEntry>();
|
|
150
|
+
for (const entry of treeData?.tree ?? []) {
|
|
151
|
+
entries.set(entry.path, entry);
|
|
152
|
+
}
|
|
153
|
+
this.treeEntries = entries;
|
|
154
|
+
return entries;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private async findEntry(path: string): Promise<GitHubTreeEntry | null> {
|
|
158
|
+
const entries = await this.getTreeEntries();
|
|
159
|
+
const fullPath = this.dir ? `${this.dir}/${path}` : path;
|
|
160
|
+
return entries.get(fullPath) ?? null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractGitHubSkillReader,
|
|
3
|
+
type AbstractGitHubSkillReaderOptions,
|
|
4
|
+
type GitHubTreeEntry,
|
|
5
|
+
} from "./base.js";
|
|
6
|
+
|
|
7
|
+
export type GitHubApiSkillReaderOptions = AbstractGitHubSkillReaderOptions & {
|
|
8
|
+
token: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export class GitHubApiSkillReader extends AbstractGitHubSkillReader {
|
|
12
|
+
constructor(options: GitHubApiSkillReaderOptions) {
|
|
13
|
+
super(options);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
protected async readFileFromEntry(
|
|
17
|
+
entry: GitHubTreeEntry,
|
|
18
|
+
): Promise<ReadableStream<Uint8Array> | null> {
|
|
19
|
+
const blobResponse = await fetch(
|
|
20
|
+
`https://api.github.com/repos/${this.owner}/${this.repo}/git/blobs/${entry.sha}`,
|
|
21
|
+
{ headers: this.buildHeaders() },
|
|
22
|
+
);
|
|
23
|
+
if (!blobResponse.ok) return null;
|
|
24
|
+
const blobData = await blobResponse.json() as { content?: string; encoding?: string };
|
|
25
|
+
if (!blobData.content || blobData.encoding !== "base64") return null;
|
|
26
|
+
const buffer = decodeBase64ToBuffer(blobData.content);
|
|
27
|
+
return new Response(buffer).body;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function decodeBase64ToBuffer(input: string): ArrayBuffer {
|
|
32
|
+
const cleaned = input.replace(/\n/g, "");
|
|
33
|
+
const binary = atob(cleaned);
|
|
34
|
+
const buffer = new ArrayBuffer(binary.length);
|
|
35
|
+
const bytes = new Uint8Array(buffer);
|
|
36
|
+
for (let i = 0; i < binary.length; i += 1) {
|
|
37
|
+
bytes[i] = binary.charCodeAt(i);
|
|
38
|
+
}
|
|
39
|
+
return buffer;
|
|
40
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractGitHubSkillReader,
|
|
3
|
+
type AbstractGitHubSkillReaderOptions,
|
|
4
|
+
type GitHubTreeEntry,
|
|
5
|
+
} from "./base.js";
|
|
6
|
+
|
|
7
|
+
export type GitHubRawSkillReaderOptions = AbstractGitHubSkillReaderOptions;
|
|
8
|
+
|
|
9
|
+
export class GitHubRawSkillReader extends AbstractGitHubSkillReader {
|
|
10
|
+
constructor(options: GitHubRawSkillReaderOptions) {
|
|
11
|
+
super(options);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
protected async readFileFromEntry(
|
|
15
|
+
entry: GitHubTreeEntry,
|
|
16
|
+
): Promise<ReadableStream<Uint8Array> | null> {
|
|
17
|
+
const gitRef = await this.resolveGitRef();
|
|
18
|
+
const rawUrl =
|
|
19
|
+
`https://raw.githubusercontent.com/${this.owner}/${this.repo}/${gitRef}/${entry.path}`;
|
|
20
|
+
const response = await fetch(rawUrl);
|
|
21
|
+
if (!response.ok) return null;
|
|
22
|
+
return response.body;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { SkillReader } from "../types.js";
|
|
2
|
+
import { GitHubApiSkillReader } from "./githubApi.js";
|
|
3
|
+
import { GitHubRawSkillReader } from "./githubRaw.js";
|
|
4
|
+
|
|
5
|
+
export type GitHubSkillReaderOptions = {
|
|
6
|
+
repoUrl: string;
|
|
7
|
+
gitRef?: string;
|
|
8
|
+
dir?: string;
|
|
9
|
+
token?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export class GitHubSkillReader extends SkillReader {
|
|
13
|
+
private reader: SkillReader;
|
|
14
|
+
|
|
15
|
+
constructor(options: GitHubSkillReaderOptions) {
|
|
16
|
+
super();
|
|
17
|
+
if (options.token) {
|
|
18
|
+
this.reader = new GitHubApiSkillReader({
|
|
19
|
+
...options,
|
|
20
|
+
token: options.token,
|
|
21
|
+
});
|
|
22
|
+
} else {
|
|
23
|
+
this.reader = new GitHubRawSkillReader(options);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
retrieveFiles(dir?: string) {
|
|
28
|
+
return this.reader.retrieveFiles(dir);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
readTextFile(path: string) {
|
|
32
|
+
return this.reader.readTextFile(path);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
readFile(path: string) {
|
|
36
|
+
return this.reader.readFile(path);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
readManifest() {
|
|
40
|
+
return this.reader.readManifest();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { GitHubApiSkillReader } from "./githubApi.js";
|
|
45
|
+
export { GitHubRawSkillReader } from "./githubRaw.js";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type ParsedGitHubRepo = {
|
|
2
|
+
owner: string;
|
|
3
|
+
repo: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export function parseGitHubRepo(repoUrl: string): ParsedGitHubRepo | null {
|
|
7
|
+
try {
|
|
8
|
+
const parsed = new URL(repoUrl);
|
|
9
|
+
if (!(parsed.hostname === "github.com" || parsed.hostname === "www.github.com")) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const match = parsed.pathname.match(/^\/([^\/]+)\/([^\/]+?)(\.git)?$/);
|
|
13
|
+
if (!match) return null;
|
|
14
|
+
return { owner: match[1], repo: match[2] };
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function buildPrefix(baseDir?: string, extraDir?: string): string {
|
|
21
|
+
const cleanedBase = baseDir?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
22
|
+
const cleanedExtra = extraDir?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
23
|
+
const combined = [cleanedBase, cleanedExtra].filter(Boolean).join("/");
|
|
24
|
+
return combined ? `${combined}/` : "";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function normalizeRelativePath(prefix: string, fullPath: string): string {
|
|
28
|
+
if (!prefix) return fullPath;
|
|
29
|
+
if (!fullPath.startsWith(prefix)) return "";
|
|
30
|
+
return fullPath.slice(prefix.length);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function buildGitHubHeaders(token?: string): Record<string, string> {
|
|
34
|
+
const headers: Record<string, string> = {
|
|
35
|
+
Accept: "application/vnd.github.v3+json",
|
|
36
|
+
"User-Agent": "goskilla-api",
|
|
37
|
+
};
|
|
38
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
39
|
+
return headers;
|
|
40
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SkillFile,
|
|
3
|
+
SkillFileManifest,
|
|
4
|
+
SkillManifest,
|
|
5
|
+
SkillZipManifest,
|
|
6
|
+
ZipManifestFile,
|
|
7
|
+
} from "./types.js";
|
|
8
|
+
|
|
9
|
+
export const SKILL_MANIFEST_VERSION = 1 as const;
|
|
10
|
+
export const SKILL_ZIP_MANIFEST_VERSION = 2 as const;
|
|
11
|
+
|
|
12
|
+
export function createSkillManifest(files: SkillFile[]): SkillFileManifest {
|
|
13
|
+
return {
|
|
14
|
+
version: SKILL_MANIFEST_VERSION,
|
|
15
|
+
generatedAt: new Date().toISOString(),
|
|
16
|
+
files,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createZipManifest(
|
|
21
|
+
files: ZipManifestFile[],
|
|
22
|
+
metadata: {
|
|
23
|
+
skillVersionId: string;
|
|
24
|
+
repoUrl: string;
|
|
25
|
+
commitHash: string;
|
|
26
|
+
dir?: string | null;
|
|
27
|
+
checksum: string;
|
|
28
|
+
compression: "deflate" | "store";
|
|
29
|
+
},
|
|
30
|
+
): SkillZipManifest {
|
|
31
|
+
return {
|
|
32
|
+
version: SKILL_ZIP_MANIFEST_VERSION,
|
|
33
|
+
storage_method: "zip",
|
|
34
|
+
compression: metadata.compression,
|
|
35
|
+
skill_version_id: metadata.skillVersionId,
|
|
36
|
+
repo_url: metadata.repoUrl,
|
|
37
|
+
commit_hash: metadata.commitHash,
|
|
38
|
+
dir: metadata.dir ?? null,
|
|
39
|
+
created_at: new Date().toISOString(),
|
|
40
|
+
checksum: metadata.checksum,
|
|
41
|
+
files,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function parseSkillManifest(text: string): SkillManifest | null {
|
|
46
|
+
try {
|
|
47
|
+
const parsed = JSON.parse(text) as SkillManifest;
|
|
48
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
49
|
+
if (!Array.isArray((parsed as { files?: unknown }).files)) return null;
|
|
50
|
+
if ((parsed as { version?: number }).version === SKILL_MANIFEST_VERSION) {
|
|
51
|
+
return parsed as SkillFileManifest;
|
|
52
|
+
}
|
|
53
|
+
if ((parsed as { version?: number }).version === SKILL_ZIP_MANIFEST_VERSION) {
|
|
54
|
+
const zipManifest = parsed as SkillZipManifest;
|
|
55
|
+
if (zipManifest.storage_method !== "zip") return null;
|
|
56
|
+
if (!zipManifest.compression) return null;
|
|
57
|
+
return zipManifest;
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function isZipManifest(manifest: SkillManifest): manifest is SkillZipManifest {
|
|
66
|
+
return (manifest as SkillZipManifest).storage_method === "zip";
|
|
67
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import "../_dnt.polyfills.js";
|
|
2
|
+
export type {
|
|
3
|
+
SkillFile,
|
|
4
|
+
SkillFileManifest,
|
|
5
|
+
SkillFrontmatter,
|
|
6
|
+
SkillManifest,
|
|
7
|
+
SkillReader,
|
|
8
|
+
SkillZipManifest,
|
|
9
|
+
ZipManifestFile,
|
|
10
|
+
} from "./types.js";
|
|
11
|
+
export {
|
|
12
|
+
createSkillManifest,
|
|
13
|
+
createZipManifest,
|
|
14
|
+
isZipManifest,
|
|
15
|
+
parseSkillManifest,
|
|
16
|
+
SKILL_MANIFEST_VERSION,
|
|
17
|
+
SKILL_ZIP_MANIFEST_VERSION,
|
|
18
|
+
} from "./manifest.js";
|
|
19
|
+
export { LocalFsSkillReader } from "./fs/mod.js";
|
|
20
|
+
export { SkillReaderFactory } from "./factory.js";
|
|
21
|
+
export type { SkillReaderFactoryOptions } from "./factory.js";
|
|
22
|
+
export { Analyzer } from "../analyzer/mod.js";
|
|
23
|
+
export type { AnalyzerAnalyzeInput } from "../analyzer/mod.js";
|
|
24
|
+
export { GitHubApiSkillReader, GitHubRawSkillReader, GitHubSkillReader } from "./github/mod.js";
|
|
25
|
+
export { CloudStorageSkillReader } from "./cloudStorage/mod.js";
|
|
26
|
+
export type { CloudStorageSkillReaderOptions } from "./cloudStorage/mod.js";
|