@nghiapt/kit 1.0.3 → 1.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.
- package/bin/index.js +2 -5
- package/index.js +8 -5
- package/package.json +1 -1
- package/core/check_workflows.py +0 -32
- package/core/context.py +0 -70
- package/core/engine.py +0 -173
- package/core/ops.py +0 -39
- package/core/optimize_workflows_bulk.py +0 -45
- package/core/state_manager.py +0 -38
- package/core/upgrade_workflows_batch.py +0 -50
- package/rules/.clinerules +0 -17
- package/rules/antigravity_global.md +0 -45
package/bin/index.js
CHANGED
|
@@ -12,7 +12,7 @@ if (process.stdin.isTTY) {
|
|
|
12
12
|
|
|
13
13
|
const HEADER = `
|
|
14
14
|
==========================================
|
|
15
|
-
Antigravity Kit Setup
|
|
15
|
+
Antigravity Kit Setup by NghiaPT
|
|
16
16
|
==========================================
|
|
17
17
|
`;
|
|
18
18
|
|
|
@@ -26,17 +26,14 @@ const LOCAL_DEST = path.join(process.cwd(), '.agent', 'workflows');
|
|
|
26
26
|
const OPTIONS = [
|
|
27
27
|
{
|
|
28
28
|
label: 'Install Global (Recommended)',
|
|
29
|
-
desc: 'Copies to ~/.gemini/antigravity/global_workflows',
|
|
30
29
|
action: async () => await installWorkflows(GLOBAL_DEST, 'Global')
|
|
31
30
|
},
|
|
32
31
|
{
|
|
33
|
-
label: 'Install Only on
|
|
34
|
-
desc: 'Copies to ./.agent/workflows',
|
|
32
|
+
label: 'Install Only on Current Project',
|
|
35
33
|
action: async () => await installWorkflows(LOCAL_DEST, 'Local Project')
|
|
36
34
|
},
|
|
37
35
|
{
|
|
38
36
|
label: 'Exit',
|
|
39
|
-
desc: 'Close the setup wizard',
|
|
40
37
|
action: () => process.exit(0)
|
|
41
38
|
}
|
|
42
39
|
];
|
package/index.js
CHANGED
|
@@ -26,17 +26,20 @@ const LOCAL_DEST = path.join(process.cwd(), '.agent', 'workflows');
|
|
|
26
26
|
const OPTIONS = [
|
|
27
27
|
{
|
|
28
28
|
label: 'Install Global (Recommended)',
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
action: async () => {
|
|
30
|
+
await installWorkflows(GLOBAL_DEST, 'Global');
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
31
33
|
},
|
|
32
34
|
{
|
|
33
35
|
label: 'Install Only on Context Project',
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
action: async () => {
|
|
37
|
+
await installWorkflows(LOCAL_DEST, 'Local Project');
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
36
40
|
},
|
|
37
41
|
{
|
|
38
42
|
label: 'Exit',
|
|
39
|
-
desc: 'Close the setup wizard',
|
|
40
43
|
action: () => process.exit(0)
|
|
41
44
|
}
|
|
42
45
|
];
|
package/package.json
CHANGED
package/core/check_workflows.py
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import re
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
def check_workflows():
|
|
6
|
-
workflows_dir = Path(r"d:\antigravity-kit\workflows")
|
|
7
|
-
print(f"Checking workflows in {workflows_dir}...")
|
|
8
|
-
|
|
9
|
-
passed = 0
|
|
10
|
-
failed = 0
|
|
11
|
-
|
|
12
|
-
for f in workflows_dir.glob("*.md"):
|
|
13
|
-
content = f.read_text(encoding='utf-8', errors='ignore')
|
|
14
|
-
|
|
15
|
-
# Check for Frontmatter
|
|
16
|
-
has_frontmatter = content.strip().startswith("---")
|
|
17
|
-
|
|
18
|
-
# Check for Role/Task (Antigravity Native indicators)
|
|
19
|
-
has_role = "# Role" in content or "Role:" in content
|
|
20
|
-
has_task = "# Task" in content or "Task:" in content or "# Process" in content
|
|
21
|
-
|
|
22
|
-
if has_frontmatter:
|
|
23
|
-
# print(f"✅ {f.name}: Valid Frontmatter")
|
|
24
|
-
passed += 1
|
|
25
|
-
else:
|
|
26
|
-
print(f"⚠️ {f.name}: MISSING Frontmatter (Legacy?)")
|
|
27
|
-
failed += 1
|
|
28
|
-
|
|
29
|
-
print(f"\nSummary: {passed} Passed, {failed} Potential Legacy Format")
|
|
30
|
-
|
|
31
|
-
if __name__ == "__main__":
|
|
32
|
-
check_workflows()
|
package/core/context.py
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import List, Set
|
|
4
|
-
# No external deps if possible, or use standard lib
|
|
5
|
-
|
|
6
|
-
# Default ignores
|
|
7
|
-
IGNORED_DIRS = {
|
|
8
|
-
'.git', '.idea', '.vscode', '__pycache__', 'node_modules',
|
|
9
|
-
'venv', 'env', 'dist', 'build', 'coverage', '.next', '.nuxt',
|
|
10
|
-
'.output', 'target', 'bin', 'obj'
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
IGNORED_EXTS = {
|
|
14
|
-
'.pyc', '.pyo', '.pyd', '.so', '.dll', '.exe', '.bin',
|
|
15
|
-
'.jpg', '.jpeg', '.png', '.gif', '.ico', '.svg', '.mp4',
|
|
16
|
-
'.mp3', '.pdf', '.zip', '.tar', '.gz', '.7z', '.rar',
|
|
17
|
-
'.db', '.sqlite', '.sqlite3', '.pkl', '.lock'
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
IGNORED_FILES = {
|
|
21
|
-
'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'poetry.lock',
|
|
22
|
-
'Gemfile.lock', 'composer.lock', 'cargo.lock'
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
def is_ignored(path: Path) -> bool:
|
|
26
|
-
if path.name in IGNORED_FILES:
|
|
27
|
-
return True
|
|
28
|
-
if path.suffix in IGNORED_EXTS:
|
|
29
|
-
return True
|
|
30
|
-
# Check parts for ignored dirs
|
|
31
|
-
if any(part in IGNORED_DIRS for part in path.parts):
|
|
32
|
-
return True
|
|
33
|
-
return False
|
|
34
|
-
|
|
35
|
-
def get_project_files(root_dir: str) -> List[Path]:
|
|
36
|
-
"""Scans the project for text files, respecting ignore rules."""
|
|
37
|
-
root = Path(root_dir)
|
|
38
|
-
files = []
|
|
39
|
-
|
|
40
|
-
# Simple walk
|
|
41
|
-
for dirpath, dirnames, filenames in os.walk(root):
|
|
42
|
-
# Modify dirnames in-place to prune ignored dirs
|
|
43
|
-
dirnames[:] = [d for d in dirnames if d not in IGNORED_DIRS and not d.startswith('.')]
|
|
44
|
-
|
|
45
|
-
for f in filenames:
|
|
46
|
-
p = Path(dirpath) / f
|
|
47
|
-
if not is_ignored(p):
|
|
48
|
-
files.append(p)
|
|
49
|
-
|
|
50
|
-
return files
|
|
51
|
-
|
|
52
|
-
def get_context_string(root_dir: str) -> str:
|
|
53
|
-
"""Generates a massive string containing all project code."""
|
|
54
|
-
files = get_project_files(root_dir)
|
|
55
|
-
context = []
|
|
56
|
-
|
|
57
|
-
context.append(f"Project Context (Root: {root_dir})\n")
|
|
58
|
-
context.append("="*50 + "\n")
|
|
59
|
-
|
|
60
|
-
for f in files:
|
|
61
|
-
try:
|
|
62
|
-
relative_path = f.relative_to(root_dir)
|
|
63
|
-
content = f.read_text(encoding='utf-8', errors='ignore')
|
|
64
|
-
|
|
65
|
-
context.append(f"\n--- FILE: {relative_path} ---\n")
|
|
66
|
-
context.append(content)
|
|
67
|
-
except Exception:
|
|
68
|
-
pass # Skip unreadable
|
|
69
|
-
|
|
70
|
-
return "\n".join(context)
|
package/core/engine.py
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
import json
|
|
3
|
-
import os
|
|
4
|
-
import argparse
|
|
5
|
-
from google import genai
|
|
6
|
-
from google.genai import types
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
|
|
9
|
-
try:
|
|
10
|
-
from .context import get_context_string
|
|
11
|
-
from .ops import read_file, write_file
|
|
12
|
-
except ImportError:
|
|
13
|
-
from context import get_context_string
|
|
14
|
-
from ops import read_file, write_file
|
|
15
|
-
|
|
16
|
-
def clean_json(text: str) -> str:
|
|
17
|
-
# Remove markdown fences ```json ... ```
|
|
18
|
-
text = re.sub(r"^```json\s*", "", text, flags=re.MULTILINE)
|
|
19
|
-
text = re.sub(r"^```\s*", "", text, flags=re.MULTILINE)
|
|
20
|
-
text = re.sub(r"```$", "", text, flags=re.MULTILINE)
|
|
21
|
-
return text.strip()
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# Load Config
|
|
25
|
-
CONFIG_PATH = Path(__file__).parent.parent / ".antigravity" / "config.json"
|
|
26
|
-
try:
|
|
27
|
-
with open(CONFIG_PATH, 'r') as f:
|
|
28
|
-
CONFIG = json.load(f)
|
|
29
|
-
API_KEY = CONFIG.get("api_key") or os.getenv("GEMINI_API_KEY")
|
|
30
|
-
MODEL_NAME = CONFIG.get("model", "gemini-2.0-flash-exp")
|
|
31
|
-
except Exception:
|
|
32
|
-
API_KEY = os.getenv("GEMINI_API_KEY")
|
|
33
|
-
MODEL_NAME = "gemini-2.0-flash-exp"
|
|
34
|
-
|
|
35
|
-
def parse_workflow(content: str) -> tuple[dict, str]:
|
|
36
|
-
if content.startswith("---"):
|
|
37
|
-
parts = re.split(r"^---$", content, maxsplit=2, flags=re.MULTILINE)
|
|
38
|
-
if len(parts) >= 3:
|
|
39
|
-
try:
|
|
40
|
-
metadata = {}
|
|
41
|
-
for line in parts[1].strip().split('\n'):
|
|
42
|
-
if ':' in line:
|
|
43
|
-
k, v = line.split(':', 1)
|
|
44
|
-
metadata[k.strip()] = v.strip()
|
|
45
|
-
return metadata, parts[2].strip()
|
|
46
|
-
except Exception:
|
|
47
|
-
pass
|
|
48
|
-
return {}, content.strip()
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
# RUNTIME INJECTION: Turns Docs into Agents
|
|
52
|
-
ANTIGRAVITY_PROTOCOL = """
|
|
53
|
-
# ANTIGRAVITY AGENT PROTOCOL (SYSTEM OVERRIDE)
|
|
54
|
-
|
|
55
|
-
You are an autonomous AI Agent running inside the Antigravity Kit.
|
|
56
|
-
The text below is not just documentation; it is your **OPERATIONAL MANUAL**.
|
|
57
|
-
|
|
58
|
-
## YOUR MANDATE:
|
|
59
|
-
1. **ACT, DON'T JUST READ**: If the user instruction is a command (e.g., "Build this"), execute it using the Manual's best practices.
|
|
60
|
-
2. **CONTEXT ACCESS**: You have full access to `[PROJECT CONTEXT]`. Read it to understand the codebase.
|
|
61
|
-
- **Do NOT** ask for file permissions.
|
|
62
|
-
- **Do NOT** hallucinate paths. Use `list_dir` to confirm.
|
|
63
|
-
3. **TOOLS**: Use `run_command` to install/build, `write_to_file` to code.
|
|
64
|
-
4. **CHAINING**: If a task is too complex, output a request to chain another agent using `python core/engine.py [workflow]`.
|
|
65
|
-
|
|
66
|
-
## MANUAL CONTENT START
|
|
67
|
-
--------------------------------------------------
|
|
68
|
-
{workflow_content}
|
|
69
|
-
--------------------------------------------------
|
|
70
|
-
## MANUAL CONTENT END
|
|
71
|
-
"""
|
|
72
|
-
|
|
73
|
-
def load_workflow(name: str) -> tuple[dict, str]:
|
|
74
|
-
base_dir = Path(__file__).parent.parent
|
|
75
|
-
path = base_dir / "workflows" / f"{name}.md"
|
|
76
|
-
if not path.exists():
|
|
77
|
-
return {}, f"Error: Workflow '{name}' not found."
|
|
78
|
-
|
|
79
|
-
raw_content = read_file(str(path))
|
|
80
|
-
metadata, stripped_content = parse_workflow(raw_content)
|
|
81
|
-
|
|
82
|
-
# INJECT PROTOCOL
|
|
83
|
-
system_prompt = ANTIGRAVITY_PROTOCOL.format(workflow_content=stripped_content)
|
|
84
|
-
|
|
85
|
-
return metadata, system_prompt
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def call_gemini(system_instruction: str, user_prompt: str, json_mode: bool = False) -> str:
|
|
89
|
-
if not API_KEY:
|
|
90
|
-
return "Error: GEMINI_API_KEY environment variable not set."
|
|
91
|
-
try:
|
|
92
|
-
client = genai.Client(api_key=API_KEY)
|
|
93
|
-
|
|
94
|
-
config = types.GenerateContentConfig(
|
|
95
|
-
system_instruction=system_instruction
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
if json_mode:
|
|
99
|
-
config.response_mime_type = "application/json"
|
|
100
|
-
|
|
101
|
-
response = client.models.generate_content(
|
|
102
|
-
model=MODEL_NAME,
|
|
103
|
-
contents=user_prompt,
|
|
104
|
-
config=config
|
|
105
|
-
)
|
|
106
|
-
return response.text
|
|
107
|
-
except Exception as e:
|
|
108
|
-
return f"Error calling Gemini: {e}"
|
|
109
|
-
|
|
110
|
-
def execute_workflow(workflow_name: str, user_request: str, project_context: str) -> str:
|
|
111
|
-
print(f"\n🚀 Executing Workflow: {workflow_name}...")
|
|
112
|
-
metadata, system_prompt = load_workflow(workflow_name)
|
|
113
|
-
if "Error" in system_prompt:
|
|
114
|
-
return system_prompt
|
|
115
|
-
|
|
116
|
-
full_prompt = f"""
|
|
117
|
-
[PROJECT CONTEXT]
|
|
118
|
-
{project_context}
|
|
119
|
-
|
|
120
|
-
[USER REQUEST]
|
|
121
|
-
{user_request}
|
|
122
|
-
"""
|
|
123
|
-
|
|
124
|
-
json_mode = metadata.get("output", "").lower() == "json"
|
|
125
|
-
response = call_gemini(system_prompt, full_prompt, json_mode=json_mode)
|
|
126
|
-
print(f"✅ {workflow_name} Completed.")
|
|
127
|
-
return response
|
|
128
|
-
|
|
129
|
-
def main():
|
|
130
|
-
parser = argparse.ArgumentParser(description="Antigravity Universal Runner")
|
|
131
|
-
parser.add_argument("workflow", help="Name of the workflow (or 'orchestrator')")
|
|
132
|
-
parser.add_argument("prompt", help="User Input")
|
|
133
|
-
args = parser.parse_args()
|
|
134
|
-
|
|
135
|
-
cwd = os.getcwd()
|
|
136
|
-
print(f"Loading Context from {cwd}...")
|
|
137
|
-
context = get_context_string(cwd)
|
|
138
|
-
|
|
139
|
-
# ORCHESTRATOR LOGIC
|
|
140
|
-
if args.workflow == "orchestrator":
|
|
141
|
-
plan_json = execute_workflow("orchestrator", args.prompt, context)
|
|
142
|
-
try:
|
|
143
|
-
# Clean before parsing
|
|
144
|
-
cleaned_json = clean_json(plan_json)
|
|
145
|
-
plan = json.loads(cleaned_json)
|
|
146
|
-
|
|
147
|
-
print(f"\n📋 Orchestrator Plan: {plan.get('thought_process', '')}")
|
|
148
|
-
|
|
149
|
-
# Chain Execution
|
|
150
|
-
previous_output = ""
|
|
151
|
-
for step in plan.get("steps", []):
|
|
152
|
-
|
|
153
|
-
step_workflow = step.get("workflow")
|
|
154
|
-
step_instruction = step.get("instruction")
|
|
155
|
-
|
|
156
|
-
# Append previous output to history/instruction
|
|
157
|
-
if previous_output:
|
|
158
|
-
step_instruction += f"\n\n[PREVIOUS AGENT OUTPUT]\n{previous_output}"
|
|
159
|
-
|
|
160
|
-
output = execute_workflow(step_workflow, step_instruction, context)
|
|
161
|
-
previous_output = output # Chain it
|
|
162
|
-
|
|
163
|
-
print(f"\n--- Output of {step_workflow} ---\n{output[:500]}...\n")
|
|
164
|
-
|
|
165
|
-
except json.JSONDecodeError:
|
|
166
|
-
print("Error: Orchestrator failed to return valid JSON.")
|
|
167
|
-
print(plan_json)
|
|
168
|
-
else:
|
|
169
|
-
# SINGLE RUN
|
|
170
|
-
print(execute_workflow(args.workflow, args.prompt, context))
|
|
171
|
-
|
|
172
|
-
if __name__ == "__main__":
|
|
173
|
-
main()
|
package/core/ops.py
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import subprocess
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
def read_file(path: str) -> str:
|
|
6
|
-
"""Reads a file and returns its content. Returns error string if failed."""
|
|
7
|
-
try:
|
|
8
|
-
with open(path, 'r', encoding='utf-8') as f:
|
|
9
|
-
return f.read()
|
|
10
|
-
except Exception as e:
|
|
11
|
-
return f"Error reading {path}: {e}"
|
|
12
|
-
|
|
13
|
-
def write_file(path: str, content: str) -> bool:
|
|
14
|
-
"""Writes content to a file. Creates parent directories if needed."""
|
|
15
|
-
try:
|
|
16
|
-
p = Path(path)
|
|
17
|
-
p.parent.mkdir(parents=True, exist_ok=True)
|
|
18
|
-
with open(p, 'w', encoding='utf-8') as f:
|
|
19
|
-
f.write(content)
|
|
20
|
-
return True
|
|
21
|
-
except Exception as e:
|
|
22
|
-
print(f"Error writing {path}: {e}")
|
|
23
|
-
return False
|
|
24
|
-
|
|
25
|
-
def run_command(command: str, cwd: str = ".") -> tuple[str, str, int]:
|
|
26
|
-
"""Runs a shell command and returns (stdout, stderr, return_code)."""
|
|
27
|
-
try:
|
|
28
|
-
result = subprocess.run(
|
|
29
|
-
command,
|
|
30
|
-
cwd=cwd,
|
|
31
|
-
shell=True,
|
|
32
|
-
capture_output=True,
|
|
33
|
-
text=True,
|
|
34
|
-
encoding='utf-8',
|
|
35
|
-
errors='replace'
|
|
36
|
-
)
|
|
37
|
-
return result.stdout, result.stderr, result.returncode
|
|
38
|
-
except Exception as e:
|
|
39
|
-
return "", str(e), -1
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import re
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
def optimize_file(path: Path):
|
|
6
|
-
content = path.read_text(encoding='utf-8', errors='ignore')
|
|
7
|
-
original_content = content
|
|
8
|
-
|
|
9
|
-
# 1. Branding Replacement
|
|
10
|
-
content = content.replace("Claude" + "Kit", "Antigravity Kit")
|
|
11
|
-
content = content.replace("ported from Claude Kit", "Native Gemini Framework")
|
|
12
|
-
content = content.replace(".claude/", ".antigravity/")
|
|
13
|
-
|
|
14
|
-
# 2. Frontmatter Injection
|
|
15
|
-
if not content.strip().startswith("---"):
|
|
16
|
-
# Synthesize frontmatter
|
|
17
|
-
description = "Antigravity Workflow"
|
|
18
|
-
# Try to grab first line description if available
|
|
19
|
-
lines = content.strip().split('\n')
|
|
20
|
-
if lines and lines[0].startswith('# '):
|
|
21
|
-
# Skip title
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
content = f"---\ndescription: {description}\noutput: markdown\n---\n\n" + content
|
|
25
|
-
|
|
26
|
-
# 3. Role Injection (If missing)
|
|
27
|
-
if not ("# Role" in content or "Role:" in content):
|
|
28
|
-
content = content.replace("---\n\n", "---\n\n# Role\nYou are an expert AI agent specializing in this workflow.\n\n")
|
|
29
|
-
|
|
30
|
-
# 4. Save if changed
|
|
31
|
-
if content != original_content:
|
|
32
|
-
path.write_text(content, encoding='utf-8')
|
|
33
|
-
print(f"✅ Optimized: {path.name}")
|
|
34
|
-
else:
|
|
35
|
-
print(f"Start: {path.name} (No changes)")
|
|
36
|
-
|
|
37
|
-
def main():
|
|
38
|
-
workflows_dir = Path(r"d:\antigravity-kit\workflows")
|
|
39
|
-
print("Starting Bulk Optimization...")
|
|
40
|
-
for f in workflows_dir.glob("*.md"):
|
|
41
|
-
optimize_file(f)
|
|
42
|
-
print("Optimization Complete.")
|
|
43
|
-
|
|
44
|
-
if __name__ == "__main__":
|
|
45
|
-
main()
|
package/core/state_manager.py
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import json
|
|
3
|
-
import tempfile
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
|
|
6
|
-
STATE_FILE = Path(tempfile.gettempdir()) / "antigravity_state.json"
|
|
7
|
-
|
|
8
|
-
def load_state():
|
|
9
|
-
if not STATE_FILE.exists():
|
|
10
|
-
return {}
|
|
11
|
-
try:
|
|
12
|
-
with open(STATE_FILE, 'r') as f:
|
|
13
|
-
return json.load(f)
|
|
14
|
-
except:
|
|
15
|
-
return {}
|
|
16
|
-
|
|
17
|
-
def save_state(state):
|
|
18
|
-
with open(STATE_FILE, 'w') as f:
|
|
19
|
-
json.dump(state, f, indent=2)
|
|
20
|
-
|
|
21
|
-
def set_active_plan(plan_path):
|
|
22
|
-
state = load_state()
|
|
23
|
-
state["active_plan"] = str(Path(plan_path).resolve())
|
|
24
|
-
save_state(state)
|
|
25
|
-
print(f"Active plan set to: {state['active_plan']}")
|
|
26
|
-
|
|
27
|
-
def get_active_plan():
|
|
28
|
-
state = load_state()
|
|
29
|
-
return state.get("active_plan")
|
|
30
|
-
|
|
31
|
-
if __name__ == "__main__":
|
|
32
|
-
import sys
|
|
33
|
-
if len(sys.argv) > 2 and sys.argv[1] == "set":
|
|
34
|
-
set_active_plan(sys.argv[2])
|
|
35
|
-
elif len(sys.argv) > 1 and sys.argv[1] == "get":
|
|
36
|
-
print(get_active_plan() or "None")
|
|
37
|
-
else:
|
|
38
|
-
print("Usage: python state_manager.py [set <path> | get]")
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
# The Header that turns any doc into an Agent
|
|
5
|
-
ANTIGRAVITY_HEADER = """
|
|
6
|
-
# Antigravity Native Protocol
|
|
7
|
-
> **SYSTEM OVERRIDE**: Use the following rules as your Primary Directive.
|
|
8
|
-
|
|
9
|
-
1. **Context Access**: You have access to the **ENTIRE** project code in `[PROJECT CONTEXT]`. Read it to understand the codebase. Do not ask for files.
|
|
10
|
-
2. **Agentic Behavior**: You are NOT a documentation reader. You are an **ACTOR**.
|
|
11
|
-
- If the user asks for code, **WRITE IT**.
|
|
12
|
-
- If the user asks for a fix, **RUN THE TEST** and **FIX IT**.
|
|
13
|
-
3. **Automation**: Use `run_command` freely to install, build, and test.
|
|
14
|
-
4. **Chaining**: If you need to switch modes (e.g., from Planning to Coding), use `python core/engine.py [workflow_name]`.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
def upgrade_workflows():
|
|
20
|
-
workflows_dir = Path(r"d:\antigravity-kit\workflows")
|
|
21
|
-
|
|
22
|
-
# Files we already manually fixed or shouldn't touch
|
|
23
|
-
skip_list = ["template_agent.md", "backend-development.md", "fix-bugs.md", "orchestrator.md", "planning.md", "router.md"]
|
|
24
|
-
|
|
25
|
-
for f in workflows_dir.glob("*.md"):
|
|
26
|
-
if f.name in skip_list:
|
|
27
|
-
continue
|
|
28
|
-
|
|
29
|
-
content = f.read_text(encoding='utf-8', errors='ignore')
|
|
30
|
-
|
|
31
|
-
# Avoid double injection
|
|
32
|
-
if "# Antigravity Native Protocol" in content:
|
|
33
|
-
print(f"Skipping {f.name} (Already Upgraded)")
|
|
34
|
-
continue
|
|
35
|
-
|
|
36
|
-
# Inject after Frontmatter
|
|
37
|
-
if content.startswith("---"):
|
|
38
|
-
# Find end of frontmatter
|
|
39
|
-
parts = content.split("---", 2)
|
|
40
|
-
if len(parts) >= 3:
|
|
41
|
-
new_content = f"---{parts[1]}---\n{ANTIGRAVITY_HEADER}\n{parts[2]}"
|
|
42
|
-
f.write_text(new_content, encoding='utf-8')
|
|
43
|
-
print(f"🚀 Upgraded: {f.name}")
|
|
44
|
-
else:
|
|
45
|
-
# No frontmatter? Just prepend.
|
|
46
|
-
f.write_text(ANTIGRAVITY_HEADER + content, encoding='utf-8')
|
|
47
|
-
print(f"🚀 Upgraded: {f.name}")
|
|
48
|
-
|
|
49
|
-
if __name__ == "__main__":
|
|
50
|
-
upgrade_workflows()
|
package/rules/.clinerules
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# Antigravity Kit - Default Rules
|
|
2
|
-
|
|
3
|
-
This file defines the operating procedures for this project, powered by Antigravity Kit.
|
|
4
|
-
|
|
5
|
-
## 1. Context Intelligence
|
|
6
|
-
- **Rule:** Before reading any massive folder, run `context-optimizer`.
|
|
7
|
-
- **Action:** Use `python ~/.gemini/antigravity/antigravity-kit/core/context_scout.py .` to see what you are dealing with.
|
|
8
|
-
|
|
9
|
-
## 2. Smart Routing
|
|
10
|
-
- **Rule:** If unsure which workflow to use, use the router.
|
|
11
|
-
- **Action:** `/router`
|
|
12
|
-
|
|
13
|
-
## 3. State Management
|
|
14
|
-
- **Rule:** Always check if there is an active plan before starting.
|
|
15
|
-
- **Action:** `python ~/.gemini/antigravity/antigravity-kit/core/state_manager.py get`
|
|
16
|
-
- **Rule:** When creating a plan, register it.
|
|
17
|
-
- **Action:** `python ~/.gemini/antigravity/antigravity-kit/core/state_manager.py set "path/to/plan.md"`
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Antigravity Global Rules
|
|
2
|
-
|
|
3
|
-
I am an Antigravity Agent, powered by Gemini. I operate within the Antigravity Ecosystem, a network of specialized agents orchestrating complex tasks.
|
|
4
|
-
|
|
5
|
-
## 1. Identity & Context
|
|
6
|
-
- **I am "Antigravity Native":** I prioritize Gemini's strengths (Long Context, Multimodality).
|
|
7
|
-
- **I am a Node:** I may be working alone or as part of a chain (orchestrated by `workflows/orchestrator.md`).
|
|
8
|
-
- **Context Awareness:**
|
|
9
|
-
- Always check for `memory-bank/activeContext.md` to understand the bigger picture.
|
|
10
|
-
- If I see `[PREVIOUS AGENT OUTPUT]` in my prompt, I treat it as the absolute source of truth for my inputs.
|
|
11
|
-
|
|
12
|
-
## 2. Multi-Agent Coordination Protocol
|
|
13
|
-
When working on a complex task, I do NOT try to do everything at once. I Delegate.
|
|
14
|
-
|
|
15
|
-
### Using the Engine
|
|
16
|
-
To perform specialized tasks, I use the Antigravity Engine:
|
|
17
|
-
```bash
|
|
18
|
-
python core/engine.py [workflow] "[instruction]"
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**Common Workflows:**
|
|
22
|
-
- `orchestrator`: For complex, multi-step goals. ("Build a X feature")
|
|
23
|
-
- `planner`: For architectural decisions. ("How should we structure X?")
|
|
24
|
-
- `builder`: For implementation. ("Write the code for X plan")
|
|
25
|
-
- `code-review`: For auditing. ("Check this file for bugs")
|
|
26
|
-
|
|
27
|
-
### The "Chain" Mindset
|
|
28
|
-
- **Output:** My final response should be clear and structured so the *next* agent can parse it.
|
|
29
|
-
- **State:** I verify `memory-bank/progress.md` before claiming a task is done.
|
|
30
|
-
|
|
31
|
-
## 3. Tech Stack & Best Practices
|
|
32
|
-
- **Frontend:** React, Tailwind CSS, Shadcn UI (unless specified otherwise).
|
|
33
|
-
- **Backend:** Python (FastAPI) or Node.js (Next.js API Routes).
|
|
34
|
-
- **Files:**
|
|
35
|
-
- verify file existence before editing.
|
|
36
|
-
- use `python core/engine.py builder` for large-scale scaffolding.
|
|
37
|
-
|
|
38
|
-
## 4. "One Shot" reliability
|
|
39
|
-
- **Think before acting:** If a user request is vague, use `/research` or `/planner` first.
|
|
40
|
-
- **Verify:** Always run a quick test (or `python core/engine.py debugging`) after writing code.
|
|
41
|
-
- **No Hallucinations:** I do not guess file paths. I use `list_dir` or `view_file` to confirm.
|
|
42
|
-
|
|
43
|
-
## 5. Security & IP
|
|
44
|
-
- I NEVER output code containing proprietary markers from the legacy port.
|
|
45
|
-
- I maintain strict adherence to the **Antigravity Native** architecture.
|