@johpaz/hive-sdk 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +97 -0
- package/README.md +78 -23
- package/bunfig.toml +4 -2
- package/docs/API-AGENTS.md +78 -27
- package/docs/API-CONTEXT-COMPILER.md +31 -34
- package/docs/API-TOOLS-SKILLS-CHANNELS.md +58 -22
- package/docs/HIVE-HARNESS.md +1 -1
- package/docs/INDEX.md +4 -4
- package/docs/TEMPLATE-HIVE-APP.md +10 -10
- package/package.json +9 -4
- package/packages/cli/package.json +2 -2
- package/packages/cli/src/commands/create-app.test.ts +36 -7
- package/packages/cli/src/commands/init.ts +3 -3
- package/packages/cli/src/commands/run.ts +1 -1
- package/packages/cli/src/commands/test.ts +37 -25
- package/packages/cli/src/commands/trace.ts +30 -28
- package/packages/cli/templates/hive-app/.env.example +10 -2
- package/packages/cli/templates/hive-app/README.md +103 -0
- package/packages/cli/templates/hive-app/hive.config.ts +9 -3
- package/packages/cli/templates/hive-app/src/agents/coordinator.ts +8 -1
- package/packages/cli/templates/hive-app/src/main.ts +12 -19
- package/packages/core/package.json +5 -4
- package/packages/core/src/agent/acceptance-checks.ts +166 -0
- package/packages/core/src/agent/agent-catalog.ts +348 -0
- package/packages/core/src/agent/agent-loop.ts +1373 -0
- package/packages/core/src/agent/capability-search.ts +186 -0
- package/packages/core/src/agent/catalog-selector.ts +103 -0
- package/packages/core/src/agent/{Compaction.ts → compaction.ts} +86 -63
- package/packages/core/src/agent/context-compiler.ts +689 -0
- package/packages/core/src/agent/conversation-store.ts +381 -0
- package/packages/core/src/agent/curator.ts +276 -0
- package/packages/core/src/agent/delegation-runtime.ts +241 -0
- package/packages/core/src/agent/goal-runner.ts +323 -0
- package/packages/core/src/agent/index.ts +17 -12
- package/packages/core/src/agent/llm-client.ts +266 -0
- package/packages/core/src/agent/llm-providers/anthropic.ts +264 -0
- package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
- package/packages/core/src/agent/{providers → llm-providers}/gemini.ts +98 -60
- package/packages/core/src/agent/llm-providers/groq.ts +5 -0
- package/packages/core/src/agent/llm-providers/hiveagents.ts +253 -0
- package/packages/core/src/agent/{providers → llm-providers}/interface.ts +73 -13
- package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
- package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
- package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
- package/packages/core/src/agent/llm-providers/modelscope.ts +5 -0
- package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
- package/packages/core/src/agent/{providers → llm-providers}/ollama.ts +31 -5
- package/packages/core/src/agent/llm-providers/openai-compat-base.ts +418 -0
- package/packages/core/src/agent/llm-providers/openai.ts +5 -0
- package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
- package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
- package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
- package/packages/core/src/agent/llm-providers/z-ai.ts +5 -0
- package/packages/core/src/agent/minimal-loadout.ts +47 -0
- package/packages/core/src/agent/playbook-selector.ts +119 -0
- package/packages/core/src/agent/{PromptBuilder.ts → prompt-builder.ts} +21 -22
- package/packages/core/src/{harness → agent}/proof-packet.ts +16 -21
- package/packages/core/src/agent/providers/index.ts +35 -16
- package/packages/core/src/agent/reflector.ts +320 -0
- package/packages/core/src/agent/routing-intent.ts +22 -0
- package/packages/core/src/{harness → agent}/run-epoch.ts +4 -3
- package/packages/core/src/{harness → agent}/run-store.ts +142 -81
- package/packages/core/src/agent/{Service.ts → service.ts} +37 -26
- package/packages/core/src/agent/skill-selector.ts +374 -0
- package/packages/core/src/agent/stuck-loop.ts +209 -0
- package/packages/core/src/agent/{selectors/ToolSelector.ts → tool-selector.ts} +188 -178
- package/packages/core/src/{ace/Tracer.ts → agent/tracer.ts} +37 -27
- package/packages/core/src/api/createAgent.test.ts +139 -27
- package/packages/core/src/api/createAgent.ts +232 -44
- package/packages/core/src/artifacts/store.ts +162 -0
- package/packages/core/src/canvas/canvas-manager.ts +161 -0
- package/packages/core/src/canvas/canvas.test.ts +8 -4
- package/packages/core/src/canvas/emitter.ts +131 -80
- package/packages/core/src/canvas/index.ts +1 -3
- package/packages/core/src/channels/base.ts +9 -1
- package/packages/core/src/channels/discord.ts +5 -4
- package/packages/core/src/channels/manager.ts +122 -30
- package/packages/core/src/channels/slack.ts +5 -4
- package/packages/core/src/channels/telegram.ts +36 -6
- package/packages/core/src/channels/webchat.ts +11 -10
- package/packages/core/src/channels/whatsapp.ts +23 -7
- package/packages/core/src/config/index.ts +13 -2
- package/packages/core/src/config/loader.ts +71 -29
- package/packages/core/src/ethics/EthicsGuard.test.ts +90 -36
- package/packages/core/src/ethics/EthicsGuard.ts +51 -47
- package/packages/core/src/events/agent-bus.ts +44 -68
- package/packages/core/src/events/channel-narration.ts +150 -0
- package/packages/core/src/events/narration.ts +82 -0
- package/packages/core/src/events/tool-narration.ts +62 -0
- package/packages/core/src/gateway/delegation-groups.ts +258 -0
- package/packages/core/src/{harness → gateway}/durable-queue.ts +102 -42
- package/packages/core/src/{harness → gateway}/job-store.ts +85 -48
- package/packages/core/src/gateway/lane-queue.ts +173 -0
- package/packages/core/src/gateway/notification-inbox.ts +57 -0
- package/packages/core/src/gateway/server.ts +1 -1
- package/packages/core/src/harness/index.ts +46 -27
- package/packages/core/src/index.ts +33 -27
- package/packages/core/src/mcp/hot-reload.ts +32 -23
- package/packages/core/src/mcp/index.ts +6 -3
- package/packages/core/src/mcp/singleton.ts +1 -4
- package/packages/core/src/mcp/tool-sync.ts +138 -0
- package/packages/core/src/memory/Scratchpad.test.ts +39 -20
- package/packages/core/src/memory/Scratchpad.ts +27 -34
- package/packages/core/src/multimodal/vision-service.ts +44 -38
- package/packages/core/src/resilience/retry.ts +95 -0
- package/packages/core/src/scheduler/CronScheduler.ts +334 -287
- package/packages/core/src/scheduler/index.ts +9 -7
- package/packages/core/src/scheduler/integration.ts +46 -26
- package/packages/core/src/scheduler/scheduler.test.ts +9 -13
- package/packages/core/src/scheduler/types.ts +7 -2
- package/packages/core/src/security/Pairing.ts +1 -1
- package/packages/core/src/skills/bundled/a2ui/a2ui_dashboard/SKILL.md +176 -0
- package/packages/core/src/skills/bundled/a2ui/a2ui_form/SKILL.md +202 -0
- package/packages/core/src/skills/bundled/a2ui/a2ui_interactive/SKILL.md +206 -0
- package/packages/core/src/skills/bundled/agents/agent_spawner/SKILL.md +173 -0
- package/packages/core/src/skills/bundled/agents/memory_manager/SKILL.md +143 -0
- package/packages/core/src/skills/bundled/agents/research_and_remember/SKILL.md +139 -0
- package/packages/core/src/skills/bundled/agents/task_orchestrator/SKILL.md +98 -0
- package/packages/core/src/skills/bundled/api/api_client/SKILL.md +132 -0
- package/packages/core/src/skills/bundled/cli/cli_pipeline/SKILL.md +135 -0
- package/packages/core/src/skills/bundled/cli/cli_safe_exec/SKILL.md +125 -0
- package/packages/core/src/skills/bundled/cli/software_engineering/SKILL.md +23 -0
- package/packages/core/src/skills/bundled/cron_manager/SKILL.md +188 -0
- package/packages/core/src/skills/bundled/cron_reminder/SKILL.md +112 -0
- package/packages/core/src/skills/bundled/filesystem/file_manager/SKILL.md +118 -0
- package/packages/core/src/skills/bundled/filesystem/file_read_and_summarize/SKILL.md +109 -0
- package/packages/core/src/skills/bundled/filesystem/file_writer/SKILL.md +129 -0
- package/packages/core/src/skills/bundled/filesystem/workspace_file_operator/SKILL.md +22 -0
- package/packages/core/src/skills/bundled/office/office_document_manager/SKILL.md +262 -0
- package/packages/core/src/skills/bundled/search_knowledge/capability_discovery/SKILL.md +75 -0
- package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +120 -0
- package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +109 -0
- package/packages/core/src/skills/bundled/web/web_monitor/SKILL.md +127 -0
- package/packages/core/src/skills/bundled/web/web_research/SKILL.md +119 -0
- package/packages/core/src/skills/bundled-data.generated.ts +731 -2678
- package/packages/core/src/skills/skills.test.ts +52 -11
- package/packages/core/src/{harness → storage}/boot-id.ts +5 -2
- package/packages/core/src/storage/bootstrap.ts +151 -0
- package/packages/core/src/storage/causal-events.ts +84 -0
- package/packages/core/src/storage/collections.ts +680 -0
- package/packages/core/src/storage/crypto.ts +205 -74
- package/packages/core/src/{harness/db-helpers.ts → storage/hive.ts} +63 -7
- package/packages/core/src/storage/hivedb.ts +61 -0
- package/packages/core/src/storage/index.ts +111 -18
- package/packages/core/src/storage/model-id.ts +53 -0
- package/packages/core/src/storage/onboarding.ts +540 -972
- package/packages/core/src/storage/reconcile.ts +238 -0
- package/packages/core/src/storage/seed.ts +572 -406
- package/packages/core/src/storage/usage.ts +285 -225
- package/packages/core/src/storage/user-email.ts +11 -0
- package/packages/core/src/swarm/AgentExecutor.ts +1 -1
- package/packages/core/src/swarm/EventBridge.ts +1 -1
- package/packages/core/src/swarm/index.ts +12 -9
- package/packages/core/src/tool-runtime/index.ts +146 -23
- package/packages/core/src/tool-runtime/tool-worker.ts +2 -2
- package/packages/core/src/tool-runtime/worker-tools.ts +27 -0
- package/packages/core/src/{canvas/a2ui-tools.ts → tools/a2ui/index.ts} +17 -8
- package/packages/core/src/tools/agents/get-available-models.ts +36 -54
- package/packages/core/src/tools/agents/index.ts +784 -292
- package/packages/core/src/tools/api/api-request.test.ts +164 -0
- package/packages/core/src/tools/api/api-request.ts +174 -0
- package/packages/core/src/tools/api/index.ts +16 -0
- package/packages/core/src/tools/cli/index.ts +4 -0
- package/packages/core/src/tools/core/index.ts +281 -112
- package/packages/core/src/tools/cron/index.ts +121 -124
- package/packages/core/src/tools/index.ts +63 -78
- package/packages/core/src/tools/office/office-escribir-xlsx.ts +3 -1
- package/packages/core/src/tools/types.ts +3 -1
- package/packages/core/src/tools/web/artifact-inspect.ts +23 -0
- package/packages/core/src/tools/web/browser-screenshot.ts +26 -5
- package/packages/core/src/tools/web/browser-service.ts +5 -0
- package/packages/core/src/tools/web/browser-type.ts +3 -8
- package/packages/core/src/tools/web/index.ts +4 -4
- package/packages/core/src/voice/index.ts +89 -63
- package/packages/core/src/workers/agent.worker.ts +2 -2
- package/packages/core/src/workers/workers.test.ts +3 -10
- package/scripts/bump-version.ts +248 -0
- package/scripts/generate-skill-bundle.ts +108 -0
- package/test/agent-loop-terminal-synthesis.test.ts +32 -0
- package/test/catalog-agents-stay-enabled.test.ts +117 -0
- package/test/causal-events.test.ts +117 -0
- package/test/compaction.test.ts +105 -0
- package/test/context-compiler.test.ts +269 -0
- package/test/curator.test.ts +130 -0
- package/test/durable-queue.test.ts +114 -0
- package/test/harness-barrel.test.ts +64 -0
- package/test/hive-helpers.test.ts +130 -0
- package/test/hivedb-search.test.ts +189 -0
- package/test/internal-turns.test.ts +166 -0
- package/test/job-idempotency.test.ts +68 -0
- package/test/job-retry-backoff.test.ts +184 -0
- package/test/job-store.test.ts +381 -0
- package/test/llm-retry.test.ts +97 -0
- package/test/memory-perf.test.ts +774 -0
- package/test/minimal-loadout.test.ts +78 -0
- package/test/model-catalog.test.ts +105 -0
- package/test/preload.ts +12 -0
- package/test/reflector.test.ts +320 -0
- package/test/retention-cap.test.ts +91 -0
- package/test/retired-capabilities-pruned.test.ts +192 -0
- package/test/run-store.test.ts +355 -0
- package/test/scratchpad.test.ts +74 -0
- package/test/secrets-durability.test.ts +119 -0
- package/test/seed-model-reseed.test.ts +155 -0
- package/test/setup-agent-seed.test.ts +264 -0
- package/test/tool-inventory.test.ts +65 -0
- package/test/tool-runtime.test.ts +258 -0
- package/test/toon.test.ts +429 -0
- package/tsconfig.json +2 -0
- package/packages/core/src/ace/Curator.ts +0 -158
- package/packages/core/src/ace/Reflector.ts +0 -200
- package/packages/core/src/ace/index.ts +0 -4
- package/packages/core/src/agent/AgentRunner.ts +0 -711
- package/packages/core/src/agent/ContextCompiler.ts +0 -567
- package/packages/core/src/agent/ContextGuard.ts +0 -91
- package/packages/core/src/agent/ConversationStore.ts +0 -254
- package/packages/core/src/agent/Hooks.ts +0 -166
- package/packages/core/src/agent/StuckLoop.ts +0 -133
- package/packages/core/src/agent/providers/LLMClient.ts +0 -149
- package/packages/core/src/agent/providers/anthropic.ts +0 -212
- package/packages/core/src/agent/providers/openai-compat.ts +0 -231
- package/packages/core/src/agent/selectors/PlaybookSelector.ts +0 -121
- package/packages/core/src/agent/selectors/SkillSelector.ts +0 -322
- package/packages/core/src/agent/selectors/index.ts +0 -6
- package/packages/core/src/auth/auth.ts +0 -121
- package/packages/core/src/auth/index.ts +0 -1
- package/packages/core/src/canvas/CanvasManager.ts +0 -390
- package/packages/core/src/canvas/canvas-tools.ts +0 -448
- package/packages/core/src/harness/collections.ts +0 -98
- package/packages/core/src/harness/goal-verifier.ts +0 -141
- package/packages/core/src/harness/harness.test.ts +0 -236
- package/packages/core/src/harness/reconcile.ts +0 -149
- package/packages/core/src/mcp/MCPToolAdapter.ts +0 -176
- package/packages/core/src/multimodal/VisionService.ts +0 -293
- package/packages/core/src/scheduler/dag/AgentExecutor.ts +0 -53
- package/packages/core/src/scheduler/dag/DAGScheduler.ts +0 -250
- package/packages/core/src/scheduler/dag/EventBridge.ts +0 -122
- package/packages/core/src/scheduler/dag/TaskGraph.ts +0 -192
- package/packages/core/src/scheduler/dag/TaskNode.ts +0 -97
- package/packages/core/src/scheduler/dag/TaskResult.ts +0 -22
- package/packages/core/src/scheduler/dag/errors.ts +0 -37
- package/packages/core/src/scheduler/dag/index.ts +0 -26
- package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +0 -97
- package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +0 -21
- package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +0 -46
- package/packages/core/src/storage/HiveDBStorage.ts +0 -64
- package/packages/core/src/storage/SQLiteStorage.ts +0 -414
- package/packages/core/src/storage/hiveSeed.ts +0 -308
- package/packages/core/src/storage/hiveStorage.test.ts +0 -38
- package/packages/core/src/storage/schema.ts +0 -689
- package/packages/core/src/storage/storage.test.ts +0 -37
- package/packages/core/src/swarm/AgentBus.ts +0 -460
- package/packages/core/src/swarm/EventBus.ts +0 -169
- package/packages/core/src/swarm/WorkerPool.ts +0 -236
- package/packages/core/src/tools/bridge-events.ts +0 -26
- package/packages/core/src/tools/canvas/index.ts +0 -375
- package/packages/core/src/tools/codebridge/index.ts +0 -342
- package/packages/core/src/tools/meeting/index.ts +0 -353
- package/packages/core/src/tools/projects/index.ts +0 -37
- package/packages/core/src/tools/projects/project-create.ts +0 -94
- package/packages/core/src/tools/projects/project-done.ts +0 -66
- package/packages/core/src/tools/projects/project-fail.ts +0 -66
- package/packages/core/src/tools/projects/project-list.ts +0 -96
- package/packages/core/src/tools/projects/project-update.ts +0 -72
- package/packages/core/src/tools/projects/task-create.ts +0 -68
- package/packages/core/src/tools/projects/task-evaluate.ts +0 -93
- package/packages/core/src/tools/projects/task-update.ts +0 -93
- package/packages/core/src/tools/voice/index.ts +0 -104
- package/packages/core/src/tools/web/api-request.test.ts +0 -170
- package/packages/core/src/tools/web/api-request.ts +0 -239
- package/test/setup-db.ts +0 -216
- /package/packages/core/src/agent/{NativeTools.ts → native-tools.ts} +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Tool } from "../types";
|
|
2
|
+
import { inspectArtifact } from "../../artifacts/store";
|
|
3
|
+
|
|
4
|
+
export const artifactInspectTool: Tool = {
|
|
5
|
+
name: "artifact_inspect",
|
|
6
|
+
description: "Inspect managed artifact metadata, integrity, MIME type and dimensions without returning or modifying its binary content.",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
artifactId: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "Managed artifact identifier returned by a Hive tool.",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
required: ["artifactId"],
|
|
16
|
+
},
|
|
17
|
+
execute: async (params, config) => {
|
|
18
|
+
const artifactId = String(params.artifactId ?? "").trim();
|
|
19
|
+
if (!artifactId) return { ok: false, error: "artifactId is required" };
|
|
20
|
+
const userId = config?.configurable?.user_id as string | undefined;
|
|
21
|
+
return inspectArtifact(artifactId, { userId });
|
|
22
|
+
},
|
|
23
|
+
};
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { Tool } from "../types.ts";
|
|
10
10
|
import { logger } from "../../utils/logger.ts";
|
|
11
11
|
import { getBrowserService, screenshotElement } from "./browser-service.ts";
|
|
12
|
+
import { createArtifact } from "../../artifacts/store.ts";
|
|
12
13
|
|
|
13
14
|
const log = logger.child("browser-screenshot");
|
|
14
15
|
|
|
@@ -53,7 +54,7 @@ export const browserScreenshotTool: Tool = {
|
|
|
53
54
|
},
|
|
54
55
|
required: [],
|
|
55
56
|
},
|
|
56
|
-
execute: async (params: Record<string, unknown
|
|
57
|
+
execute: async (params: Record<string, unknown>, config?: any) => {
|
|
57
58
|
const url = params.url as string | undefined;
|
|
58
59
|
const fullPage = (params.fullPage as boolean) ?? false;
|
|
59
60
|
const selector = params.selector as string | undefined;
|
|
@@ -99,14 +100,34 @@ export const browserScreenshotTool: Tool = {
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
const currentUrl = view.url;
|
|
102
|
-
|
|
103
|
+
const bytes = Buffer.from(screenshot, "base64");
|
|
104
|
+
const effectiveFormat = selector ? "png" : format;
|
|
105
|
+
const mimeType = effectiveFormat === "png" ? "image/png" : "image/jpeg";
|
|
106
|
+
const configurable = config?.configurable ?? {};
|
|
107
|
+
const artifact = await createArtifact({
|
|
108
|
+
bytes,
|
|
109
|
+
mimeType,
|
|
110
|
+
kind: "browser_screenshot",
|
|
111
|
+
userId: String(configurable.user_id ?? ""),
|
|
112
|
+
runId: configurable.run_id ? String(configurable.run_id) : null,
|
|
113
|
+
taskId: configurable.task_id ? String(configurable.task_id) : null,
|
|
114
|
+
rootDir: configurable.artifact_dir ? String(configurable.artifact_dir) : undefined,
|
|
115
|
+
width,
|
|
116
|
+
height,
|
|
117
|
+
});
|
|
118
|
+
log.info(`Screenshot stored as artifact ${artifact.id} (${artifact.size} bytes, ${mimeType})`);
|
|
103
119
|
|
|
104
120
|
return {
|
|
105
121
|
ok: true,
|
|
106
122
|
url: currentUrl,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
123
|
+
artifact_id: artifact.id,
|
|
124
|
+
kind: artifact.kind,
|
|
125
|
+
mime_type: artifact.mime_type,
|
|
126
|
+
size: artifact.size,
|
|
127
|
+
sha256: artifact.sha256,
|
|
128
|
+
status: artifact.status,
|
|
129
|
+
expires_at: artifact.expires_at,
|
|
130
|
+
format: effectiveFormat,
|
|
110
131
|
fullPage,
|
|
111
132
|
selector,
|
|
112
133
|
viewport: { width, height },
|
|
@@ -178,6 +178,11 @@ export class AgentBrowserView {
|
|
|
178
178
|
args.push("--screenshot-quality", String(options.quality));
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
+
// If clip/selector is provided, agent-browser screenshot accepts a positional selector
|
|
182
|
+
// For element screenshots, we can pass a selector as first positional arg
|
|
183
|
+
// But we don't have selector in options here — the old CDPClient didn't use it either
|
|
184
|
+
// screenshotElement helper handles element-specific screenshots
|
|
185
|
+
|
|
181
186
|
const res = await this.run(args);
|
|
182
187
|
if (!res.success) throw new Error(res.error || "screenshot failed");
|
|
183
188
|
|
|
@@ -68,17 +68,12 @@ export const browserTypeTool: Tool = {
|
|
|
68
68
|
await Bun.sleep(500);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
// click(selector) waits for actionability then focuses the element
|
|
72
|
-
await view.click(selector, { timeout });
|
|
73
|
-
|
|
74
71
|
if (clear) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
await view.
|
|
72
|
+
await (view as any).fill(selector, text);
|
|
73
|
+
} else {
|
|
74
|
+
await (view as any).typeIn(selector, text);
|
|
78
75
|
}
|
|
79
76
|
|
|
80
|
-
await view.type(text);
|
|
81
|
-
|
|
82
77
|
const currentUrl = view.url;
|
|
83
78
|
log.info(`Type successful: "${text.substring(0, 50)}${text.length > 50 ? "..." : ""}" into ${selector}`);
|
|
84
79
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Web Tools - Browser automation + Web utilities
|
|
3
3
|
*
|
|
4
|
-
* Browser tools use
|
|
4
|
+
* Browser tools use agent-browser (Rust CLI, auto-managed).
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { Tool } from "../types.ts";
|
|
8
8
|
import { webSearchTool } from "./web-search.ts";
|
|
9
9
|
import { webFetchTool } from "./web-fetch.ts";
|
|
10
|
-
import { apiRequestTool } from "./api-request.ts";
|
|
11
10
|
import { browserNavigateTool } from "./browser-navigate.ts";
|
|
12
11
|
import { browserScreenshotTool } from "./browser-screenshot.ts";
|
|
13
12
|
import { browserClickTool } from "./browser-click.ts";
|
|
@@ -15,12 +14,12 @@ import { browserTypeTool } from "./browser-type.ts";
|
|
|
15
14
|
import { browserExtractTool } from "./browser-extract.ts";
|
|
16
15
|
import { browserScriptTool } from "./browser-script.ts";
|
|
17
16
|
import { browserWaitTool } from "./browser-wait.ts";
|
|
17
|
+
import { artifactInspectTool } from "./artifact-inspect.ts";
|
|
18
18
|
|
|
19
19
|
export function createTools(): Tool[] {
|
|
20
20
|
return [
|
|
21
21
|
webSearchTool,
|
|
22
22
|
webFetchTool,
|
|
23
|
-
apiRequestTool,
|
|
24
23
|
browserNavigateTool,
|
|
25
24
|
browserScreenshotTool,
|
|
26
25
|
browserClickTool,
|
|
@@ -28,12 +27,12 @@ export function createTools(): Tool[] {
|
|
|
28
27
|
browserExtractTool,
|
|
29
28
|
browserScriptTool,
|
|
30
29
|
browserWaitTool,
|
|
30
|
+
artifactInspectTool,
|
|
31
31
|
];
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export * from "./web-search.ts";
|
|
35
35
|
export * from "./web-fetch.ts";
|
|
36
|
-
export * from "./api-request.ts";
|
|
37
36
|
export * from "./browser-navigate.ts";
|
|
38
37
|
export * from "./browser-screenshot.ts";
|
|
39
38
|
export * from "./browser-click.ts";
|
|
@@ -42,3 +41,4 @@ export * from "./browser-extract.ts";
|
|
|
42
41
|
export * from "./browser-script.ts";
|
|
43
42
|
export * from "./browser-wait.ts";
|
|
44
43
|
export * from "./browser-service.ts";
|
|
44
|
+
export * from "./artifact-inspect.ts";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { col } from "../storage/hive";
|
|
2
|
+
import type { ChannelDoc, ModelDoc } from "../storage/collections";
|
|
2
3
|
import { loadProviderApiKey } from "../storage/crypto";
|
|
3
4
|
import { logger } from "../utils/logger";
|
|
4
5
|
|
|
@@ -79,20 +80,11 @@ class VoiceService {
|
|
|
79
80
|
return VoiceService.instance;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
getChannelVoiceConfig(channelId: string): VoiceConfig {
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
`).get(channelId) as {
|
|
88
|
-
voice_enabled: number;
|
|
89
|
-
tts_enabled: number;
|
|
90
|
-
stt_provider: string | null;
|
|
91
|
-
tts_provider: string | null;
|
|
92
|
-
tts_voice_id: string | null;
|
|
93
|
-
} | undefined;
|
|
94
|
-
|
|
95
|
-
if (!result) {
|
|
83
|
+
async getChannelVoiceConfig(channelId: string): Promise<VoiceConfig> {
|
|
84
|
+
const channelsCol = await col<ChannelDoc>("channels");
|
|
85
|
+
const entry = await channelsCol.get(channelId);
|
|
86
|
+
|
|
87
|
+
if (!entry) {
|
|
96
88
|
return {
|
|
97
89
|
voiceEnabled: false,
|
|
98
90
|
ttsEnabled: false,
|
|
@@ -103,26 +95,62 @@ class VoiceService {
|
|
|
103
95
|
}
|
|
104
96
|
|
|
105
97
|
return {
|
|
106
|
-
voiceEnabled:
|
|
107
|
-
ttsEnabled:
|
|
108
|
-
sttProvider:
|
|
109
|
-
ttsProvider:
|
|
110
|
-
ttsVoiceId:
|
|
98
|
+
voiceEnabled: entry.doc.voice_enabled,
|
|
99
|
+
ttsEnabled: entry.doc.tts_enabled,
|
|
100
|
+
sttProvider: entry.doc.stt_provider,
|
|
101
|
+
ttsProvider: entry.doc.tts_provider,
|
|
102
|
+
ttsVoiceId: entry.doc.tts_voice_id,
|
|
111
103
|
};
|
|
112
104
|
}
|
|
113
105
|
|
|
106
|
+
/** Provider de un modelo según la BD; acepta también un id de provider (canales antiguos). */
|
|
107
|
+
private async getModelProvider(modelId: string): Promise<string | null> {
|
|
108
|
+
try {
|
|
109
|
+
const modelsCol = await col<ModelDoc>("models");
|
|
110
|
+
const model = await modelsCol.get(modelId);
|
|
111
|
+
if (model?.doc.provider_id) return model.doc.provider_id;
|
|
112
|
+
const providersCol = await col<import("../storage/collections").ProviderDoc>("providers");
|
|
113
|
+
const provider = await providersCol.get(modelId);
|
|
114
|
+
return provider?.doc.id || null;
|
|
115
|
+
} catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Primer modelo STT/TTS activo de un provider activo, como fallback desde la BD. */
|
|
121
|
+
private async getFirstActiveVoiceModel(type: "stt" | "tts"): Promise<{ id: string; provider: string } | null> {
|
|
122
|
+
try {
|
|
123
|
+
const modelsCol = await col<ModelDoc>("models");
|
|
124
|
+
const providersCol = await col<import("../storage/collections").ProviderDoc>("providers");
|
|
125
|
+
const models = (await modelsCol.findBy("model_type", type)).filter(e => e.doc.active);
|
|
126
|
+
for (const m of models) {
|
|
127
|
+
const provider = await providersCol.get(m.doc.provider_id);
|
|
128
|
+
if (provider?.doc.active) return { id: m.doc.id, provider: m.doc.provider_id };
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
} catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
114
136
|
async transcribe(audio: AudioInput, modelId: string): Promise<string> {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
137
|
+
let provider = await this.getModelProvider(modelId);
|
|
138
|
+
let resolvedModelId = modelId;
|
|
139
|
+
|
|
140
|
+
if (!provider) {
|
|
141
|
+
const fallback = await this.getFirstActiveVoiceModel("stt");
|
|
142
|
+
if (!fallback) throw new Error(`STT model "${modelId}" not found and no active STT models in the database`);
|
|
143
|
+
log.warn(`STT model ${modelId} not found in DB, falling back to ${fallback.provider}/${fallback.id}`);
|
|
144
|
+
provider = fallback.provider;
|
|
145
|
+
resolvedModelId = fallback.id;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
switch (provider) {
|
|
149
|
+
case "groq": return this.transcribeWithGroq(audio, resolvedModelId);
|
|
150
|
+
case "openai": return this.transcribeWithOpenAIWhisper(audio);
|
|
151
|
+
default:
|
|
152
|
+
throw new Error(`STT not supported for provider "${provider}" (model ${resolvedModelId})`);
|
|
122
153
|
}
|
|
123
|
-
|
|
124
|
-
log.warn(`Unknown STT provider ${modelId}, defaulting to Groq Whisper`);
|
|
125
|
-
return this.transcribeWithGroq(audio, "whisper-large-v3-turbo");
|
|
126
154
|
}
|
|
127
155
|
|
|
128
156
|
private async getProviderApiKey(providerId: string): Promise<string | null> {
|
|
@@ -229,26 +257,26 @@ class VoiceService {
|
|
|
229
257
|
}
|
|
230
258
|
|
|
231
259
|
async speak(text: string, modelId: string, voiceId?: string): Promise<AudioOutput> {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return this.
|
|
246
|
-
|
|
247
|
-
return this.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
260
|
+
let provider = modelId === "piper-local" ? "piper" : await this.getModelProvider(modelId);
|
|
261
|
+
let resolvedModelId = modelId;
|
|
262
|
+
|
|
263
|
+
if (!provider) {
|
|
264
|
+
const fallback = await this.getFirstActiveVoiceModel("tts");
|
|
265
|
+
if (!fallback) throw new Error(`TTS model "${modelId}" not found and no active TTS models in the database`);
|
|
266
|
+
log.warn(`TTS model ${modelId} not found in DB, falling back to ${fallback.provider}/${fallback.id}`);
|
|
267
|
+
provider = fallback.provider;
|
|
268
|
+
resolvedModelId = fallback.id;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
switch (provider) {
|
|
272
|
+
case "piper": return this.speakWithPiper(text, voiceId);
|
|
273
|
+
case "elevenlabs": return this.speakWithElevenLabs(text, resolvedModelId, voiceId);
|
|
274
|
+
case "openai": return this.speakWithOpenAI(text, resolvedModelId, voiceId);
|
|
275
|
+
case "gemini": return this.speakWithGemini(text, resolvedModelId, voiceId);
|
|
276
|
+
case "qwen": return this.speakWithQwen(text, resolvedModelId, voiceId);
|
|
277
|
+
default:
|
|
278
|
+
throw new Error(`TTS not supported for provider "${provider}" (model ${resolvedModelId})`);
|
|
279
|
+
}
|
|
252
280
|
}
|
|
253
281
|
|
|
254
282
|
private async speakWithPiper(text: string, voiceId?: string): Promise<AudioOutput> {
|
|
@@ -448,21 +476,19 @@ class VoiceService {
|
|
|
448
476
|
};
|
|
449
477
|
}
|
|
450
478
|
|
|
451
|
-
getConfiguredVoiceProviders(): { groq: boolean; elevenlabs: boolean; openai: boolean; gemini: boolean; qwen: boolean } {
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
return !!row;
|
|
458
|
-
};
|
|
479
|
+
async getConfiguredVoiceProviders(): Promise<{ groq: boolean; elevenlabs: boolean; openai: boolean; gemini: boolean; qwen: boolean }> {
|
|
480
|
+
const hasDbKey = async (providerId: string): Promise<boolean> => !!(await loadProviderApiKey(providerId));
|
|
481
|
+
|
|
482
|
+
const [groq, elevenlabs, openai, gemini, qwen] = await Promise.all([
|
|
483
|
+
hasDbKey("groq"), hasDbKey("elevenlabs"), hasDbKey("openai"), hasDbKey("gemini"), hasDbKey("qwen"),
|
|
484
|
+
]);
|
|
459
485
|
|
|
460
486
|
return {
|
|
461
|
-
groq:
|
|
462
|
-
elevenlabs:
|
|
463
|
-
openai:
|
|
464
|
-
gemini:
|
|
465
|
-
qwen:
|
|
487
|
+
groq: groq || !!(process.env.GROQ_API_KEY),
|
|
488
|
+
elevenlabs: elevenlabs || !!(process.env.ELEVENLABS_API_KEY),
|
|
489
|
+
openai: openai || !!(process.env.OPENAI_API_KEY),
|
|
490
|
+
gemini: gemini || !!(process.env.GEMINI_API_KEY),
|
|
491
|
+
qwen: qwen || !!(process.env.DASHSCOPE_API_KEY),
|
|
466
492
|
};
|
|
467
493
|
}
|
|
468
494
|
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* Sends: { type: "AGENT_RESULT", taskId, result } | { type: "AGENT_CHUNK", taskId, chunk }
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { runAgent } from "../agent/
|
|
9
|
-
import type { StreamChunk } from "../agent/
|
|
8
|
+
import { runAgent } from "../agent/agent-loop.ts";
|
|
9
|
+
import type { StreamChunk } from "../agent/agent-loop.ts";
|
|
10
10
|
|
|
11
11
|
declare var self: {
|
|
12
12
|
onmessage: ((event: { data: WorkerMessage }) => void) | null;
|
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
process.env.HIVE_DB_PATH = ":memory:";
|
|
2
|
+
|
|
3
|
+
import { describe, expect, it } from "bun:test";
|
|
2
4
|
import { createWorker, WorkerPool } from "./index.ts";
|
|
3
|
-
import { setupTestDb, teardownTestDb, insertTestAgent, insertTestProvider } from "../../../../test/setup-db.ts";
|
|
4
5
|
|
|
5
6
|
describe("createWorker", () => {
|
|
6
|
-
beforeAll(() => {
|
|
7
|
-
setupTestDb();
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
afterAll(() => {
|
|
11
|
-
teardownTestDb();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
7
|
it("creates a worker instance with config", () => {
|
|
15
8
|
const worker = createWorker({
|
|
16
9
|
name: "test-worker",
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Bump de versión del SDK.
|
|
5
|
+
*
|
|
6
|
+
* Portado de `hive/scripts/bump-version.ts`, adaptado a este repo: acá el
|
|
7
|
+
* artefacto publicado es **sólo el paquete raíz** (`@johpaz/hive-sdk`);
|
|
8
|
+
* `packages/core` y `packages/cli` son workspaces internos que se versionan en
|
|
9
|
+
* paralelo por consistencia, no se publican.
|
|
10
|
+
*
|
|
11
|
+
* El push del tag `vX.Y.Z` es lo que dispara `.github/workflows/publish.yml`.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
const dryRun = args.includes("--dry-run");
|
|
16
|
+
const shouldPush = args.includes("--push");
|
|
17
|
+
const npmTagArg = args.find((a) => a.startsWith("--npm-tag="));
|
|
18
|
+
const npmTag = npmTagArg ? npmTagArg.split("=")[1] : "latest";
|
|
19
|
+
const positional = args.filter((a) => !a.startsWith("--"));
|
|
20
|
+
const bumpType = positional[0] as "patch" | "minor" | "major" | string;
|
|
21
|
+
const explicitVersion = positional[0]?.match(/^\d+\.\d+\.\d+(-[\w.]+)?$/) ? positional[0] : null;
|
|
22
|
+
|
|
23
|
+
if (!bumpType || (!["patch", "minor", "major"].includes(bumpType) && !explicitVersion)) {
|
|
24
|
+
console.log("Usage:");
|
|
25
|
+
console.log(" bun scripts/bump-version.ts patch|minor|major [--push] [--dry-run] [--npm-tag=<tag>]");
|
|
26
|
+
console.log(" bun scripts/bump-version.ts 0.1.5 [--push] [--dry-run] [--npm-tag=<tag>]");
|
|
27
|
+
console.log("");
|
|
28
|
+
console.log(" (sin flags) Solo actualiza archivos locales (package.json, README, CHANGELOG).");
|
|
29
|
+
console.log(" No toca git. Revisá el diff vos mismo.");
|
|
30
|
+
console.log(" --dry-run Muestra qué cambiaría, sin escribir nada.");
|
|
31
|
+
console.log(" --push Además de bumpear: commitea, crea el tag vX.Y.Z y pushea.");
|
|
32
|
+
console.log(" El tag dispara publish.yml, que publica en npm.");
|
|
33
|
+
console.log(" --npm-tag=X dist-tag de npm (default: latest). Usá `next` o `beta` para");
|
|
34
|
+
console.log(" una preview que no se instale con `bun add @johpaz/hive-sdk`.");
|
|
35
|
+
console.log("");
|
|
36
|
+
console.log("Ejemplos:");
|
|
37
|
+
console.log(" bun scripts/bump-version.ts 0.1.5 # solo archivos");
|
|
38
|
+
console.log(" bun scripts/bump-version.ts 0.1.5 --push # release a latest");
|
|
39
|
+
console.log(" bun scripts/bump-version.ts 0.2.0-rc.1 --push --npm-tag=next");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function bumpVersion(current: string, type: "patch" | "minor" | "major"): string {
|
|
44
|
+
const [major, minor, patch] = current.split("-")[0].split(".").map(Number);
|
|
45
|
+
return type === "major"
|
|
46
|
+
? `${major + 1}.0.0`
|
|
47
|
+
: type === "minor"
|
|
48
|
+
? `${major}.${minor + 1}.0`
|
|
49
|
+
: `${major}.${minor}.${patch + 1}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function confirm(message: string): Promise<boolean> {
|
|
53
|
+
const readline = await import("node:readline/promises");
|
|
54
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
55
|
+
const answer = await rl.question(`${message} (escribe "si" para confirmar): `);
|
|
56
|
+
rl.close();
|
|
57
|
+
return answer.trim().toLowerCase() === "si";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** El raíz es el que se publica; los workspaces van en paralelo por consistencia. */
|
|
61
|
+
const packageFiles = [
|
|
62
|
+
"package.json",
|
|
63
|
+
"packages/core/package.json",
|
|
64
|
+
"packages/cli/package.json",
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
/** Menciones de versión en prosa que no salen de ningún package.json. */
|
|
68
|
+
function textReplacements(newVersion: string) {
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
path: "README.md",
|
|
72
|
+
pattern: /\*Hive SDK v[\d.]+(?:-[\w.]+)? — MIT\*/g,
|
|
73
|
+
replacement: `*Hive SDK v${newVersion} — MIT*`,
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function main() {
|
|
79
|
+
const rootPkg = JSON.parse(await Bun.file("package.json").text());
|
|
80
|
+
const currentVersion: string = rootPkg.version;
|
|
81
|
+
const newVersion = explicitVersion || bumpVersion(currentVersion, bumpType as "patch" | "minor" | "major");
|
|
82
|
+
|
|
83
|
+
console.log(`\n📦 Bumping version: ${currentVersion} → ${newVersion}`);
|
|
84
|
+
console.log(` npm dist-tag: ${npmTag}\n`);
|
|
85
|
+
|
|
86
|
+
if (newVersion === currentVersion && !explicitVersion) {
|
|
87
|
+
console.log("⚠️ La versión nueva es igual a la actual. Abortando.");
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// npm rechaza republicar una versión existente: mejor enterarse acá que en CI.
|
|
92
|
+
try {
|
|
93
|
+
const published = await fetch(`https://registry.npmjs.org/${rootPkg.name}`)
|
|
94
|
+
.then((r) => (r.ok ? r.json() : null)) as { versions?: Record<string, unknown> } | null;
|
|
95
|
+
if (published?.versions?.[newVersion]) {
|
|
96
|
+
console.log(`⚠️ ${rootPkg.name}@${newVersion} YA está publicada en npm.`);
|
|
97
|
+
console.log(` Un publish con esta versión falla con 403. Elegí otra.\n`);
|
|
98
|
+
if (!dryRun) process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
console.log(" (no se pudo consultar npm — sigo igual)\n");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (dryRun) {
|
|
105
|
+
console.log("🔎 Dry run — nada se escribe.\n");
|
|
106
|
+
for (const filePath of packageFiles) {
|
|
107
|
+
try {
|
|
108
|
+
const json = JSON.parse(await Bun.file(filePath).text());
|
|
109
|
+
console.log(` ${filePath}: ${json.version} → ${newVersion}`);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
console.log(` ⚠️ ${filePath}: ${(e as Error).message}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for (const file of textReplacements(newVersion)) {
|
|
115
|
+
try {
|
|
116
|
+
const content = await Bun.file(file.path).text();
|
|
117
|
+
const matches = content.match(file.pattern);
|
|
118
|
+
console.log(` ${file.path}: ${matches ? `${matches.length} coincidencia(s)` : "sin coincidencias (revisar patrón)"}`);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
console.log(` ⚠️ ${file.path}: ${(e as Error).message}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (shouldPush) {
|
|
124
|
+
console.log(`\n Luego: git add -A && git commit -m "chore: release v${newVersion}"`);
|
|
125
|
+
console.log(` git tag v${newVersion} && git push origin main && git push origin v${newVersion}`);
|
|
126
|
+
console.log(` → publish.yml publica con dist-tag "${npmTag}"`);
|
|
127
|
+
} else {
|
|
128
|
+
console.log(`\n Sin --push: no se toca git.`);
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
for (const filePath of packageFiles) {
|
|
134
|
+
try {
|
|
135
|
+
const json = JSON.parse(await Bun.file(filePath).text());
|
|
136
|
+
const oldVersion = json.version;
|
|
137
|
+
json.version = newVersion;
|
|
138
|
+
await Bun.write(filePath, JSON.stringify(json, null, 2) + "\n");
|
|
139
|
+
console.log(`✅ ${filePath}`);
|
|
140
|
+
console.log(` ${json.name}: ${oldVersion} → ${newVersion}`);
|
|
141
|
+
} catch (e) {
|
|
142
|
+
console.log(`⚠️ ${filePath}: ${(e as Error).message}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (const file of textReplacements(newVersion)) {
|
|
147
|
+
try {
|
|
148
|
+
const content = await Bun.file(file.path).text();
|
|
149
|
+
const matched = file.pattern.test(content);
|
|
150
|
+
file.pattern.lastIndex = 0; // test() con /g deja estado — resetear
|
|
151
|
+
const newContent = content.replace(file.pattern, file.replacement);
|
|
152
|
+
|
|
153
|
+
if (!matched) {
|
|
154
|
+
console.log(`⚠️ ${file.path}: el patrón no matcheó nada — revisar manualmente`);
|
|
155
|
+
} else if (newContent !== content) {
|
|
156
|
+
await Bun.write(file.path, newContent);
|
|
157
|
+
console.log(`✅ ${file.path}`);
|
|
158
|
+
} else {
|
|
159
|
+
console.log(`✅ ${file.path} (ya estaba en ${newVersion})`);
|
|
160
|
+
}
|
|
161
|
+
} catch (e) {
|
|
162
|
+
console.log(`⚠️ ${file.path}: ${(e as Error).message}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// El CHANGELOG lo escribe una persona; acá sólo avisamos si falta la entrada.
|
|
167
|
+
try {
|
|
168
|
+
const changelog = await Bun.file("CHANGELOG.md").text();
|
|
169
|
+
if (!changelog.includes(`## ${newVersion}`)) {
|
|
170
|
+
console.log(`\n⚠️ CHANGELOG.md no tiene una sección "## ${newVersion}". Agregala antes de publicar.`);
|
|
171
|
+
}
|
|
172
|
+
} catch {
|
|
173
|
+
console.log("\n⚠️ No hay CHANGELOG.md.");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const { execSync } = await import("child_process");
|
|
177
|
+
const run = (cmd: string) => execSync(cmd, { stdio: "inherit" });
|
|
178
|
+
|
|
179
|
+
console.log(`\n✨ Archivos actualizados. Versión: ${newVersion}\n`);
|
|
180
|
+
|
|
181
|
+
if (!shouldPush) {
|
|
182
|
+
console.log("Sin --push: no se tocó git. Revisá `git diff`, y cuando estés conforme:");
|
|
183
|
+
console.log(` bun scripts/bump-version.ts ${explicitVersion || bumpType} --push${npmTag !== "latest" ? ` --npm-tag=${npmTag}` : ""}\n`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ── Git: commit, tag y push — con confirmación antes de publicar ──────────
|
|
188
|
+
console.log("Antes de publicar corro typecheck y tests.\n");
|
|
189
|
+
try {
|
|
190
|
+
run("bun run typecheck");
|
|
191
|
+
run("bun test");
|
|
192
|
+
} catch {
|
|
193
|
+
console.log("\n❌ typecheck o tests fallaron. No se publica.");
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
console.log("\nEsto es lo que se va a commitear (git add -A):\n");
|
|
198
|
+
run("git status --short");
|
|
199
|
+
|
|
200
|
+
const tagExists = (() => {
|
|
201
|
+
try {
|
|
202
|
+
execSync(`git rev-parse v${newVersion}`, { stdio: "ignore" });
|
|
203
|
+
return true;
|
|
204
|
+
} catch {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
})();
|
|
208
|
+
|
|
209
|
+
if (tagExists) {
|
|
210
|
+
console.log(`\n⚠️ El tag v${newVersion} ya existe localmente. Suele indicar que esta`);
|
|
211
|
+
console.log(` versión ya se publicó. Abortando — si es intencional, borralo primero`);
|
|
212
|
+
console.log(` (git tag -d v${newVersion}) y volvé a correr con --push.`);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const branch = execSync("git branch --show-current").toString().trim();
|
|
217
|
+
|
|
218
|
+
console.log(`\nEsto va a: commitear todo lo de arriba como "chore: release v${newVersion}",`);
|
|
219
|
+
console.log(`crear el tag v${newVersion}, y pushear ${branch} + el tag a origin.`);
|
|
220
|
+
console.log(`El push del tag dispara publish.yml, que publica en npm con dist-tag "${npmTag}".\n`);
|
|
221
|
+
|
|
222
|
+
const ok = await confirm(`¿Publicar v${newVersion} como "${npmTag}"?`);
|
|
223
|
+
if (!ok) {
|
|
224
|
+
console.log("Cancelado. No se tocó git.");
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
console.log("🔧 Committing changes...");
|
|
229
|
+
run("git add -A");
|
|
230
|
+
try {
|
|
231
|
+
run(`git commit -m "chore: release v${newVersion}"`);
|
|
232
|
+
} catch {
|
|
233
|
+
console.log(" (nothing to commit, skipping)");
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
console.log(`🏷️ Creating tag v${newVersion}...`);
|
|
237
|
+
// El dist-tag viaja en el mensaje del tag: publish.yml lo lee de ahí.
|
|
238
|
+
run(`git tag -a v${newVersion} -m "release v${newVersion} [npm-tag:${npmTag}]"`);
|
|
239
|
+
|
|
240
|
+
console.log("🚀 Pushing commit and tag...");
|
|
241
|
+
run(`git push origin ${branch}`);
|
|
242
|
+
run(`git push origin v${newVersion}`);
|
|
243
|
+
|
|
244
|
+
console.log(`\n🎉 Released v${newVersion} (dist-tag: ${npmTag})\n`);
|
|
245
|
+
console.log(`Verificá en unos minutos: npm view ${rootPkg.name} dist-tags\n`);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
main().catch(console.error);
|