vibe-engineering 0.1.7__py3-none-any.whl

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.
src/__init__.py ADDED
File without changes
src/cli/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ """CLI module for command-line interface."""
2
+ from .commands import app
3
+
4
+ __all__ = ["app"]
src/cli/commands.py ADDED
@@ -0,0 +1,224 @@
1
+ """CLI commands for vibe-engineering."""
2
+ import typer
3
+ from rich.console import Console
4
+ from rich.table import Table
5
+ from rich.panel import Panel
6
+ from rich.text import Text
7
+ from rich.progress import Progress, SpinnerColumn, TextColumn
8
+ from rich import box
9
+ import time
10
+
11
+ from src.db import MongoDBClient, get_documents
12
+ from src.llm import FireworksClient
13
+ from src.schemas import SpecifySchema
14
+
15
+ app = typer.Typer(
16
+ name="vibe",
17
+ help="🚀 Vibe Engineering - AI-powered specification and memory management CLI",
18
+ add_completion=False,
19
+ rich_markup_mode="rich"
20
+ )
21
+
22
+
23
+ @app.command()
24
+ def status():
25
+ """🔍 Show system status and configuration."""
26
+ console = Console()
27
+
28
+ console.print("\n[bold blue]🚀 Vibe Engineering Status[/bold blue]\n")
29
+
30
+ # System status panel
31
+ status_info = "[green]✅ CLI Active[/green]\n"
32
+ status_info += "[cyan]Version:[/cyan] 0.1.0\n"
33
+ status_info += "[cyan]Environment:[/cyan] Production"
34
+
35
+ status_panel = Panel(
36
+ status_info,
37
+ title="📊 System Status",
38
+ border_style="blue",
39
+ box=box.ROUNDED
40
+ )
41
+ console.print(status_panel)
42
+
43
+ # Quick help
44
+ help_text = """[yellow]💡 Quick Commands:[/yellow]
45
+
46
+ • [cyan]vibe team[/cyan] Show team members
47
+ • [cyan]vibe specify[/cyan] Generate specifications
48
+ • [cyan]vibe status[/cyan] Show this status
49
+ • [cyan]vibe --help[/cyan] Full command list"""
50
+
51
+ help_panel = Panel(
52
+ help_text,
53
+ title="🆘 Quick Help",
54
+ border_style="yellow",
55
+ box=box.ROUNDED
56
+ )
57
+ console.print(help_panel)
58
+
59
+
60
+ @app.command()
61
+ def version():
62
+ """📦 Show version information."""
63
+ console = Console()
64
+
65
+ version_text = Text("🚀 Vibe Engineering v0.1.0", style="bold blue")
66
+ console.print(Panel(version_text, box=box.DOUBLE))
67
+
68
+
69
+ @app.command()
70
+ def team():
71
+ """👥 Display the team members from the database."""
72
+ console = Console()
73
+
74
+ with Progress(
75
+ SpinnerColumn(),
76
+ TextColumn("[progress.description]{task.description}"),
77
+ console=console
78
+ ) as progress:
79
+ task = progress.add_task("Loading team members...", total=None)
80
+
81
+ try:
82
+ with MongoDBClient() as db_client:
83
+ documents = get_documents(
84
+ db_client=db_client,
85
+ db_name="master",
86
+ collection_name="team",
87
+ query={}
88
+ )
89
+ team_members = [doc["name"] for doc in documents]
90
+ progress.update(task, completed=True)
91
+
92
+ if not team_members:
93
+ console.print("\n[red]❌ No team members found.[/red]")
94
+ console.print("[yellow]💡 Tip: Check your database connection and team collection[/yellow]")
95
+ return
96
+
97
+ # Create a beautiful table
98
+ table = Table(
99
+ title="🚀 Vibe Engineering Team",
100
+ title_style="bold magenta",
101
+ box=box.ROUNDED,
102
+ show_header=True,
103
+ header_style="bold blue"
104
+ )
105
+ table.add_column("#", style="cyan", justify="center", width=4)
106
+ table.add_column("👤 Name", style="green", justify="left")
107
+ table.add_column("📊 Status", style="bright_blue", justify="center")
108
+ table.add_column("🕒 Last Seen", style="yellow", justify="center")
109
+
110
+ # Add team members to the table
111
+ for i, member in enumerate(team_members, 1):
112
+ table.add_row(
113
+ str(i),
114
+ member,
115
+ "✨ Active",
116
+ "Just now"
117
+ )
118
+
119
+ # Display the table with some extra styling
120
+ console.print()
121
+ console.print(table)
122
+
123
+ # Summary panel
124
+ summary = f"[bold green]Total Members:[/bold green] {len(team_members)}\n"
125
+ summary += "[bold blue]All Active:[/bold blue] ✅\n"
126
+ summary += "[bold yellow]Team Health:[/bold yellow] 🟢 Excellent"
127
+
128
+ summary_panel = Panel(
129
+ summary,
130
+ title="📈 Team Summary",
131
+ border_style="green",
132
+ box=box.ROUNDED
133
+ )
134
+ console.print(summary_panel)
135
+
136
+ except Exception as e:
137
+ progress.update(task, completed=True)
138
+ console.print(f"\n[red]❌ Error loading team:[/red] {e}")
139
+ console.print("[yellow]💡 Check your MongoDB connection and configuration[/yellow]")
140
+
141
+
142
+ @app.command()
143
+ def specify(
144
+ prompt: str = typer.Argument(..., help="The specification prompt to process"),
145
+ output_format: str = typer.Option("json", "--format", "-f", help="Output format: json, yaml, markdown"),
146
+ save: bool = typer.Option(False, "--save", "-s", help="Save the specification to database"),
147
+ verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output")
148
+ ):
149
+ """✨ Generate a specification schema using AI."""
150
+ console = Console()
151
+
152
+ console.print(f"\n[bold blue]✨ Generating Specification[/bold blue]\n")
153
+
154
+ if verbose:
155
+ console.print(f"[cyan]📝 Prompt:[/cyan] {prompt}")
156
+ console.print(f"[cyan]📄 Format:[/cyan] {output_format}")
157
+ console.print(f"[cyan]💾 Save:[/cyan] {'Yes' if save else 'No'}")
158
+ console.print()
159
+
160
+ with Progress(
161
+ SpinnerColumn(),
162
+ TextColumn("[progress.description]{task.description}"),
163
+ console=console
164
+ ) as progress:
165
+ task = progress.add_task("🤖 Processing with AI...", total=None)
166
+
167
+ try:
168
+ llm_client = FireworksClient()
169
+ response = llm_client.generate_with_schema(
170
+ prompt=prompt,
171
+ schema=SpecifySchema.model_json_schema(),
172
+ schema_name="SpecifySchema",
173
+ )
174
+ progress.update(task, completed=True)
175
+
176
+ # Display results
177
+ console.print()
178
+ result_panel = Panel(
179
+ response,
180
+ title="📋 Generated Specification",
181
+ border_style="green",
182
+ box=box.ROUNDED
183
+ )
184
+ console.print(result_panel)
185
+
186
+ if save:
187
+ console.print("\n[yellow]💾 Saving to database...[/yellow]")
188
+ # TODO: Implement save functionality
189
+ console.print("[green]✅ Specification saved successfully![/green]")
190
+
191
+ # Next steps
192
+ next_steps = """[yellow]💡 Next Steps:[/yellow]
193
+
194
+ • Review and refine the specification
195
+ • Save to database with [cyan]--save[/cyan] flag
196
+ • Use [cyan]vibe plan[/cyan] to create implementation plan
197
+ • Generate tasks with [cyan]vibe tasks[/cyan]"""
198
+
199
+ steps_panel = Panel(
200
+ next_steps,
201
+ title="🚀 What's Next?",
202
+ border_style="yellow",
203
+ box=box.ROUNDED
204
+ )
205
+ console.print(steps_panel)
206
+
207
+ except Exception as e:
208
+ progress.update(task, completed=True)
209
+ console.print(f"\n[red]❌ Error generating specification:[/red] {e}")
210
+ console.print("[yellow]💡 Check your API keys and network connection[/yellow]")
211
+
212
+
213
+ @app.callback()
214
+ def main():
215
+ """
216
+ 🚀 [bold blue]Vibe Engineering[/bold blue] - AI-powered specification and memory management CLI
217
+
218
+ [dim]Manage your project specifications, team knowledge, and development workflows with AI assistance.[/dim]
219
+ """
220
+ pass
221
+
222
+
223
+ if __name__ == "__main__":
224
+ app()
src/db/__init__.py ADDED
@@ -0,0 +1,22 @@
1
+ """Database module for MongoDB interactions."""
2
+ from .client import MongoDBClient
3
+ from .operations import (
4
+ upsert_document,
5
+ get_document,
6
+ get_documents,
7
+ delete_document,
8
+ delete_documents,
9
+ insert_document,
10
+ insert_documents,
11
+ )
12
+
13
+ __all__ = [
14
+ "MongoDBClient",
15
+ "upsert_document",
16
+ "get_document",
17
+ "get_documents",
18
+ "delete_document",
19
+ "delete_documents",
20
+ "insert_document",
21
+ "insert_documents",
22
+ ]
src/db/client.py ADDED
@@ -0,0 +1,61 @@
1
+ """MongoDB client connection management."""
2
+ import os
3
+ from typing import Optional
4
+
5
+ import certifi
6
+ from dotenv import load_dotenv
7
+ from pymongo import MongoClient
8
+ from pymongo.database import Database
9
+
10
+
11
+ class MongoDBClient:
12
+ """Manages MongoDB connections and provides access to database resources."""
13
+
14
+ def __init__(self, uri: Optional[str] = None):
15
+ """
16
+ Initialize MongoDB client.
17
+
18
+ Args:
19
+ uri: MongoDB connection URI. If not provided, reads from MONGODB_URI env var.
20
+ """
21
+ load_dotenv()
22
+ self.uri = uri or os.getenv("MONGODB_URI")
23
+
24
+ if not self.uri:
25
+ raise ValueError("MONGODB_URI environment variable is not set")
26
+
27
+ self._client: Optional[MongoClient] = None
28
+
29
+ def connect(self) -> MongoClient:
30
+ """Establish connection to MongoDB."""
31
+ if self._client is None:
32
+ self._client = MongoClient(self.uri, tlsCAFile=certifi.where())
33
+ return self._client
34
+
35
+ def get_database(self, db_name: str = "master") -> Database:
36
+ """
37
+ Get a database instance.
38
+
39
+ Args:
40
+ db_name: Name of the database. Defaults to "master".
41
+
42
+ Returns:
43
+ Database instance.
44
+ """
45
+ client = self.connect()
46
+ return client.get_database(db_name)
47
+
48
+ def close(self):
49
+ """Close the MongoDB connection."""
50
+ if self._client is not None:
51
+ self._client.close()
52
+ self._client = None
53
+
54
+ def __enter__(self):
55
+ """Context manager entry."""
56
+ self.connect()
57
+ return self
58
+
59
+ def __exit__(self, exc_type, exc_val, exc_tb):
60
+ """Context manager exit."""
61
+ self.close()
src/db/operations.py ADDED
@@ -0,0 +1,193 @@
1
+ """Generic CRUD operations for MongoDB."""
2
+ from typing import Dict, Any, List, Optional
3
+
4
+ from .client import MongoDBClient
5
+
6
+
7
+ def upsert_document(
8
+ db_client: MongoDBClient,
9
+ db_name: str,
10
+ collection_name: str,
11
+ query: Dict[str, Any],
12
+ document: Dict[str, Any],
13
+ upsert: bool = True
14
+ ) -> Any:
15
+ """
16
+ Upsert a single document in MongoDB.
17
+
18
+ Args:
19
+ db_client: MongoDB client instance.
20
+ db_name: Database name.
21
+ collection_name: Collection name.
22
+ query: Query to find existing document.
23
+ document: Document data to insert/update.
24
+ upsert: If True, insert if document doesn't exist. Defaults to True.
25
+
26
+ Returns:
27
+ Result of the update operation.
28
+ """
29
+ db = db_client.get_database(db_name)
30
+ collection = db[collection_name]
31
+
32
+ result = collection.update_one(query, {"$set": document}, upsert=upsert)
33
+ return result
34
+
35
+
36
+ def get_document(
37
+ db_client: MongoDBClient,
38
+ db_name: str,
39
+ collection_name: str,
40
+ query: Dict[str, Any]
41
+ ) -> Optional[Dict[str, Any]]:
42
+ """
43
+ Get a single document from MongoDB.
44
+
45
+ Args:
46
+ db_client: MongoDB client instance.
47
+ db_name: Database name.
48
+ collection_name: Collection name.
49
+ query: Query criteria to find the document.
50
+
51
+ Returns:
52
+ Document if found, None otherwise.
53
+ """
54
+ db = db_client.get_database(db_name)
55
+ collection = db[collection_name]
56
+
57
+ return collection.find_one(query)
58
+
59
+
60
+ def get_documents(
61
+ db_client: MongoDBClient,
62
+ db_name: str,
63
+ collection_name: str,
64
+ query: Dict[str, Any],
65
+ limit: Optional[int] = None,
66
+ sort: Optional[List[tuple]] = None
67
+ ) -> List[Dict[str, Any]]:
68
+ """
69
+ Get multiple documents from MongoDB.
70
+
71
+ Args:
72
+ db_client: MongoDB client instance.
73
+ db_name: Database name.
74
+ collection_name: Collection name.
75
+ query: Query criteria to find documents.
76
+ limit: Maximum number of documents to return. None for all.
77
+ sort: List of (field, direction) tuples for sorting.
78
+
79
+ Returns:
80
+ List of documents matching the query.
81
+ """
82
+ db = db_client.get_database(db_name)
83
+ collection = db[collection_name]
84
+
85
+ cursor = collection.find(query)
86
+
87
+ if sort:
88
+ cursor = cursor.sort(sort)
89
+
90
+ if limit:
91
+ cursor = cursor.limit(limit)
92
+
93
+ return list(cursor)
94
+
95
+
96
+ def delete_document(
97
+ db_client: MongoDBClient,
98
+ db_name: str,
99
+ collection_name: str,
100
+ query: Dict[str, Any]
101
+ ) -> int:
102
+ """
103
+ Delete a single document from MongoDB.
104
+
105
+ Args:
106
+ db_client: MongoDB client instance.
107
+ db_name: Database name.
108
+ collection_name: Collection name.
109
+ query: Query criteria to find the document to delete.
110
+
111
+ Returns:
112
+ Number of documents deleted (0 or 1).
113
+ """
114
+ db = db_client.get_database(db_name)
115
+ collection = db[collection_name]
116
+
117
+ result = collection.delete_one(query)
118
+ return result.deleted_count
119
+
120
+
121
+ def delete_documents(
122
+ db_client: MongoDBClient,
123
+ db_name: str,
124
+ collection_name: str,
125
+ query: Dict[str, Any]
126
+ ) -> int:
127
+ """
128
+ Delete multiple documents from MongoDB.
129
+
130
+ Args:
131
+ db_client: MongoDB client instance.
132
+ db_name: Database name.
133
+ collection_name: Collection name.
134
+ query: Query criteria to find documents to delete.
135
+
136
+ Returns:
137
+ Number of documents deleted.
138
+ """
139
+ db = db_client.get_database(db_name)
140
+ collection = db[collection_name]
141
+
142
+ result = collection.delete_many(query)
143
+ return result.deleted_count
144
+
145
+
146
+ def insert_document(
147
+ db_client: MongoDBClient,
148
+ db_name: str,
149
+ collection_name: str,
150
+ document: Dict[str, Any]
151
+ ) -> Any:
152
+ """
153
+ Insert a single document into MongoDB.
154
+
155
+ Args:
156
+ db_client: MongoDB client instance.
157
+ db_name: Database name.
158
+ collection_name: Collection name.
159
+ document: Document to insert.
160
+
161
+ Returns:
162
+ Inserted document ID.
163
+ """
164
+ db = db_client.get_database(db_name)
165
+ collection = db[collection_name]
166
+
167
+ result = collection.insert_one(document)
168
+ return result.inserted_id
169
+
170
+
171
+ def insert_documents(
172
+ db_client: MongoDBClient,
173
+ db_name: str,
174
+ collection_name: str,
175
+ documents: List[Dict[str, Any]]
176
+ ) -> List[Any]:
177
+ """
178
+ Insert multiple documents into MongoDB.
179
+
180
+ Args:
181
+ db_client: MongoDB client instance.
182
+ db_name: Database name.
183
+ collection_name: Collection name.
184
+ documents: List of documents to insert.
185
+
186
+ Returns:
187
+ List of inserted document IDs.
188
+ """
189
+ db = db_client.get_database(db_name)
190
+ collection = db[collection_name]
191
+
192
+ result = collection.insert_many(documents)
193
+ return result.inserted_ids
src/llm/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ """LLM module for AI integrations."""
2
+ from .client import FireworksClient
3
+ from .embeddings import VoyageEmbeddings
4
+ from .segmentation import SpecificationSegmenter
5
+
6
+ __all__ = ["FireworksClient", "VoyageEmbeddings", "SpecificationSegmenter"]
src/llm/client.py ADDED
@@ -0,0 +1,72 @@
1
+ """LLM client for Fireworks AI integration."""
2
+ import os
3
+ from typing import Dict, Any, Optional
4
+
5
+ from dotenv import load_dotenv
6
+ from fireworks import LLM
7
+
8
+
9
+ class FireworksClient:
10
+ """Client for interacting with Fireworks AI LLM services."""
11
+
12
+ def __init__(self, api_key: Optional[str] = None, model: str = "deepseek-v3p1-terminus"):
13
+ """
14
+ Initialize Fireworks AI client.
15
+
16
+ Args:
17
+ api_key: Fireworks API key. If not provided, reads from FIREWORKS_API_KEY env var.
18
+ model: Model name to use. Defaults to "deepseek-v3p1-terminus".
19
+ """
20
+ load_dotenv()
21
+ self.api_key = api_key or os.getenv("FIREWORKS_API_KEY")
22
+
23
+ if not self.api_key:
24
+ raise ValueError("FIREWORKS_API_KEY environment variable is not set")
25
+
26
+ self.model = model
27
+ self._client = LLM(model=self.model, deployment_type="auto", api_key=self.api_key)
28
+
29
+ def generate_with_schema(self, prompt: str, schema: Dict[str, Any], schema_name: str = "ResponseSchema") -> str:
30
+ """
31
+ Generate a response following a specific JSON schema.
32
+
33
+ Args:
34
+ prompt: User prompt to send to the LLM.
35
+ schema: Pydantic model JSON schema to enforce.
36
+ schema_name: Name of the schema. Defaults to "ResponseSchema".
37
+
38
+ Returns:
39
+ Generated response content as a string.
40
+ """
41
+ response = self._client.chat.completions.create(
42
+ response_format={
43
+ "type": "json_schema",
44
+ "json_schema": {
45
+ "name": schema_name,
46
+ "schema": schema,
47
+ },
48
+ },
49
+ messages=[{"role": "user", "content": prompt}],
50
+ )
51
+
52
+ return response.choices[0].message.content
53
+
54
+ def chat(self, messages: list, temperature: float = 0.7, max_tokens: int = 2000) -> str:
55
+ """
56
+ Simple chat completion without schema enforcement.
57
+
58
+ Args:
59
+ messages: List of message dicts with 'role' and 'content' keys.
60
+ temperature: Sampling temperature. Defaults to 0.7.
61
+ max_tokens: Maximum tokens to generate. Defaults to 2000.
62
+
63
+ Returns:
64
+ Generated response content as a string.
65
+ """
66
+ response = self._client.chat.completions.create(
67
+ messages=messages,
68
+ temperature=temperature,
69
+ max_tokens=max_tokens,
70
+ )
71
+
72
+ return response.choices[0].message.content
src/llm/embeddings.py ADDED
@@ -0,0 +1,86 @@
1
+ """Embedding generation using Voyage AI."""
2
+ import os
3
+ from typing import Optional, List
4
+
5
+ import requests
6
+ from dotenv import load_dotenv
7
+
8
+
9
+ class VoyageEmbeddings:
10
+ """Client for generating embeddings using Voyage AI."""
11
+
12
+ def __init__(self, api_key: Optional[str] = None, model: str = "voyage-2"):
13
+ """
14
+ Initialize Voyage AI embeddings client.
15
+
16
+ Args:
17
+ api_key: Voyage API key. If not provided, reads from VOYAGE_API_KEY env var.
18
+ model: Model name to use. Defaults to "voyage-2".
19
+ """
20
+ load_dotenv()
21
+ self.api_key = api_key or os.getenv("VOYAGE_API_KEY")
22
+ self.model = model
23
+ self.default_dimension = 1024 # Default for voyage-2
24
+
25
+ def embed(self, text: str) -> Optional[List[float]]:
26
+ """
27
+ Generate embedding for given text.
28
+
29
+ Args:
30
+ text: Text to embed.
31
+
32
+ Returns:
33
+ List of floats representing the embedding, or None if API key not set.
34
+ """
35
+ if not self.api_key:
36
+ # Return a dummy embedding for testing
37
+ return [0.0] * self.default_dimension
38
+
39
+ try:
40
+ response = requests.post(
41
+ "https://api.voyageai.com/v1/embeddings",
42
+ headers={
43
+ "Authorization": f"Bearer {self.api_key}",
44
+ "Content-Type": "application/json",
45
+ },
46
+ json={"input": text, "model": self.model},
47
+ timeout=30,
48
+ )
49
+ response.raise_for_status()
50
+ data = response.json()
51
+ return data["data"][0]["embedding"]
52
+ except Exception as e:
53
+ print(f"Warning: Embedding failed: {e}")
54
+ # Return dummy embedding on failure
55
+ return [0.0] * self.default_dimension
56
+
57
+ def embed_batch(self, texts: List[str]) -> List[Optional[List[float]]]:
58
+ """
59
+ Generate embeddings for multiple texts.
60
+
61
+ Args:
62
+ texts: List of texts to embed.
63
+
64
+ Returns:
65
+ List of embeddings corresponding to input texts.
66
+ """
67
+ if not self.api_key:
68
+ return [[0.0] * self.default_dimension for _ in texts]
69
+
70
+ try:
71
+ response = requests.post(
72
+ "https://api.voyageai.com/v1/embeddings",
73
+ headers={
74
+ "Authorization": f"Bearer {self.api_key}",
75
+ "Content-Type": "application/json",
76
+ },
77
+ json={"input": texts, "model": self.model},
78
+ timeout=30,
79
+ )
80
+ response.raise_for_status()
81
+ data = response.json()
82
+ return [item["embedding"] for item in data["data"]]
83
+ except Exception as e:
84
+ print(f"Warning: Batch embedding failed: {e}")
85
+ # Return dummy embeddings on failure
86
+ return [[0.0] * self.default_dimension for _ in texts]
@@ -0,0 +1,108 @@
1
+ """LLM-based prompt segmentation for specification ingestion."""
2
+ import os
3
+ import json
4
+ from typing import List, Dict
5
+
6
+ import requests
7
+ from dotenv import load_dotenv
8
+
9
+
10
+ # Constants for specification segmentation
11
+ LLM_SYSTEM_PROMPT = """You convert WHAT/WHY product prompts into JSONL "memories".
12
+ Fields: kind ∈ {vibe,spec,constraint,non_goal,metric,example,open_question}, title, content (≤ 8 lines), tags[], deps[].
13
+ Rules: no implementation/tech details; one idea per memory; create open_question if info is missing; concise & reusable; tags from a small set like ["ux","photos","albums","a11y","perf"].
14
+ Output JSONL only."""
15
+
16
+ FALLBACK_MEMORIES = """
17
+ {"kind": "spec", "title": "Photo album organization", "content": "Application organizes photos into separate albums", "tags": ["photos", "albums"], "deps": []}
18
+ {"kind": "spec", "title": "Album date grouping", "content": "Albums are grouped by date", "tags": ["albums", "organization"], "deps": []}
19
+ {"kind": "spec", "title": "Drag and drop reordering", "content": "Albums can be re-organized by dragging and dropping on the main page", "tags": ["ux", "albums"], "deps": []}
20
+ {"kind": "constraint", "title": "Albums cannot be nested", "content": "Albums are never contained within other albums", "tags": ["albums", "constraint"], "deps": []}
21
+ {"kind": "spec", "title": "Tiled photo previews", "content": "Within each album, photos are previewed in a tile-like interface", "tags": ["photos", "ux"], "deps": []}
22
+ {"kind": "open_question", "title": "Tile size configuration", "content": "What should be the default tile size and can users customize it?", "tags": ["ux", "photos"], "deps": []}
23
+ """.strip()
24
+
25
+
26
+ class SpecificationSegmenter:
27
+ """Segments prompts into atomic memory specifications using LLM."""
28
+
29
+ def __init__(self, api_key: str = None, model: str = None):
30
+ """
31
+ Initialize specification segmenter.
32
+
33
+ Args:
34
+ api_key: Fireworks API key. If not provided, reads from FIREWORKS_API_KEY env var.
35
+ model: Model to use. If not provided, reads from FIREWORKS_MODEL env var or uses default.
36
+ """
37
+ load_dotenv()
38
+ self.api_key = api_key or os.getenv("FIREWORKS_API_KEY")
39
+ self.model = model or os.getenv(
40
+ "FIREWORKS_MODEL", "accounts/fireworks/models/llama-v3p1-70b-instruct"
41
+ )
42
+
43
+ def segment_to_jsonl(self, prompt_text: str, tags: List[str]) -> str:
44
+ """
45
+ Segment prompt into JSONL memories using Fireworks AI LLM or fallback.
46
+
47
+ Args:
48
+ prompt_text: The specification prompt to segment.
49
+ tags: List of tags to suggest to the LLM.
50
+
51
+ Returns:
52
+ JSONL string containing segmented memories.
53
+ """
54
+ if not self.api_key:
55
+ # Return fallback memories
56
+ return FALLBACK_MEMORIES
57
+
58
+ try:
59
+ response = requests.post(
60
+ "https://api.fireworks.ai/inference/v1/chat/completions",
61
+ headers={
62
+ "Authorization": f"Bearer {self.api_key}",
63
+ "Content-Type": "application/json",
64
+ },
65
+ json={
66
+ "model": self.model,
67
+ "messages": [
68
+ {"role": "system", "content": LLM_SYSTEM_PROMPT},
69
+ {
70
+ "role": "user",
71
+ "content": f"Tags to use: {', '.join(tags) if tags else 'derive appropriate tags'}\n\nPrompt:\n{prompt_text}",
72
+ },
73
+ ],
74
+ "temperature": 0.7,
75
+ "max_tokens": 2000,
76
+ },
77
+ timeout=30,
78
+ )
79
+ response.raise_for_status()
80
+ data = response.json()
81
+
82
+ # Extract the assistant's response
83
+ content = data["choices"][0]["message"]["content"]
84
+ return content.strip()
85
+
86
+ except Exception as e:
87
+ print(f"Warning: LLM segmentation failed: {e}")
88
+ print("Falling back to example memories")
89
+ return FALLBACK_MEMORIES
90
+
91
+ def parse_jsonl(self, jsonl_text: str) -> List[Dict]:
92
+ """
93
+ Parse JSONL text into list of dictionaries.
94
+
95
+ Args:
96
+ jsonl_text: JSONL formatted string.
97
+
98
+ Returns:
99
+ List of parsed JSON objects.
100
+ """
101
+ items = []
102
+ for line in jsonl_text.strip().split("\n"):
103
+ if line.strip():
104
+ try:
105
+ items.append(json.loads(line))
106
+ except json.JSONDecodeError as e:
107
+ print(f"Warning: Failed to parse JSONL line: {e}")
108
+ return items
@@ -0,0 +1,4 @@
1
+ """Schemas module for data models."""
2
+ from .models import DecayModel, MetadataModel, SpecifySchema
3
+
4
+ __all__ = ["DecayModel", "MetadataModel", "SpecifySchema"]
src/schemas/models.py ADDED
@@ -0,0 +1,45 @@
1
+ """Pydantic models for data validation."""
2
+ from typing import List, Optional
3
+
4
+ from bson import ObjectId
5
+ from pydantic import BaseModel, Field
6
+
7
+
8
+ class DecayModel(BaseModel):
9
+ """Model for memory decay parameters."""
10
+
11
+ lambda_: float = Field(..., alias="lambda")
12
+ pinned: bool
13
+
14
+ class Config:
15
+ populate_by_name = True
16
+
17
+
18
+ class MetadataModel(BaseModel):
19
+ """Model for memory metadata."""
20
+
21
+ source: str
22
+ content_hash: str
23
+
24
+
25
+ class SpecifySchema(BaseModel):
26
+ """Schema for specification/memory documents."""
27
+
28
+ memory_id: str
29
+ project_id: str
30
+ created_at: str # ISO 8601 datetime string
31
+ author: str
32
+ kind: str
33
+ title: str
34
+ content: str
35
+ tags: List[str]
36
+ deps: List[str]
37
+ priority: float
38
+ decay: DecayModel
39
+ metadata: MetadataModel
40
+ embedding: Optional[List[float]] = None
41
+
42
+ class Config:
43
+ populate_by_name = True
44
+ arbitrary_types_allowed = True
45
+ json_encoders = {ObjectId: str}
@@ -0,0 +1,262 @@
1
+ Metadata-Version: 2.4
2
+ Name: vibe-engineering
3
+ Version: 0.1.7
4
+ Summary: Add your description here
5
+ Home-page: https://github.com/vibeengineering/vibe-engineering
6
+ Author: Vibe Engineering Team
7
+ Author-email: team@vibeengineering.com
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: certifi>=2024.12.14
11
+ Requires-Dist: fireworks-ai>=0.19.19
12
+ Requires-Dist: pydantic>=2.12.0
13
+ Requires-Dist: pymongo>=4.15.3
14
+ Requires-Dist: python-dotenv>=1.1.1
15
+ Requires-Dist: requests>=2.32.0
16
+ Requires-Dist: rich>=14.2.0
17
+ Requires-Dist: typer>=0.19.2
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: home-page
21
+ Dynamic: requires-python
22
+
23
+ # 🚀 Vibe Engineering CLI
24
+
25
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
26
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
27
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
28
+
29
+ > **AI-powered specification and memory management CLI for modern development teams**
30
+
31
+ Vibe Engineering is a powerful command-line tool that helps development teams manage specifications, project knowledge, and development workflows using AI assistance. Built with VoyageAI embeddings and MongoDB vector search for intelligent document management.
32
+
33
+ ## ✨ Features
34
+
35
+ - 🤖 **AI-Powered Specifications** - Generate detailed specs using advanced LLMs
36
+ - 🧠 **Memory Management** - Store and retrieve project knowledge with vector search
37
+ - 👥 **Team Collaboration** - Track team members and project ownership
38
+ - 📊 **Rich CLI Experience** - Beautiful, interactive command-line interface
39
+ - 🔍 **Vector Search** - Find relevant information using semantic similarity
40
+ - 📝 **Multiple Formats** - Export specifications in JSON, YAML, and Markdown
41
+
42
+ ## 🚀 Quick Install
43
+
44
+ ### PowerShell (Windows)
45
+ ```powershell
46
+ PowerShell -ExecutionPolicy Bypass -Command "iwr -useb https://raw.githubusercontent.com/vibeengineering/vibe-engineering/main/install.ps1 | iex"
47
+ ```
48
+
49
+ ### Bash (Linux/macOS)
50
+ ```bash
51
+ curl -sSL https://raw.githubusercontent.com/vibeengineering/vibe-engineering/main/install.sh | bash
52
+ ```
53
+
54
+ ### Manual Installation
55
+ ```bash
56
+ # Clone the repository
57
+ git clone https://github.com/vibeengineering/vibe-engineering.git
58
+ cd vibe-engineering
59
+
60
+ # Install dependencies
61
+ pip install -r requirements.txt
62
+
63
+ # Install the CLI
64
+ pip install -e .
65
+
66
+ # Setup configuration
67
+ cp .env.dist .env
68
+ # Edit .env with your API keys
69
+ ```
70
+
71
+ ## ⚙️ Configuration
72
+
73
+ 1. **Copy environment template:**
74
+ ```bash
75
+ cp .env.dist .env
76
+ ```
77
+
78
+ 2. **Configure your API keys in `.env`:**
79
+ ```bash
80
+ # VoyageAI Configuration
81
+ VOYAGE_API_KEY=your_voyage_api_key_here
82
+ VOYAGE_MODEL=voyage-2
83
+
84
+ # MongoDB Configuration
85
+ MONGODB_URI=your_mongodb_connection_string
86
+ MONGO_DB=your_database_name
87
+ MONGO_COLLECTION=memories
88
+
89
+ # Fireworks AI Configuration
90
+ FIREWORKS_API_KEY=your_fireworks_api_key_here
91
+ FIREWORKS_MODEL=accounts/fireworks/models/llama-v3p1-70b-instruct
92
+ ```
93
+
94
+ ## 📖 Usage
95
+
96
+ ### Basic Commands
97
+
98
+ ```bash
99
+ # Show system status
100
+ vibe status
101
+
102
+ # Display team members
103
+ vibe team
104
+
105
+ # Generate AI specification
106
+ vibe specify "Create a user authentication system"
107
+
108
+ # Show version
109
+ vibe version
110
+
111
+ # Get help
112
+ vibe --help
113
+ ```
114
+
115
+ ### Advanced Usage
116
+
117
+ ```bash
118
+ # Generate specification with options
119
+ vibe specify "Add payment processing" --format json --save --verbose
120
+
121
+ # Custom output formats
122
+ vibe specify "User dashboard" --format markdown
123
+
124
+ # Save specification to database
125
+ vibe specify "API rate limiting" --save
126
+ ```
127
+
128
+ ## 📋 Commands Reference
129
+
130
+ | Command | Description | Example |
131
+ |---------|-------------|---------|
132
+ | `vibe status` | 🔍 Show system status and configuration | `vibe status` |
133
+ | `vibe team` | 👥 Display team members from database | `vibe team` |
134
+ | `vibe specify` | ✨ Generate AI-powered specifications | `vibe specify "Add user auth"` |
135
+ | `vibe version` | 📦 Show version information | `vibe version` |
136
+
137
+ ### Specify Command Options
138
+
139
+ ```bash
140
+ vibe specify PROMPT [OPTIONS]
141
+
142
+ Options:
143
+ -f, --format Output format: json, yaml, markdown (default: json)
144
+ -s, --save Save specification to database
145
+ -v, --verbose Show detailed output
146
+ --help Show help message
147
+ ```
148
+
149
+ ## 🏗️ Architecture
150
+
151
+ ```
152
+ ├── src/
153
+ │ ├── cli/ # Command-line interface
154
+ │ ├── db/ # Database operations (MongoDB)
155
+ │ ├── llm/ # LLM clients (Fireworks, VoyageAI)
156
+ │ └── schemas/ # Data models and schemas
157
+ ├── install.ps1 # PowerShell installer
158
+ ├── install.sh # Bash installer
159
+ ├── setup.py # Python package setup
160
+ └── requirements.txt # Dependencies
161
+ ```
162
+
163
+ ## 🛠️ Development
164
+
165
+ ### Prerequisites
166
+ - Python 3.10+
167
+ - MongoDB (Atlas or local)
168
+ - VoyageAI API key
169
+ - Fireworks AI API key
170
+
171
+ ### Setup Development Environment
172
+
173
+ ```bash
174
+ # Clone repository
175
+ git clone https://github.com/vibeengineering/vibe-engineering.git
176
+ cd vibe-engineering
177
+
178
+ # Install development dependencies
179
+ pip install -r requirements-dev.txt
180
+
181
+ # Install in development mode
182
+ pip install -e .
183
+
184
+ # Run tests
185
+ pytest
186
+
187
+ # Format code
188
+ black .
189
+
190
+ # Type checking
191
+ mypy src/
192
+ ```
193
+
194
+ ### Running Locally
195
+
196
+ ```bash
197
+ # Run CLI directly
198
+ python -m src.cli --help
199
+
200
+ # Or use the installed command
201
+ vibe --help
202
+ ```
203
+
204
+ ## 🔧 Configuration Options
205
+
206
+ ### Environment Variables
207
+
208
+ | Variable | Description | Default |
209
+ |----------|-------------|---------|
210
+ | `VOYAGE_API_KEY` | VoyageAI API key for embeddings | Required |
211
+ | `VOYAGE_MODEL` | VoyageAI model to use | `voyage-2` |
212
+ | `MONGODB_URI` | MongoDB connection string | Required |
213
+ | `MONGO_DB` | Database name | `master` |
214
+ | `MONGO_COLLECTION` | Collection name | `memories` |
215
+ | `FIREWORKS_API_KEY` | Fireworks AI API key | Required |
216
+ | `FIREWORKS_MODEL` | Fireworks model to use | `llama-v3p1-70b-instruct` |
217
+
218
+ ## 🚦 System Requirements
219
+
220
+ - **Python**: 3.10 or higher
221
+ - **Memory**: 512MB RAM minimum
222
+ - **Storage**: 100MB free space
223
+ - **Network**: Internet connection for AI APIs
224
+ - **Database**: MongoDB Atlas or local MongoDB instance
225
+
226
+ ## 📚 Documentation
227
+
228
+ - [Installation Guide](./docs/installation.md)
229
+ - [Configuration Reference](./docs/configuration.md)
230
+ - [API Documentation](./docs/api.md)
231
+ - [Contributing Guide](./CONTRIBUTING.md)
232
+
233
+ ## 🤝 Contributing
234
+
235
+ We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.
236
+
237
+ 1. Fork the repository
238
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
239
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
240
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
241
+ 5. Open a Pull Request
242
+
243
+ ## 📄 License
244
+
245
+ This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
246
+
247
+ ## 🆘 Support
248
+
249
+ - 📧 Email: support@vibeengineering.com
250
+ - 💬 GitHub Issues: [Create an issue](https://github.com/vibeengineering/vibe-engineering/issues)
251
+ - 📖 Documentation: [Read the docs](https://docs.vibeengineering.com)
252
+
253
+ ## 🙏 Acknowledgments
254
+
255
+ - Built with [Typer](https://typer.tiangolo.com/) for the CLI framework
256
+ - Powered by [VoyageAI](https://www.voyageai.com/) for embeddings
257
+ - Uses [Fireworks AI](https://fireworks.ai/) for LLM capabilities
258
+ - Styled with [Rich](https://rich.readthedocs.io/) for beautiful terminal output
259
+
260
+ ---
261
+
262
+ **Made with ❤️ by the Vibe Engineering Team**
@@ -0,0 +1,16 @@
1
+ src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ src/cli/__init__.py,sha256=jJ7tHuLwJcPDuk45xRuu8xbMBQL45k5oZ6EcNa9MD8k,94
3
+ src/cli/commands.py,sha256=dlZoLSR9n4InbdeAXJXxKmATMGOwLW70ylXlBIJ_808,7885
4
+ src/db/__init__.py,sha256=zrfEUYNVRhGAq0DgIWBkxoM8L0jJNgy1_GhtBVJvhYA,470
5
+ src/db/client.py,sha256=a-KZDyJjUWB1y15p1pxPn_q8UPDLVtOSvidx8XvULlU,1741
6
+ src/db/operations.py,sha256=nJ2AJrYOaOi9L8ZJgQjr4eukKbr2al0tFls83S8M8GY,4881
7
+ src/llm/__init__.py,sha256=LLtIL6wbsmZ2MAs9u34K84pMu_keg6X-HccCZzinPlQ,247
8
+ src/llm/client.py,sha256=5daBZrf4sZ8_9OBFEsWWNoEMvctupDRWxheS3rXWJAw,2542
9
+ src/llm/embeddings.py,sha256=wH-aihD6HfkJtUn4TJGpqLz9BYnX5i0SyRT0tf8hb2E,2987
10
+ src/llm/segmentation.py,sha256=zex5Elfk_ph0nFFzszxtagN6o1SmTu1BsHJ9W9Njlb0,4753
11
+ src/schemas/__init__.py,sha256=rdw4M8Gm95XN5sPgfReQO0WLePty-OE-4OYjSFrGlBM,163
12
+ src/schemas/models.py,sha256=aIO8qtG0gdL6pWc0cyhYC1jqevpNIfkOQJYSA3Lc_Ew,1011
13
+ vibe_engineering-0.1.7.dist-info/METADATA,sha256=4qsfe3zn4Ln8TQ3l6z17azo6i9Pn4zW9jrJGbI48n98,7650
14
+ vibe_engineering-0.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ vibe_engineering-0.1.7.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
16
+ vibe_engineering-0.1.7.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ src