@oh-my-pi/pi-coding-agent 8.0.20 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +125 -0
- package/docs/session.md +111 -46
- package/examples/custom-tools/hello/index.ts +1 -1
- package/examples/custom-tools/todo/index.ts +3 -4
- package/examples/extensions/api-demo.ts +0 -1
- package/examples/extensions/chalk-logger.ts +2 -3
- package/examples/extensions/hello.ts +0 -1
- package/examples/extensions/pirate.ts +0 -1
- package/examples/extensions/plan-mode.ts +15 -16
- package/examples/extensions/todo.ts +3 -4
- package/examples/extensions/tools.ts +1 -2
- package/examples/extensions/with-deps/index.ts +0 -1
- package/examples/hooks/auto-commit-on-exit.ts +1 -2
- package/examples/hooks/confirm-destructive.ts +0 -1
- package/examples/hooks/custom-compaction.ts +1 -2
- package/examples/hooks/dirty-repo-guard.ts +0 -1
- package/examples/hooks/file-trigger.ts +3 -4
- package/examples/hooks/git-checkpoint.ts +0 -1
- package/examples/hooks/handoff.ts +3 -4
- package/examples/hooks/permission-gate.ts +1 -2
- package/examples/hooks/protected-paths.ts +1 -2
- package/examples/hooks/qna.ts +2 -3
- package/examples/hooks/snake.ts +4 -5
- package/examples/hooks/status-line.ts +0 -1
- package/examples/sdk/01-minimal.ts +2 -3
- package/examples/sdk/02-custom-model.ts +2 -3
- package/examples/sdk/03-custom-prompt.ts +3 -4
- package/examples/sdk/04-skills.ts +2 -3
- package/examples/sdk/06-extensions.ts +1 -2
- package/examples/sdk/06-hooks.ts +6 -7
- package/examples/sdk/07-context-files.ts +0 -1
- package/examples/sdk/08-prompt-templates.ts +0 -1
- package/examples/sdk/08-slash-commands.ts +0 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +0 -1
- package/examples/sdk/10-settings.ts +0 -1
- package/examples/sdk/11-sessions.ts +0 -1
- package/package.json +54 -23
- package/scripts/format-prompts.ts +0 -1
- package/src/capability/context-file.ts +3 -4
- package/src/capability/extension-module.ts +3 -4
- package/src/capability/extension.ts +3 -4
- package/src/capability/fs.ts +20 -21
- package/src/capability/hook.ts +3 -4
- package/src/capability/index.ts +15 -16
- package/src/capability/instruction.ts +3 -4
- package/src/capability/mcp.ts +3 -4
- package/src/capability/prompt.ts +3 -4
- package/src/capability/rule.ts +3 -4
- package/src/capability/settings.ts +2 -3
- package/src/capability/skill.ts +3 -4
- package/src/capability/slash-command.ts +3 -4
- package/src/capability/ssh.ts +3 -4
- package/src/capability/system-prompt.ts +3 -4
- package/src/capability/tool.ts +3 -4
- package/src/cli/args.ts +5 -6
- package/src/cli/config-cli.ts +6 -7
- package/src/cli/file-processor.ts +19 -17
- package/src/cli/jupyter-cli.ts +105 -0
- package/src/cli/list-models.ts +10 -11
- package/src/cli/plugin-cli.ts +20 -25
- package/src/cli/session-picker.ts +2 -3
- package/src/cli/setup-cli.ts +2 -3
- package/src/cli/stats-cli.ts +2 -3
- package/src/cli/update-cli.ts +25 -22
- package/src/commit/agentic/agent.ts +307 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +351 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +26 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +40 -0
- package/src/commit/agentic/state.ts +69 -0
- package/src/commit/agentic/tools/analyze-file.ts +131 -0
- package/src/commit/agentic/tools/git-file-diff.ts +194 -0
- package/src/commit/agentic/tools/git-hunk.ts +50 -0
- package/src/commit/agentic/tools/git-overview.ts +84 -0
- package/src/commit/agentic/tools/index.ts +56 -0
- package/src/commit/agentic/tools/propose-changelog.ts +128 -0
- package/src/commit/agentic/tools/propose-commit.ts +154 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/split-commit.ts +280 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +200 -0
- package/src/commit/analysis/conventional.ts +165 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +112 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +36 -0
- package/src/commit/changelog/generate.ts +110 -0
- package/src/commit/changelog/index.ts +233 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +93 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/git/errors.ts +11 -0
- package/src/commit/git/index.ts +212 -0
- package/src/commit/git/operations.ts +53 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +63 -0
- package/src/commit/map-reduce/map-phase.ts +178 -0
- package/src/commit/map-reduce/reduce-phase.ts +145 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +80 -0
- package/src/commit/pipeline.ts +240 -0
- package/src/commit/prompts/analysis-system.md +155 -0
- package/src/commit/prompts/analysis-user.md +41 -0
- package/src/commit/prompts/changelog-system.md +56 -0
- package/src/commit/prompts/changelog-user.md +19 -0
- package/src/commit/prompts/file-observer-system.md +26 -0
- package/src/commit/prompts/file-observer-user.md +9 -0
- package/src/commit/prompts/reduce-system.md +60 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +4 -0
- package/src/commit/prompts/summary-system.md +52 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/types.ts +109 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/config/file-lock.ts +121 -0
- package/src/config/keybindings.ts +6 -8
- package/src/config/model-registry.ts +65 -38
- package/src/config/model-resolver.ts +18 -19
- package/src/config/prompt-templates.ts +11 -11
- package/src/config/settings-manager.ts +141 -50
- package/src/config.ts +64 -66
- package/src/cursor.ts +11 -9
- package/src/discovery/agents-md.ts +11 -12
- package/src/discovery/builtin.ts +68 -73
- package/src/discovery/claude.ts +41 -42
- package/src/discovery/cline.ts +11 -12
- package/src/discovery/codex.ts +52 -53
- package/src/discovery/cursor.ts +9 -10
- package/src/discovery/gemini.ts +17 -22
- package/src/discovery/github.ts +13 -14
- package/src/discovery/helpers.ts +35 -34
- package/src/discovery/index.ts +22 -24
- package/src/discovery/mcp-json.ts +8 -9
- package/src/discovery/ssh.ts +8 -9
- package/src/discovery/vscode.ts +4 -5
- package/src/discovery/windsurf.ts +6 -7
- package/src/exa/company.ts +1 -2
- package/src/exa/index.ts +2 -3
- package/src/exa/linkedin.ts +1 -2
- package/src/exa/mcp-client.ts +14 -16
- package/src/exa/render.ts +10 -11
- package/src/exa/researcher.ts +1 -2
- package/src/exa/search.ts +1 -2
- package/src/exa/types.ts +0 -1
- package/src/exa/websets.ts +1 -2
- package/src/exec/bash-executor.ts +3 -4
- package/src/exec/exec.ts +0 -1
- package/src/export/custom-share.ts +5 -6
- package/src/export/html/index.ts +24 -21
- package/src/export/ttsr.ts +2 -3
- package/src/extensibility/custom-commands/bundled/review/index.ts +7 -8
- package/src/extensibility/custom-commands/loader.ts +18 -15
- package/src/extensibility/custom-commands/types.ts +2 -3
- package/src/extensibility/custom-tools/loader.ts +11 -12
- package/src/extensibility/custom-tools/types.ts +7 -8
- package/src/extensibility/custom-tools/wrapper.ts +2 -3
- package/src/extensibility/extensions/loader.ts +76 -54
- package/src/extensibility/extensions/runner.ts +11 -12
- package/src/extensibility/extensions/types.ts +20 -27
- package/src/extensibility/extensions/wrapper.ts +3 -4
- package/src/extensibility/hooks/index.ts +1 -1
- package/src/extensibility/hooks/loader.ts +9 -10
- package/src/extensibility/hooks/runner.ts +7 -8
- package/src/extensibility/hooks/tool-wrapper.ts +0 -1
- package/src/extensibility/hooks/types.ts +11 -18
- package/src/extensibility/plugins/doctor.ts +3 -3
- package/src/extensibility/plugins/installer.ts +27 -27
- package/src/extensibility/plugins/loader.ts +59 -56
- package/src/extensibility/plugins/manager.ts +211 -171
- package/src/extensibility/plugins/parser.ts +1 -1
- package/src/extensibility/plugins/paths.ts +8 -8
- package/src/extensibility/skills.ts +63 -60
- package/src/extensibility/slash-commands.ts +10 -10
- package/src/index.ts +54 -54
- package/src/internal-urls/agent-protocol.ts +21 -11
- package/src/internal-urls/artifact-protocol.ts +17 -13
- package/src/internal-urls/router.ts +1 -2
- package/src/internal-urls/rule-protocol.ts +3 -4
- package/src/internal-urls/skill-protocol.ts +3 -4
- package/src/ipy/executor.ts +109 -9
- package/src/ipy/gateway-coordinator.ts +79 -90
- package/src/ipy/kernel.ts +32 -30
- package/src/ipy/modules.ts +13 -13
- package/src/lsp/client.ts +21 -10
- package/src/lsp/clients/biome-client.ts +1 -2
- package/src/lsp/clients/index.ts +3 -3
- package/src/lsp/clients/lsp-linter-client.ts +4 -5
- package/src/lsp/config.ts +15 -15
- package/src/lsp/edits.ts +4 -5
- package/src/lsp/index.ts +43 -44
- package/src/lsp/lspmux.ts +8 -8
- package/src/lsp/render.ts +99 -61
- package/src/lsp/utils.ts +3 -3
- package/src/main.ts +71 -37
- package/src/mcp/client.ts +2 -3
- package/src/mcp/config.ts +5 -6
- package/src/mcp/json-rpc.ts +0 -1
- package/src/mcp/loader.ts +6 -7
- package/src/mcp/manager.ts +17 -18
- package/src/mcp/tool-bridge.ts +4 -9
- package/src/mcp/tool-cache.ts +2 -3
- package/src/mcp/transports/http.ts +2 -4
- package/src/mcp/transports/stdio.ts +1 -2
- package/src/migrations.ts +63 -52
- package/src/modes/components/armin.ts +4 -5
- package/src/modes/components/assistant-message.ts +33 -5
- package/src/modes/components/bash-execution.ts +7 -8
- package/src/modes/components/bordered-loader.ts +3 -3
- package/src/modes/components/branch-summary-message.ts +3 -3
- package/src/modes/components/compaction-summary-message.ts +3 -3
- package/src/modes/components/countdown-timer.ts +0 -1
- package/src/modes/components/custom-message.ts +5 -5
- package/src/modes/components/diff.ts +1 -1
- package/src/modes/components/dynamic-border.ts +2 -2
- package/src/modes/components/extensions/extension-dashboard.ts +6 -7
- package/src/modes/components/extensions/extension-list.ts +2 -3
- package/src/modes/components/extensions/inspector-panel.ts +3 -4
- package/src/modes/components/extensions/state-manager.ts +25 -26
- package/src/modes/components/extensions/types.ts +1 -2
- package/src/modes/components/footer.ts +47 -43
- package/src/modes/components/history-search.ts +2 -2
- package/src/modes/components/hook-editor.ts +3 -4
- package/src/modes/components/hook-input.ts +2 -3
- package/src/modes/components/hook-message.ts +5 -5
- package/src/modes/components/hook-selector.ts +2 -3
- package/src/modes/components/keybinding-hints.ts +2 -3
- package/src/modes/components/login-dialog.ts +2 -2
- package/src/modes/components/model-selector.ts +12 -12
- package/src/modes/components/oauth-selector.ts +2 -2
- package/src/modes/components/plugin-settings.ts +20 -20
- package/src/modes/components/python-execution.ts +7 -8
- package/src/modes/components/queue-mode-selector.ts +3 -3
- package/src/modes/components/read-tool-group.ts +2 -2
- package/src/modes/components/session-selector.ts +4 -4
- package/src/modes/components/settings-defs.ts +77 -69
- package/src/modes/components/settings-selector.ts +16 -16
- package/src/modes/components/show-images-selector.ts +2 -2
- package/src/modes/components/status-line/segments.ts +4 -4
- package/src/modes/components/status-line/separators.ts +1 -1
- package/src/modes/components/status-line/types.ts +2 -2
- package/src/modes/components/status-line-segment-editor.ts +7 -8
- package/src/modes/components/status-line.ts +12 -12
- package/src/modes/components/theme-selector.ts +8 -7
- package/src/modes/components/thinking-selector.ts +4 -4
- package/src/modes/components/todo-display.ts +2 -2
- package/src/modes/components/todo-reminder.ts +4 -4
- package/src/modes/components/tool-execution.ts +16 -19
- package/src/modes/components/tree-selector.ts +12 -12
- package/src/modes/components/ttsr-notification.ts +5 -5
- package/src/modes/components/user-message-selector.ts +1 -1
- package/src/modes/components/user-message.ts +1 -1
- package/src/modes/components/visual-truncate.ts +0 -1
- package/src/modes/components/welcome.ts +4 -4
- package/src/modes/controllers/command-controller.ts +46 -47
- package/src/modes/controllers/event-controller.ts +16 -20
- package/src/modes/controllers/extension-ui-controller.ts +40 -46
- package/src/modes/controllers/input-controller.ts +17 -18
- package/src/modes/controllers/selector-controller.ts +103 -91
- package/src/modes/index.ts +3 -3
- package/src/modes/interactive-mode.ts +31 -31
- package/src/modes/print-mode.ts +12 -13
- package/src/modes/rpc/rpc-client.ts +7 -8
- package/src/modes/rpc/rpc-mode.ts +24 -28
- package/src/modes/rpc/rpc-types.ts +3 -4
- package/src/modes/theme/mermaid-cache.ts +89 -0
- package/src/modes/theme/theme.ts +130 -53
- package/src/modes/types.ts +10 -10
- package/src/modes/utils/ui-helpers.ts +17 -17
- package/src/patch/applicator.ts +18 -19
- package/src/patch/diff.ts +1 -2
- package/src/patch/fuzzy.ts +1 -2
- package/src/patch/index.ts +11 -18
- package/src/patch/normalize.ts +4 -4
- package/src/patch/normative.ts +1 -2
- package/src/patch/parser.ts +8 -9
- package/src/patch/shared.ts +43 -16
- package/src/prompts/tools/task.md +2 -0
- package/src/sdk.ts +100 -65
- package/src/session/agent-session.ts +84 -85
- package/src/session/agent-storage.ts +43 -39
- package/src/session/artifacts.ts +32 -10
- package/src/session/auth-storage.ts +50 -39
- package/src/session/compaction/branch-summarization.ts +7 -10
- package/src/session/compaction/compaction.ts +8 -19
- package/src/session/compaction/utils.ts +6 -9
- package/src/session/history-storage.ts +10 -10
- package/src/session/messages.ts +4 -5
- package/src/session/session-manager.ts +76 -65
- package/src/session/session-storage.ts +57 -69
- package/src/session/storage-migration.ts +14 -56
- package/src/session/streaming-output.ts +2 -2
- package/src/ssh/connection-manager.ts +43 -50
- package/src/ssh/ssh-executor.ts +2 -2
- package/src/ssh/sshfs-mount.ts +11 -18
- package/src/system-prompt.ts +28 -35
- package/src/task/agents.ts +45 -30
- package/src/task/commands.ts +6 -7
- package/src/task/discovery.ts +39 -76
- package/src/task/executor.ts +14 -15
- package/src/task/index.ts +40 -34
- package/src/task/output-manager.ts +93 -0
- package/src/task/parallel.ts +0 -1
- package/src/task/render.ts +24 -30
- package/src/task/subprocess-tool-registry.ts +1 -2
- package/src/task/worker-protocol.ts +3 -3
- package/src/task/worker.ts +33 -39
- package/src/task/worktree.ts +19 -19
- package/src/tools/ask.ts +41 -20
- package/src/tools/bash-interceptor.ts +1 -5
- package/src/tools/bash.ts +91 -97
- package/src/tools/calculator.ts +49 -47
- package/src/tools/complete.ts +4 -5
- package/src/tools/context.ts +2 -2
- package/src/tools/fetch.ts +84 -124
- package/src/tools/find.ts +94 -98
- package/src/tools/gemini-image.ts +14 -14
- package/src/tools/grep.ts +100 -116
- package/src/tools/index.ts +80 -55
- package/src/tools/list-limit.ts +1 -1
- package/src/tools/ls.ts +44 -70
- package/src/tools/notebook.ts +51 -67
- package/src/tools/output-meta.ts +3 -4
- package/src/tools/output-utils.ts +2 -2
- package/src/tools/path-utils.ts +5 -5
- package/src/tools/python.ts +104 -217
- package/src/tools/read.ts +92 -33
- package/src/tools/render-utils.ts +8 -23
- package/src/tools/renderers.ts +6 -7
- package/src/tools/review.ts +8 -11
- package/src/tools/ssh.ts +69 -49
- package/src/tools/todo-write.ts +37 -25
- package/src/tools/tool-errors.ts +3 -3
- package/src/tools/tool-result.ts +3 -8
- package/src/tools/write.ts +99 -75
- package/src/tui/code-cell.ts +109 -0
- package/src/tui/file-list.ts +47 -0
- package/src/tui/index.ts +11 -0
- package/src/tui/output-block.ts +72 -0
- package/src/tui/status-line.ts +39 -0
- package/src/tui/tree-list.ts +55 -0
- package/src/tui/types.ts +16 -0
- package/src/tui/utils.ts +48 -0
- package/src/utils/changelog.ts +9 -10
- package/src/utils/clipboard.ts +11 -11
- package/src/utils/file-mentions.ts +4 -10
- package/src/utils/frontmatter.ts +6 -3
- package/src/utils/fuzzy.ts +2 -2
- package/src/utils/image-convert.ts +1 -1
- package/src/utils/image-resize.ts +1 -1
- package/src/utils/mime.ts +2 -2
- package/src/utils/shell-snapshot.ts +11 -13
- package/src/utils/shell.ts +4 -5
- package/src/utils/title-generator.ts +8 -9
- package/src/utils/tools-manager.ts +23 -23
- package/src/vendor/photon/index.js +1099 -1059
- package/src/vendor/photon/photon_rs_bg.wasm +0 -0
- package/src/web/scrapers/artifacthub.ts +1 -1
- package/src/web/scrapers/arxiv.ts +2 -2
- package/src/web/scrapers/bluesky.ts +2 -2
- package/src/web/scrapers/cheatsh.ts +1 -1
- package/src/web/scrapers/chocolatey.ts +2 -2
- package/src/web/scrapers/choosealicense.ts +5 -5
- package/src/web/scrapers/cisa-kev.ts +1 -1
- package/src/web/scrapers/crossref.ts +2 -2
- package/src/web/scrapers/devto.ts +3 -3
- package/src/web/scrapers/discogs.ts +3 -4
- package/src/web/scrapers/discourse.ts +1 -1
- package/src/web/scrapers/dockerhub.ts +1 -1
- package/src/web/scrapers/fdroid.ts +2 -2
- package/src/web/scrapers/firefox-addons.ts +3 -3
- package/src/web/scrapers/flathub.ts +1 -1
- package/src/web/scrapers/github.ts +3 -3
- package/src/web/scrapers/gitlab.ts +4 -4
- package/src/web/scrapers/hackernews.ts +2 -2
- package/src/web/scrapers/huggingface.ts +1 -1
- package/src/web/scrapers/iacr.ts +2 -2
- package/src/web/scrapers/index.ts +0 -1
- package/src/web/scrapers/jetbrains-marketplace.ts +1 -1
- package/src/web/scrapers/lemmy.ts +2 -2
- package/src/web/scrapers/maven.ts +2 -2
- package/src/web/scrapers/mdn.ts +2 -4
- package/src/web/scrapers/metacpan.ts +2 -2
- package/src/web/scrapers/musicbrainz.ts +1 -2
- package/src/web/scrapers/npm.ts +1 -1
- package/src/web/scrapers/nuget.ts +2 -2
- package/src/web/scrapers/nvd.ts +3 -3
- package/src/web/scrapers/ollama.ts +7 -9
- package/src/web/scrapers/opencorporates.ts +2 -2
- package/src/web/scrapers/openlibrary.ts +6 -6
- package/src/web/scrapers/orcid.ts +0 -1
- package/src/web/scrapers/osv.ts +2 -2
- package/src/web/scrapers/packagist.ts +1 -1
- package/src/web/scrapers/pubmed.ts +1 -2
- package/src/web/scrapers/rawg.ts +2 -2
- package/src/web/scrapers/readthedocs.ts +1 -2
- package/src/web/scrapers/repology.ts +2 -2
- package/src/web/scrapers/rfc.ts +1 -1
- package/src/web/scrapers/searchcode.ts +2 -2
- package/src/web/scrapers/semantic-scholar.ts +1 -1
- package/src/web/scrapers/snapcraft.ts +2 -2
- package/src/web/scrapers/sourcegraph.ts +1 -1
- package/src/web/scrapers/spdx.ts +3 -3
- package/src/web/scrapers/spotify.ts +0 -1
- package/src/web/scrapers/twitter.ts +1 -1
- package/src/web/scrapers/types.ts +1 -2
- package/src/web/scrapers/utils.ts +5 -5
- package/src/web/scrapers/wikidata.ts +3 -3
- package/src/web/scrapers/youtube.ts +9 -14
- package/src/web/search/auth.ts +5 -10
- package/src/web/search/index.ts +11 -21
- package/src/web/search/providers/anthropic.ts +3 -9
- package/src/web/search/providers/exa.ts +6 -10
- package/src/web/search/providers/perplexity.ts +5 -5
- package/src/web/search/render.ts +129 -175
- package/tsconfig.json +0 -42
|
Binary file
|
|
@@ -119,7 +119,7 @@ export const handleArtifactHub: SpecialHandler = async (
|
|
|
119
119
|
|
|
120
120
|
// Maintainers
|
|
121
121
|
if (pkg.maintainers?.length) {
|
|
122
|
-
const maintainerNames = pkg.maintainers.map(
|
|
122
|
+
const maintainerNames = pkg.maintainers.map(m => m.name).join(", ");
|
|
123
123
|
md += `**Maintainers:** ${maintainerNames}\n`;
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -40,12 +40,12 @@ export const handleArxiv: SpecialHandler = async (
|
|
|
40
40
|
const summary = entry.querySelector("summary")?.text?.trim();
|
|
41
41
|
const authors = entry
|
|
42
42
|
.querySelectorAll("author name")
|
|
43
|
-
.map(
|
|
43
|
+
.map(n => n.text?.trim())
|
|
44
44
|
.filter(Boolean);
|
|
45
45
|
const published = entry.querySelector("published")?.text?.trim()?.split("T")[0];
|
|
46
46
|
const categories = entry
|
|
47
47
|
.querySelectorAll("category")
|
|
48
|
-
.map(
|
|
48
|
+
.map(c => c.getAttribute("term"))
|
|
49
49
|
.filter(Boolean);
|
|
50
50
|
const pdfLink = entry.querySelector('link[title="pdf"]')?.getAttribute("href");
|
|
51
51
|
|
|
@@ -93,7 +93,7 @@ function formatPost(post: BlueskyPost, isQuote = false): string {
|
|
|
93
93
|
md += `> **${name}** (${handle}) - ${date}\n>\n`;
|
|
94
94
|
md += post.record.text
|
|
95
95
|
.split("\n")
|
|
96
|
-
.map(
|
|
96
|
+
.map(line => `> ${line}`)
|
|
97
97
|
.join("\n");
|
|
98
98
|
md += "\n";
|
|
99
99
|
} else {
|
|
@@ -126,7 +126,7 @@ function formatPost(post: BlueskyPost, isQuote = false): string {
|
|
|
126
126
|
md += `> **${rec.author.displayName || rec.author.handle}** (@${rec.author.handle})\n`;
|
|
127
127
|
md += rec.value.text
|
|
128
128
|
.split("\n")
|
|
129
|
-
.map(
|
|
129
|
+
.map(line => `> ${line}`)
|
|
130
130
|
.join("\n");
|
|
131
131
|
md += "\n";
|
|
132
132
|
}
|
|
@@ -43,7 +43,7 @@ export const handleCheatSh: SpecialHandler = async (
|
|
|
43
43
|
const content = result.content.trim();
|
|
44
44
|
const lines = content.split("\n");
|
|
45
45
|
const hasCodeIndicators = lines.some(
|
|
46
|
-
|
|
46
|
+
line =>
|
|
47
47
|
line.startsWith("$") ||
|
|
48
48
|
line.startsWith("#") ||
|
|
49
49
|
line.includes("()") ||
|
|
@@ -110,7 +110,7 @@ export const handleChocolatey: SpecialHandler = async (
|
|
|
110
110
|
if (pkg.LicenseUrl) md += `**License:** ${pkg.LicenseUrl}\n`;
|
|
111
111
|
|
|
112
112
|
if (pkg.Tags) {
|
|
113
|
-
const tags = pkg.Tags.split(/\s+/).filter(
|
|
113
|
+
const tags = pkg.Tags.split(/\s+/).filter(t => t.length > 0);
|
|
114
114
|
if (tags.length > 0) {
|
|
115
115
|
md += `**Tags:** ${tags.join(", ")}\n`;
|
|
116
116
|
}
|
|
@@ -127,7 +127,7 @@ export const handleChocolatey: SpecialHandler = async (
|
|
|
127
127
|
|
|
128
128
|
if (pkg.Dependencies) {
|
|
129
129
|
// Dependencies format: "id:version|id:version"
|
|
130
|
-
const deps = pkg.Dependencies.split("|").filter(
|
|
130
|
+
const deps = pkg.Dependencies.split("|").filter(d => d.trim().length > 0);
|
|
131
131
|
if (deps.length > 0) {
|
|
132
132
|
md += `\n## Dependencies\n\n`;
|
|
133
133
|
for (const dep of deps) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseFrontmatter } from "
|
|
1
|
+
import { parseFrontmatter } from "../../utils/frontmatter";
|
|
2
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
3
3
|
import { finalizeOutput, loadPage } from "./types";
|
|
4
4
|
|
|
@@ -16,14 +16,14 @@ function normalizeList(value: unknown): string[] {
|
|
|
16
16
|
if (Array.isArray(value)) {
|
|
17
17
|
return value
|
|
18
18
|
.filter((item): item is string => typeof item === "string")
|
|
19
|
-
.map(
|
|
20
|
-
.filter(
|
|
19
|
+
.map(item => item.trim())
|
|
20
|
+
.filter(item => item.length > 0);
|
|
21
21
|
}
|
|
22
22
|
if (typeof value === "string") {
|
|
23
23
|
return value
|
|
24
24
|
.split(",")
|
|
25
|
-
.map(
|
|
26
|
-
.filter(
|
|
25
|
+
.map(item => item.trim())
|
|
26
|
+
.filter(item => item.length > 0);
|
|
27
27
|
}
|
|
28
28
|
return [];
|
|
29
29
|
}
|
|
@@ -60,7 +60,7 @@ export const handleCisaKev: SpecialHandler = async (
|
|
|
60
60
|
return null;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
const entry = data.vulnerabilities?.find(
|
|
63
|
+
const entry = data.vulnerabilities?.find(item => item.cveID?.toUpperCase() === cveId);
|
|
64
64
|
if (!entry) return null;
|
|
65
65
|
|
|
66
66
|
let md = `# ${entry.cveID}\n\n`;
|
|
@@ -42,7 +42,7 @@ function extractDoi(pathname: string): string | null {
|
|
|
42
42
|
function formatAuthors(authors?: CrossrefAuthor[]): string | null {
|
|
43
43
|
if (!authors || authors.length === 0) return null;
|
|
44
44
|
const names = authors
|
|
45
|
-
.map(
|
|
45
|
+
.map(author => {
|
|
46
46
|
if (author.name) return author.name;
|
|
47
47
|
const parts = [author.given, author.family].filter(Boolean);
|
|
48
48
|
return parts.length > 0 ? parts.join(" ") : null;
|
|
@@ -67,7 +67,7 @@ function formatDate(date?: CrossrefDate): string | null {
|
|
|
67
67
|
|
|
68
68
|
function formatAbstract(abstract?: string): string | null {
|
|
69
69
|
if (!abstract) return null;
|
|
70
|
-
const normalized = abstract.replace(/<\/?jats:p[^>]*>/g,
|
|
70
|
+
const normalized = abstract.replace(/<\/?jats:p[^>]*>/g, match => (match.startsWith("</") ? "</p>" : "<p>"));
|
|
71
71
|
const markdown = htmlToBasicMarkdown(normalized);
|
|
72
72
|
return markdown.trim().length > 0 ? markdown : null;
|
|
73
73
|
}
|
|
@@ -62,7 +62,7 @@ export const handleDevTo: SpecialHandler = async (
|
|
|
62
62
|
md += `by **${article.user?.name || "Unknown"}** (@${article.user?.username || "unknown"})`;
|
|
63
63
|
md += `${readTime}${reactStr}\n`;
|
|
64
64
|
md += `*${new Date(article.published_at || article.published_timestamp || "").toISOString().split("T")[0]}*\n`;
|
|
65
|
-
if (tags.length > 0) md += `Tags: ${tags.map(
|
|
65
|
+
if (tags.length > 0) md += `Tags: ${tags.map(t => `#${t}`).join(", ")}\n`;
|
|
66
66
|
if (article.description) md += `\n${article.description}\n`;
|
|
67
67
|
md += `\n---\n\n`;
|
|
68
68
|
}
|
|
@@ -104,7 +104,7 @@ export const handleDevTo: SpecialHandler = async (
|
|
|
104
104
|
md += `### ${article.title}\n\n`;
|
|
105
105
|
md += `${readTime.substring(3)}${reactStr}\n`;
|
|
106
106
|
md += `*${new Date(article.published_at || article.published_timestamp || "").toISOString().split("T")[0]}*\n`;
|
|
107
|
-
if (tags.length > 0) md += `Tags: ${tags.map(
|
|
107
|
+
if (tags.length > 0) md += `Tags: ${tags.map(t => `#${t}`).join(", ")}\n`;
|
|
108
108
|
if (article.description) md += `\n${article.description}\n`;
|
|
109
109
|
md += `\n---\n\n`;
|
|
110
110
|
}
|
|
@@ -146,7 +146,7 @@ export const handleDevTo: SpecialHandler = async (
|
|
|
146
146
|
if (readTime > 0) md += `**Reading time:** ${readTime} min\n`;
|
|
147
147
|
if (reactions > 0) md += `**Reactions:** ${formatCount(reactions)}\n`;
|
|
148
148
|
if (comments > 0) md += `**Comments:** ${formatCount(comments)}\n`;
|
|
149
|
-
if (tags.length > 0) md += `**Tags:** ${tags.map(
|
|
149
|
+
if (tags.length > 0) md += `**Tags:** ${tags.map(t => `#${t}`).join(", ")}\n`;
|
|
150
150
|
md += `\n---\n\n`;
|
|
151
151
|
|
|
152
152
|
// Prefer body_markdown over body_html
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* Uses the Discogs API to extract structured metadata about releases.
|
|
5
5
|
* API docs: https://www.discogs.com/developers
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
7
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
9
8
|
import { finalizeOutput, loadPage } from "./types";
|
|
10
9
|
|
|
@@ -76,7 +75,7 @@ interface DiscogsMaster {
|
|
|
76
75
|
function formatArtists(artists: DiscogsArtist[] | undefined): string {
|
|
77
76
|
if (!artists?.length) return "Unknown Artist";
|
|
78
77
|
return artists
|
|
79
|
-
.map(
|
|
78
|
+
.map(a => {
|
|
80
79
|
const name = a.anv || a.name;
|
|
81
80
|
const join = a.join || ", ";
|
|
82
81
|
return name + (a.join ? ` ${join} ` : "");
|
|
@@ -126,7 +125,7 @@ function formatFormats(formats: DiscogsFormat[] | undefined): string {
|
|
|
126
125
|
if (!formats?.length) return "";
|
|
127
126
|
|
|
128
127
|
return formats
|
|
129
|
-
.map(
|
|
128
|
+
.map(f => {
|
|
130
129
|
const parts: string[] = [];
|
|
131
130
|
if (f.qty && parseInt(f.qty, 10) > 1) parts.push(`${f.qty}×`);
|
|
132
131
|
parts.push(f.name);
|
|
@@ -142,7 +141,7 @@ function formatFormats(formats: DiscogsFormat[] | undefined): string {
|
|
|
142
141
|
function formatLabels(labels: DiscogsLabel[] | undefined): string {
|
|
143
142
|
if (!labels?.length) return "";
|
|
144
143
|
return labels
|
|
145
|
-
.map(
|
|
144
|
+
.map(l => {
|
|
146
145
|
if (l.catno && l.catno !== "none") return `${l.name} (${l.catno})`;
|
|
147
146
|
return l.name;
|
|
148
147
|
})
|
|
@@ -157,7 +157,7 @@ export const handleDiscourse: SpecialHandler = async (
|
|
|
157
157
|
const fetchedAt = new Date().toISOString();
|
|
158
158
|
|
|
159
159
|
const posts: DiscoursePost[] = [...(topic.post_stream?.posts ?? [])];
|
|
160
|
-
if (requestedPost && !posts.some(
|
|
160
|
+
if (requestedPost && !posts.some(post => post.id === requestedPost?.id)) {
|
|
161
161
|
posts.unshift(requestedPost);
|
|
162
162
|
}
|
|
163
163
|
|
|
@@ -134,7 +134,7 @@ export const handleDockerHub: SpecialHandler = async (
|
|
|
134
134
|
const size = tag.full_size ? formatSize(tag.full_size) : "-";
|
|
135
135
|
const archs =
|
|
136
136
|
tag.images
|
|
137
|
-
?.map(
|
|
137
|
+
?.map(img => img.architecture)
|
|
138
138
|
.filter(Boolean)
|
|
139
139
|
.join(", ") || "-";
|
|
140
140
|
const updated = tag.last_updated ? new Date(tag.last_updated).toISOString().split("T")[0] : "-";
|
|
@@ -30,7 +30,7 @@ function pickLocalizedText(value?: LocalizedText): string | undefined {
|
|
|
30
30
|
if (typeof value === "string") return value;
|
|
31
31
|
const preferred = value["en-US"] ?? value.en_US ?? value.en;
|
|
32
32
|
if (preferred) return preferred;
|
|
33
|
-
const first = Object.values(value).find(
|
|
33
|
+
const first = Object.values(value).find(entry => typeof entry === "string");
|
|
34
34
|
return first;
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -61,7 +61,7 @@ function collectAntiFeatures(data: FdroidPackage): string[] {
|
|
|
61
61
|
function resolveSuggestedVersion(data: FdroidPackage): string | undefined {
|
|
62
62
|
if (data.suggestedVersionName) return data.suggestedVersionName;
|
|
63
63
|
if (data.suggestedVersionCode) {
|
|
64
|
-
const match = data.packages?.find(
|
|
64
|
+
const match = data.packages?.find(pkg => pkg.versionCode === data.suggestedVersionCode);
|
|
65
65
|
if (match?.versionName) return match.versionName;
|
|
66
66
|
}
|
|
67
67
|
return data.packages?.[0]?.versionName;
|
|
@@ -71,7 +71,7 @@ function normalizeCategories(categories?: string[] | Record<string, string[]>):
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
const seen = new Set<string>();
|
|
74
|
-
return values.filter(
|
|
74
|
+
return values.filter(item => {
|
|
75
75
|
if (seen.has(item)) return false;
|
|
76
76
|
seen.add(item);
|
|
77
77
|
return true;
|
|
@@ -135,8 +135,8 @@ export const handleFirefoxAddons: SpecialHandler = async (
|
|
|
135
135
|
const description = descriptionRaw ? htmlToBasicMarkdown(descriptionRaw) : undefined;
|
|
136
136
|
|
|
137
137
|
const authors = (data.authors ?? [])
|
|
138
|
-
.map(
|
|
139
|
-
.map(
|
|
138
|
+
.map(author => author.name ?? "")
|
|
139
|
+
.map(author => author.trim())
|
|
140
140
|
.filter(Boolean);
|
|
141
141
|
|
|
142
142
|
const ratingAverage = data.ratings?.average;
|
|
@@ -141,7 +141,7 @@ async function renderGitHubIssue(
|
|
|
141
141
|
md += `**#${issue.number}** · ${issue.state} · opened by @${issue.user.login}\n`;
|
|
142
142
|
md += `Created: ${issue.created_at} · Updated: ${issue.updated_at}\n`;
|
|
143
143
|
if (issue.labels.length > 0) {
|
|
144
|
-
md += `Labels: ${issue.labels.map(
|
|
144
|
+
md += `Labels: ${issue.labels.map(l => l.name).join(", ")}\n`;
|
|
145
145
|
}
|
|
146
146
|
md += `\n---\n\n`;
|
|
147
147
|
md += issue.body || "*No description provided.*";
|
|
@@ -196,7 +196,7 @@ async function renderGitHubIssuesList(
|
|
|
196
196
|
|
|
197
197
|
for (const issue of issues) {
|
|
198
198
|
if (issue.pull_request) continue; // Skip PRs in issues list
|
|
199
|
-
const labels = issue.labels.length > 0 ? ` [${issue.labels.map(
|
|
199
|
+
const labels = issue.labels.length > 0 ? ` [${issue.labels.map(l => l.name).join(", ")}]` : "";
|
|
200
200
|
md += `- **#${issue.number}** ${issue.title}${labels}\n`;
|
|
201
201
|
md += ` by @${issue.user.login} · ${issue.comments} comments · ${issue.created_at}\n\n`;
|
|
202
202
|
}
|
|
@@ -259,7 +259,7 @@ async function renderGitHubTree(
|
|
|
259
259
|
md += "```\n\n";
|
|
260
260
|
|
|
261
261
|
// Look for README in this directory
|
|
262
|
-
const readmeFile = items.find(
|
|
262
|
+
const readmeFile = items.find(item => item.type === "file" && /^readme\.md$/i.test(item.name));
|
|
263
263
|
if (readmeFile) {
|
|
264
264
|
const readmePath = dirPath ? `${dirPath}/${readmeFile.name}` : readmeFile.name;
|
|
265
265
|
const rawUrl = `https://raw.githubusercontent.com/${gh.owner}/${gh.repo}/${ref}/${readmePath}`;
|
|
@@ -197,8 +197,8 @@ async function renderGitLabTree(
|
|
|
197
197
|
md += `**Ref:** ${gl.ref}\n\n`;
|
|
198
198
|
|
|
199
199
|
// Separate directories and files
|
|
200
|
-
const dirs = tree.filter(
|
|
201
|
-
const files = tree.filter(
|
|
200
|
+
const dirs = tree.filter(item => item.type === "tree");
|
|
201
|
+
const files = tree.filter(item => item.type === "blob");
|
|
202
202
|
|
|
203
203
|
if (dirs.length > 0) {
|
|
204
204
|
md += `## Directories (${dirs.length})\n\n`;
|
|
@@ -260,7 +260,7 @@ async function renderGitLabIssue(
|
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
if (issue.assignees && issue.assignees.length > 0) {
|
|
263
|
-
md += `**Assignees:** ${issue.assignees.map(
|
|
263
|
+
md += `**Assignees:** ${issue.assignees.map(a => a.name).join(", ")}\n`;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
md += `\n---\n\n## Description\n\n`;
|
|
@@ -317,7 +317,7 @@ async function renderGitLabMR(
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
if (mr.assignees && mr.assignees.length > 0) {
|
|
320
|
-
md += `**Assignees:** ${mr.assignees.map(
|
|
320
|
+
md += `**Assignees:** ${mr.assignees.map(a => a.name).join(", ")}\n`;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
md += `\n---\n\n## Description\n\n`;
|
|
@@ -29,7 +29,7 @@ async function fetchItem(id: number, timeout: number, signal?: AbortSignal): Pro
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async function fetchItems(ids: number[], timeout: number, limit = 20, signal?: AbortSignal): Promise<HNItem[]> {
|
|
32
|
-
const promises = ids.slice(0, limit).map(
|
|
32
|
+
const promises = ids.slice(0, limit).map(id => fetchItem(id, timeout, signal));
|
|
33
33
|
const results = await Promise.all(promises);
|
|
34
34
|
return results.filter((item): item is HNItem => item !== null && !item.deleted && !item.dead);
|
|
35
35
|
}
|
|
@@ -103,7 +103,7 @@ async function renderStory(item: HNItem, timeout: number, depth = 0, signal?: Ab
|
|
|
103
103
|
if (comment.text) {
|
|
104
104
|
const text = decodeHNText(comment.text);
|
|
105
105
|
const lines = text.split("\n");
|
|
106
|
-
output += `${lines.map(
|
|
106
|
+
output += `${lines.map(line => `${indent}${line}`).join("\n")}\n\n`;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
if (comment.kids && comment.kids.length > 0 && depth < 1) {
|
|
@@ -360,7 +360,7 @@ export const handleHuggingFace: SpecialHandler = async (url: string, timeout: nu
|
|
|
360
360
|
if (user.numSpaces !== undefined) md += `**Spaces:** ${formatCount(user.numSpaces)}\n`;
|
|
361
361
|
|
|
362
362
|
if (user.orgs?.length) {
|
|
363
|
-
md += `**Organizations:** ${user.orgs.map(
|
|
363
|
+
md += `**Organizations:** ${user.orgs.map(o => o.name).join(", ")}\n`;
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
const { content, truncated } = finalizeOutput(md);
|
package/src/web/scrapers/iacr.ts
CHANGED
|
@@ -38,10 +38,10 @@ export const handleIacr: SpecialHandler = async (
|
|
|
38
38
|
doc.querySelector('meta[name="citation_title"]')?.getAttribute("content");
|
|
39
39
|
const authors = doc
|
|
40
40
|
.querySelectorAll('meta[name="citation_author"]')
|
|
41
|
-
.map(
|
|
41
|
+
.map(m => m.getAttribute("content"))
|
|
42
42
|
.filter(Boolean);
|
|
43
43
|
// Abstract is in <p> after <h5>Abstract</h5>
|
|
44
|
-
const abstractHeading = doc.querySelectorAll("h5").find(
|
|
44
|
+
const abstractHeading = doc.querySelectorAll("h5").find(h => h.text?.includes("Abstract"));
|
|
45
45
|
const abstract =
|
|
46
46
|
abstractHeading?.parentNode?.querySelector("p")?.text?.trim() ||
|
|
47
47
|
doc.querySelector('meta[name="description"]')?.getAttribute("content");
|
|
@@ -114,7 +114,7 @@ export const handleJetBrainsMarketplace: SpecialHandler = async (
|
|
|
114
114
|
const vendorName = plugin.vendor?.name ?? plugin.vendor?.publicName;
|
|
115
115
|
const descriptionSource = plugin.description ?? plugin.preview ?? "";
|
|
116
116
|
const description = descriptionSource ? htmlToBasicMarkdown(descriptionSource) : "";
|
|
117
|
-
const tags = (plugin.tags ?? []).map(
|
|
117
|
+
const tags = (plugin.tags ?? []).map(tag => tag.name).filter(Boolean) as string[];
|
|
118
118
|
const rating = extractRating(plugin);
|
|
119
119
|
const buildCompatibility = update ? formatBuildCompatibility(update) : null;
|
|
120
120
|
|
|
@@ -87,14 +87,14 @@ function formatAuthor(creator: LemmyCreator): string {
|
|
|
87
87
|
function indentBlock(text: string, indent: string): string {
|
|
88
88
|
return text
|
|
89
89
|
.split("\n")
|
|
90
|
-
.map(
|
|
90
|
+
.map(line => `${indent}${line}`)
|
|
91
91
|
.join("\n");
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
function renderComments(comments: LemmyCommentView[]): string {
|
|
95
95
|
const childrenByParent = new Map<number, LemmyCommentView[]>();
|
|
96
96
|
|
|
97
|
-
const commentIds = new Set(comments.map(
|
|
97
|
+
const commentIds = new Set(comments.map(view => view.comment.id));
|
|
98
98
|
|
|
99
99
|
for (const commentView of comments) {
|
|
100
100
|
const parentId = commentView.comment.parent_id;
|
|
@@ -124,10 +124,10 @@ export const handleMaven: SpecialHandler = async (
|
|
|
124
124
|
|
|
125
125
|
// Add available classifiers/extensions if present
|
|
126
126
|
if (doc.ec && doc.ec.length > 0) {
|
|
127
|
-
const extensions = doc.ec.filter(
|
|
127
|
+
const extensions = doc.ec.filter(e => e && e !== "-");
|
|
128
128
|
if (extensions.length > 0) {
|
|
129
129
|
md += `\n## Available Extensions\n\n`;
|
|
130
|
-
md += `${extensions.map(
|
|
130
|
+
md += `${extensions.map(e => `- ${e}`).join("\n")}\n`;
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
package/src/web/scrapers/mdn.ts
CHANGED
|
@@ -82,11 +82,9 @@ function convertMDNBody(sections: MDNSection[]): string {
|
|
|
82
82
|
case "table":
|
|
83
83
|
if (value.rows && value.rows.length > 0) {
|
|
84
84
|
// Simple markdown table
|
|
85
|
-
const header = value.rows[0].map(
|
|
85
|
+
const header = value.rows[0].map(cell => htmlToBasicMarkdown(cell)).join(" | ");
|
|
86
86
|
const separator = value.rows[0].map(() => "---").join(" | ");
|
|
87
|
-
const bodyRows = value.rows
|
|
88
|
-
.slice(1)
|
|
89
|
-
.map((row) => row.map((cell) => htmlToBasicMarkdown(cell)).join(" | "));
|
|
87
|
+
const bodyRows = value.rows.slice(1).map(row => row.map(cell => htmlToBasicMarkdown(cell)).join(" | "));
|
|
90
88
|
|
|
91
89
|
parts.push(`| ${header} |`);
|
|
92
90
|
parts.push(`| ${separator} |`);
|
|
@@ -183,7 +183,7 @@ function formatModuleMarkdown(module: ModuleResponse, release: ReleaseResponse |
|
|
|
183
183
|
|
|
184
184
|
// Show runtime dependencies
|
|
185
185
|
const runtimeDeps = release.dependency?.filter(
|
|
186
|
-
|
|
186
|
+
d => d.phase === "runtime" && d.relationship === "requires" && d.module !== "perl",
|
|
187
187
|
);
|
|
188
188
|
if (runtimeDeps?.length) {
|
|
189
189
|
md += `\n## Dependencies\n\n`;
|
|
@@ -233,7 +233,7 @@ function formatReleaseMarkdown(release: ReleaseResponse): string {
|
|
|
233
233
|
|
|
234
234
|
// Show runtime dependencies
|
|
235
235
|
const runtimeDeps = release.dependency?.filter(
|
|
236
|
-
|
|
236
|
+
d => d.phase === "runtime" && d.relationship === "requires" && d.module !== "perl",
|
|
237
237
|
);
|
|
238
238
|
if (runtimeDeps?.length) {
|
|
239
239
|
md += `\n## Dependencies\n\n`;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MusicBrainz URL handler for artists, releases, and recordings
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
4
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
6
5
|
import { finalizeOutput, loadPage } from "./types";
|
|
7
6
|
|
|
@@ -133,7 +132,7 @@ function formatArtistCredits(credits: MusicBrainzArtistCredit[] | undefined): st
|
|
|
133
132
|
if (!credits?.length) return null;
|
|
134
133
|
|
|
135
134
|
const names = credits
|
|
136
|
-
.map(
|
|
135
|
+
.map(credit => credit.name || credit.artist?.name)
|
|
137
136
|
.filter((name): name is string => Boolean(name));
|
|
138
137
|
|
|
139
138
|
if (!names.length) return null;
|
package/src/web/scrapers/npm.ts
CHANGED
|
@@ -84,7 +84,7 @@ export const handleNpm: SpecialHandler = async (
|
|
|
84
84
|
const repoUrl = typeof pkg.repository === "string" ? pkg.repository : pkg.repository?.url;
|
|
85
85
|
if (repoUrl) md += `**Repository:** ${repoUrl.replace(/^git\+/, "").replace(/\.git$/, "")}\n`;
|
|
86
86
|
if (pkg.keywords?.length) md += `**Keywords:** ${pkg.keywords.join(", ")}\n`;
|
|
87
|
-
if (pkg.maintainers?.length) md += `**Maintainers:** ${pkg.maintainers.map(
|
|
87
|
+
if (pkg.maintainers?.length) md += `**Maintainers:** ${pkg.maintainers.map(m => m.name).join(", ")}\n`;
|
|
88
88
|
|
|
89
89
|
if (pkg.dependencies && Object.keys(pkg.dependencies).length > 0) {
|
|
90
90
|
md += `\n## Dependencies\n\n`;
|
|
@@ -106,7 +106,7 @@ export const handleNuGet: SpecialHandler = async (
|
|
|
106
106
|
|
|
107
107
|
if (pageItems) {
|
|
108
108
|
const found = pageItems.find(
|
|
109
|
-
|
|
109
|
+
item => item.catalogEntry.version.toLowerCase() === requestedVersion.toLowerCase(),
|
|
110
110
|
);
|
|
111
111
|
if (found) {
|
|
112
112
|
targetEntry = found.catalogEntry;
|
|
@@ -162,7 +162,7 @@ export const handleNuGet: SpecialHandler = async (
|
|
|
162
162
|
|
|
163
163
|
// Show dependencies by target framework
|
|
164
164
|
if (targetEntry.dependencyGroups?.length) {
|
|
165
|
-
const hasAnyDeps = targetEntry.dependencyGroups.some(
|
|
165
|
+
const hasAnyDeps = targetEntry.dependencyGroups.some(g => g.dependencies?.length);
|
|
166
166
|
if (hasAnyDeps) {
|
|
167
167
|
md += `\n## Dependencies\n\n`;
|
|
168
168
|
for (const group of targetEntry.dependencyGroups) {
|
package/src/web/scrapers/nvd.ts
CHANGED
|
@@ -119,7 +119,7 @@ export const handleNvd: SpecialHandler = async (
|
|
|
119
119
|
md += ` · **Modified:** ${formatDate(vuln.lastModified)}\n\n`;
|
|
120
120
|
|
|
121
121
|
// Description
|
|
122
|
-
const desc = vuln.descriptions.find(
|
|
122
|
+
const desc = vuln.descriptions.find(d => d.lang === "en")?.value;
|
|
123
123
|
if (desc) {
|
|
124
124
|
md += `## Description\n\n${desc}\n\n`;
|
|
125
125
|
}
|
|
@@ -165,8 +165,8 @@ export const handleNvd: SpecialHandler = async (
|
|
|
165
165
|
|
|
166
166
|
// Weaknesses (CWE)
|
|
167
167
|
const cwes = vuln.weaknesses
|
|
168
|
-
?.flatMap(
|
|
169
|
-
.filter(
|
|
168
|
+
?.flatMap(w => w.description)
|
|
169
|
+
.filter(d => d.lang === "en" && d.value !== "NVD-CWE-Other" && d.value !== "NVD-CWE-noinfo");
|
|
170
170
|
|
|
171
171
|
if (cwes?.length) {
|
|
172
172
|
md += `## Weaknesses\n\n`;
|
|
@@ -108,7 +108,7 @@ function formatSize(bytes: number): string {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
function buildModelPath(parts: string[]): string {
|
|
111
|
-
return parts.map(
|
|
111
|
+
return parts.map(part => encodeURIComponent(part)).join("/");
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
function parseOllamaUrl(url: string): { modelRef: string; baseRef: string; pageUrl: string } | null {
|
|
@@ -152,7 +152,7 @@ function sortTags(tags: string[]): string[] {
|
|
|
152
152
|
|
|
153
153
|
function formatTagList(tags: string[], maxItems: number): string {
|
|
154
154
|
const limited = tags.slice(0, maxItems);
|
|
155
|
-
const formatted = limited.map(
|
|
155
|
+
const formatted = limited.map(tag => `\`${tag}\``).join(", ");
|
|
156
156
|
if (tags.length > maxItems) {
|
|
157
157
|
return `${formatted} (and ${tags.length - maxItems} more)`;
|
|
158
158
|
}
|
|
@@ -205,17 +205,17 @@ export const handleOllama: SpecialHandler = async (
|
|
|
205
205
|
|
|
206
206
|
const baseLower = baseRef.toLowerCase();
|
|
207
207
|
const models = tagsData?.models ?? [];
|
|
208
|
-
const matchingModels = models.filter(
|
|
208
|
+
const matchingModels = models.filter(model => {
|
|
209
209
|
const name = (model.model ?? model.name ?? "").toLowerCase();
|
|
210
210
|
return name === baseLower || name.startsWith(`${baseLower}:`);
|
|
211
211
|
});
|
|
212
212
|
|
|
213
213
|
const tagRef = modelRef.includes(":") ? modelRef : null;
|
|
214
|
-
const selectedTag = tagRef ? matchingModels.find(
|
|
214
|
+
const selectedTag = tagRef ? matchingModels.find(model => (model.model ?? model.name ?? "") === tagRef) : null;
|
|
215
215
|
|
|
216
216
|
const availableTagsRaw = matchingModels
|
|
217
|
-
.map(
|
|
218
|
-
.filter(
|
|
217
|
+
.map(model => model.model ?? model.name ?? "")
|
|
218
|
+
.filter(tag => tag.length > 0);
|
|
219
219
|
const availableTags = sortTags(Array.from(new Set(availableTagsRaw)));
|
|
220
220
|
|
|
221
221
|
const fallbackTags = sortTags(Array.from(new Set(htmlTags)));
|
|
@@ -223,9 +223,7 @@ export const handleOllama: SpecialHandler = async (
|
|
|
223
223
|
|
|
224
224
|
const parameterSizes = collectParameterSizes(selectedTag ? [selectedTag] : matchingModels, htmlParameterSizes);
|
|
225
225
|
|
|
226
|
-
const sizes = matchingModels
|
|
227
|
-
.map((model) => model.size)
|
|
228
|
-
.filter((size): size is number => typeof size === "number");
|
|
226
|
+
const sizes = matchingModels.map(model => model.size).filter((size): size is number => typeof size === "number");
|
|
229
227
|
let sizeLine: string | null = null;
|
|
230
228
|
|
|
231
229
|
if (selectedTag?.size) {
|
|
@@ -166,8 +166,8 @@ export const handleOpenCorporates: SpecialHandler = async (
|
|
|
166
166
|
|
|
167
167
|
// Officers/Directors
|
|
168
168
|
if (company.officers && company.officers.length > 0) {
|
|
169
|
-
const activeOfficers = company.officers.filter(
|
|
170
|
-
const inactiveOfficers = company.officers.filter(
|
|
169
|
+
const activeOfficers = company.officers.filter(o => !o.officer.inactive && !o.officer.end_date);
|
|
170
|
+
const inactiveOfficers = company.officers.filter(o => o.officer.inactive || o.officer.end_date);
|
|
171
171
|
|
|
172
172
|
if (activeOfficers.length > 0) {
|
|
173
173
|
md += `## Current Officers (${activeOfficers.length})\n\n`;
|
|
@@ -129,7 +129,7 @@ async function fetchWork(workId: string, timeout: number, signal?: AbortSignal):
|
|
|
129
129
|
// Fetch author names if we have author keys
|
|
130
130
|
if (work.authors?.length) {
|
|
131
131
|
const authorNames = await fetchAuthorNames(
|
|
132
|
-
work.authors.map(
|
|
132
|
+
work.authors.map(a => a.author.key),
|
|
133
133
|
timeout,
|
|
134
134
|
signal,
|
|
135
135
|
);
|
|
@@ -179,7 +179,7 @@ async function fetchEdition(editionId: string, timeout: number, signal?: AbortSi
|
|
|
179
179
|
// Fetch author names
|
|
180
180
|
if (edition.authors?.length) {
|
|
181
181
|
const authorNames = await fetchAuthorNames(
|
|
182
|
-
edition.authors.map(
|
|
182
|
+
edition.authors.map(a => a.key),
|
|
183
183
|
timeout,
|
|
184
184
|
signal,
|
|
185
185
|
);
|
|
@@ -250,11 +250,11 @@ async function fetchByIsbn(isbn: string, timeout: number, signal?: AbortSignal):
|
|
|
250
250
|
let md = `# ${book.title}\n\n`;
|
|
251
251
|
|
|
252
252
|
if (book.authors?.length) {
|
|
253
|
-
md += `**Authors:** ${book.authors.map(
|
|
253
|
+
md += `**Authors:** ${book.authors.map(a => a.name).join(", ")}\n`;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
if (book.publishers?.length) {
|
|
257
|
-
md += `**Publishers:** ${book.publishers.map(
|
|
257
|
+
md += `**Publishers:** ${book.publishers.map(p => p.name).join(", ")}\n`;
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
if (book.publish_date) {
|
|
@@ -280,7 +280,7 @@ async function fetchByIsbn(isbn: string, timeout: number, signal?: AbortSignal):
|
|
|
280
280
|
if (book.subjects?.length) {
|
|
281
281
|
md += `## Subjects\n\n${book.subjects
|
|
282
282
|
.slice(0, 20)
|
|
283
|
-
.map(
|
|
283
|
+
.map(s => s.name)
|
|
284
284
|
.join(", ")}\n`;
|
|
285
285
|
}
|
|
286
286
|
|
|
@@ -291,7 +291,7 @@ async function fetchAuthorNames(authorKeys: string[], timeout: number, signal?:
|
|
|
291
291
|
const names: string[] = [];
|
|
292
292
|
|
|
293
293
|
// Fetch authors in parallel (limit to first 5)
|
|
294
|
-
const promises = authorKeys.slice(0, 5).map(async
|
|
294
|
+
const promises = authorKeys.slice(0, 5).map(async key => {
|
|
295
295
|
const authorKey = key.startsWith("/authors/") ? key : `/authors/${key}`;
|
|
296
296
|
const apiUrl = `https://openlibrary.org${authorKey}.json`;
|
|
297
297
|
try {
|