ebade 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -8
- package/ROADMAP.md +4 -4
- package/cli/scaffold.js +238 -3
- package/demo.gif +0 -0
- package/demo.mp4 +0 -0
- package/landing/index.html +31 -0
- package/landing/style.css +293 -24
- package/package.json +3 -1
- package/packages/vscode-extension/README.md +42 -0
- package/packages/vscode-extension/ebade-0.1.0.vsix +0 -0
- package/packages/vscode-extension/images/icon.svg +6 -0
- package/packages/vscode-extension/language-configuration.json +24 -0
- package/packages/vscode-extension/package.json +53 -0
- package/packages/vscode-extension/syntaxes/ebade.tmLanguage.json +54 -0
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
[](./packages/mcp-server)
|
|
9
9
|
[](./ROADMAP.md)
|
|
10
10
|
[](./docs/GREEN-AI.md)
|
|
11
|
+
[](./SYNTAX.md)
|
|
11
12
|
[](https://github.com/sponsors/hasankemaldemirci)
|
|
12
13
|
|
|
13
14
|
> **The first framework designed for AI agents, readable by humans.**
|
|
@@ -16,7 +17,12 @@
|
|
|
16
17
|
>
|
|
17
18
|
> *Capture the essence of code. Less tokens. Less carbon. Same result.* 🌱
|
|
18
19
|
|
|
20
|
+
## 🎬 See it in action
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
19
24
|
```typescript
|
|
25
|
+
|
|
20
26
|
// ❌ Before: 100+ lines of boilerplate
|
|
21
27
|
export default function CheckoutPage() {
|
|
22
28
|
const [cart, setCart] = useState([]);
|
|
@@ -65,18 +71,27 @@ Then AI agents can use:
|
|
|
65
71
|
### For Humans (CLI)
|
|
66
72
|
|
|
67
73
|
```bash
|
|
68
|
-
# Scaffold a new project
|
|
69
|
-
npx ebade scaffold
|
|
70
|
-
|
|
71
|
-
# Compile intents to code
|
|
72
|
-
npx ebade build
|
|
74
|
+
# Scaffold a new project from an ebade file
|
|
75
|
+
npx ebade scaffold examples/saas-dashboard.ebade.yaml ./my-app
|
|
73
76
|
|
|
74
|
-
#
|
|
75
|
-
npx ebade
|
|
77
|
+
# See all commands
|
|
78
|
+
npx ebade --help
|
|
76
79
|
```
|
|
77
80
|
|
|
78
81
|
---
|
|
79
82
|
|
|
83
|
+
## 🤖 Integrated AI Synergy
|
|
84
|
+
|
|
85
|
+
**ebade** projects automatically configure themselves for AI collaboration. When you scaffold a project, it generates specialized instruction files for major AI agents:
|
|
86
|
+
|
|
87
|
+
- **Cursor**: `.cursorrules`
|
|
88
|
+
- **Claude / Windsurf**: `.clauderules`
|
|
89
|
+
- **GitHub Copilot**: `.github/copilot-instructions.md`
|
|
90
|
+
|
|
91
|
+
These files teach the AI agents exactly how to work with ebade intents, ensuring they never "hallucinate" boilerplate and always stay token-efficient.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
80
95
|
## 📊 Benchmark: ~70% Fewer Tokens (Tested)
|
|
81
96
|
|
|
82
97
|
We measured token usage across common development tasks:
|
|
@@ -206,8 +221,9 @@ pages:
|
|
|
206
221
|
- search-bar
|
|
207
222
|
- product-grid
|
|
208
223
|
- pagination
|
|
209
|
-
|
|
224
|
+
|
|
210
225
|
- path: /checkout
|
|
226
|
+
|
|
211
227
|
intent: checkout-flow
|
|
212
228
|
auth: required
|
|
213
229
|
components:
|
package/ROADMAP.md
CHANGED
|
@@ -44,10 +44,10 @@ Replace string templates with actual AST-based compilation.
|
|
|
44
44
|
- [ ] Code generator (AST → React/Next.js)
|
|
45
45
|
- [ ] Support for multiple framework targets
|
|
46
46
|
|
|
47
|
-
### 1.5 CLI Improvements
|
|
47
|
+
### 1.5 CLI Improvements ✅
|
|
48
48
|
|
|
49
|
-
- [
|
|
50
|
-
- [
|
|
49
|
+
- [x] `ebade init` - interactive project setup
|
|
50
|
+
- [x] `ebade dev` - watch mode with local agent sync
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
@@ -122,7 +122,7 @@ Replace string templates with actual AST-based compilation.
|
|
|
122
122
|
|
|
123
123
|
## Current Status
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
### Phase 1 - Foundation (Nearly Complete)
|
|
126
126
|
|
|
127
127
|
The MCP server is live. CLI has premium UX. Two comprehensive examples (E-commerce + SaaS Dashboard) are ready. AI agents can now use ebade to scaffold full Next.js apps with **~70% fewer tokens**.
|
|
128
128
|
|
package/cli/scaffold.js
CHANGED
|
@@ -11,6 +11,8 @@ import fs from "fs";
|
|
|
11
11
|
import path from "path";
|
|
12
12
|
import yaml from "yaml";
|
|
13
13
|
import ora from "ora";
|
|
14
|
+
import prompts from "prompts";
|
|
15
|
+
import chokidar from "chokidar";
|
|
14
16
|
|
|
15
17
|
// ============================================
|
|
16
18
|
// ANSI Renk Kodları (Terminal çıktısı için)
|
|
@@ -472,6 +474,38 @@ body {
|
|
|
472
474
|
`;
|
|
473
475
|
}
|
|
474
476
|
|
|
477
|
+
function generateAgentRules(config) {
|
|
478
|
+
return `
|
|
479
|
+
# ebade Agent-First Framework Rules
|
|
480
|
+
|
|
481
|
+
You are an AI developer working on a project built with the **ebade Agent-First Framework**.
|
|
482
|
+
This project is designed specifically for AI-Human collaboration.
|
|
483
|
+
|
|
484
|
+
## 🧠 Core Philosophy
|
|
485
|
+
- **Intent > Implementation**: Focus on WHAT the code should do.
|
|
486
|
+
- **Source of Truth**: The structure is defined in \`project.ebade.yaml\`. Always refer to it before making structural changes.
|
|
487
|
+
- **Consistency**: All generated code should match the intents defined in \`app/\`, \`components/\`, and \`api/\`.
|
|
488
|
+
|
|
489
|
+
## 🛠 Framework Patterns
|
|
490
|
+
|
|
491
|
+
### 1. Decorators (Comments)
|
|
492
|
+
All files generated by ebade contain semantic decorators in their headers. Keep them intact:
|
|
493
|
+
- @page('/path'): Marks a Next.js Page.
|
|
494
|
+
- @intent('name'): Describes the purpose of the file.
|
|
495
|
+
- @requires(['components']): Lists dependencies.
|
|
496
|
+
|
|
497
|
+
### 2. Design System
|
|
498
|
+
- Use CSS Variables defined in \`app/globals.css\`.
|
|
499
|
+
- Prefer these tokens: var(--color-primary), var(--color-secondary), var(--radius-default).
|
|
500
|
+
|
|
501
|
+
## 🤝 AI Collaboration Guidelines
|
|
502
|
+
1. **When adding a new page**: First, suggest updating \`project.ebade.yaml\` if possible.
|
|
503
|
+
2. **When modifying components**: Ensure they remain decoupled and respect the design system props.
|
|
504
|
+
|
|
505
|
+
Built with ebade - The Agent-First Framework for the next era of development. 🌱
|
|
506
|
+
`;
|
|
507
|
+
}
|
|
508
|
+
|
|
475
509
|
// ============================================
|
|
476
510
|
// Utility Functions
|
|
477
511
|
// ============================================
|
|
@@ -665,6 +699,25 @@ function scaffold(ebadePath, outputDir) {
|
|
|
665
699
|
);
|
|
666
700
|
log.file("next-env.d.ts");
|
|
667
701
|
|
|
702
|
+
// Agent Rules
|
|
703
|
+
const agentRules = generateAgentRules(config).trim();
|
|
704
|
+
|
|
705
|
+
// .cursorrules (Cursor)
|
|
706
|
+
fs.writeFileSync(path.join(projectDir, ".cursorrules"), agentRules);
|
|
707
|
+
log.file(".cursorrules");
|
|
708
|
+
|
|
709
|
+
// .clauderules (Claude/Windsurf)
|
|
710
|
+
fs.writeFileSync(path.join(projectDir, ".clauderules"), agentRules);
|
|
711
|
+
log.file(".clauderules");
|
|
712
|
+
|
|
713
|
+
// GitHub Copilot instructions
|
|
714
|
+
ensureDir(path.join(projectDir, ".github"));
|
|
715
|
+
fs.writeFileSync(
|
|
716
|
+
path.join(projectDir, ".github/copilot-instructions.md"),
|
|
717
|
+
agentRules
|
|
718
|
+
);
|
|
719
|
+
log.file(".github/copilot-instructions.md");
|
|
720
|
+
|
|
668
721
|
// ========== Generate Database Schema ==========
|
|
669
722
|
if (config.data) {
|
|
670
723
|
log.section("Generating database schema");
|
|
@@ -740,17 +793,175 @@ ${colors.dim}Usage:${colors.reset}
|
|
|
740
793
|
npx ebade <command> [options]
|
|
741
794
|
|
|
742
795
|
${colors.dim}Commands:${colors.reset}
|
|
796
|
+
init Create a new ebade project interactively
|
|
743
797
|
scaffold <file> [output] Scaffold a project from ebade file
|
|
798
|
+
dev <file> [output] Watch ebade file and re-scaffold on changes
|
|
744
799
|
|
|
745
800
|
${colors.dim}Examples:${colors.reset}
|
|
746
|
-
npx ebade
|
|
747
|
-
npx ebade scaffold
|
|
801
|
+
npx ebade init
|
|
802
|
+
npx ebade scaffold examples/saas-dashboard.ebade.yaml ./output
|
|
803
|
+
npx ebade dev my-project.ebade.yaml ./my-app
|
|
748
804
|
|
|
749
805
|
${colors.dim}Learn more:${colors.reset}
|
|
750
806
|
https://ebade.dev
|
|
751
807
|
`);
|
|
752
808
|
}
|
|
753
809
|
|
|
810
|
+
// ============================================
|
|
811
|
+
// Init Command (Interactive Setup)
|
|
812
|
+
// ============================================
|
|
813
|
+
async function init() {
|
|
814
|
+
console.log(`
|
|
815
|
+
${LOGO}
|
|
816
|
+
`);
|
|
817
|
+
|
|
818
|
+
const response = await prompts([
|
|
819
|
+
{
|
|
820
|
+
type: "text",
|
|
821
|
+
name: "projectName",
|
|
822
|
+
message: "Project name:",
|
|
823
|
+
initial: "my-ebade-app",
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
type: "select",
|
|
827
|
+
name: "template",
|
|
828
|
+
message: "Choose a template:",
|
|
829
|
+
choices: [
|
|
830
|
+
{ title: "SaaS Dashboard", value: "saas-dashboard" },
|
|
831
|
+
{ title: "E-commerce", value: "ecommerce" },
|
|
832
|
+
{ title: "Landing Page", value: "landing" },
|
|
833
|
+
{ title: "Empty Project", value: "empty" },
|
|
834
|
+
],
|
|
835
|
+
},
|
|
836
|
+
{
|
|
837
|
+
type: "text",
|
|
838
|
+
name: "primaryColor",
|
|
839
|
+
message: "Primary color (hex):",
|
|
840
|
+
initial: "#6366f1",
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
type: "confirm",
|
|
844
|
+
name: "autoScaffold",
|
|
845
|
+
message: "Scaffold project now?",
|
|
846
|
+
initial: true,
|
|
847
|
+
},
|
|
848
|
+
]);
|
|
849
|
+
|
|
850
|
+
if (!response.projectName) {
|
|
851
|
+
console.log(`${colors.yellow}Cancelled.${colors.reset}`);
|
|
852
|
+
process.exit(0);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
const outputDir = `./${response.projectName}`;
|
|
856
|
+
ensureDir(outputDir);
|
|
857
|
+
|
|
858
|
+
let yamlContent;
|
|
859
|
+
if (response.template === "empty") {
|
|
860
|
+
yamlContent = `# ebade Project Configuration
|
|
861
|
+
# Generated by ebade init
|
|
862
|
+
|
|
863
|
+
project:
|
|
864
|
+
name: ${response.projectName}
|
|
865
|
+
type: custom
|
|
866
|
+
version: "1.0.0"
|
|
867
|
+
|
|
868
|
+
design:
|
|
869
|
+
style: minimal-modern
|
|
870
|
+
colors:
|
|
871
|
+
primary: "${response.primaryColor}"
|
|
872
|
+
secondary: "#f59e0b"
|
|
873
|
+
font: Inter
|
|
874
|
+
borderRadius: md
|
|
875
|
+
|
|
876
|
+
pages:
|
|
877
|
+
- path: /
|
|
878
|
+
intent: landing-page
|
|
879
|
+
components:
|
|
880
|
+
- hero-section
|
|
881
|
+
|
|
882
|
+
api: []
|
|
883
|
+
data: []
|
|
884
|
+
`;
|
|
885
|
+
} else {
|
|
886
|
+
// Get the directory of the current script (cli/scaffold.js)
|
|
887
|
+
const scriptDir = path.dirname(new URL(import.meta.url).pathname);
|
|
888
|
+
const templatePath = path.join(
|
|
889
|
+
scriptDir,
|
|
890
|
+
"..",
|
|
891
|
+
"examples",
|
|
892
|
+
response.template === "saas-dashboard"
|
|
893
|
+
? "saas-dashboard.ebade.yaml"
|
|
894
|
+
: "ecommerce.ebade.yaml"
|
|
895
|
+
);
|
|
896
|
+
if (fs.existsSync(templatePath)) {
|
|
897
|
+
yamlContent = fs.readFileSync(templatePath, "utf-8");
|
|
898
|
+
yamlContent = yamlContent.replace(
|
|
899
|
+
/name: .*/,
|
|
900
|
+
`name: ${response.projectName}`
|
|
901
|
+
);
|
|
902
|
+
} else {
|
|
903
|
+
console.error(
|
|
904
|
+
`${colors.red}Error:${colors.reset} Template not found. Using empty template.`
|
|
905
|
+
);
|
|
906
|
+
yamlContent = `project:\n name: ${response.projectName}\n type: custom\n`;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
const ebadeFilePath = path.join(outputDir, "project.ebade.yaml");
|
|
911
|
+
fs.writeFileSync(ebadeFilePath, yamlContent);
|
|
912
|
+
|
|
913
|
+
console.log(`
|
|
914
|
+
${colors.green}✓${colors.reset} Created ${colors.cyan}${ebadeFilePath}${colors.reset}
|
|
915
|
+
`);
|
|
916
|
+
|
|
917
|
+
if (response.autoScaffold) {
|
|
918
|
+
scaffold(ebadeFilePath, outputDir);
|
|
919
|
+
} else {
|
|
920
|
+
console.log(`
|
|
921
|
+
${colors.dim}Next steps:${colors.reset}
|
|
922
|
+
${colors.gray}1.${colors.reset} Edit ${colors.cyan}${ebadeFilePath}${colors.reset}
|
|
923
|
+
${colors.gray}2.${colors.reset} Run ${colors.cyan}npx ebade scaffold ${ebadeFilePath} ${outputDir}${colors.reset}
|
|
924
|
+
`);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// ============================================
|
|
929
|
+
// Dev Command (Watch Mode)
|
|
930
|
+
// ============================================
|
|
931
|
+
function dev(ebadeFile, outputDir) {
|
|
932
|
+
console.log(`
|
|
933
|
+
${LOGO}
|
|
934
|
+
`);
|
|
935
|
+
|
|
936
|
+
console.log(
|
|
937
|
+
`${colors.cyan}👀 Watching${colors.reset} ${colors.bright}${ebadeFile}${colors.reset} for changes...\n`
|
|
938
|
+
);
|
|
939
|
+
console.log(`${colors.dim}Press Ctrl+C to stop.${colors.reset}\n`);
|
|
940
|
+
|
|
941
|
+
// Initial scaffold
|
|
942
|
+
scaffold(ebadeFile, outputDir);
|
|
943
|
+
|
|
944
|
+
// Watch for changes
|
|
945
|
+
const watcher = chokidar.watch(ebadeFile, {
|
|
946
|
+
persistent: true,
|
|
947
|
+
ignoreInitial: true,
|
|
948
|
+
});
|
|
949
|
+
|
|
950
|
+
watcher.on("change", () => {
|
|
951
|
+
console.log(
|
|
952
|
+
`\n${colors.yellow}⚡ Change detected!${colors.reset} Re-scaffolding...\n`
|
|
953
|
+
);
|
|
954
|
+
scaffold(ebadeFile, outputDir);
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
watcher.on("error", (error) => {
|
|
958
|
+
console.error(`${colors.red}Watcher error:${colors.reset}`, error);
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// ============================================
|
|
963
|
+
// Command Router
|
|
964
|
+
// ============================================
|
|
754
965
|
if (
|
|
755
966
|
args.length === 0 ||
|
|
756
967
|
command === "help" ||
|
|
@@ -761,7 +972,9 @@ if (
|
|
|
761
972
|
process.exit(0);
|
|
762
973
|
}
|
|
763
974
|
|
|
764
|
-
if (command === "
|
|
975
|
+
if (command === "init") {
|
|
976
|
+
await init();
|
|
977
|
+
} else if (command === "scaffold") {
|
|
765
978
|
const ebadeFile = args[1];
|
|
766
979
|
const outputDir = args[2] || "./output";
|
|
767
980
|
|
|
@@ -783,6 +996,28 @@ if (command === "scaffold") {
|
|
|
783
996
|
}
|
|
784
997
|
|
|
785
998
|
scaffold(ebadeFile, outputDir);
|
|
999
|
+
} else if (command === "dev") {
|
|
1000
|
+
const ebadeFile = args[1];
|
|
1001
|
+
const outputDir = args[2] || "./output";
|
|
1002
|
+
|
|
1003
|
+
if (!ebadeFile) {
|
|
1004
|
+
console.error(
|
|
1005
|
+
`${colors.red}Error:${colors.reset} Please provide an ebade file path.`
|
|
1006
|
+
);
|
|
1007
|
+
console.log(
|
|
1008
|
+
`\n${colors.dim}Usage:${colors.reset} npx ebade dev <file.ebade.yaml> [output-dir]\n`
|
|
1009
|
+
);
|
|
1010
|
+
process.exit(1);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
if (!fs.existsSync(ebadeFile)) {
|
|
1014
|
+
console.error(
|
|
1015
|
+
`${colors.red}Error:${colors.reset} ebade file not found: ${ebadeFile}`
|
|
1016
|
+
);
|
|
1017
|
+
process.exit(1);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
dev(ebadeFile, outputDir);
|
|
786
1021
|
} else {
|
|
787
1022
|
console.error(
|
|
788
1023
|
`${colors.red}Error:${colors.reset} Unknown command: ${command}`
|
package/demo.gif
CHANGED
|
Binary file
|
package/demo.mp4
CHANGED
|
Binary file
|
package/landing/index.html
CHANGED
|
@@ -226,6 +226,37 @@
|
|
|
226
226
|
</section>
|
|
227
227
|
</main>
|
|
228
228
|
|
|
229
|
+
<footer class="site-footer">
|
|
230
|
+
<div class="footer-container">
|
|
231
|
+
<div class="footer-brand">
|
|
232
|
+
<div class="footer-logo">🧠 ebade</div>
|
|
233
|
+
<p class="footer-slogan">Capture the essence of code.<br>Less tokens. Less carbon. Same result. 🌱</p>
|
|
234
|
+
</div>
|
|
235
|
+
<div class="footer-links">
|
|
236
|
+
<div class="footer-column">
|
|
237
|
+
<h4>Product</h4>
|
|
238
|
+
<a href="#technology">Technology</a>
|
|
239
|
+
<a href="#benchmarks">Benchmarks</a>
|
|
240
|
+
<a href="https://github.com/hasankemaldemirci/ebade/tree/main/examples" target="_blank">Examples</a>
|
|
241
|
+
</div>
|
|
242
|
+
<div class="footer-column">
|
|
243
|
+
<h4>Resources</h4>
|
|
244
|
+
<a href="https://github.com/hasankemaldemirci/ebade" target="_blank">GitHub</a>
|
|
245
|
+
<a href="https://www.npmjs.com/package/ebade" target="_blank">npm</a>
|
|
246
|
+
<a href="https://github.com/hasankemaldemirci/ebade/blob/main/ROADMAP.md" target="_blank">Roadmap</a>
|
|
247
|
+
</div>
|
|
248
|
+
<div class="footer-column">
|
|
249
|
+
<h4>Contact</h4>
|
|
250
|
+
<a href="mailto:hello@ebade.dev">hello@ebade.dev</a>
|
|
251
|
+
<a href="https://github.com/sponsors/hasankemaldemirci" target="_blank">Sponsor 💜</a>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
<div class="footer-bottom">
|
|
256
|
+
<p>© 2026 ebade. The Agent-First Framework.</p>
|
|
257
|
+
<p class="footer-tagline">Code = f(Intent) // Kind to Earth 🌍</p>
|
|
258
|
+
</div>
|
|
259
|
+
</footer>
|
|
229
260
|
|
|
230
261
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
|
|
231
262
|
<script src="main.js"></script>
|
package/landing/style.css
CHANGED
|
@@ -111,22 +111,13 @@ body {
|
|
|
111
111
|
.nav-github {
|
|
112
112
|
display: flex;
|
|
113
113
|
align-items: center;
|
|
114
|
-
gap: 0.
|
|
115
|
-
padding: 0.3rem 0.6rem;
|
|
116
|
-
border-radius: 6px;
|
|
117
|
-
transition: all 0.2s ease;
|
|
118
|
-
border: 1px solid transparent;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.nav-github:hover {
|
|
122
|
-
background: rgba(0, 0, 0, 0.03);
|
|
123
|
-
border-color: rgba(0, 0, 0, 0.05);
|
|
114
|
+
gap: 0.4rem;
|
|
124
115
|
}
|
|
125
116
|
|
|
126
117
|
.nav-github i,
|
|
127
118
|
.nav-github svg {
|
|
128
|
-
width:
|
|
129
|
-
height:
|
|
119
|
+
width: 16px;
|
|
120
|
+
height: 16px;
|
|
130
121
|
}
|
|
131
122
|
|
|
132
123
|
.star-icon-nav {
|
|
@@ -577,40 +568,318 @@ h1 span {
|
|
|
577
568
|
}
|
|
578
569
|
|
|
579
570
|
/* Footer */
|
|
580
|
-
.
|
|
581
|
-
|
|
582
|
-
|
|
571
|
+
.site-footer {
|
|
572
|
+
background: #000;
|
|
573
|
+
color: #fff;
|
|
574
|
+
padding: 6rem 3rem 2rem;
|
|
575
|
+
position: relative;
|
|
576
|
+
z-index: 10;
|
|
583
577
|
}
|
|
584
578
|
|
|
585
|
-
.footer-
|
|
579
|
+
.footer-container {
|
|
580
|
+
max-width: 1400px;
|
|
581
|
+
margin: 0 auto;
|
|
586
582
|
display: flex;
|
|
587
583
|
justify-content: space-between;
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
584
|
+
gap: 4rem;
|
|
585
|
+
flex-wrap: wrap;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
.footer-brand {
|
|
589
|
+
max-width: 300px;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.footer-logo {
|
|
593
|
+
font-size: 1.5rem;
|
|
594
|
+
font-weight: 900;
|
|
595
|
+
margin-bottom: 1rem;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.footer-slogan {
|
|
599
|
+
color: rgba(255, 255, 255, 0.5);
|
|
600
|
+
font-size: 0.95rem;
|
|
601
|
+
line-height: 1.6;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.footer-links {
|
|
605
|
+
display: flex;
|
|
606
|
+
gap: 5rem;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.footer-column {
|
|
610
|
+
display: flex;
|
|
611
|
+
flex-direction: column;
|
|
612
|
+
gap: 0.75rem;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
.footer-column h4 {
|
|
616
|
+
font-size: 0.8rem;
|
|
617
|
+
text-transform: uppercase;
|
|
618
|
+
letter-spacing: 1px;
|
|
619
|
+
color: rgba(255, 255, 255, 0.4);
|
|
620
|
+
margin-bottom: 0.5rem;
|
|
591
621
|
}
|
|
592
622
|
|
|
593
|
-
.
|
|
594
|
-
|
|
623
|
+
.footer-column a {
|
|
624
|
+
color: rgba(255, 255, 255, 0.7);
|
|
595
625
|
text-decoration: none;
|
|
596
|
-
|
|
626
|
+
font-size: 0.95rem;
|
|
627
|
+
transition: color 0.2s;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
.footer-column a:hover {
|
|
631
|
+
color: var(--primary);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.footer-bottom {
|
|
635
|
+
max-width: 1400px;
|
|
636
|
+
margin: 4rem auto 0;
|
|
637
|
+
padding-top: 2rem;
|
|
638
|
+
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
|
639
|
+
display: flex;
|
|
640
|
+
justify-content: space-between;
|
|
641
|
+
font-size: 0.85rem;
|
|
642
|
+
color: rgba(255, 255, 255, 0.4);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
.footer-tagline {
|
|
646
|
+
font-family: var(--font-mono);
|
|
647
|
+
color: var(--accent-emerald);
|
|
597
648
|
}
|
|
598
649
|
|
|
599
650
|
@media (max-width: 1024px) {
|
|
600
651
|
h1 {
|
|
601
652
|
font-size: 4rem;
|
|
602
653
|
}
|
|
654
|
+
|
|
603
655
|
.grid-3 {
|
|
604
656
|
grid-template-columns: 1fr;
|
|
605
657
|
}
|
|
658
|
+
|
|
606
659
|
.comparison-modern {
|
|
607
|
-
|
|
660
|
+
grid-template-columns: 1fr;
|
|
661
|
+
gap: 1rem;
|
|
608
662
|
}
|
|
663
|
+
|
|
664
|
+
.transform-arrow {
|
|
665
|
+
padding: 1rem 0;
|
|
666
|
+
}
|
|
667
|
+
|
|
609
668
|
.stats-box {
|
|
610
669
|
flex-direction: column;
|
|
611
|
-
gap:
|
|
670
|
+
gap: 3rem;
|
|
671
|
+
padding: 3rem 2rem;
|
|
612
672
|
}
|
|
673
|
+
|
|
613
674
|
.stat-divider {
|
|
614
675
|
display: none;
|
|
615
676
|
}
|
|
616
677
|
}
|
|
678
|
+
|
|
679
|
+
@media (max-width: 768px) {
|
|
680
|
+
/* Nav - Simplified for mobile */
|
|
681
|
+
.full-nav {
|
|
682
|
+
padding: 1rem 1.5rem;
|
|
683
|
+
flex-direction: column;
|
|
684
|
+
gap: 0.75rem;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
.logo {
|
|
688
|
+
font-size: 1.3rem;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
.nav-links {
|
|
692
|
+
width: 100%;
|
|
693
|
+
justify-content: center;
|
|
694
|
+
gap: 0.75rem;
|
|
695
|
+
flex-wrap: wrap;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.nav-links a {
|
|
699
|
+
font-size: 0.8rem;
|
|
700
|
+
padding: 0.4rem 0.6rem;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
.nav-github span {
|
|
704
|
+
display: none; /* Hide "GitHub" text, show only icon */
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
.nav-cta {
|
|
708
|
+
padding: 0.5rem 1rem;
|
|
709
|
+
font-size: 0.8rem;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/* Hero */
|
|
713
|
+
.hero-full {
|
|
714
|
+
padding: 0 1.5rem;
|
|
715
|
+
padding-top: 120px; /* Account for stacked nav */
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
h1 {
|
|
719
|
+
font-size: 2.5rem;
|
|
720
|
+
margin-bottom: 1.5rem;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.hero-description {
|
|
724
|
+
font-size: 1rem;
|
|
725
|
+
margin-bottom: 2.5rem;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.hero-actions {
|
|
729
|
+
flex-direction: column;
|
|
730
|
+
gap: 1rem;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
.btn-glow,
|
|
734
|
+
.btn-minimal {
|
|
735
|
+
width: 100%;
|
|
736
|
+
justify-content: center;
|
|
737
|
+
padding: 1rem 2rem;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
.scroll-indicator {
|
|
741
|
+
display: none;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/* Sections */
|
|
745
|
+
.section-dark {
|
|
746
|
+
border-radius: 30px 30px 0 0;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
.section-container {
|
|
750
|
+
padding: 4rem 1.5rem;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
.section-header h2 {
|
|
754
|
+
font-size: 2.5rem;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
.section-header p {
|
|
758
|
+
font-size: 1rem;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/* Transform Arrow - Vertical connecting both cards */
|
|
762
|
+
.transform-arrow {
|
|
763
|
+
padding: 1.5rem 0;
|
|
764
|
+
height: auto;
|
|
765
|
+
margin: 0;
|
|
766
|
+
z-index: 0;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
.transform-arrow::after {
|
|
770
|
+
/* Reset horizontal positioning */
|
|
771
|
+
top: -100px;
|
|
772
|
+
bottom: -100px;
|
|
773
|
+
left: 50%;
|
|
774
|
+
right: auto;
|
|
775
|
+
/* Make it vertical */
|
|
776
|
+
width: 2px;
|
|
777
|
+
height: 300px;
|
|
778
|
+
/* Center and position behind cards */
|
|
779
|
+
transform: translateX(-50%);
|
|
780
|
+
z-index: -1;
|
|
781
|
+
/* Vertical gradient */
|
|
782
|
+
background: linear-gradient(
|
|
783
|
+
to bottom,
|
|
784
|
+
transparent,
|
|
785
|
+
rgba(79, 70, 229, 0.5),
|
|
786
|
+
transparent
|
|
787
|
+
);
|
|
788
|
+
background-size: 100% 100%;
|
|
789
|
+
animation: none;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
.transform-arrow i,
|
|
793
|
+
.transform-arrow svg {
|
|
794
|
+
width: 32px;
|
|
795
|
+
height: 32px;
|
|
796
|
+
transform: rotate(90deg);
|
|
797
|
+
animation: none;
|
|
798
|
+
z-index: 5;
|
|
799
|
+
position: relative;
|
|
800
|
+
background: #0d1117;
|
|
801
|
+
border-radius: 50%;
|
|
802
|
+
padding: 6px;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/* Code Cards - ensure they're above the line */
|
|
806
|
+
.code-card {
|
|
807
|
+
position: relative;
|
|
808
|
+
z-index: 2;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/* Code Cards */
|
|
812
|
+
.code-card pre {
|
|
813
|
+
padding: 1rem;
|
|
814
|
+
font-size: 0.75rem;
|
|
815
|
+
overflow-x: auto;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
/* Stats */
|
|
819
|
+
.stat .val {
|
|
820
|
+
font-size: 3rem;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/* Features */
|
|
824
|
+
.feature-item {
|
|
825
|
+
padding: 2rem;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
.feature-item h3 {
|
|
829
|
+
font-size: 1.4rem;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/* Footer */
|
|
833
|
+
.site-footer {
|
|
834
|
+
padding: 4rem 1.5rem 2rem;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
.footer-container {
|
|
838
|
+
flex-direction: column;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
.footer-brand {
|
|
842
|
+
max-width: 100%;
|
|
843
|
+
text-align: center;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
.footer-links {
|
|
847
|
+
flex-wrap: wrap;
|
|
848
|
+
gap: 2rem;
|
|
849
|
+
justify-content: center;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
.footer-column {
|
|
853
|
+
text-align: center;
|
|
854
|
+
min-width: 120px;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
.footer-bottom {
|
|
858
|
+
flex-direction: column;
|
|
859
|
+
gap: 0.5rem;
|
|
860
|
+
text-align: center;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
@media (max-width: 480px) {
|
|
865
|
+
.logo {
|
|
866
|
+
font-size: 1.25rem;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
h1 {
|
|
870
|
+
font-size: 2rem;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
.badge-modern {
|
|
874
|
+
font-size: 0.65rem;
|
|
875
|
+
padding: 0.4rem 0.75rem;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
.section-header h2 {
|
|
879
|
+
font-size: 2rem;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.stat .val {
|
|
883
|
+
font-size: 2.5rem;
|
|
884
|
+
}
|
|
885
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ebade",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "ebade - Agent-First Framework. The first framework designed for AI agents, readable by humans.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "cli/scaffold.js",
|
|
@@ -35,7 +35,9 @@
|
|
|
35
35
|
"url": "https://github.com/hasankemaldemirci/ebade/issues"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
+
"chokidar": "^5.0.0",
|
|
38
39
|
"ora": "^9.0.0",
|
|
40
|
+
"prompts": "^2.4.2",
|
|
39
41
|
"yaml": "^2.3.4"
|
|
40
42
|
},
|
|
41
43
|
"engines": {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# ebade VS Code Extension
|
|
2
|
+
|
|
3
|
+
Syntax highlighting, snippets, and language support for `.ebade.yaml` files.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
### 🎨 Syntax Highlighting
|
|
8
|
+
- Keywords: `project`, `pages`, `api`, `data`, `design`
|
|
9
|
+
- Decorators: `@page`, `@intent`, `@requires`
|
|
10
|
+
- Strings, numbers, booleans
|
|
11
|
+
- Comments
|
|
12
|
+
|
|
13
|
+
### ✨ Snippets
|
|
14
|
+
| Prefix | Description |
|
|
15
|
+
|--------|-------------|
|
|
16
|
+
| `ebade-project` | Full project template |
|
|
17
|
+
| `ebade-page` | New page definition |
|
|
18
|
+
| `ebade-api` | New API endpoint |
|
|
19
|
+
| `ebade-data` | New data model |
|
|
20
|
+
| `ebade-component` | Component reference |
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
### From VSIX (Local)
|
|
25
|
+
```bash
|
|
26
|
+
cd packages/vscode-extension
|
|
27
|
+
npx vsce package
|
|
28
|
+
code --install-extension ebade-*.vsix
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### From Marketplace (Coming Soon)
|
|
32
|
+
Search for "ebade" in VS Code Extensions.
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
1. Create a file with `.ebade.yaml` extension
|
|
37
|
+
2. Start typing `ebade-` to see available snippets
|
|
38
|
+
3. Enjoy syntax highlighting! 🎉
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
Built with 💜 by the ebade team.
|
|
Binary file
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
2
|
+
<rect width="32" height="32" rx="6" fill="#4F46E5"/>
|
|
3
|
+
<text x="50%" y="52%" dominant-baseline="middle" text-anchor="middle"
|
|
4
|
+
font-family="system-ui, -apple-system, sans-serif"
|
|
5
|
+
font-size="22" font-weight="900" fill="white">e</text>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comments": {
|
|
3
|
+
"lineComment": "#"
|
|
4
|
+
},
|
|
5
|
+
"brackets": [
|
|
6
|
+
["{", "}"],
|
|
7
|
+
["[", "]"]
|
|
8
|
+
],
|
|
9
|
+
"autoClosingPairs": [
|
|
10
|
+
{ "open": "{", "close": "}" },
|
|
11
|
+
{ "open": "[", "close": "]" },
|
|
12
|
+
{ "open": "\"", "close": "\"" },
|
|
13
|
+
{ "open": "'", "close": "'" }
|
|
14
|
+
],
|
|
15
|
+
"surroundingPairs": [
|
|
16
|
+
["{", "}"],
|
|
17
|
+
["[", "]"],
|
|
18
|
+
["\"", "\""],
|
|
19
|
+
["'", "'"]
|
|
20
|
+
],
|
|
21
|
+
"folding": {
|
|
22
|
+
"offSide": true
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ebade",
|
|
3
|
+
"displayName": "ebade - Agent-First Framework",
|
|
4
|
+
"description": "Syntax highlighting and snippets for ebade (.ebade.yaml) files",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"publisher": "hasankemaldemirci",
|
|
7
|
+
"engines": {
|
|
8
|
+
"vscode": "^1.85.0"
|
|
9
|
+
},
|
|
10
|
+
"categories": [
|
|
11
|
+
"Programming Languages",
|
|
12
|
+
"Snippets"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"ebade",
|
|
16
|
+
"agent-first",
|
|
17
|
+
"ai",
|
|
18
|
+
"yaml",
|
|
19
|
+
"framework"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/hasankemaldemirci/ebade"
|
|
24
|
+
},
|
|
25
|
+
"contributes": {
|
|
26
|
+
"languages": [
|
|
27
|
+
{
|
|
28
|
+
"id": "ebade",
|
|
29
|
+
"aliases": [
|
|
30
|
+
"ebade",
|
|
31
|
+
"ebade-yaml"
|
|
32
|
+
],
|
|
33
|
+
"extensions": [
|
|
34
|
+
".ebade.yaml"
|
|
35
|
+
],
|
|
36
|
+
"configuration": "./language-configuration.json"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"grammars": [
|
|
40
|
+
{
|
|
41
|
+
"language": "ebade",
|
|
42
|
+
"scopeName": "source.ebade",
|
|
43
|
+
"path": "./syntaxes/ebade.tmLanguage.json"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"snippets": [
|
|
47
|
+
{
|
|
48
|
+
"language": "ebade",
|
|
49
|
+
"path": "./snippets/ebade.json"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ebade",
|
|
3
|
+
"scopeName": "source.ebade",
|
|
4
|
+
"fileTypes": ["ebade.yaml"],
|
|
5
|
+
"patterns": [
|
|
6
|
+
{ "include": "#comments" },
|
|
7
|
+
{ "include": "#keywords" },
|
|
8
|
+
{ "include": "#decorators" },
|
|
9
|
+
{ "include": "#strings" },
|
|
10
|
+
{ "include": "#numbers" },
|
|
11
|
+
{ "include": "#booleans" },
|
|
12
|
+
{ "include": "#keys" }
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"comments": {
|
|
16
|
+
"match": "#.*$",
|
|
17
|
+
"name": "comment.line.number-sign.ebade"
|
|
18
|
+
},
|
|
19
|
+
"keywords": {
|
|
20
|
+
"match": "\\b(project|pages|api|data|design|auth|components|intent|path|methods|outcomes|requires|style|colors|font|borderRadius|type|version|name)\\b",
|
|
21
|
+
"name": "keyword.control.ebade"
|
|
22
|
+
},
|
|
23
|
+
"decorators": {
|
|
24
|
+
"match": "@(page|intent|requires|outcomes|data|validate|style|compose|on|expects)\\b",
|
|
25
|
+
"name": "entity.name.function.decorator.ebade"
|
|
26
|
+
},
|
|
27
|
+
"strings": {
|
|
28
|
+
"patterns": [
|
|
29
|
+
{
|
|
30
|
+
"match": "'[^']*'",
|
|
31
|
+
"name": "string.quoted.single.ebade"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"match": "\"[^\"]*\"",
|
|
35
|
+
"name": "string.quoted.double.ebade"
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
"numbers": {
|
|
40
|
+
"match": "\\b[0-9]+\\.?[0-9]*\\b",
|
|
41
|
+
"name": "constant.numeric.ebade"
|
|
42
|
+
},
|
|
43
|
+
"booleans": {
|
|
44
|
+
"match": "\\b(true|false|required|optional|public|private)\\b",
|
|
45
|
+
"name": "constant.language.ebade"
|
|
46
|
+
},
|
|
47
|
+
"keys": {
|
|
48
|
+
"match": "^\\s*-?\\s*([a-zA-Z_][a-zA-Z0-9_-]*)\\s*:",
|
|
49
|
+
"captures": {
|
|
50
|
+
"1": { "name": "variable.other.key.ebade" }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|