helix-lang 11.0.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/README.md +168 -0
- package/dist/architect.d.ts +14 -0
- package/dist/architect.d.ts.map +1 -0
- package/dist/architect.js +127 -0
- package/dist/architect.js.map +1 -0
- package/dist/bin/helix.d.ts +20 -0
- package/dist/bin/helix.d.ts.map +1 -0
- package/dist/bin/helix.js +921 -0
- package/dist/bin/helix.js.map +1 -0
- package/dist/commands/collaborate/index.d.ts +2 -0
- package/dist/commands/collaborate/index.d.ts.map +1 -0
- package/dist/commands/collaborate/index.js +129 -0
- package/dist/commands/collaborate/index.js.map +1 -0
- package/dist/commands/collaborate/server.d.ts +31 -0
- package/dist/commands/collaborate/server.d.ts.map +1 -0
- package/dist/commands/collaborate/server.js +159 -0
- package/dist/commands/collaborate/server.js.map +1 -0
- package/dist/commands/deploy/index.d.ts +25 -0
- package/dist/commands/deploy/index.d.ts.map +1 -0
- package/dist/commands/deploy/index.js +130 -0
- package/dist/commands/deploy/index.js.map +1 -0
- package/dist/commands/deploy/platforms/fly.d.ts +9 -0
- package/dist/commands/deploy/platforms/fly.d.ts.map +1 -0
- package/dist/commands/deploy/platforms/fly.js +68 -0
- package/dist/commands/deploy/platforms/fly.js.map +1 -0
- package/dist/commands/deploy/platforms/railway.d.ts +9 -0
- package/dist/commands/deploy/platforms/railway.d.ts.map +1 -0
- package/dist/commands/deploy/platforms/railway.js +115 -0
- package/dist/commands/deploy/platforms/railway.js.map +1 -0
- package/dist/commands/deploy/platforms/vercel.d.ts +10 -0
- package/dist/commands/deploy/platforms/vercel.d.ts.map +1 -0
- package/dist/commands/deploy/platforms/vercel.js +126 -0
- package/dist/commands/deploy/platforms/vercel.js.map +1 -0
- package/dist/commands/deploy.d.ts +6 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +56 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/evolve/analyzers/performance.d.ts +13 -0
- package/dist/commands/evolve/analyzers/performance.d.ts.map +1 -0
- package/dist/commands/evolve/analyzers/performance.js +591 -0
- package/dist/commands/evolve/analyzers/performance.js.map +1 -0
- package/dist/commands/evolve/analyzers/security.d.ts +21 -0
- package/dist/commands/evolve/analyzers/security.d.ts.map +1 -0
- package/dist/commands/evolve/analyzers/security.js +280 -0
- package/dist/commands/evolve/analyzers/security.js.map +1 -0
- package/dist/commands/evolve/index.d.ts +2 -0
- package/dist/commands/evolve/index.d.ts.map +1 -0
- package/dist/commands/evolve/index.js +122 -0
- package/dist/commands/evolve/index.js.map +1 -0
- package/dist/commands/generate.d.ts +6 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +277 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/install.d.ts +2 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +176 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/library/index.d.ts +27 -0
- package/dist/commands/library/index.d.ts.map +1 -0
- package/dist/commands/library/index.js +126 -0
- package/dist/commands/library/index.js.map +1 -0
- package/dist/commands/migrate.d.ts +5 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +258 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/new.d.ts +6 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +195 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/preflight.d.ts +20 -0
- package/dist/commands/preflight.d.ts.map +1 -0
- package/dist/commands/preflight.js +182 -0
- package/dist/commands/preflight.js.map +1 -0
- package/dist/commands/preview.d.ts +13 -0
- package/dist/commands/preview.d.ts.map +1 -0
- package/dist/commands/preview.js +260 -0
- package/dist/commands/preview.js.map +1 -0
- package/dist/commands/run.d.ts +6 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +96 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/spawn.d.ts +11 -0
- package/dist/commands/spawn.d.ts.map +1 -0
- package/dist/commands/spawn.js +916 -0
- package/dist/commands/spawn.js.map +1 -0
- package/dist/compiler.d.ts +12 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +92 -0
- package/dist/compiler.js.map +1 -0
- package/dist/core/file-writer.d.ts +36 -0
- package/dist/core/file-writer.d.ts.map +1 -0
- package/dist/core/file-writer.js +268 -0
- package/dist/core/file-writer.js.map +1 -0
- package/dist/core/registry.d.ts +57 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +222 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/self-healing.d.ts +47 -0
- package/dist/core/self-healing.d.ts.map +1 -0
- package/dist/core/self-healing.js +250 -0
- package/dist/core/self-healing.js.map +1 -0
- package/dist/core/types.d.ts +126 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +7 -0
- package/dist/core/types.js.map +1 -0
- package/dist/generators/databases/mongodb.d.ts +10 -0
- package/dist/generators/databases/mongodb.d.ts.map +1 -0
- package/dist/generators/databases/mongodb.js +83 -0
- package/dist/generators/databases/mongodb.js.map +1 -0
- package/dist/generators/databases/redis.d.ts +2 -0
- package/dist/generators/databases/redis.d.ts.map +1 -0
- package/dist/generators/databases/redis.js +140 -0
- package/dist/generators/databases/redis.js.map +1 -0
- package/dist/generators/flutter.d.ts +32 -0
- package/dist/generators/flutter.d.ts.map +1 -0
- package/dist/generators/flutter.js +628 -0
- package/dist/generators/flutter.js.map +1 -0
- package/dist/openrouter.d.ts +68 -0
- package/dist/openrouter.d.ts.map +1 -0
- package/dist/openrouter.js +241 -0
- package/dist/openrouter.js.map +1 -0
- package/dist/page-generator.d.ts +22 -0
- package/dist/page-generator.d.ts.map +1 -0
- package/dist/page-generator.js +192 -0
- package/dist/page-generator.js.map +1 -0
- package/dist/parser.d.ts +76 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +691 -0
- package/dist/parser.js.map +1 -0
- package/dist/prompts/master-architect.d.ts +9 -0
- package/dist/prompts/master-architect.d.ts.map +1 -0
- package/dist/prompts/master-architect.js +150 -0
- package/dist/prompts/master-architect.js.map +1 -0
- package/dist/researcher.d.ts +12 -0
- package/dist/researcher.d.ts.map +1 -0
- package/dist/researcher.js +85 -0
- package/dist/researcher.js.map +1 -0
- package/dist/self-heal.d.ts +29 -0
- package/dist/self-heal.d.ts.map +1 -0
- package/dist/self-heal.js +260 -0
- package/dist/self-heal.js.map +1 -0
- package/dist/services/SupabaseDeployer.d.ts +9 -0
- package/dist/services/SupabaseDeployer.d.ts.map +1 -0
- package/dist/services/SupabaseDeployer.js +50 -0
- package/dist/services/SupabaseDeployer.js.map +1 -0
- package/dist/test-generator.d.ts +18 -0
- package/dist/test-generator.d.ts.map +1 -0
- package/dist/test-generator.js +180 -0
- package/dist/test-generator.js.map +1 -0
- package/dist/themes/index.d.ts +52 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +273 -0
- package/dist/themes/index.js.map +1 -0
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +81 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/constitutional-validator.d.ts +73 -0
- package/dist/utils/constitutional-validator.d.ts.map +1 -0
- package/dist/utils/constitutional-validator.js +249 -0
- package/dist/utils/constitutional-validator.js.map +1 -0
- package/library/auth-flow/app/api/auth/[...nextauth]/route.ts +31 -0
- package/library/auth-flow/app/api/auth/login/route.ts +90 -0
- package/library/auth-flow/app/api/auth/register/route.ts +91 -0
- package/library/auth-flow/components/auth/AuthMiddleware.tsx +139 -0
- package/library/auth-flow/components/auth/LoginForm.tsx +125 -0
- package/library/auth-flow/components/auth/RegisterForm.tsx +168 -0
- package/library/auth-flow/components/auth/nextauth-config.ts +99 -0
- package/library/auth-flow/manifest.json +29 -0
- package/library/auth-flow/schema.prisma +45 -0
- package/library/dashboard-analytics/components/dashboard/ActivityFeed.tsx +109 -0
- package/library/dashboard-analytics/components/dashboard/LineChart.tsx +180 -0
- package/library/dashboard-analytics/components/dashboard/StatsCard.tsx +47 -0
- package/library/dashboard-analytics/components/dashboard/SummaryGrid.tsx +39 -0
- package/library/dashboard-analytics/manifest.json +19 -0
- package/library/data-table/components/table/BulkActions.tsx +59 -0
- package/library/data-table/components/table/ColumnToggle.tsx +65 -0
- package/library/data-table/components/table/DataTable.tsx +318 -0
- package/library/data-table/components/table/ExportCSV.tsx +52 -0
- package/library/data-table/components/table/SearchFilter.tsx +48 -0
- package/library/data-table/manifest.json +20 -0
- package/library/file-upload/app/api/upload/route.ts +107 -0
- package/library/file-upload/components/upload/DropZone.tsx +268 -0
- package/library/file-upload/components/upload/FilePreview.tsx +82 -0
- package/library/file-upload/components/upload/UploadProgress.tsx +92 -0
- package/library/file-upload/components/upload/fileStorage.ts +142 -0
- package/library/file-upload/manifest.json +21 -0
- package/library/notification-system/app/api/notifications/route.ts +121 -0
- package/library/notification-system/components/notifications/NotificationBell.tsx +154 -0
- package/library/notification-system/components/notifications/NotificationProvider.tsx +161 -0
- package/library/notification-system/components/notifications/Toast.tsx +112 -0
- package/library/notification-system/manifest.json +20 -0
- package/package.json +66 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter Service Module v11.0
|
|
3
|
+
* OpenClaw-Aligned Routing + Ollama Local GPU fallback
|
|
4
|
+
* + Exponential backoff retry, cost tracking, request timeouts
|
|
5
|
+
*
|
|
6
|
+
* Model Strategy (synced with OpenClaw):
|
|
7
|
+
* - Code generation: DeepSeek Chat (best coder, $0.14/M input)
|
|
8
|
+
* - Research/light: Llama 3.3 70B (free tier)
|
|
9
|
+
* - Local fallback: Ollama on Omen PC (GPU, free)
|
|
10
|
+
*/
|
|
11
|
+
interface CostEntry {
|
|
12
|
+
model: string;
|
|
13
|
+
promptTokens: number;
|
|
14
|
+
completionTokens: number;
|
|
15
|
+
cost: number;
|
|
16
|
+
timestamp: Date;
|
|
17
|
+
}
|
|
18
|
+
/** Get a summary of session costs */
|
|
19
|
+
export declare function getCostSummary(): {
|
|
20
|
+
totalCost: number;
|
|
21
|
+
callCount: number;
|
|
22
|
+
entries: CostEntry[];
|
|
23
|
+
};
|
|
24
|
+
/** Reset the cost tracker (e.g. between sessions) */
|
|
25
|
+
export declare function resetCostTracker(): void;
|
|
26
|
+
export declare const DEFAULT_MODEL: string;
|
|
27
|
+
export declare const RESEARCH_MODEL: string;
|
|
28
|
+
/** Use local Ollama for lightweight tasks (SCOPE, repairs) */
|
|
29
|
+
export declare const LOCAL_MODEL = "ollama/local";
|
|
30
|
+
export interface OpenRouterMessage {
|
|
31
|
+
role: "system" | "user" | "assistant";
|
|
32
|
+
content: string;
|
|
33
|
+
}
|
|
34
|
+
export interface OpenRouterResponse {
|
|
35
|
+
id: string;
|
|
36
|
+
choices: Array<{
|
|
37
|
+
message: {
|
|
38
|
+
role: string;
|
|
39
|
+
content: string;
|
|
40
|
+
};
|
|
41
|
+
finish_reason: string;
|
|
42
|
+
}>;
|
|
43
|
+
usage?: {
|
|
44
|
+
prompt_tokens: number;
|
|
45
|
+
completion_tokens: number;
|
|
46
|
+
total_tokens: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface CompletionOptions {
|
|
50
|
+
model?: string;
|
|
51
|
+
maxTokens?: number;
|
|
52
|
+
temperature?: number;
|
|
53
|
+
/** Enable Qwen Thinking Mode for self-healing retries */
|
|
54
|
+
thinking?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Creates a chat completion — routes to Ollama or OpenRouter
|
|
58
|
+
*
|
|
59
|
+
* If model is LOCAL_MODEL ("ollama/local"), tries Ollama first and falls back to OpenRouter.
|
|
60
|
+
* Otherwise, goes straight to OpenRouter.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createCompletion(systemPrompt: string, userMessage: string, options?: CompletionOptions): Promise<string>;
|
|
63
|
+
/**
|
|
64
|
+
* Available models on OpenRouter - OpenClaw-aligned priority
|
|
65
|
+
*/
|
|
66
|
+
export declare const AVAILABLE_MODELS: string[];
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=openrouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../src/openrouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgBH,UAAU,SAAS;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CACnB;AAyBD,qCAAqC;AACrC,wBAAgB,cAAc,IAAI;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,EAAE,CAAA;CAAE,CAE/F;AAED,qDAAqD;AACrD,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC;AAkBD,eAAO,MAAM,aAAa,QAA8D,CAAC;AACzF,eAAO,MAAM,cAAc,QAA0E,CAAC;AACtG,8DAA8D;AAC9D,eAAO,MAAM,WAAW,iBAAiB,CAAC;AAE1C,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,KAAK,CAAC;QACX,OAAO,EAAE;YACL,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACnB,CAAC;QACF,aAAa,EAAE,MAAM,CAAC;KACzB,CAAC,CAAC;IACH,KAAK,CAAC,EAAE;QACJ,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;KACxB,CAAC;CACL;AAED,MAAM,WAAW,iBAAiB;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAqDD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAClC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,iBAAsB,GAChC,OAAO,CAAC,MAAM,CAAC,CA6HjB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,UAW5B,CAAC"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenRouter Service Module v11.0
|
|
4
|
+
* OpenClaw-Aligned Routing + Ollama Local GPU fallback
|
|
5
|
+
* + Exponential backoff retry, cost tracking, request timeouts
|
|
6
|
+
*
|
|
7
|
+
* Model Strategy (synced with OpenClaw):
|
|
8
|
+
* - Code generation: DeepSeek Chat (best coder, $0.14/M input)
|
|
9
|
+
* - Research/light: Llama 3.3 70B (free tier)
|
|
10
|
+
* - Local fallback: Ollama on Omen PC (GPU, free)
|
|
11
|
+
*/
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AVAILABLE_MODELS = exports.LOCAL_MODEL = exports.RESEARCH_MODEL = exports.DEFAULT_MODEL = void 0;
|
|
17
|
+
exports.getCostSummary = getCostSummary;
|
|
18
|
+
exports.resetCostTracker = resetCostTracker;
|
|
19
|
+
exports.createCompletion = createCompletion;
|
|
20
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
21
|
+
// ── Cost Tracking ──────────────────────────────────────────────────────
|
|
22
|
+
/** Pricing per million tokens: [input, output] */
|
|
23
|
+
const MODEL_PRICING = {
|
|
24
|
+
"deepseek/deepseek-chat": [0.14, 0.28],
|
|
25
|
+
"meta-llama/llama-3.3-70b-instruct": [0, 0],
|
|
26
|
+
"minimax/minimax-01": [0.50, 1.50],
|
|
27
|
+
"anthropic/claude-3.5-sonnet": [3.00, 15.00],
|
|
28
|
+
"google/gemini-pro-1.5": [3.50, 10.50],
|
|
29
|
+
"openai/gpt-4o": [2.50, 10.00],
|
|
30
|
+
};
|
|
31
|
+
let sessionCostTotal = 0;
|
|
32
|
+
const costLog = [];
|
|
33
|
+
function trackCost(model, usage) {
|
|
34
|
+
if (!usage)
|
|
35
|
+
return;
|
|
36
|
+
const pricing = MODEL_PRICING[model];
|
|
37
|
+
if (!pricing) {
|
|
38
|
+
// Unknown model — log zero cost
|
|
39
|
+
costLog.push({ model, promptTokens: usage.prompt_tokens, completionTokens: usage.completion_tokens, cost: 0, timestamp: new Date() });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const [inputRate, outputRate] = pricing;
|
|
43
|
+
const cost = (usage.prompt_tokens / 1_000_000) * inputRate + (usage.completion_tokens / 1_000_000) * outputRate;
|
|
44
|
+
sessionCostTotal += cost;
|
|
45
|
+
costLog.push({ model, promptTokens: usage.prompt_tokens, completionTokens: usage.completion_tokens, cost, timestamp: new Date() });
|
|
46
|
+
if (cost > 0) {
|
|
47
|
+
console.log(chalk_1.default.gray(`💰 Cost: $${cost.toFixed(6)} | Session total: $${sessionCostTotal.toFixed(6)}`));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Get a summary of session costs */
|
|
51
|
+
function getCostSummary() {
|
|
52
|
+
return { totalCost: sessionCostTotal, callCount: costLog.length, entries: [...costLog] };
|
|
53
|
+
}
|
|
54
|
+
/** Reset the cost tracker (e.g. between sessions) */
|
|
55
|
+
function resetCostTracker() {
|
|
56
|
+
sessionCostTotal = 0;
|
|
57
|
+
costLog.length = 0;
|
|
58
|
+
}
|
|
59
|
+
// ── Retry Logic ────────────────────────────────────────────────────────
|
|
60
|
+
const RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504]);
|
|
61
|
+
const MAX_RETRIES = 3;
|
|
62
|
+
const RETRY_DELAYS_MS = [1000, 3000, 9000];
|
|
63
|
+
const API_TIMEOUT_MS = 60_000;
|
|
64
|
+
// OpenRouter API Configuration
|
|
65
|
+
const OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1/chat/completions";
|
|
66
|
+
// Ollama (local) Configuration
|
|
67
|
+
const OLLAMA_URL = process.env.OLLAMA_URL || "http://localhost:11434";
|
|
68
|
+
const OLLAMA_MODEL = process.env.OLLAMA_MODEL || "qwen2.5-coder:7b";
|
|
69
|
+
// Model defaults from environment - OpenClaw-aligned stack
|
|
70
|
+
exports.DEFAULT_MODEL = process.env.HELIX_DEFAULT_MODEL || "deepseek/deepseek-chat";
|
|
71
|
+
exports.RESEARCH_MODEL = process.env.HELIX_RESEARCH_MODEL || "meta-llama/llama-3.3-70b-instruct";
|
|
72
|
+
/** Use local Ollama for lightweight tasks (SCOPE, repairs) */
|
|
73
|
+
exports.LOCAL_MODEL = "ollama/local";
|
|
74
|
+
/**
|
|
75
|
+
* Check if Ollama is running on the Omen PC
|
|
76
|
+
*/
|
|
77
|
+
async function isOllamaAvailable() {
|
|
78
|
+
try {
|
|
79
|
+
const controller = new AbortController();
|
|
80
|
+
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
81
|
+
const resp = await fetch(`${OLLAMA_URL}/api/tags`, { signal: controller.signal });
|
|
82
|
+
clearTimeout(timeout);
|
|
83
|
+
return resp.ok;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Call Ollama locally on Omen PC (GPU-accelerated, free)
|
|
91
|
+
*/
|
|
92
|
+
async function callOllama(systemPrompt, userMessage, maxTokens) {
|
|
93
|
+
const prompt = `${systemPrompt}\n\n${userMessage}`;
|
|
94
|
+
const response = await fetch(`${OLLAMA_URL}/api/generate`, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: { "Content-Type": "application/json" },
|
|
97
|
+
body: JSON.stringify({
|
|
98
|
+
model: OLLAMA_MODEL,
|
|
99
|
+
prompt,
|
|
100
|
+
stream: false,
|
|
101
|
+
options: { num_predict: maxTokens },
|
|
102
|
+
}),
|
|
103
|
+
});
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
throw new Error(`Ollama error: ${response.status}`);
|
|
106
|
+
}
|
|
107
|
+
const data = await response.json();
|
|
108
|
+
// Log performance
|
|
109
|
+
if (data.eval_count && data.eval_duration) {
|
|
110
|
+
const tokPerSec = (data.eval_count / (data.eval_duration / 1e9)).toFixed(1);
|
|
111
|
+
console.log(chalk_1.default.gray(`📊 Ollama: ${data.eval_count} tokens @ ${tokPerSec} tok/sec (GPU)`));
|
|
112
|
+
}
|
|
113
|
+
return data.response;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Creates a chat completion — routes to Ollama or OpenRouter
|
|
117
|
+
*
|
|
118
|
+
* If model is LOCAL_MODEL ("ollama/local"), tries Ollama first and falls back to OpenRouter.
|
|
119
|
+
* Otherwise, goes straight to OpenRouter.
|
|
120
|
+
*/
|
|
121
|
+
async function createCompletion(systemPrompt, userMessage, options = {}) {
|
|
122
|
+
const model = options.model || exports.DEFAULT_MODEL;
|
|
123
|
+
const maxTokens = options.maxTokens || 4096;
|
|
124
|
+
const temperature = options.temperature || 0.7;
|
|
125
|
+
const useLocal = model === exports.LOCAL_MODEL;
|
|
126
|
+
// Try Ollama first for local model requests
|
|
127
|
+
if (useLocal) {
|
|
128
|
+
const ollamaUp = await isOllamaAvailable();
|
|
129
|
+
if (ollamaUp) {
|
|
130
|
+
console.log(chalk_1.default.gray(`🤖 Model: ${OLLAMA_MODEL} [Omen GPU]`));
|
|
131
|
+
try {
|
|
132
|
+
return await callOllama(systemPrompt, userMessage, maxTokens);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
console.log(chalk_1.default.yellow(`⚠️ Ollama failed (${err.message}), falling back to OpenRouter`));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
console.log(chalk_1.default.gray(`🤖 Ollama offline — using OpenRouter fallback`));
|
|
140
|
+
}
|
|
141
|
+
// Fall through to OpenRouter with RESEARCH_MODEL as fallback
|
|
142
|
+
options.model = exports.RESEARCH_MODEL;
|
|
143
|
+
}
|
|
144
|
+
// OpenRouter path
|
|
145
|
+
const apiKey = process.env.OPENROUTER_API_KEY;
|
|
146
|
+
if (!apiKey) {
|
|
147
|
+
throw new Error("OPENROUTER_API_KEY not found in environment");
|
|
148
|
+
}
|
|
149
|
+
const finalModel = useLocal ? exports.RESEARCH_MODEL : model;
|
|
150
|
+
console.log(chalk_1.default.gray(`🤖 Model: ${finalModel}${options.thinking ? ' [Thinking Mode]' : ''}${useLocal ? ' [fallback]' : ''}`));
|
|
151
|
+
const messages = [
|
|
152
|
+
{ role: "system", content: systemPrompt },
|
|
153
|
+
{ role: "user", content: userMessage },
|
|
154
|
+
];
|
|
155
|
+
// Build request body
|
|
156
|
+
const body = {
|
|
157
|
+
model: finalModel,
|
|
158
|
+
messages,
|
|
159
|
+
max_tokens: maxTokens,
|
|
160
|
+
temperature,
|
|
161
|
+
};
|
|
162
|
+
// Enable thinking/reasoning mode if requested (DeepSeek supports this)
|
|
163
|
+
if (options.thinking) {
|
|
164
|
+
body.reasoning = { effort: "high" };
|
|
165
|
+
}
|
|
166
|
+
// Retry loop with exponential backoff
|
|
167
|
+
let lastError = null;
|
|
168
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
169
|
+
if (attempt > 0) {
|
|
170
|
+
const delay = RETRY_DELAYS_MS[attempt - 1];
|
|
171
|
+
console.log(chalk_1.default.yellow(`⏳ Retry ${attempt}/${MAX_RETRIES - 1} after ${delay}ms...`));
|
|
172
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
173
|
+
}
|
|
174
|
+
const controller = new AbortController();
|
|
175
|
+
const timeout = setTimeout(() => controller.abort(), API_TIMEOUT_MS);
|
|
176
|
+
try {
|
|
177
|
+
const response = await fetch(OPENROUTER_BASE_URL, {
|
|
178
|
+
method: "POST",
|
|
179
|
+
headers: {
|
|
180
|
+
"Content-Type": "application/json",
|
|
181
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
182
|
+
"HTTP-Referer": "https://helix-lang.dev",
|
|
183
|
+
"X-Title": "Helix CLI",
|
|
184
|
+
},
|
|
185
|
+
body: JSON.stringify(body),
|
|
186
|
+
signal: controller.signal,
|
|
187
|
+
});
|
|
188
|
+
clearTimeout(timeout);
|
|
189
|
+
if (!response.ok) {
|
|
190
|
+
const errorText = await response.text();
|
|
191
|
+
lastError = new Error(`OpenRouter API error: ${response.status} - ${errorText}`);
|
|
192
|
+
// Don't retry on client errors (except 429)
|
|
193
|
+
if (!RETRYABLE_STATUS_CODES.has(response.status)) {
|
|
194
|
+
throw lastError;
|
|
195
|
+
}
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const data = (await response.json());
|
|
199
|
+
if (!data.choices || data.choices.length === 0) {
|
|
200
|
+
throw new Error("No response from OpenRouter API");
|
|
201
|
+
}
|
|
202
|
+
const content = data.choices[0].message.content;
|
|
203
|
+
// Log token usage if available
|
|
204
|
+
if (data.usage) {
|
|
205
|
+
console.log(chalk_1.default.gray(`📊 Tokens: ${data.usage.prompt_tokens} prompt + ${data.usage.completion_tokens} completion = ${data.usage.total_tokens} total`));
|
|
206
|
+
}
|
|
207
|
+
// Track cost
|
|
208
|
+
trackCost(finalModel, data.usage);
|
|
209
|
+
return content;
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
clearTimeout(timeout);
|
|
213
|
+
if (err.name === "AbortError") {
|
|
214
|
+
lastError = new Error(`OpenRouter API request timed out after ${API_TIMEOUT_MS}ms`);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// Re-throw non-retryable errors
|
|
218
|
+
if (lastError && !RETRYABLE_STATUS_CODES.has(parseInt(lastError.message.match(/error: (\d+)/)?.[1] || "0"))) {
|
|
219
|
+
throw err;
|
|
220
|
+
}
|
|
221
|
+
lastError = err;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
throw lastError || new Error("OpenRouter API request failed after all retries");
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Available models on OpenRouter - OpenClaw-aligned priority
|
|
228
|
+
*/
|
|
229
|
+
exports.AVAILABLE_MODELS = [
|
|
230
|
+
"deepseek/deepseek-chat", // Primary: code generation ($0.14/M)
|
|
231
|
+
"meta-llama/llama-3.3-70b-instruct", // Research: free tier
|
|
232
|
+
"minimax/minimax-01", // Creative: writing/design
|
|
233
|
+
"moonshotai/kimi-k2.5", // Coding fallback
|
|
234
|
+
"anthropic/claude-3.5-sonnet", // Premium fallback
|
|
235
|
+
"google/gemini-pro-1.5",
|
|
236
|
+
"google/gemini-flash-1.5",
|
|
237
|
+
"openai/gpt-4o",
|
|
238
|
+
"qwen/qwen3.5-plus-02-15",
|
|
239
|
+
"deepseek/deepseek-chat-v3-0324",
|
|
240
|
+
];
|
|
241
|
+
//# sourceMappingURL=openrouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../src/openrouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helix Page Generator — Multi-page app generation
|
|
3
|
+
* Generates layouts, navigation, and per-page route components for Next.js App Router
|
|
4
|
+
*/
|
|
5
|
+
import { HelixPage, HelixStrand } from './parser';
|
|
6
|
+
/**
|
|
7
|
+
* Generate a root layout with navigation between pages
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateLayout(pages: HelixPage[], appName: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Generate a sidebar layout variant
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateSidebarLayout(pages: HelixPage[], appName: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Generate a page component that displays CRUD for its assigned strands
|
|
16
|
+
*/
|
|
17
|
+
export declare function generatePageComponent(page: HelixPage, strands: HelixStrand[]): string;
|
|
18
|
+
/**
|
|
19
|
+
* Generate a redirect page.tsx for the app root that goes to the first page
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateRootRedirect(firstRoute: string): string;
|
|
22
|
+
//# sourceMappingURL=page-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-generator.d.ts","sourceRoot":"","sources":["../src/page-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAElD;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA2C1E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAyCjF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAyFrF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAO/D"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Helix Page Generator — Multi-page app generation
|
|
4
|
+
* Generates layouts, navigation, and per-page route components for Next.js App Router
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.generateLayout = generateLayout;
|
|
8
|
+
exports.generateSidebarLayout = generateSidebarLayout;
|
|
9
|
+
exports.generatePageComponent = generatePageComponent;
|
|
10
|
+
exports.generateRootRedirect = generateRootRedirect;
|
|
11
|
+
/**
|
|
12
|
+
* Generate a root layout with navigation between pages
|
|
13
|
+
*/
|
|
14
|
+
function generateLayout(pages, appName) {
|
|
15
|
+
const navLinks = pages
|
|
16
|
+
.map(p => ` <Link href="${p.route}" className="px-4 py-2 rounded-lg hover:bg-white/10 transition-colors">${p.name}</Link>`)
|
|
17
|
+
.join('\n');
|
|
18
|
+
return `import type { Metadata } from "next";
|
|
19
|
+
import Link from "next/link";
|
|
20
|
+
import "./globals.css";
|
|
21
|
+
|
|
22
|
+
export const metadata: Metadata = {
|
|
23
|
+
title: "${appName}",
|
|
24
|
+
description: "Generated by Helix v11.0",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default function RootLayout({
|
|
28
|
+
children,
|
|
29
|
+
}: {
|
|
30
|
+
children: React.ReactNode;
|
|
31
|
+
}) {
|
|
32
|
+
return (
|
|
33
|
+
<html lang="en">
|
|
34
|
+
<body>
|
|
35
|
+
<div className="min-h-screen bg-gradient-to-br from-gray-900 via-gray-800 to-gray-900">
|
|
36
|
+
{/* Navigation */}
|
|
37
|
+
<nav className="border-b border-white/10 bg-black/20 backdrop-blur-xl">
|
|
38
|
+
<div className="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between">
|
|
39
|
+
<h1 className="text-xl font-bold text-white">${appName}</h1>
|
|
40
|
+
<div className="flex gap-2 text-sm text-gray-300">
|
|
41
|
+
${navLinks}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</nav>
|
|
45
|
+
|
|
46
|
+
{/* Page Content */}
|
|
47
|
+
<main className="max-w-7xl mx-auto px-6 py-8">
|
|
48
|
+
{children}
|
|
49
|
+
</main>
|
|
50
|
+
</div>
|
|
51
|
+
</body>
|
|
52
|
+
</html>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generate a sidebar layout variant
|
|
59
|
+
*/
|
|
60
|
+
function generateSidebarLayout(pages, appName) {
|
|
61
|
+
const navLinks = pages
|
|
62
|
+
.map(p => ` <Link href="${p.route}" className="block px-4 py-2 rounded-lg hover:bg-white/10 transition-colors text-gray-300 hover:text-white">${p.name}</Link>`)
|
|
63
|
+
.join('\n');
|
|
64
|
+
return `import type { Metadata } from "next";
|
|
65
|
+
import Link from "next/link";
|
|
66
|
+
import "./globals.css";
|
|
67
|
+
|
|
68
|
+
export const metadata: Metadata = {
|
|
69
|
+
title: "${appName}",
|
|
70
|
+
description: "Generated by Helix v11.0",
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default function RootLayout({
|
|
74
|
+
children,
|
|
75
|
+
}: {
|
|
76
|
+
children: React.ReactNode;
|
|
77
|
+
}) {
|
|
78
|
+
return (
|
|
79
|
+
<html lang="en">
|
|
80
|
+
<body>
|
|
81
|
+
<div className="min-h-screen flex bg-gradient-to-br from-gray-900 via-gray-800 to-gray-900">
|
|
82
|
+
{/* Sidebar */}
|
|
83
|
+
<aside className="w-64 border-r border-white/10 bg-black/30 backdrop-blur-xl p-6">
|
|
84
|
+
<h1 className="text-xl font-bold text-white mb-8">${appName}</h1>
|
|
85
|
+
<nav className="flex flex-col gap-1 text-sm">
|
|
86
|
+
${navLinks}
|
|
87
|
+
</nav>
|
|
88
|
+
</aside>
|
|
89
|
+
|
|
90
|
+
{/* Main Content */}
|
|
91
|
+
<main className="flex-1 p-8">
|
|
92
|
+
{children}
|
|
93
|
+
</main>
|
|
94
|
+
</div>
|
|
95
|
+
</body>
|
|
96
|
+
</html>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Generate a page component that displays CRUD for its assigned strands
|
|
103
|
+
*/
|
|
104
|
+
function generatePageComponent(page, strands) {
|
|
105
|
+
const pageStrands = strands.filter(s => page.strands.includes(s.name));
|
|
106
|
+
if (pageStrands.length === 0) {
|
|
107
|
+
return `'use client';
|
|
108
|
+
|
|
109
|
+
export default function ${page.name}Page() {
|
|
110
|
+
return (
|
|
111
|
+
<div>
|
|
112
|
+
<h1 className="text-2xl font-bold text-white mb-4">${page.name}</h1>
|
|
113
|
+
<p className="text-gray-400">No data models assigned to this page.</p>
|
|
114
|
+
</div>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
`;
|
|
118
|
+
}
|
|
119
|
+
const imports = [`'use client';`, `import { useState, useEffect } from 'react';`];
|
|
120
|
+
const stateDecls = [];
|
|
121
|
+
const fetchCalls = [];
|
|
122
|
+
const sections = [];
|
|
123
|
+
for (const strand of pageStrands) {
|
|
124
|
+
const name = strand.name;
|
|
125
|
+
const lower = name.toLowerCase();
|
|
126
|
+
const plural = lower + 's';
|
|
127
|
+
stateDecls.push(` const [${plural}, set${name}s] = useState<any[]>([]);`);
|
|
128
|
+
stateDecls.push(` const [${lower}Loading, set${name}Loading] = useState(true);`);
|
|
129
|
+
fetchCalls.push(` fetch('/api/${plural}')
|
|
130
|
+
.then(r => r.json())
|
|
131
|
+
.then(d => { set${name}s(d.data || d); set${name}Loading(false); })
|
|
132
|
+
.catch(() => set${name}Loading(false));`);
|
|
133
|
+
const fieldCols = strand.fields.slice(0, 5).map(f => ` <th className="text-left p-3 text-gray-400 text-sm font-medium">${f.name}</th>`).join('\n');
|
|
134
|
+
const fieldCells = strand.fields.slice(0, 5).map(f => ` <td className="p-3 text-gray-300">{String(item.${f.name} ?? '')}</td>`).join('\n');
|
|
135
|
+
sections.push(`
|
|
136
|
+
{/* ${name} Section */}
|
|
137
|
+
<section className="bg-white/5 rounded-2xl border border-white/10 p-6">
|
|
138
|
+
<h2 className="text-lg font-semibold text-white mb-4">${name}s</h2>
|
|
139
|
+
{${lower}Loading ? (
|
|
140
|
+
<p className="text-gray-400">Loading...</p>
|
|
141
|
+
) : ${plural}.length === 0 ? (
|
|
142
|
+
<p className="text-gray-400">No ${plural} found.</p>
|
|
143
|
+
) : (
|
|
144
|
+
<div className="overflow-x-auto">
|
|
145
|
+
<table className="w-full">
|
|
146
|
+
<thead className="border-b border-white/10">
|
|
147
|
+
<tr>
|
|
148
|
+
${fieldCols}
|
|
149
|
+
</tr>
|
|
150
|
+
</thead>
|
|
151
|
+
<tbody className="divide-y divide-white/5">
|
|
152
|
+
{${plural}.map((item: any, i: number) => (
|
|
153
|
+
<tr key={item.id || i} className="hover:bg-white/5">
|
|
154
|
+
${fieldCells}
|
|
155
|
+
</tr>
|
|
156
|
+
))}
|
|
157
|
+
</tbody>
|
|
158
|
+
</table>
|
|
159
|
+
</div>
|
|
160
|
+
)}
|
|
161
|
+
</section>`);
|
|
162
|
+
}
|
|
163
|
+
return `${imports.join('\n')}
|
|
164
|
+
|
|
165
|
+
export default function ${page.name}Page() {
|
|
166
|
+
${stateDecls.join('\n')}
|
|
167
|
+
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
${fetchCalls.join('\n')}
|
|
170
|
+
}, []);
|
|
171
|
+
|
|
172
|
+
return (
|
|
173
|
+
<div className="space-y-8">
|
|
174
|
+
<h1 className="text-2xl font-bold text-white">${page.name}</h1>
|
|
175
|
+
${sections.join('\n')}
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
`;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Generate a redirect page.tsx for the app root that goes to the first page
|
|
183
|
+
*/
|
|
184
|
+
function generateRootRedirect(firstRoute) {
|
|
185
|
+
return `import { redirect } from 'next/navigation';
|
|
186
|
+
|
|
187
|
+
export default function Home() {
|
|
188
|
+
redirect('${firstRoute}');
|
|
189
|
+
}
|
|
190
|
+
`;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=page-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-generator.js","sourceRoot":"","sources":["../src/page-generator.ts"],"names":[],"mappings":"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"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helix Parser - Parses .helix blueprint files into structured AST
|
|
3
|
+
*/
|
|
4
|
+
export interface HelixField {
|
|
5
|
+
name: string;
|
|
6
|
+
type: string;
|
|
7
|
+
constraints?: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface HelixRelation {
|
|
10
|
+
name: string;
|
|
11
|
+
target: string;
|
|
12
|
+
isMany: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface HelixStrand {
|
|
15
|
+
name: string;
|
|
16
|
+
fields: HelixField[];
|
|
17
|
+
relations: HelixRelation[];
|
|
18
|
+
strategies: HelixStrategy[];
|
|
19
|
+
}
|
|
20
|
+
export interface HelixStrategy {
|
|
21
|
+
name: string;
|
|
22
|
+
action: string;
|
|
23
|
+
condition?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface HelixView {
|
|
26
|
+
name: string;
|
|
27
|
+
properties: Record<string, string>;
|
|
28
|
+
}
|
|
29
|
+
export interface HelixPage {
|
|
30
|
+
name: string;
|
|
31
|
+
route: string;
|
|
32
|
+
layout?: string;
|
|
33
|
+
strands: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface HelixAST {
|
|
36
|
+
strands: HelixStrand[];
|
|
37
|
+
views: HelixView[];
|
|
38
|
+
strategies: HelixStrategy[];
|
|
39
|
+
pages: HelixPage[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parse a .helix file content into an AST
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseHelix(content: string): HelixAST;
|
|
45
|
+
/**
|
|
46
|
+
* Convert Helix types to Prisma types
|
|
47
|
+
*/
|
|
48
|
+
export declare function toPrismaType(helixType: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Generate Prisma schema from AST
|
|
51
|
+
*/
|
|
52
|
+
export declare function generatePrismaSchema(ast: HelixAST): string;
|
|
53
|
+
/**
|
|
54
|
+
* Generate API route handler from strand
|
|
55
|
+
* v11.0 - With input validation, pagination, rate limiting, error handling
|
|
56
|
+
*/
|
|
57
|
+
export declare function generateAPIRoute(strand: HelixStrand): string;
|
|
58
|
+
/**
|
|
59
|
+
* Generate UI page component from view
|
|
60
|
+
* FIX: Uses camelCase for Prisma, adapts to model fields instead of hardcoding is_completed
|
|
61
|
+
*/
|
|
62
|
+
export declare function generateUIPage(view: HelixView, strand: HelixStrand, allStrands?: HelixStrand[], themeClasses?: {
|
|
63
|
+
primaryButton: string;
|
|
64
|
+
secondaryButton: string;
|
|
65
|
+
card: string;
|
|
66
|
+
text: string;
|
|
67
|
+
textMuted: string;
|
|
68
|
+
heading: string;
|
|
69
|
+
badge: string;
|
|
70
|
+
statusColors: {
|
|
71
|
+
success: string;
|
|
72
|
+
warning: string;
|
|
73
|
+
info: string;
|
|
74
|
+
};
|
|
75
|
+
}): string;
|
|
76
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,EAAE,aAAa,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACrB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,KAAK,EAAE,SAAS,EAAE,CAAC;CACtB;AAUD;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAmIpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAqBtD;AAWD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAmD1D;AAOD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAoM5D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,WAAW,EAAE,EAAE,YAAY,CAAC,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,MAAM,CAgR3T"}
|