awel 0.1.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.
Files changed (85) hide show
  1. package/LICENSE +200 -0
  2. package/README.md +98 -0
  3. package/babel-plugin-awel-source.cjs +79 -0
  4. package/bin/awel.js +2 -0
  5. package/dist/cli/agent.d.ts +6 -0
  6. package/dist/cli/agent.js +266 -0
  7. package/dist/cli/babel-setup.d.ts +1 -0
  8. package/dist/cli/babel-setup.js +180 -0
  9. package/dist/cli/comment-popup.d.ts +2 -0
  10. package/dist/cli/comment-popup.js +206 -0
  11. package/dist/cli/config.d.ts +14 -0
  12. package/dist/cli/config.js +29 -0
  13. package/dist/cli/devserver.d.ts +17 -0
  14. package/dist/cli/devserver.js +43 -0
  15. package/dist/cli/index.d.ts +1 -0
  16. package/dist/cli/index.js +34 -0
  17. package/dist/cli/inspector.d.ts +2 -0
  18. package/dist/cli/inspector.js +117 -0
  19. package/dist/cli/logger.d.ts +10 -0
  20. package/dist/cli/logger.js +40 -0
  21. package/dist/cli/plan-store.d.ts +14 -0
  22. package/dist/cli/plan-store.js +18 -0
  23. package/dist/cli/providers/registry.d.ts +17 -0
  24. package/dist/cli/providers/registry.js +112 -0
  25. package/dist/cli/providers/types.d.ts +17 -0
  26. package/dist/cli/providers/types.js +1 -0
  27. package/dist/cli/providers/vercel.d.ts +4 -0
  28. package/dist/cli/providers/vercel.js +483 -0
  29. package/dist/cli/proxy.d.ts +5 -0
  30. package/dist/cli/proxy.js +72 -0
  31. package/dist/cli/server.d.ts +7 -0
  32. package/dist/cli/server.js +104 -0
  33. package/dist/cli/session.d.ts +32 -0
  34. package/dist/cli/session.js +77 -0
  35. package/dist/cli/skills/react-best-practices.md +2934 -0
  36. package/dist/cli/skills/skills/react-best-practices.md +2934 -0
  37. package/dist/cli/sse.d.ts +17 -0
  38. package/dist/cli/sse.js +51 -0
  39. package/dist/cli/subprocess.d.ts +30 -0
  40. package/dist/cli/subprocess.js +163 -0
  41. package/dist/cli/tools/ask-user.d.ts +11 -0
  42. package/dist/cli/tools/ask-user.js +28 -0
  43. package/dist/cli/tools/bash.d.ts +4 -0
  44. package/dist/cli/tools/bash.js +30 -0
  45. package/dist/cli/tools/code-search.d.ts +4 -0
  46. package/dist/cli/tools/code-search.js +70 -0
  47. package/dist/cli/tools/edit.d.ts +6 -0
  48. package/dist/cli/tools/edit.js +37 -0
  49. package/dist/cli/tools/glob.d.ts +4 -0
  50. package/dist/cli/tools/glob.js +29 -0
  51. package/dist/cli/tools/grep.d.ts +5 -0
  52. package/dist/cli/tools/grep.js +146 -0
  53. package/dist/cli/tools/index.d.ts +86 -0
  54. package/dist/cli/tools/index.js +41 -0
  55. package/dist/cli/tools/ls.d.ts +3 -0
  56. package/dist/cli/tools/ls.js +31 -0
  57. package/dist/cli/tools/multi-edit.d.ts +8 -0
  58. package/dist/cli/tools/multi-edit.js +53 -0
  59. package/dist/cli/tools/propose-plan.d.ts +4 -0
  60. package/dist/cli/tools/propose-plan.js +21 -0
  61. package/dist/cli/tools/react-best-practices.d.ts +3 -0
  62. package/dist/cli/tools/react-best-practices.js +55 -0
  63. package/dist/cli/tools/read.d.ts +3 -0
  64. package/dist/cli/tools/read.js +24 -0
  65. package/dist/cli/tools/restart-dev-server.d.ts +3 -0
  66. package/dist/cli/tools/restart-dev-server.js +18 -0
  67. package/dist/cli/tools/todo.d.ts +8 -0
  68. package/dist/cli/tools/todo.js +59 -0
  69. package/dist/cli/tools/web-fetch.d.ts +5 -0
  70. package/dist/cli/tools/web-fetch.js +116 -0
  71. package/dist/cli/tools/web-search.d.ts +5 -0
  72. package/dist/cli/tools/web-search.js +74 -0
  73. package/dist/cli/tools/write.d.ts +4 -0
  74. package/dist/cli/tools/write.js +26 -0
  75. package/dist/cli/types.d.ts +16 -0
  76. package/dist/cli/types.js +2 -0
  77. package/dist/cli/undo.d.ts +49 -0
  78. package/dist/cli/undo.js +212 -0
  79. package/dist/cli/verbose.d.ts +7 -0
  80. package/dist/cli/verbose.js +60 -0
  81. package/dist/dashboard/assets/index-Bk--q3wu.js +313 -0
  82. package/dist/dashboard/assets/index-DkWV03So.css +1 -0
  83. package/dist/dashboard/index.html +16 -0
  84. package/dist/host/host.js +274 -0
  85. package/package.json +67 -0
@@ -0,0 +1,40 @@
1
+ // ─── Prefixed Logger ─────────────────────────────────────────
2
+ // Colored [awel] / [next] prefixes for terminal output so the
3
+ // user can distinguish Awel's messages from the Next.js app's.
4
+ import { createInterface } from 'readline';
5
+ // ANSI 256-color helpers — darker shades that stay visible on light backgrounds
6
+ const cyan = (s) => `\x1b[38;5;30m${s}\x1b[39m`;
7
+ const magenta = (s) => `\x1b[38;5;127m${s}\x1b[39m`;
8
+ const bold = (s) => `\x1b[1m${s}\x1b[22m`;
9
+ const AWEL_PREFIX = bold(cyan('[awel]'));
10
+ const NEXT_PREFIX = bold(magenta('[next]'));
11
+ function prefixedWriter(prefix, stream) {
12
+ return (...args) => {
13
+ const message = args.map(String).join(' ');
14
+ for (const line of message.split('\n')) {
15
+ stream.write(`${prefix} ${line}\n`);
16
+ }
17
+ };
18
+ }
19
+ export const awel = {
20
+ log: prefixedWriter(AWEL_PREFIX, process.stdout),
21
+ error: prefixedWriter(AWEL_PREFIX, process.stderr),
22
+ };
23
+ /**
24
+ * Pipe a child process's stdout/stderr line-by-line, prefixing
25
+ * each line with the magenta [next] tag.
26
+ */
27
+ export function pipeChildOutput(child) {
28
+ if (child.stdout) {
29
+ const rl = createInterface({ input: child.stdout });
30
+ rl.on('line', (line) => {
31
+ process.stdout.write(`${NEXT_PREFIX} ${line}\n`);
32
+ });
33
+ }
34
+ if (child.stderr) {
35
+ const rl = createInterface({ input: child.stderr });
36
+ rl.on('line', (line) => {
37
+ process.stderr.write(`${NEXT_PREFIX} ${line}\n`);
38
+ });
39
+ }
40
+ }
@@ -0,0 +1,14 @@
1
+ export interface StoredPlan {
2
+ planId: string;
3
+ plan: {
4
+ title: string;
5
+ content: string;
6
+ };
7
+ originalPrompt: string;
8
+ modelId: string;
9
+ approved: boolean;
10
+ }
11
+ export declare function storePlan(plan: StoredPlan): void;
12
+ export declare function getActivePlan(): StoredPlan | null;
13
+ export declare function approvePlan(): boolean;
14
+ export declare function clearActivePlan(): void;
@@ -0,0 +1,18 @@
1
+ // ─── Plan Store ──────────────────────────────────────────────
2
+ // Module-level singleton storing the active plan proposed by the agent.
3
+ let activePlan = null;
4
+ export function storePlan(plan) {
5
+ activePlan = plan;
6
+ }
7
+ export function getActivePlan() {
8
+ return activePlan;
9
+ }
10
+ export function approvePlan() {
11
+ if (!activePlan)
12
+ return false;
13
+ activePlan.approved = true;
14
+ return true;
15
+ }
16
+ export function clearActivePlan() {
17
+ activePlan = null;
18
+ }
@@ -0,0 +1,17 @@
1
+ import type { StreamProvider, ModelDefinition } from './types.js';
2
+ export declare const PROVIDER_ENV_KEYS: Record<string, string>;
3
+ export declare function resolveProvider(modelId: string): {
4
+ provider: StreamProvider;
5
+ modelProvider: string;
6
+ };
7
+ export interface ModelWithAvailability extends ModelDefinition {
8
+ available: boolean;
9
+ unavailableReason?: string;
10
+ }
11
+ /**
12
+ * Returns the model catalog enriched with availability info.
13
+ * Each entry includes `available: boolean` and an optional `unavailableReason`.
14
+ * The `claude-code` provider checks for the `claude` CLI binary instead of an env var.
15
+ * Providers without a known env key mapping default to available.
16
+ */
17
+ export declare function getModelCatalogWithAvailability(): ModelWithAvailability[];
@@ -0,0 +1,112 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { createVercelProvider } from './vercel.js';
3
+ // ─── Model Catalog ───────────────────────────────────────────
4
+ const MODEL_CATALOG = [
5
+ // Claude Code models (via ai-sdk-provider-claude-code — uses Claude CLI binary, no API key)
6
+ { id: 'sonnet', label: 'Claude Sonnet', provider: 'claude-code' },
7
+ { id: 'opus', label: 'Claude Opus', provider: 'claude-code' },
8
+ { id: 'haiku', label: 'Claude Haiku', provider: 'claude-code' },
9
+ // Anthropic API models (@ai-sdk/anthropic — uses ANTHROPIC_API_KEY)
10
+ { id: 'claude-sonnet-4-5', label: 'Claude Sonnet 4.5', provider: 'anthropic' },
11
+ { id: 'claude-opus-4-5', label: 'Claude Opus 4.5', provider: 'anthropic' },
12
+ { id: 'claude-haiku-4-5', label: 'Claude Haiku 4.5', provider: 'anthropic' },
13
+ // OpenAI models (@ai-sdk/openai)
14
+ { id: 'gpt-5.2-codex', label: 'GPT-5.2 Codex', provider: 'openai' },
15
+ { id: 'gpt-5.1-codex', label: 'GPT-5.1 Codex', provider: 'openai' },
16
+ { id: 'gpt-5.2-pro', label: 'GPT-5.2 Pro', provider: 'openai' },
17
+ { id: 'gpt-5.2-chat-latest', label: 'GPT-5.2 Chat Latest', provider: 'openai' },
18
+ { id: 'gpt-5-nano', label: 'GPT-5 Nano', provider: 'openai' },
19
+ { id: 'gpt-5-mini', label: 'GPT-5 Mini', provider: 'openai' },
20
+ // Google AI models (@ai-sdk/google)
21
+ { id: 'gemini-3-pro-preview', label: 'Gemini 3 Pro', provider: 'google-ai' },
22
+ { id: 'gemini-3-flash-preview', label: 'Gemini 3 Flash', provider: 'google-ai' },
23
+ { id: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro', provider: 'google-ai' },
24
+ { id: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash', provider: 'google-ai' },
25
+ // Qwen models (qwen-ai-provider — uses DASHSCOPE_API_KEY)
26
+ { id: 'qwen-max', label: 'Qwen Max', provider: 'qwen' },
27
+ { id: 'qwen-plus-latest', label: 'Qwen Plus', provider: 'qwen' },
28
+ // MiniMax models (vercel-minimax-ai-provider — uses MINIMAX_API_KEY)
29
+ { id: 'MiniMax-M2', label: 'MiniMax M2', provider: 'minimax' },
30
+ // Vercel AI Gateway — Claude models via gateway (Claude Max / API key)
31
+ { id: 'anthropic/claude-sonnet-4-5', label: 'Sonnet 4.5 (Gateway)', provider: 'vercel-gateway' },
32
+ { id: 'anthropic/claude-opus-4-5', label: 'Opus 4.5 (Gateway)', provider: 'vercel-gateway' },
33
+ { id: 'anthropic/claude-sonnet-4', label: 'Sonnet 4 (Gateway)', provider: 'vercel-gateway' },
34
+ { id: 'anthropic/claude-opus-4', label: 'Opus 4 (Gateway)', provider: 'vercel-gateway' },
35
+ ];
36
+ export const PROVIDER_ENV_KEYS = {
37
+ // claude-code: uses Claude Code CLI binary, checked separately
38
+ anthropic: 'ANTHROPIC_API_KEY',
39
+ openai: 'OPENAI_API_KEY',
40
+ 'google-ai': 'GOOGLE_GENERATIVE_AI_API_KEY',
41
+ 'vercel-gateway': 'AI_GATEWAY_API_KEY',
42
+ qwen: 'DASHSCOPE_API_KEY',
43
+ minimax: 'MINIMAX_API_KEY',
44
+ };
45
+ /**
46
+ * Checks whether the `claude` CLI binary is available in PATH.
47
+ * Cached after first call since the binary won't appear/disappear mid-session.
48
+ */
49
+ let _claudeBinaryAvailable = null;
50
+ function isClaudeBinaryAvailable() {
51
+ if (_claudeBinaryAvailable !== null)
52
+ return _claudeBinaryAvailable;
53
+ try {
54
+ execSync('which claude', { stdio: 'ignore' });
55
+ _claudeBinaryAvailable = true;
56
+ }
57
+ catch {
58
+ _claudeBinaryAvailable = false;
59
+ }
60
+ return _claudeBinaryAvailable;
61
+ }
62
+ // ─── Provider Resolution ─────────────────────────────────────
63
+ export function resolveProvider(modelId) {
64
+ const model = MODEL_CATALOG.find(m => m.id === modelId);
65
+ if (!model) {
66
+ throw new Error(`Unknown model: ${modelId}. Use GET /api/models for available models.`);
67
+ }
68
+ let provider;
69
+ switch (model.provider) {
70
+ case 'claude-code':
71
+ case 'anthropic':
72
+ case 'openai':
73
+ case 'google-ai':
74
+ case 'vercel-gateway':
75
+ case 'qwen':
76
+ case 'minimax':
77
+ provider = createVercelProvider(modelId, model.provider);
78
+ break;
79
+ default:
80
+ throw new Error(`No provider implementation for: ${model.provider}`);
81
+ }
82
+ return { provider, modelProvider: model.provider };
83
+ }
84
+ /**
85
+ * Returns the model catalog enriched with availability info.
86
+ * Each entry includes `available: boolean` and an optional `unavailableReason`.
87
+ * The `claude-code` provider checks for the `claude` CLI binary instead of an env var.
88
+ * Providers without a known env key mapping default to available.
89
+ */
90
+ export function getModelCatalogWithAvailability() {
91
+ return MODEL_CATALOG.map((model) => {
92
+ // Claude Code provider: check for the `claude` binary, not an API key
93
+ if (model.provider === 'claude-code') {
94
+ const hasBinary = isClaudeBinaryAvailable();
95
+ return {
96
+ ...model,
97
+ available: hasBinary,
98
+ ...(!hasBinary && { unavailableReason: 'Claude Code CLI not installed' }),
99
+ };
100
+ }
101
+ const envKey = PROVIDER_ENV_KEYS[model.provider];
102
+ if (!envKey) {
103
+ return { ...model, available: true };
104
+ }
105
+ const hasKey = !!process.env[envKey];
106
+ return {
107
+ ...model,
108
+ available: hasKey,
109
+ ...(!hasKey && { unavailableReason: `${envKey} not set` }),
110
+ };
111
+ });
112
+ }
@@ -0,0 +1,17 @@
1
+ import type { SSEStreamingApi } from 'hono/streaming';
2
+ import type { ModelMessage, AssistantModelMessage, ToolModelMessage } from 'ai';
3
+ export type ResponseMessage = AssistantModelMessage | ToolModelMessage;
4
+ export interface ProviderConfig {
5
+ projectCwd: string;
6
+ targetPort: number;
7
+ /** When aborted, the provider should stop the LLM stream and exit early. */
8
+ signal?: AbortSignal;
9
+ }
10
+ export interface StreamProvider {
11
+ streamResponse(stream: SSEStreamingApi, messages: ModelMessage[], config: ProviderConfig): Promise<ResponseMessage[]>;
12
+ }
13
+ export interface ModelDefinition {
14
+ id: string;
15
+ label: string;
16
+ provider: 'claude-code' | 'anthropic' | 'openai' | 'google-ai' | 'vercel-gateway' | 'qwen' | 'minimax';
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { StreamProvider } from './types.js';
2
+ type VercelProviderType = 'claude-code' | 'anthropic' | 'openai' | 'google-ai' | 'vercel-gateway' | 'qwen' | 'minimax';
3
+ export declare function createVercelProvider(modelId: string, providerType: VercelProviderType): StreamProvider;
4
+ export {};