@oh-my-pi/pi-coding-agent 13.2.0 → 13.3.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 +54 -1
- package/package.json +7 -7
- package/scripts/format-prompts.ts +33 -14
- package/scripts/generate-docs-index.ts +2 -2
- package/src/capability/index.ts +1 -2
- package/src/cli/args.ts +3 -3
- package/src/cli/config-cli.ts +1 -1
- package/src/cli/file-processor.ts +1 -2
- package/src/cli/grep-cli.ts +1 -1
- package/src/cli/jupyter-cli.ts +1 -1
- package/src/cli/plugin-cli.ts +1 -1
- package/src/cli/setup-cli.ts +1 -1
- package/src/cli/shell-cli.ts +1 -1
- package/src/cli/ssh-cli.ts +1 -1
- package/src/cli/stats-cli.ts +1 -2
- package/src/cli/update-cli.ts +1 -2
- package/src/cli/web-search-cli.ts +1 -1
- package/src/cli.ts +1 -1
- package/src/commands/launch.ts +2 -1
- package/src/commit/agentic/agent.ts +2 -1
- package/src/commit/agentic/index.ts +1 -2
- package/src/commit/agentic/prompts/system.md +3 -3
- package/src/commit/agentic/tools/propose-changelog.ts +30 -19
- package/src/commit/changelog/generate.ts +16 -6
- package/src/commit/changelog/index.ts +2 -1
- package/src/commit/pipeline.ts +1 -2
- package/src/commit/prompts/reduce-system.md +1 -1
- package/src/commit/types.ts +10 -1
- package/src/config/keybindings.ts +1 -2
- package/src/config/model-registry.ts +1 -1
- package/src/config/prompt-templates.ts +14 -2
- package/src/config/settings-schema.ts +36 -4
- package/src/config/settings.ts +19 -2
- package/src/config.ts +1 -2
- package/src/debug/index.ts +1 -1
- package/src/debug/report-bundle.ts +1 -2
- package/src/debug/system-info.ts +1 -2
- package/src/discovery/agents.ts +2 -2
- package/src/discovery/builtin.ts +8 -9
- package/src/discovery/claude-plugins.ts +2 -2
- package/src/discovery/claude.ts +30 -12
- package/src/discovery/codex.ts +3 -3
- package/src/discovery/cursor.ts +5 -4
- package/src/discovery/gemini.ts +5 -5
- package/src/discovery/helpers.ts +47 -69
- package/src/discovery/mcp-json.ts +3 -3
- package/src/discovery/opencode.ts +7 -8
- package/src/discovery/ssh.ts +3 -3
- package/src/discovery/vscode.ts +3 -2
- package/src/discovery/windsurf.ts +3 -2
- package/src/exa/company.ts +1 -1
- package/src/exa/factory.ts +1 -6
- package/src/exa/linkedin.ts +1 -1
- package/src/exa/mcp-client.ts +19 -8
- package/src/exa/search.ts +2 -2
- package/src/exa/types.ts +3 -3
- package/src/exec/bash-executor.ts +2 -1
- package/src/exec/non-interactive-env.ts +43 -0
- package/src/export/custom-share.ts +1 -1
- package/src/export/html/index.ts +1 -2
- package/src/extensibility/custom-commands/loader.ts +1 -2
- package/src/extensibility/plugins/installer.ts +1 -2
- package/src/extensibility/plugins/loader.ts +1 -2
- package/src/extensibility/plugins/manager.ts +3 -2
- package/src/extensibility/skills.ts +59 -115
- package/src/index.ts +1 -3
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/ipy/executor.ts +1 -2
- package/src/ipy/gateway-coordinator.ts +1 -2
- package/src/ipy/modules.ts +1 -1
- package/src/ipy/runtime.ts +2 -3
- package/src/main.ts +1 -2
- package/src/mcp/config.ts +2 -2
- package/src/mcp/transports/stdio.ts +1 -2
- package/src/memories/index.ts +1 -2
- package/src/modes/components/extensions/extension-dashboard.ts +1 -1
- package/src/modes/components/extensions/inspector-panel.ts +8 -2
- package/src/modes/components/footer.ts +1 -2
- package/src/modes/components/settings-defs.ts +17 -1
- package/src/modes/components/status-line/segments.ts +1 -2
- package/src/modes/components/status-line.ts +7 -5
- package/src/modes/components/tool-execution.ts +3 -10
- package/src/modes/components/welcome.ts +1 -1
- package/src/modes/controllers/command-controller.ts +1 -2
- package/src/modes/controllers/mcp-command-controller.ts +5 -4
- package/src/modes/controllers/selector-controller.ts +22 -1
- package/src/modes/controllers/ssh-command-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +11 -3
- package/src/modes/oauth-manual-input.ts +42 -0
- package/src/modes/shared.ts +1 -2
- package/src/modes/theme/theme.ts +1 -2
- package/src/modes/types.ts +2 -0
- package/src/patch/hashline.ts +19 -1
- package/src/patch/index.ts +1 -25
- package/src/prompts/agents/designer.md +7 -10
- package/src/prompts/agents/explore.md +15 -23
- package/src/prompts/agents/init.md +23 -23
- package/src/prompts/agents/plan.md +14 -77
- package/src/prompts/agents/reviewer.md +6 -5
- package/src/prompts/agents/task.md +13 -11
- package/src/prompts/compaction/branch-summary.md +3 -3
- package/src/prompts/compaction/compaction-short-summary.md +7 -7
- package/src/prompts/compaction/compaction-summary-context.md +1 -1
- package/src/prompts/compaction/compaction-summary.md +5 -5
- package/src/prompts/compaction/compaction-turn-prefix.md +3 -3
- package/src/prompts/compaction/compaction-update-summary.md +11 -11
- package/src/prompts/memories/consolidation.md +5 -5
- package/src/prompts/memories/read-path.md +6 -6
- package/src/prompts/memories/stage_one_input.md +1 -1
- package/src/prompts/memories/stage_one_system.md +5 -5
- package/src/prompts/review-request.md +4 -4
- package/src/prompts/system/agent-creation-architect.md +17 -17
- package/src/prompts/system/agent-creation-user.md +2 -2
- package/src/prompts/system/commit-message-system.md +2 -0
- package/src/prompts/system/custom-system-prompt.md +4 -4
- package/src/prompts/system/plan-mode-active.md +20 -20
- package/src/prompts/system/plan-mode-approved.md +7 -7
- package/src/prompts/system/plan-mode-reference.md +2 -2
- package/src/prompts/system/plan-mode-subagent.md +8 -8
- package/src/prompts/system/subagent-submit-reminder.md +5 -5
- package/src/prompts/system/subagent-system-prompt.md +29 -22
- package/src/prompts/system/subagent-user-prompt.md +7 -3
- package/src/prompts/system/summarization-system.md +1 -1
- package/src/prompts/system/system-prompt.md +214 -226
- package/src/prompts/system/title-system.md +2 -2
- package/src/prompts/system/ttsr-interrupt.md +1 -1
- package/src/prompts/system/web-search.md +16 -16
- package/src/prompts/tools/ask.md +1 -3
- package/src/prompts/tools/await.md +2 -4
- package/src/prompts/tools/bash.md +5 -7
- package/src/prompts/tools/browser.md +4 -6
- package/src/prompts/tools/calculator.md +1 -3
- package/src/prompts/tools/cancel-job.md +2 -4
- package/src/prompts/tools/exit-plan-mode.md +7 -7
- package/src/prompts/tools/fetch.md +0 -2
- package/src/prompts/tools/find.md +3 -5
- package/src/prompts/tools/gemini-image.md +6 -22
- package/src/prompts/tools/grep.md +4 -6
- package/src/prompts/tools/hashline.md +56 -15
- package/src/prompts/tools/lsp.md +1 -3
- package/src/prompts/tools/patch.md +7 -9
- package/src/prompts/tools/python.md +10 -14
- package/src/prompts/tools/read.md +0 -2
- package/src/prompts/tools/replace.md +5 -7
- package/src/prompts/tools/ssh.md +3 -5
- package/src/prompts/tools/task-summary.md +4 -4
- package/src/prompts/tools/task.md +7 -9
- package/src/prompts/tools/todo-write.md +7 -9
- package/src/prompts/tools/web-search.md +3 -5
- package/src/prompts/tools/write.md +3 -5
- package/src/sdk.ts +4 -2
- package/src/session/agent-session.ts +10 -26
- package/src/session/agent-storage.ts +1 -2
- package/src/session/history-storage.ts +1 -2
- package/src/session/session-manager.ts +10 -2
- package/src/slash-commands/builtin-registry.ts +26 -1
- package/src/ssh/connection-manager.ts +11 -2
- package/src/ssh/sshfs-mount.ts +7 -1
- package/src/system-prompt.ts +29 -103
- package/src/task/agents.ts +1 -1
- package/src/task/index.ts +211 -70
- package/src/task/render.ts +24 -8
- package/src/task/types.ts +6 -1
- package/src/task/worktree.ts +394 -32
- package/src/tools/ask.ts +0 -1
- package/src/tools/bash-interactive.ts +2 -45
- package/src/tools/bash.ts +5 -5
- package/src/tools/browser.ts +1 -2
- package/src/tools/gemini-image.ts +8 -28
- package/src/tools/json-tree.ts +2 -1
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +1 -2
- package/src/tools/submit-result.ts +22 -23
- package/src/utils/commit-message-generator.ts +132 -0
- package/src/utils/tools-manager.ts +1 -2
- package/src/web/scrapers/artifacthub.ts +2 -1
- package/src/web/scrapers/aur.ts +2 -1
- package/src/web/scrapers/biorxiv.ts +2 -1
- package/src/web/scrapers/bluesky.ts +2 -1
- package/src/web/scrapers/chocolatey.ts +2 -1
- package/src/web/scrapers/cisa-kev.ts +2 -1
- package/src/web/scrapers/clojars.ts +2 -1
- package/src/web/scrapers/coingecko.ts +2 -1
- package/src/web/scrapers/crates-io.ts +2 -1
- package/src/web/scrapers/crossref.ts +2 -1
- package/src/web/scrapers/discogs.ts +3 -1
- package/src/web/scrapers/discourse.ts +2 -1
- package/src/web/scrapers/dockerhub.ts +2 -1
- package/src/web/scrapers/fdroid.ts +2 -1
- package/src/web/scrapers/firefox-addons.ts +2 -1
- package/src/web/scrapers/flathub.ts +2 -1
- package/src/web/scrapers/gitlab.ts +1 -1
- package/src/web/scrapers/go-pkg.ts +2 -1
- package/src/web/scrapers/hackage.ts +2 -1
- package/src/web/scrapers/hackernews.ts +2 -1
- package/src/web/scrapers/hex.ts +2 -1
- package/src/web/scrapers/huggingface.ts +2 -1
- package/src/web/scrapers/jetbrains-marketplace.ts +2 -1
- package/src/web/scrapers/lemmy.ts +2 -1
- package/src/web/scrapers/lobsters.ts +2 -1
- package/src/web/scrapers/mastodon.ts +2 -1
- package/src/web/scrapers/maven.ts +2 -1
- package/src/web/scrapers/mdn.ts +2 -1
- package/src/web/scrapers/metacpan.ts +2 -1
- package/src/web/scrapers/musicbrainz.ts +3 -1
- package/src/web/scrapers/npm.ts +2 -1
- package/src/web/scrapers/nuget.ts +2 -1
- package/src/web/scrapers/nvd.ts +2 -1
- package/src/web/scrapers/ollama.ts +2 -1
- package/src/web/scrapers/open-vsx.ts +2 -1
- package/src/web/scrapers/opencorporates.ts +2 -1
- package/src/web/scrapers/openlibrary.ts +2 -1
- package/src/web/scrapers/orcid.ts +3 -1
- package/src/web/scrapers/osv.ts +2 -1
- package/src/web/scrapers/packagist.ts +2 -1
- package/src/web/scrapers/pub-dev.ts +2 -1
- package/src/web/scrapers/pubmed.ts +2 -1
- package/src/web/scrapers/pypi.ts +2 -1
- package/src/web/scrapers/rawg.ts +2 -8
- package/src/web/scrapers/reddit.ts +2 -1
- package/src/web/scrapers/repology.ts +2 -1
- package/src/web/scrapers/rfc.ts +2 -1
- package/src/web/scrapers/rubygems.ts +2 -1
- package/src/web/scrapers/searchcode.ts +2 -1
- package/src/web/scrapers/sec-edgar.ts +2 -1
- package/src/web/scrapers/semantic-scholar.ts +2 -1
- package/src/web/scrapers/snapcraft.ts +2 -1
- package/src/web/scrapers/sourcegraph.ts +2 -1
- package/src/web/scrapers/spdx.ts +2 -1
- package/src/web/scrapers/stackoverflow.ts +2 -1
- package/src/web/scrapers/terraform.ts +2 -1
- package/src/web/scrapers/types.ts +0 -11
- package/src/web/scrapers/vimeo.ts +2 -1
- package/src/web/scrapers/vscode-marketplace.ts +2 -1
- package/src/web/scrapers/w3c.ts +2 -1
- package/src/web/scrapers/wikidata.ts +2 -1
- package/src/web/search/index.ts +10 -14
- package/src/web/search/provider.ts +2 -2
- package/src/web/search/providers/codex.ts +1 -2
- package/src/web/search/providers/exa.ts +42 -10
- package/src/web/search/providers/gemini.ts +1 -1
- package/src/web/search/providers/perplexity.ts +20 -9
- package/src/web/search/providers/utils.ts +1 -1
|
@@ -13,8 +13,8 @@ import { resolveReadPath } from "./path-utils";
|
|
|
13
13
|
const DEFAULT_MODEL = "gemini-3-pro-image-preview";
|
|
14
14
|
const DEFAULT_OPENROUTER_MODEL = "google/gemini-3-pro-image-preview";
|
|
15
15
|
const DEFAULT_ANTIGRAVITY_MODEL = "gemini-3-pro-image";
|
|
16
|
-
const
|
|
17
|
-
const MAX_IMAGE_SIZE =
|
|
16
|
+
const IMAGE_TIMEOUT = 3 * 60 * 1000; // 3 minutes
|
|
17
|
+
const MAX_IMAGE_SIZE = 35 * 1024 * 1024;
|
|
18
18
|
|
|
19
19
|
const ANTIGRAVITY_ENDPOINT = "https://daily-cloudcode-pa.sandbox.googleapis.com";
|
|
20
20
|
const IMAGE_SYSTEM_INSTRUCTION =
|
|
@@ -76,13 +76,7 @@ const baseImageSchema = Type.Object(
|
|
|
76
76
|
style: Type.Optional(
|
|
77
77
|
Type.String({
|
|
78
78
|
description:
|
|
79
|
-
"Artistic style, mood, color grading (e.g., 'film noir mood, cinematic color grading', 'Studio Ghibli watercolor', 'photorealistic').",
|
|
80
|
-
}),
|
|
81
|
-
),
|
|
82
|
-
camera: Type.Optional(
|
|
83
|
-
Type.String({
|
|
84
|
-
description:
|
|
85
|
-
"Lens and camera specs (e.g., 'Shot on 35mm, f/1.8', 'macro lens, extreme close-up', '85mm portrait lens').",
|
|
79
|
+
"Artistic style, mood, color grading, camera (e.g., 'film noir mood, cinematic color grading', 'Studio Ghibli watercolor', 'photorealistic').",
|
|
86
80
|
}),
|
|
87
81
|
),
|
|
88
82
|
text: Type.Optional(
|
|
@@ -94,23 +88,16 @@ const baseImageSchema = Type.Object(
|
|
|
94
88
|
changes: Type.Optional(
|
|
95
89
|
Type.Array(Type.String(), {
|
|
96
90
|
description:
|
|
97
|
-
"For edits: specific changes to make (e.g., ['Change the tie to green', 'Remove the car in background']). Use with input_images.",
|
|
98
|
-
}),
|
|
99
|
-
),
|
|
100
|
-
preserve: Type.Optional(
|
|
101
|
-
Type.String({
|
|
102
|
-
description:
|
|
103
|
-
"For edits: what to keep unchanged (e.g., 'identity, face, hairstyle, lighting'). Use with input_images and changes.",
|
|
91
|
+
"For edits: specific changes to make, as well as, what to keep unchanged (e.g., ['Change the tie to green', 'Remove the car in background']). Use with input_images.",
|
|
104
92
|
}),
|
|
105
93
|
),
|
|
106
94
|
aspect_ratio: Type.Optional(aspectRatioSchema),
|
|
107
95
|
image_size: Type.Optional(imageSizeSchema),
|
|
108
|
-
|
|
96
|
+
input: Type.Optional(
|
|
109
97
|
Type.Array(inputImageSchema, {
|
|
110
98
|
description: "Optional input images for edits or variations.",
|
|
111
99
|
}),
|
|
112
100
|
),
|
|
113
|
-
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (default: 120)" })),
|
|
114
101
|
},
|
|
115
102
|
{ additionalProperties: false },
|
|
116
103
|
);
|
|
@@ -136,7 +123,6 @@ function assemblePrompt(params: GeminiImageParams): string {
|
|
|
136
123
|
// Technical details as separate sentences
|
|
137
124
|
if (params.composition) parts.push(params.composition);
|
|
138
125
|
if (params.lighting) parts.push(params.lighting);
|
|
139
|
-
if (params.camera) parts.push(params.camera);
|
|
140
126
|
if (params.style) parts.push(params.style);
|
|
141
127
|
|
|
142
128
|
// Join with periods for sentence structure
|
|
@@ -150,9 +136,6 @@ function assemblePrompt(params: GeminiImageParams): string {
|
|
|
150
136
|
// Edit mode: changes and preserve directives
|
|
151
137
|
if (params.changes?.length) {
|
|
152
138
|
prompt += `\n\nChanges:\n${params.changes.map(c => `- ${c}`).join("\n")}`;
|
|
153
|
-
if (params.preserve) {
|
|
154
|
-
prompt += `\n\nPreserve: ${params.preserve}`;
|
|
155
|
-
}
|
|
156
139
|
}
|
|
157
140
|
|
|
158
141
|
return prompt;
|
|
@@ -638,16 +621,13 @@ export const geminiImageTool: CustomTool<typeof geminiImageSchema, GeminiImageTo
|
|
|
638
621
|
const cwd = ctx.sessionManager.getCwd();
|
|
639
622
|
|
|
640
623
|
const resolvedImages: InlineImageData[] = [];
|
|
641
|
-
if (params.
|
|
642
|
-
for (const input of params.
|
|
624
|
+
if (params.input?.length) {
|
|
625
|
+
for (const input of params.input) {
|
|
643
626
|
resolvedImages.push(await resolveInputImage(input, cwd));
|
|
644
627
|
}
|
|
645
628
|
}
|
|
646
629
|
|
|
647
|
-
const
|
|
648
|
-
// Clamp to reasonable range: 1s - 600s (10 min)
|
|
649
|
-
const timeoutSeconds = Math.max(1, Math.min(600, rawTimeout));
|
|
650
|
-
const requestSignal = ptree.combineSignals(signal, timeoutSeconds * 1000);
|
|
630
|
+
const requestSignal = ptree.combineSignals(signal, IMAGE_TIMEOUT);
|
|
651
631
|
|
|
652
632
|
if (provider === "antigravity") {
|
|
653
633
|
if (!apiKey.projectId) {
|
package/src/tools/json-tree.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* JSON tree rendering utilities shared across tool renderers.
|
|
3
3
|
*/
|
|
4
|
+
import { INTENT_FIELD } from "@oh-my-pi/pi-agent-core";
|
|
4
5
|
import type { Theme } from "../modes/theme/theme";
|
|
5
6
|
import { truncateToWidth } from "./render-utils";
|
|
6
7
|
|
|
@@ -13,7 +14,7 @@ export const JSON_TREE_SCALAR_LEN_COLLAPSED = 60;
|
|
|
13
14
|
export const JSON_TREE_SCALAR_LEN_EXPANDED = 2000;
|
|
14
15
|
|
|
15
16
|
/** Keys injected by the harness that should not be displayed to users */
|
|
16
|
-
const HIDDEN_ARG_KEYS = new Set([
|
|
17
|
+
const HIDDEN_ARG_KEYS = new Set([INTENT_FIELD]);
|
|
17
18
|
|
|
18
19
|
/** Strip harness-internal keys from tool args for display */
|
|
19
20
|
export function stripInternalArgs(args: Record<string, unknown>): Record<string, unknown> {
|
package/src/tools/python.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallb
|
|
|
4
4
|
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
5
5
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
6
6
|
import { Markdown, Text } from "@oh-my-pi/pi-tui";
|
|
7
|
-
import { getProjectDir } from "@oh-my-pi/pi-utils
|
|
7
|
+
import { getProjectDir } from "@oh-my-pi/pi-utils";
|
|
8
8
|
import { type Static, Type } from "@sinclair/typebox";
|
|
9
9
|
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
10
10
|
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
package/src/tools/read.ts
CHANGED
|
@@ -5,8 +5,7 @@ import type { ImageContent, TextContent } from "@oh-my-pi/pi-ai";
|
|
|
5
5
|
import { FileType, glob } from "@oh-my-pi/pi-natives";
|
|
6
6
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
7
7
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
8
|
-
import { ptree, untilAborted } from "@oh-my-pi/pi-utils";
|
|
9
|
-
import { getRemoteDir } from "@oh-my-pi/pi-utils/dirs";
|
|
8
|
+
import { getRemoteDir, ptree, untilAborted } from "@oh-my-pi/pi-utils";
|
|
10
9
|
import { type Static, Type } from "@sinclair/typebox";
|
|
11
10
|
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
12
11
|
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* Subagents must call this tool to finish and return structured JSON output.
|
|
5
5
|
*/
|
|
6
6
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
7
|
-
import {
|
|
8
|
-
import type { Static, TObject } from "@sinclair/typebox";
|
|
7
|
+
import type { Static, TSchema } from "@sinclair/typebox";
|
|
9
8
|
import { Type } from "@sinclair/typebox";
|
|
10
9
|
import Ajv, { type ErrorObject, type ValidateFunction } from "ajv";
|
|
11
10
|
import { subprocessToolRegistry } from "../task/subprocess-tool-registry";
|
|
@@ -52,13 +51,13 @@ function formatAjvErrors(errors: ErrorObject[] | null | undefined): string {
|
|
|
52
51
|
.join("; ");
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
export class SubmitResultTool implements AgentTool<
|
|
54
|
+
export class SubmitResultTool implements AgentTool<TSchema, SubmitResultDetails> {
|
|
56
55
|
readonly name = "submit_result";
|
|
57
56
|
readonly label = "Submit Result";
|
|
58
57
|
readonly description =
|
|
59
58
|
"Finish the task with structured JSON output. Call exactly once at the end of the task.\n\n" +
|
|
60
|
-
"If you cannot complete the task, call with
|
|
61
|
-
readonly parameters:
|
|
59
|
+
"If you cannot complete the task, call with an error message payload.";
|
|
60
|
+
readonly parameters: TSchema;
|
|
62
61
|
readonly strict = true;
|
|
63
62
|
|
|
64
63
|
readonly #validate?: ValidateFunction;
|
|
@@ -92,45 +91,45 @@ export class SubmitResultTool implements AgentTool<TObject, SubmitResultDetails>
|
|
|
92
91
|
})
|
|
93
92
|
: Type.Object({}, { additionalProperties: true, description: "Structured JSON output (no schema specified)" });
|
|
94
93
|
|
|
95
|
-
this.parameters = Type.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}),
|
|
101
|
-
),
|
|
102
|
-
|
|
103
|
-
});
|
|
94
|
+
this.parameters = Type.Union([
|
|
95
|
+
Type.Object({
|
|
96
|
+
data: dataSchema,
|
|
97
|
+
}),
|
|
98
|
+
Type.Object({
|
|
99
|
+
error: Type.String({ description: "Error message when the task cannot be completed" }),
|
|
100
|
+
}),
|
|
101
|
+
]);
|
|
104
102
|
}
|
|
105
103
|
|
|
106
104
|
async execute(
|
|
107
105
|
_toolCallId: string,
|
|
108
|
-
params: Static<
|
|
106
|
+
params: Static<TSchema>,
|
|
109
107
|
_signal?: AbortSignal,
|
|
110
108
|
_onUpdate?: AgentToolUpdateCallback<SubmitResultDetails>,
|
|
111
109
|
_context?: AgentToolContext,
|
|
112
110
|
): Promise<AgentToolResult<SubmitResultDetails>> {
|
|
113
|
-
const
|
|
111
|
+
const raw = params as Record<string, unknown>;
|
|
112
|
+
const errorMessage = typeof raw.error === "string" ? raw.error : undefined;
|
|
113
|
+
const status = errorMessage !== undefined ? "aborted" : "success";
|
|
114
|
+
const data = raw.data;
|
|
114
115
|
|
|
115
|
-
// Skip validation when aborting - data is optional for aborts
|
|
116
116
|
if (status === "success") {
|
|
117
|
-
if (
|
|
118
|
-
throw new Error("data is required when
|
|
117
|
+
if (data === undefined || data === null) {
|
|
118
|
+
throw new Error("data is required when submit_result indicates success");
|
|
119
119
|
}
|
|
120
120
|
if (this.#schemaError) {
|
|
121
121
|
throw new Error(`Invalid output schema: ${this.#schemaError}`);
|
|
122
122
|
}
|
|
123
|
-
if (this.#validate && !this.#validate(
|
|
123
|
+
if (this.#validate && !this.#validate(data)) {
|
|
124
124
|
throw new Error(`Output does not match schema: ${formatAjvErrors(this.#validate.errors)}`);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
const responseText =
|
|
129
|
-
status === "aborted" ? `Task aborted: ${params.error || "No reason provided"}` : "Result submitted.";
|
|
128
|
+
const responseText = status === "aborted" ? `Task aborted: ${errorMessage}` : "Result submitted.";
|
|
130
129
|
|
|
131
130
|
return {
|
|
132
131
|
content: [{ type: "text", text: responseText }],
|
|
133
|
-
details: { data
|
|
132
|
+
details: { data, status, error: errorMessage },
|
|
134
133
|
};
|
|
135
134
|
}
|
|
136
135
|
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate commit messages from diffs using a smol, fast model.
|
|
3
|
+
* Follows the same pattern as title-generator.ts.
|
|
4
|
+
*/
|
|
5
|
+
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
6
|
+
import { completeSimple } from "@oh-my-pi/pi-ai";
|
|
7
|
+
import { logger } from "@oh-my-pi/pi-utils";
|
|
8
|
+
import type { ModelRegistry } from "../config/model-registry";
|
|
9
|
+
import { parseModelString } from "../config/model-resolver";
|
|
10
|
+
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
11
|
+
import MODEL_PRIO from "../priority.json" with { type: "json" };
|
|
12
|
+
import commitSystemPrompt from "../prompts/system/commit-message-system.md" with { type: "text" };
|
|
13
|
+
|
|
14
|
+
const COMMIT_SYSTEM_PROMPT = renderPromptTemplate(commitSystemPrompt);
|
|
15
|
+
const MAX_DIFF_CHARS = 4000;
|
|
16
|
+
|
|
17
|
+
/** File patterns that should be excluded from commit message generation diffs. */
|
|
18
|
+
const NOISE_SUFFIXES = [".lock", ".lockb", "-lock.json", "-lock.yaml"];
|
|
19
|
+
|
|
20
|
+
/** Strip diff hunks for noisy files that drown out real changes. */
|
|
21
|
+
function filterDiffNoise(diff: string): string {
|
|
22
|
+
const lines = diff.split("\n");
|
|
23
|
+
const filtered: string[] = [];
|
|
24
|
+
let skip = false;
|
|
25
|
+
for (const line of lines) {
|
|
26
|
+
if (line.startsWith("diff --git ")) {
|
|
27
|
+
const bPath = line.split(" b/")[1];
|
|
28
|
+
skip = bPath != null && NOISE_SUFFIXES.some(s => bPath.endsWith(s));
|
|
29
|
+
}
|
|
30
|
+
if (!skip) filtered.push(line);
|
|
31
|
+
}
|
|
32
|
+
return filtered.join("\n");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getSmolModelCandidates(registry: ModelRegistry, savedSmolModel?: string): Model<Api>[] {
|
|
36
|
+
const availableModels = registry.getAvailable();
|
|
37
|
+
if (availableModels.length === 0) return [];
|
|
38
|
+
|
|
39
|
+
const candidates: Model<Api>[] = [];
|
|
40
|
+
const addCandidate = (model?: Model<Api>): void => {
|
|
41
|
+
if (!model) return;
|
|
42
|
+
if (candidates.some(c => c.provider === model.provider && c.id === model.id)) return;
|
|
43
|
+
candidates.push(model);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
if (savedSmolModel) {
|
|
47
|
+
const parsed = parseModelString(savedSmolModel);
|
|
48
|
+
if (parsed) {
|
|
49
|
+
const match = availableModels.find(m => m.provider === parsed.provider && m.id === parsed.id);
|
|
50
|
+
addCandidate(match);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
for (const pattern of MODEL_PRIO.smol) {
|
|
55
|
+
const needle = pattern.toLowerCase();
|
|
56
|
+
addCandidate(availableModels.find(m => m.id.toLowerCase() === needle));
|
|
57
|
+
addCandidate(availableModels.find(m => m.id.toLowerCase().includes(needle)));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const model of availableModels) {
|
|
61
|
+
addCandidate(model);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return candidates;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Generate a commit message from a unified diff.
|
|
69
|
+
* Returns null if generation fails (caller should fall back to generic message).
|
|
70
|
+
*/
|
|
71
|
+
export async function generateCommitMessage(
|
|
72
|
+
diff: string,
|
|
73
|
+
registry: ModelRegistry,
|
|
74
|
+
savedSmolModel?: string,
|
|
75
|
+
sessionId?: string,
|
|
76
|
+
): Promise<string | null> {
|
|
77
|
+
const candidates = getSmolModelCandidates(registry, savedSmolModel);
|
|
78
|
+
if (candidates.length === 0) {
|
|
79
|
+
logger.debug("commit-msg-generator: no smol model found");
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const cleanDiff = filterDiffNoise(diff);
|
|
84
|
+
const truncatedDiff =
|
|
85
|
+
cleanDiff.length > MAX_DIFF_CHARS ? `${cleanDiff.slice(0, MAX_DIFF_CHARS)}\n… (truncated)` : cleanDiff;
|
|
86
|
+
if (!truncatedDiff.trim()) {
|
|
87
|
+
logger.debug("commit-msg-generator: diff is empty after noise filtering");
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const userMessage = `<diff>\n${truncatedDiff}\n</diff>`;
|
|
91
|
+
|
|
92
|
+
for (const model of candidates) {
|
|
93
|
+
const apiKey = await registry.getApiKey(model, sessionId);
|
|
94
|
+
if (!apiKey) continue;
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const response = await completeSimple(
|
|
98
|
+
model,
|
|
99
|
+
{
|
|
100
|
+
systemPrompt: COMMIT_SYSTEM_PROMPT,
|
|
101
|
+
messages: [{ role: "user", content: userMessage, timestamp: Date.now() }],
|
|
102
|
+
},
|
|
103
|
+
{ apiKey, maxTokens: 60 },
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
if (response.stopReason === "error") {
|
|
107
|
+
logger.debug("commit-msg-generator: error", { model: model.id, error: response.errorMessage });
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let msg = "";
|
|
112
|
+
for (const content of response.content) {
|
|
113
|
+
if (content.type === "text") msg += content.text;
|
|
114
|
+
}
|
|
115
|
+
msg = msg.trim();
|
|
116
|
+
if (!msg) continue;
|
|
117
|
+
|
|
118
|
+
// Clean up: remove wrapping quotes, backticks, trailing period
|
|
119
|
+
msg = msg.replace(/^[`"']|[`"']$/g, "").replace(/\.$/, "");
|
|
120
|
+
|
|
121
|
+
logger.debug("commit-msg-generator: generated", { model: model.id, msg });
|
|
122
|
+
return msg;
|
|
123
|
+
} catch (err) {
|
|
124
|
+
logger.debug("commit-msg-generator: error", {
|
|
125
|
+
model: model.id,
|
|
126
|
+
error: err instanceof Error ? err.message : String(err),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import { logger, ptree, TempDir } from "@oh-my-pi/pi-utils";
|
|
5
|
-
import { APP_NAME, getToolsDir } from "@oh-my-pi/pi-utils/dirs";
|
|
4
|
+
import { APP_NAME, getToolsDir, logger, ptree, TempDir } from "@oh-my-pi/pi-utils";
|
|
6
5
|
|
|
7
6
|
const TOOLS_DIR = getToolsDir();
|
|
8
7
|
const TOOL_DOWNLOAD_TIMEOUT_MS = 15000;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatIsoDate, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatIsoDate, formatNumber, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface ArtifactHubMaintainer {
|
|
5
6
|
name: string;
|
package/src/web/scrapers/aur.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatIsoDate, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatIsoDate, formatNumber, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface AurPackage {
|
|
5
6
|
Name: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, loadPage
|
|
3
|
+
import { buildResult, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface BiorxivPaper {
|
|
5
6
|
biorxiv_doi?: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatNumber, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
const API_BASE = "https://public.api.bsky.app/xrpc";
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatIsoDate, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatIsoDate, formatNumber, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface NuGetODataEntry {
|
|
5
6
|
Id: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, loadPage
|
|
3
|
+
import { buildResult, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface KevEntry {
|
|
5
6
|
cveID: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatNumber, loadPage } from "./types";
|
|
3
4
|
import { asNumber, asString, isRecord } from "./utils";
|
|
4
5
|
|
|
5
6
|
function formatLicenses(licenses: unknown): string[] {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatNumber, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface CoinGeckoResponse {
|
|
5
6
|
id: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatNumber, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Check if content looks like HTML
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, htmlToBasicMarkdown, loadPage
|
|
3
|
+
import { buildResult, htmlToBasicMarkdown, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface CrossrefAuthor {
|
|
5
6
|
given?: string;
|
|
@@ -4,8 +4,10 @@
|
|
|
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
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
7
9
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
8
|
-
import { buildResult, loadPage
|
|
10
|
+
import { buildResult, loadPage } from "./types";
|
|
9
11
|
|
|
10
12
|
interface DiscogsArtist {
|
|
11
13
|
name: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatIsoDate, htmlToBasicMarkdown, loadPage
|
|
3
|
+
import { buildResult, formatIsoDate, htmlToBasicMarkdown, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface DiscourseUser {
|
|
5
6
|
username?: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import { formatBytes } from "../../tools/render-utils";
|
|
2
3
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
3
|
-
import { buildResult, formatIsoDate, formatNumber, loadPage
|
|
4
|
+
import { buildResult, formatIsoDate, formatNumber, loadPage } from "./types";
|
|
4
5
|
|
|
5
6
|
interface DockerHubRepo {
|
|
6
7
|
name: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { LocalizedText, RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, getLocalizedText, loadPage
|
|
3
|
+
import { buildResult, getLocalizedText, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
type FdroidPackage = {
|
|
5
6
|
packageName?: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { LocalizedText, RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatNumber, getLocalizedText, htmlToBasicMarkdown, loadPage
|
|
3
|
+
import { buildResult, formatNumber, getLocalizedText, htmlToBasicMarkdown, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
type AddonFile = {
|
|
5
6
|
permissions?: string[];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatIsoDate, formatNumber, htmlToBasicMarkdown, loadPage
|
|
3
|
+
import { buildResult, formatIsoDate, formatNumber, htmlToBasicMarkdown, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface FlathubScreenshotSize {
|
|
5
6
|
src?: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import { parse as parseHtml } from "node-html-parser";
|
|
2
3
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
3
|
-
import { buildResult, htmlToBasicMarkdown, loadPage
|
|
4
|
+
import { buildResult, htmlToBasicMarkdown, loadPage } from "./types";
|
|
4
5
|
|
|
5
6
|
interface GoModuleInfo {
|
|
6
7
|
Version: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, loadPage
|
|
3
|
+
import { buildResult, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface HackageVersionMap {
|
|
5
6
|
[version: string]: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, decodeHtmlEntities, formatIsoDate, loadPage
|
|
3
|
+
import { buildResult, decodeHtmlEntities, formatIsoDate, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface HNItem {
|
|
5
6
|
id: number;
|
package/src/web/scrapers/hex.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatIsoDate, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatIsoDate, formatNumber, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Handle Hex.pm (Elixir package registry) URLs via API
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatNumber, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface HfModelData {
|
|
5
6
|
modelId: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatNumber, htmlToBasicMarkdown, loadPage
|
|
3
|
+
import { buildResult, formatNumber, htmlToBasicMarkdown, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface PluginVendor {
|
|
5
6
|
name?: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, loadPage
|
|
3
|
+
import { buildResult, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface LemmyCreator {
|
|
5
6
|
name: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatIsoDate, loadPage
|
|
3
|
+
import { buildResult, formatIsoDate, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
// =============================================================================
|
|
5
6
|
// Lobste.rs Types
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatNumber, htmlToBasicMarkdown, loadPage
|
|
3
|
+
import { buildResult, formatNumber, htmlToBasicMarkdown, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface MastodonAccount {
|
|
5
6
|
id: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatIsoDate, formatNumber, loadPage
|
|
3
|
+
import { buildResult, formatIsoDate, formatNumber, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface MavenDoc {
|
|
5
6
|
id: string;
|
package/src/web/scrapers/mdn.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, htmlToBasicMarkdown, loadPage
|
|
3
|
+
import { buildResult, htmlToBasicMarkdown, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface MDNSection {
|
|
5
6
|
type: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
2
|
-
import { buildResult, formatIsoDate, loadPage
|
|
3
|
+
import { buildResult, formatIsoDate, loadPage } from "./types";
|
|
3
4
|
|
|
4
5
|
interface ModuleResponse {
|
|
5
6
|
name: string;
|