@kalphq/cli 0.0.0-dev-20260416063606 → 0.0.0-dev-20260416084549
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/dist/acorn-I3UGQPDC.js +3132 -0
- package/dist/acorn-I3UGQPDC.js.map +1 -0
- package/dist/angular-5QCYWYQS.js +3032 -0
- package/dist/angular-5QCYWYQS.js.map +1 -0
- package/dist/babel-VVMWCS4G.js +7298 -0
- package/dist/babel-VVMWCS4G.js.map +1 -0
- package/dist/chunk-2H7UOFLK.js +11 -0
- package/dist/chunk-2H7UOFLK.js.map +1 -0
- package/dist/chunk-GFEVTHUW.js +19843 -0
- package/dist/chunk-GFEVTHUW.js.map +1 -0
- package/dist/chunk-LAKPXKSS.js +37 -0
- package/dist/chunk-LAKPXKSS.js.map +1 -0
- package/dist/create-T76IFYRP.js +72 -0
- package/dist/create-T76IFYRP.js.map +1 -0
- package/dist/estree-3QNQSWX3.js +4614 -0
- package/dist/estree-3QNQSWX3.js.map +1 -0
- package/dist/flow-CCY52CGJ.js +27548 -0
- package/dist/flow-CCY52CGJ.js.map +1 -0
- package/dist/glimmer-WEH5BTZ2.js +2896 -0
- package/dist/glimmer-WEH5BTZ2.js.map +1 -0
- package/dist/graphql-UERTLN2S.js +1268 -0
- package/dist/graphql-UERTLN2S.js.map +1 -0
- package/dist/html-2G7A573F.js +2928 -0
- package/dist/html-2G7A573F.js.map +1 -0
- package/dist/index.js +56 -3
- package/dist/index.js.map +1 -1
- package/dist/{init-FLJXMJQZ.js → init-SDITDMG6.js} +24 -36
- package/dist/init-SDITDMG6.js.map +1 -0
- package/dist/link-YKDZ7Y6K.js +23 -0
- package/dist/link-YKDZ7Y6K.js.map +1 -0
- package/dist/login-LBEXP7ET.js +27 -0
- package/dist/login-LBEXP7ET.js.map +1 -0
- package/dist/logout-S3PV4WE7.js +27 -0
- package/dist/logout-S3PV4WE7.js.map +1 -0
- package/dist/markdown-XILCBMG4.js +3553 -0
- package/dist/markdown-XILCBMG4.js.map +1 -0
- package/dist/meriyah-THC5AUEQ.js +2686 -0
- package/dist/meriyah-THC5AUEQ.js.map +1 -0
- package/dist/postcss-WBGWHY5F.js +5082 -0
- package/dist/postcss-WBGWHY5F.js.map +1 -0
- package/dist/push-YFAB7TWQ.js +104 -0
- package/dist/push-YFAB7TWQ.js.map +1 -0
- package/dist/typescript-NS3CY6IL.js +13205 -0
- package/dist/typescript-NS3CY6IL.js.map +1 -0
- package/dist/yaml-2RE4A77K.js +4226 -0
- package/dist/yaml-2RE4A77K.js.map +1 -0
- package/package.json +2 -2
- package/templates/agents/b2b-sales/index.ts +32 -3
- package/templates/agents/b2b-sales/signals/deal-won.ts +31 -0
- package/templates/agents/b2b-sales/signals/hot-lead-alert.ts +29 -0
- package/templates/agents/b2b-sales/steps/qualify-prospect.ts +50 -0
- package/templates/agents/b2b-sales/tools/send-slack-notification.ts +26 -0
- package/templates/agents/b2b-sales/webhooks/crm-inbound.ts +27 -0
- package/templates/agents/b2b-sales/webhooks/stripe-payment.ts +27 -0
- package/templates/agents/customer-support/index.ts +37 -5
- package/templates/agents/customer-support/signals/escalation-needed.ts +28 -0
- package/templates/agents/customer-support/signals/ticket-resolved.ts +29 -0
- package/templates/agents/customer-support/steps/escalate-ticket.ts +53 -0
- package/templates/agents/customer-support/tools/create-jira-issue.ts +30 -0
- package/templates/agents/customer-support/webhooks/slack-escalation.ts +27 -0
- package/templates/agents/customer-support/webhooks/zendesk-ticket.ts +29 -0
- package/templates/agents/financial-agent/index.ts +24 -2
- package/templates/agents/financial-agent/signals/market-alert.ts +31 -0
- package/templates/agents/financial-agent/signals/portfolio-rebalance.ts +27 -0
- package/templates/agents/financial-agent/steps/rebalance-check.ts +55 -0
- package/templates/agents/financial-agent/tools/send-email-alert.ts +31 -0
- package/templates/agents/financial-agent/webhooks/exchange-webhook.ts +33 -0
- package/templates/agents/financial-agent/webhooks/tradingview-alert.ts +30 -0
- package/templates/agents/minimal/index.ts +10 -2
- package/templates/agents/minimal/signals/error-alert.ts +26 -0
- package/templates/agents/minimal/signals/task-complete.ts +25 -0
- package/templates/agents/minimal/steps/transform-data.ts +32 -0
- package/templates/agents/minimal/tools/http-request.ts +26 -0
- package/templates/agents/minimal/webhooks/generic-inbound.ts +25 -0
- package/templates/agents/minimal/webhooks/health-check.ts +23 -0
- package/dist/build-2V4OQ3G3.js +0 -122
- package/dist/build-2V4OQ3G3.js.map +0 -1
- package/dist/chunk-FBVCQTQN.js +0 -108
- package/dist/chunk-FBVCQTQN.js.map +0 -1
- package/dist/create-AMCRXGOA.js +0 -116
- package/dist/create-AMCRXGOA.js.map +0 -1
- package/dist/init-FLJXMJQZ.js.map +0 -1
- package/templates/agents/b2b-sales/signals/.gitkeep +0 -0
- package/templates/agents/b2b-sales/webhooks/.gitkeep +0 -0
- package/templates/agents/customer-support/signals/.gitkeep +0 -0
- package/templates/agents/customer-support/webhooks/.gitkeep +0 -0
- package/templates/agents/financial-agent/signals/.gitkeep +0 -0
- package/templates/agents/financial-agent/webhooks/.gitkeep +0 -0
- package/templates/agents/minimal/signals/.gitkeep +0 -0
- package/templates/agents/minimal/webhooks/.gitkeep +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { createStep } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const rebalanceCheck = createStep({
|
|
5
|
+
id: "rebalance_check",
|
|
6
|
+
description: "Analyzes portfolio and recommends rebalancing actions.",
|
|
7
|
+
input: z.object({
|
|
8
|
+
portfolioValue: z.number(),
|
|
9
|
+
targetAllocation: z.record(z.number()), // { stocks: 60, bonds: 30, cash: 10 }
|
|
10
|
+
currentAllocation: z.record(z.number()),
|
|
11
|
+
riskTolerance: z.string(), // "conservative", "moderate", "aggressive"
|
|
12
|
+
}),
|
|
13
|
+
output: z.object({
|
|
14
|
+
needsRebalance: z.boolean(),
|
|
15
|
+
driftPercent: z.number(),
|
|
16
|
+
recommendations: z.array(z.object({
|
|
17
|
+
asset: z.string(),
|
|
18
|
+
action: z.string(), // "buy", "sell", "hold"
|
|
19
|
+
amount: z.number(),
|
|
20
|
+
})),
|
|
21
|
+
}),
|
|
22
|
+
async run({ portfolioValue, targetAllocation, currentAllocation, riskTolerance }) {
|
|
23
|
+
const recommendations: Array<{ asset: string; action: string; amount: number }> = [];
|
|
24
|
+
let maxDrift = 0;
|
|
25
|
+
|
|
26
|
+
// Calculate drift for each asset
|
|
27
|
+
for (const [asset, targetPct] of Object.entries(targetAllocation)) {
|
|
28
|
+
const currentPct = currentAllocation[asset] ?? 0;
|
|
29
|
+
const drift = Math.abs(currentPct - targetPct);
|
|
30
|
+
maxDrift = Math.max(maxDrift, drift);
|
|
31
|
+
|
|
32
|
+
// Generate recommendation if drift > 5%
|
|
33
|
+
if (drift > 5) {
|
|
34
|
+
const targetValue = portfolioValue * (targetPct / 100);
|
|
35
|
+
const currentValue = portfolioValue * (currentPct / 100);
|
|
36
|
+
const diff = targetValue - currentValue;
|
|
37
|
+
|
|
38
|
+
recommendations.push({
|
|
39
|
+
asset,
|
|
40
|
+
action: diff > 0 ? "buy" : "sell",
|
|
41
|
+
amount: Math.abs(diff),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Conservative portfolios rebalance at lower drift
|
|
47
|
+
const threshold = riskTolerance === "conservative" ? 3 : riskTolerance === "aggressive" ? 8 : 5;
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
needsRebalance: maxDrift > threshold,
|
|
51
|
+
driftPercent: maxDrift,
|
|
52
|
+
recommendations,
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createTool } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const sendEmailAlert = createTool({
|
|
5
|
+
id: "send_email_alert",
|
|
6
|
+
description: "Sends email notifications for significant portfolio events.",
|
|
7
|
+
input: z.object({
|
|
8
|
+
to: z.string(),
|
|
9
|
+
subject: z.string(),
|
|
10
|
+
alertType: z.string(), // "price_movement", "rebalance_needed", "dividend", "risk_alert"
|
|
11
|
+
data: z.record(z.unknown()),
|
|
12
|
+
}),
|
|
13
|
+
async execute({ to, subject, alertType, data }) {
|
|
14
|
+
// In real implementation, integrate with SendGrid, AWS SES, etc.
|
|
15
|
+
|
|
16
|
+
const emailBody = JSON.stringify({
|
|
17
|
+
alertType,
|
|
18
|
+
timestamp: new Date().toISOString(),
|
|
19
|
+
data,
|
|
20
|
+
}, null, 2);
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
sent: true,
|
|
24
|
+
recipient: to,
|
|
25
|
+
subject,
|
|
26
|
+
alertType,
|
|
27
|
+
messageId: `msg_${Date.now()}`,
|
|
28
|
+
preview: emailBody.slice(0, 200),
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { defineWebhook } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Exchange webhook for order execution confirmations
|
|
6
|
+
*/
|
|
7
|
+
export const exchangeWebhook = defineWebhook({
|
|
8
|
+
id: "exchange_webhook",
|
|
9
|
+
input: z.object({
|
|
10
|
+
orderId: z.string(),
|
|
11
|
+
symbol: z.string(),
|
|
12
|
+
side: z.string(), // "buy", "sell"
|
|
13
|
+
status: z.string(), // "filled", "partial", "rejected"
|
|
14
|
+
filledQty: z.number(),
|
|
15
|
+
avgPrice: z.number(),
|
|
16
|
+
commission: z.number(),
|
|
17
|
+
}),
|
|
18
|
+
async handler({ orderId, symbol, side, status, filledQty, avgPrice, commission }) {
|
|
19
|
+
// Process order execution from exchange
|
|
20
|
+
// In real implementation, update portfolio holdings
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
confirmed: true,
|
|
24
|
+
orderId,
|
|
25
|
+
symbol,
|
|
26
|
+
side,
|
|
27
|
+
status,
|
|
28
|
+
totalValue: filledQty * avgPrice,
|
|
29
|
+
commission,
|
|
30
|
+
netProceeds: filledQty * avgPrice - commission,
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { defineWebhook } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* TradingView alert webhook for technical indicator signals
|
|
6
|
+
*/
|
|
7
|
+
export const tradingviewAlert = defineWebhook({
|
|
8
|
+
id: "tradingview_alert",
|
|
9
|
+
input: z.object({
|
|
10
|
+
symbol: z.string(),
|
|
11
|
+
indicator: z.string(), // "RSI", "MACD", "BB", "EMA_CROSS"
|
|
12
|
+
signal: z.string(), // "buy", "sell", "neutral"
|
|
13
|
+
value: z.number(),
|
|
14
|
+
timeframe: z.string(), // "1h", "4h", "1d"
|
|
15
|
+
price: z.number(),
|
|
16
|
+
}),
|
|
17
|
+
async handler({ symbol, indicator, signal, value, timeframe, price }) {
|
|
18
|
+
// Process technical indicator alert from TradingView
|
|
19
|
+
// In real implementation, trigger portfolio rebalancing
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
processed: true,
|
|
23
|
+
symbol,
|
|
24
|
+
indicator,
|
|
25
|
+
signal,
|
|
26
|
+
timestamp: new Date().toISOString(),
|
|
27
|
+
significance: signal === "buy" && value < 30 ? "high" : "medium",
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
});
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { asAgentId, defineAgent } from "@kalphq/sdk";
|
|
2
2
|
import { exampleStep } from "./steps/example-step.js";
|
|
3
|
+
import { transformData } from "./steps/transform-data.js";
|
|
3
4
|
import { exampleTool } from "./tools/example-tool.js";
|
|
5
|
+
import { httpRequest } from "./tools/http-request.js";
|
|
6
|
+
import { genericInbound } from "./webhooks/generic-inbound.js";
|
|
7
|
+
import { healthCheck } from "./webhooks/health-check.js";
|
|
8
|
+
import { taskComplete } from "./signals/task-complete.js";
|
|
9
|
+
import { errorAlert } from "./signals/error-alert.js";
|
|
4
10
|
|
|
5
11
|
export default defineAgent({
|
|
6
12
|
id: asAgentId("__AGENT_NAME__"),
|
|
7
13
|
name: "__AGENT_NAME__",
|
|
8
|
-
steps: [exampleStep],
|
|
9
|
-
tools: [exampleTool],
|
|
14
|
+
steps: [exampleStep, transformData],
|
|
15
|
+
tools: [exampleTool, httpRequest],
|
|
16
|
+
webhooks: [genericInbound, healthCheck],
|
|
17
|
+
signals: [taskComplete, errorAlert],
|
|
10
18
|
|
|
11
19
|
async onMessage(message, ctx) {
|
|
12
20
|
const stepped = await ctx.runStep(exampleStep, { message: message.text });
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createSignal } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal sent when an error occurs
|
|
6
|
+
*/
|
|
7
|
+
export const errorAlert = createSignal({
|
|
8
|
+
id: "error_alert",
|
|
9
|
+
input: z.object({
|
|
10
|
+
errorId: z.string(),
|
|
11
|
+
message: z.string(),
|
|
12
|
+
severity: z.string(), // "low", "medium", "high", "critical"
|
|
13
|
+
context: z.record(z.unknown()).optional(),
|
|
14
|
+
}),
|
|
15
|
+
async handler({ errorId, message, severity, context }) {
|
|
16
|
+
// Signal error to monitoring system
|
|
17
|
+
// In real implementation, send to error tracking service
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
logged: true,
|
|
21
|
+
errorId,
|
|
22
|
+
severity,
|
|
23
|
+
alertSent: severity === "high" || severity === "critical",
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createSignal } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal sent when a task completes successfully
|
|
6
|
+
*/
|
|
7
|
+
export const taskComplete = createSignal({
|
|
8
|
+
id: "task_complete",
|
|
9
|
+
input: z.object({
|
|
10
|
+
taskId: z.string(),
|
|
11
|
+
result: z.string(),
|
|
12
|
+
duration: z.number(), // seconds
|
|
13
|
+
}),
|
|
14
|
+
async handler({ taskId, result, duration }) {
|
|
15
|
+
// Signal completion to orchestrator
|
|
16
|
+
// In real implementation, update task queue
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
acknowledged: true,
|
|
20
|
+
taskId,
|
|
21
|
+
status: "completed",
|
|
22
|
+
duration,
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createStep } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const transformData = createStep({
|
|
5
|
+
id: "transform_data",
|
|
6
|
+
description: "Transforms input data to a standardized format.",
|
|
7
|
+
input: z.object({
|
|
8
|
+
data: z.record(z.unknown()),
|
|
9
|
+
format: z.string(), // "json", "csv", "xml"
|
|
10
|
+
}),
|
|
11
|
+
output: z.object({
|
|
12
|
+
transformed: z.boolean(),
|
|
13
|
+
result: z.record(z.unknown()),
|
|
14
|
+
format: z.string(),
|
|
15
|
+
}),
|
|
16
|
+
async run({ data, format }) {
|
|
17
|
+
// Simple transformation example
|
|
18
|
+
const result: Record<string, unknown> = {};
|
|
19
|
+
|
|
20
|
+
for (const [key, value] of Object.entries(data)) {
|
|
21
|
+
// Normalize keys to snake_case
|
|
22
|
+
const normalizedKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
23
|
+
result[normalizedKey] = value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
transformed: true,
|
|
28
|
+
result,
|
|
29
|
+
format: format.toLowerCase(),
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createTool } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const httpRequest = createTool({
|
|
5
|
+
id: "http_request",
|
|
6
|
+
description: "Generic HTTP client for external API calls.",
|
|
7
|
+
input: z.object({
|
|
8
|
+
url: z.string(),
|
|
9
|
+
method: z.string().default("GET"), // "GET", "POST", "PUT", "DELETE"
|
|
10
|
+
headers: z.record(z.string()).optional(),
|
|
11
|
+
body: z.string().optional(),
|
|
12
|
+
}),
|
|
13
|
+
async execute({ url, method, headers, body }) {
|
|
14
|
+
// In real implementation, use fetch or axios
|
|
15
|
+
// This is a stub showing the pattern
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
statusCode: 200,
|
|
19
|
+
status: "ok",
|
|
20
|
+
url,
|
|
21
|
+
method,
|
|
22
|
+
bodyLength: body?.length ?? 0,
|
|
23
|
+
timestamp: new Date().toISOString(),
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineWebhook } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generic inbound webhook example
|
|
6
|
+
*/
|
|
7
|
+
export const genericInbound = defineWebhook({
|
|
8
|
+
id: "generic_inbound",
|
|
9
|
+
input: z.object({
|
|
10
|
+
event: z.string(),
|
|
11
|
+
payload: z.record(z.unknown()),
|
|
12
|
+
timestamp: z.string().optional(),
|
|
13
|
+
}),
|
|
14
|
+
async handler({ event, payload, timestamp }) {
|
|
15
|
+
// Process generic inbound webhook
|
|
16
|
+
// In real implementation, route to appropriate handler
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
received: true,
|
|
20
|
+
event,
|
|
21
|
+
payloadKeys: Object.keys(payload),
|
|
22
|
+
processedAt: new Date().toISOString(),
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineWebhook } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Health check endpoint for monitoring
|
|
6
|
+
*/
|
|
7
|
+
export const healthCheck = defineWebhook({
|
|
8
|
+
id: "health_check",
|
|
9
|
+
input: z.object({
|
|
10
|
+
check: z.string().default("ping"),
|
|
11
|
+
}),
|
|
12
|
+
async handler({ check }) {
|
|
13
|
+
// Simple health check response
|
|
14
|
+
// In real implementation, check dependencies
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
status: "healthy",
|
|
18
|
+
check,
|
|
19
|
+
uptime: "100%",
|
|
20
|
+
timestamp: new Date().toISOString(),
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
});
|
package/dist/build-2V4OQ3G3.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/commands/build.ts
|
|
4
|
-
import { defineCommand } from "citty";
|
|
5
|
-
import * as p from "@clack/prompts";
|
|
6
|
-
import pc from "picocolors";
|
|
7
|
-
import { readFile } from "fs/promises";
|
|
8
|
-
import { resolve as resolve2, relative } from "path";
|
|
9
|
-
import { z } from "zod";
|
|
10
|
-
import * as esbuild from "esbuild";
|
|
11
|
-
|
|
12
|
-
// src/commands/utils.ts
|
|
13
|
-
import { readdir, stat } from "fs/promises";
|
|
14
|
-
import { resolve, dirname } from "path";
|
|
15
|
-
async function glob(pattern) {
|
|
16
|
-
const normalized = pattern.replace(/\\/g, "/");
|
|
17
|
-
const dir = dirname(dirname(normalized));
|
|
18
|
-
const filename = normalized.split("/").pop() ?? "";
|
|
19
|
-
const results = [];
|
|
20
|
-
try {
|
|
21
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
22
|
-
for (const entry of entries) {
|
|
23
|
-
if (!entry.isDirectory()) continue;
|
|
24
|
-
const candidate = resolve(dir, entry.name, filename);
|
|
25
|
-
try {
|
|
26
|
-
const s = await stat(candidate);
|
|
27
|
-
if (s.isFile()) results.push(candidate);
|
|
28
|
-
} catch {
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
} catch {
|
|
32
|
-
}
|
|
33
|
-
return results;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// src/commands/build.ts
|
|
37
|
-
var LOGO = "\u{1F98B}";
|
|
38
|
-
var build_default = defineCommand({
|
|
39
|
-
meta: { name: "build", description: "Bundle agents for deployment" },
|
|
40
|
-
async run() {
|
|
41
|
-
await _build();
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
var KalpConfigSchema = z.object({
|
|
45
|
-
projectId: z.string().min(1),
|
|
46
|
-
region: z.string().optional(),
|
|
47
|
-
secrets: z.array(z.string()).optional()
|
|
48
|
-
});
|
|
49
|
-
async function _build() {
|
|
50
|
-
p.intro(`${LOGO} ${pc.bold("kalp build")}`);
|
|
51
|
-
const cwd = process.cwd();
|
|
52
|
-
const configPath = resolve2(cwd, "kalp.config.ts");
|
|
53
|
-
const s = p.spinner();
|
|
54
|
-
s.start("Reading kalp.config.ts");
|
|
55
|
-
let configRaw = "";
|
|
56
|
-
try {
|
|
57
|
-
configRaw = await readFile(configPath, "utf-8");
|
|
58
|
-
} catch {
|
|
59
|
-
s.stop(pc.red("kalp.config.ts not found"));
|
|
60
|
-
p.outro(`${pc.dim("Run")} ${pc.cyan("kalp init")} ${pc.dim("first.")}`);
|
|
61
|
-
process.exit(1);
|
|
62
|
-
}
|
|
63
|
-
const match = configRaw.match(/defineConfig\(\s*(\{[\s\S]*?\})\s*\)/);
|
|
64
|
-
if (!match?.[1]) {
|
|
65
|
-
s.stop(pc.red("Could not parse kalp.config.ts"));
|
|
66
|
-
process.exit(1);
|
|
67
|
-
}
|
|
68
|
-
let parsed;
|
|
69
|
-
try {
|
|
70
|
-
const fn = new Function(`return ${match[1]}`);
|
|
71
|
-
parsed = KalpConfigSchema.parse(fn());
|
|
72
|
-
} catch (err) {
|
|
73
|
-
s.stop(pc.red("Invalid kalp.config.ts"));
|
|
74
|
-
if (err instanceof z.ZodError) {
|
|
75
|
-
for (const issue of err.issues) {
|
|
76
|
-
p.log.error(` ${issue.path.join(".")}: ${issue.message}`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
81
|
-
s.stop(`Project ${pc.cyan(parsed.projectId)} validated`);
|
|
82
|
-
s.start("Discovering agents");
|
|
83
|
-
const agentEntries = await glob(resolve2(cwd, "agents/*/index.ts"));
|
|
84
|
-
if (agentEntries.length === 0) {
|
|
85
|
-
s.stop(pc.yellow("No agents found in agents/"));
|
|
86
|
-
p.outro(pc.dim("Create an agent first."));
|
|
87
|
-
process.exit(0);
|
|
88
|
-
}
|
|
89
|
-
s.stop(`Found ${pc.cyan(String(agentEntries.length))} agent(s)`);
|
|
90
|
-
s.start("Bundling agents");
|
|
91
|
-
const outdir = resolve2(cwd, "meta/dist");
|
|
92
|
-
try {
|
|
93
|
-
await esbuild.build({
|
|
94
|
-
entryPoints: agentEntries,
|
|
95
|
-
bundle: true,
|
|
96
|
-
platform: "node",
|
|
97
|
-
target: "es2022",
|
|
98
|
-
format: "esm",
|
|
99
|
-
outdir,
|
|
100
|
-
minify: true,
|
|
101
|
-
treeShaking: true,
|
|
102
|
-
external: ["@kalphq/sdk"],
|
|
103
|
-
logLevel: "silent"
|
|
104
|
-
});
|
|
105
|
-
} catch (err) {
|
|
106
|
-
s.stop(pc.red("Build failed"));
|
|
107
|
-
console.error(err);
|
|
108
|
-
process.exit(1);
|
|
109
|
-
}
|
|
110
|
-
s.stop("Bundle ready");
|
|
111
|
-
const lines = agentEntries.map(
|
|
112
|
-
(e) => ` ${pc.dim("\u2022")} ${pc.cyan(relative(cwd, e))}`
|
|
113
|
-
);
|
|
114
|
-
p.note(lines.join("\n"), "Bundled agents");
|
|
115
|
-
p.outro(
|
|
116
|
-
`${LOGO} ${pc.green("Build complete.")} ${pc.dim(`Output \u2192 meta/dist/`)}`
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
export {
|
|
120
|
-
build_default as default
|
|
121
|
-
};
|
|
122
|
-
//# sourceMappingURL=build-2V4OQ3G3.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/build.ts","../src/commands/utils.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve, relative } from \"node:path\";\nimport { z } from \"zod\";\nimport * as esbuild from \"esbuild\";\nimport { glob } from \"./utils.js\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"build\", description: \"Bundle agents for deployment\" },\n async run() {\n await _build();\n },\n});\n\nconst KalpConfigSchema = z.object({\n projectId: z.string().min(1),\n region: z.string().optional(),\n secrets: z.array(z.string()).optional(),\n});\n\nasync function _build(): Promise<void> {\n p.intro(`${LOGO} ${pc.bold(\"kalp build\")}`);\n\n const cwd = process.cwd();\n const configPath = resolve(cwd, \"kalp.config.ts\");\n\n // ── Validate kalp.config.ts ────────────────────────────────────────────\n const s = p.spinner();\n s.start(\"Reading kalp.config.ts\");\n\n let configRaw = \"\";\n try {\n configRaw = await readFile(configPath, \"utf-8\");\n } catch {\n s.stop(pc.red(\"kalp.config.ts not found\"));\n p.outro(`${pc.dim(\"Run\")} ${pc.cyan(\"kalp init\")} ${pc.dim(\"first.\")}`);\n process.exit(1);\n }\n\n // Extract the config object from defineConfig({...}) using a lightweight regex\n const match = configRaw.match(/defineConfig\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)/);\n if (!match?.[1]) {\n s.stop(pc.red(\"Could not parse kalp.config.ts\"));\n process.exit(1);\n }\n\n let parsed: z.infer<typeof KalpConfigSchema>;\n try {\n // Evaluate the config object (safe: it's the user's own config file)\n const fn = new Function(`return ${match[1]}`);\n parsed = KalpConfigSchema.parse(fn());\n } catch (err) {\n s.stop(pc.red(\"Invalid kalp.config.ts\"));\n if (err instanceof z.ZodError) {\n for (const issue of err.issues) {\n p.log.error(` ${issue.path.join(\".\")}: ${issue.message}`);\n }\n }\n process.exit(1);\n }\n\n s.stop(`Project ${pc.cyan(parsed.projectId)} validated`);\n\n // ── Discover agent entry points ────────────────────────────────────────\n s.start(\"Discovering agents\");\n\n const agentEntries = await glob(resolve(cwd, \"agents/*/index.ts\"));\n if (agentEntries.length === 0) {\n s.stop(pc.yellow(\"No agents found in agents/\"));\n p.outro(pc.dim(\"Create an agent first.\"));\n process.exit(0);\n }\n\n s.stop(`Found ${pc.cyan(String(agentEntries.length))} agent(s)`);\n\n // ── Bundle with esbuild ────────────────────────────────────────────────\n s.start(\"Bundling agents\");\n\n const outdir = resolve(cwd, \"meta/dist\");\n try {\n await esbuild.build({\n entryPoints: agentEntries,\n bundle: true,\n platform: \"node\",\n target: \"es2022\",\n format: \"esm\",\n outdir,\n minify: true,\n treeShaking: true,\n external: [\"@kalphq/sdk\"],\n logLevel: \"silent\",\n });\n } catch (err) {\n s.stop(pc.red(\"Build failed\"));\n console.error(err);\n process.exit(1);\n }\n\n s.stop(\"Bundle ready\");\n\n // ── Summary ────────────────────────────────────────────────────────────\n const lines = agentEntries.map(\n (e: string) => ` ${pc.dim(\"•\")} ${pc.cyan(relative(cwd, e))}`,\n );\n p.note(lines.join(\"\\n\"), \"Bundled agents\");\n\n p.outro(\n `${LOGO} ${pc.green(\"Build complete.\")} ${pc.dim(`Output → meta/dist/`)}`,\n );\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport { resolve, dirname } from \"node:path\";\n\nexport async function glob(pattern: string): Promise<string[]> {\n // Normalize to forward slashes for consistent parsing (Windows/Unix)\n const normalized = pattern.replace(/\\\\/g, \"/\");\n const dir = dirname(dirname(normalized));\n const filename = normalized.split(\"/\").pop() ?? \"\";\n\n const results: string[] = [];\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const candidate = resolve(dir, entry.name, filename);\n try {\n const s = await stat(candidate);\n if (s.isFile()) results.push(candidate);\n } catch {\n // file doesn't exist in this subdirectory\n }\n }\n } catch {\n // parent directory doesn't exist\n }\n\n return results;\n}\n"],"mappings":"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","names":["resolve","resolve"]}
|
package/dist/chunk-FBVCQTQN.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/templates/index.ts
|
|
4
|
-
var TEMPLATES = [
|
|
5
|
-
{
|
|
6
|
-
id: "customer-support",
|
|
7
|
-
label: "Customer Support",
|
|
8
|
-
hint: "ticket routing, escalation, knowledge base",
|
|
9
|
-
secrets: ["OPENAI_API_KEY"]
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
id: "b2b-sales",
|
|
13
|
-
label: "B2B Sales Outreach",
|
|
14
|
-
hint: "CRM enrichment, lead scoring",
|
|
15
|
-
secrets: ["OPENAI_API_KEY", "CRM_API_KEY"]
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
id: "financial-agent",
|
|
19
|
-
label: "Financial Agent",
|
|
20
|
-
hint: "market signals, portfolio analysis",
|
|
21
|
-
secrets: ["OPENAI_API_KEY", "MARKET_DATA_API_KEY"]
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
id: "minimal",
|
|
25
|
-
label: "Minimal Skeleton",
|
|
26
|
-
hint: "bare structure, start from scratch",
|
|
27
|
-
secrets: []
|
|
28
|
-
}
|
|
29
|
-
];
|
|
30
|
-
function getTemplateMeta(id) {
|
|
31
|
-
return TEMPLATES.find((t) => t.id === id);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// src/scaffold.ts
|
|
35
|
-
import { writeFile, readFile, readdir, cp } from "fs/promises";
|
|
36
|
-
import { fileURLToPath } from "url";
|
|
37
|
-
import { join, dirname } from "path";
|
|
38
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
39
|
-
var __dirname = dirname(__filename);
|
|
40
|
-
var TEMPLATES_DIR = join(__dirname, "..", "templates");
|
|
41
|
-
async function replacePlaceholders(dir, map) {
|
|
42
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
43
|
-
for (const entry of entries) {
|
|
44
|
-
const fp = join(dir, entry.name);
|
|
45
|
-
if (entry.isDirectory()) {
|
|
46
|
-
await replacePlaceholders(fp, map);
|
|
47
|
-
} else if (entry.isFile() && entry.name !== ".gitkeep") {
|
|
48
|
-
try {
|
|
49
|
-
let src = await readFile(fp, "utf-8");
|
|
50
|
-
let changed = false;
|
|
51
|
-
for (const [from, to] of Object.entries(map)) {
|
|
52
|
-
if (src.includes(from)) {
|
|
53
|
-
src = src.replaceAll(from, to);
|
|
54
|
-
changed = true;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
if (changed) await writeFile(fp, src, "utf-8");
|
|
58
|
-
} catch {
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
async function scaffoldProject(opts) {
|
|
64
|
-
const { projectName, targetDir } = opts;
|
|
65
|
-
await cp(join(TEMPLATES_DIR, "project"), targetDir, {
|
|
66
|
-
recursive: true,
|
|
67
|
-
force: true
|
|
68
|
-
});
|
|
69
|
-
const kalpConfig = `import { defineConfig } from "@kalphq/sdk";
|
|
70
|
-
|
|
71
|
-
export default defineConfig({
|
|
72
|
-
projectId: "${projectName}",
|
|
73
|
-
secrets: [],
|
|
74
|
-
});
|
|
75
|
-
`;
|
|
76
|
-
await writeFile(join(targetDir, "kalp.config.ts"), kalpConfig, "utf-8");
|
|
77
|
-
await replacePlaceholders(targetDir, { __PROJECT_NAME__: projectName });
|
|
78
|
-
}
|
|
79
|
-
async function scaffoldAgent(opts) {
|
|
80
|
-
const { agentName, templateId, cwd } = opts;
|
|
81
|
-
const meta = getTemplateMeta(templateId);
|
|
82
|
-
const agentDir = join(cwd, "agents", agentName);
|
|
83
|
-
await cp(join(TEMPLATES_DIR, "agents", templateId), agentDir, {
|
|
84
|
-
recursive: true,
|
|
85
|
-
force: true
|
|
86
|
-
});
|
|
87
|
-
await replacePlaceholders(agentDir, { __AGENT_NAME__: agentName });
|
|
88
|
-
if (meta.secrets.length > 0) {
|
|
89
|
-
const envPath = join(cwd, ".env");
|
|
90
|
-
let envExisting = "";
|
|
91
|
-
try {
|
|
92
|
-
envExisting = await readFile(envPath, "utf-8");
|
|
93
|
-
} catch {
|
|
94
|
-
}
|
|
95
|
-
const toAdd = meta.secrets.filter((s) => !envExisting.includes(s)).map((s) => `${s}=`).join("\n");
|
|
96
|
-
if (toAdd) {
|
|
97
|
-
const content = envExisting ? envExisting.trimEnd() + "\n" + toAdd + "\n" : toAdd + "\n";
|
|
98
|
-
await writeFile(envPath, content, "utf-8");
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export {
|
|
104
|
-
TEMPLATES,
|
|
105
|
-
scaffoldProject,
|
|
106
|
-
scaffoldAgent
|
|
107
|
-
};
|
|
108
|
-
//# sourceMappingURL=chunk-FBVCQTQN.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/templates/index.ts","../src/scaffold.ts"],"sourcesContent":["export type TemplateId =\n | \"customer-support\"\n | \"b2b-sales\"\n | \"financial-agent\"\n | \"minimal\";\n\nexport interface TemplateMeta {\n id: TemplateId;\n label: string;\n hint: string;\n secrets: string[];\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n {\n id: \"customer-support\",\n label: \"Customer Support\",\n hint: \"ticket routing, escalation, knowledge base\",\n secrets: [\"OPENAI_API_KEY\"],\n },\n {\n id: \"b2b-sales\",\n label: \"B2B Sales Outreach\",\n hint: \"CRM enrichment, lead scoring\",\n secrets: [\"OPENAI_API_KEY\", \"CRM_API_KEY\"],\n },\n {\n id: \"financial-agent\",\n label: \"Financial Agent\",\n hint: \"market signals, portfolio analysis\",\n secrets: [\"OPENAI_API_KEY\", \"MARKET_DATA_API_KEY\"],\n },\n {\n id: \"minimal\",\n label: \"Minimal Skeleton\",\n hint: \"bare structure, start from scratch\",\n secrets: [],\n },\n];\n\nexport function getTemplateMeta(id: TemplateId): TemplateMeta {\n return TEMPLATES.find((t) => t.id === id)!;\n}\n","import { writeFile, readFile, readdir, cp } from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\nimport { join, dirname } from \"node:path\";\nimport { getTemplateMeta, type TemplateId } from \"./templates/index.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport const TEMPLATES_DIR = join(__dirname, \"..\", \"templates\");\n\nasync function replacePlaceholders(\n dir: string,\n map: Record<string, string>,\n): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fp = join(dir, entry.name);\n if (entry.isDirectory()) {\n await replacePlaceholders(fp, map);\n } else if (entry.isFile() && entry.name !== \".gitkeep\") {\n try {\n let src = await readFile(fp, \"utf-8\");\n let changed = false;\n for (const [from, to] of Object.entries(map)) {\n if (src.includes(from)) {\n src = src.replaceAll(from, to);\n changed = true;\n }\n }\n if (changed) await writeFile(fp, src, \"utf-8\");\n } catch {\n // binary file — skip\n }\n }\n }\n}\n\nexport async function scaffoldProject(opts: {\n projectName: string;\n targetDir: string;\n}): Promise<void> {\n const { projectName, targetDir } = opts;\n\n // ── Copy project template (flat) to target directory ──────────────────\n await cp(join(TEMPLATES_DIR, \"project\"), targetDir, {\n recursive: true,\n force: true,\n });\n\n // ── kalp.config.ts ────────────────────────────────────────────────────\n const kalpConfig = `import { defineConfig } from \"@kalphq/sdk\";\n\nexport default defineConfig({\n projectId: \"${projectName}\",\n secrets: [],\n});\n`;\n await writeFile(join(targetDir, \"kalp.config.ts\"), kalpConfig, \"utf-8\");\n\n // ── Replace placeholders across the whole target ──────────────────────\n await replacePlaceholders(targetDir, { __PROJECT_NAME__: projectName });\n}\n\nexport async function scaffoldAgent(opts: {\n agentName: string;\n templateId: TemplateId;\n cwd: string;\n}): Promise<void> {\n const { agentName, templateId, cwd } = opts;\n const meta = getTemplateMeta(templateId);\n const agentDir = join(cwd, \"agents\", agentName);\n\n // ── Agent files via fs.cp ─────────────────────────────────────────────\n await cp(join(TEMPLATES_DIR, \"agents\", templateId), agentDir, {\n recursive: true,\n force: true,\n });\n await replacePlaceholders(agentDir, { __AGENT_NAME__: agentName });\n\n // ── .env at root (append missing secrets) ─────────────────────────────\n if (meta.secrets.length > 0) {\n const envPath = join(cwd, \".env\");\n let envExisting = \"\";\n try {\n envExisting = await readFile(envPath, \"utf-8\");\n } catch {\n // doesn't exist yet\n }\n const toAdd = meta.secrets\n .filter((s) => !envExisting.includes(s))\n .map((s) => `${s}=`)\n .join(\"\\n\");\n if (toAdd) {\n const content = envExisting\n ? envExisting.trimEnd() + \"\\n\" + toAdd + \"\\n\"\n : toAdd + \"\\n\";\n await writeFile(envPath, content, \"utf-8\");\n }\n }\n}\n"],"mappings":"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","names":[]}
|