auto-context-cli 1.0.6__tar.gz → 1.0.7__tar.gz
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.
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/PKG-INFO +3 -3
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/README.md +2 -2
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/pyproject.toml +1 -1
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/init_cmd.py +142 -2
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/update_cmd.py +19 -3
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/main.py +4 -2
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/AGENTS.template.md +5 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/GEMINI.template.md +5 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/maintain_context.template.md +5 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rules/code-standards.md +6 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rules/hub-satellite-architecture.md +2 -2
- auto_context_cli-1.0.7/src/auto_context/templates/rules/registry.json +226 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/.gitignore +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/LICENSE +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/__init__.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/__init__.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/import_cmd.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/mcp.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/memory.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/scan_cmd.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/commands/share.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/config.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/scanner.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/security.py +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/context.local.template.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/context.template.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/mcp_config.template.json +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/profile.template.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rule.template.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rules/readme-docs-sync.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rules/security-boundaries.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skill.template.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skills/browser-testing/SKILL.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skills/docker-ops/SKILL.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skills/git-workflow/SKILL.md +0 -0
- {auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skills/server-diagnostics/SKILL.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: auto-context-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.7
|
|
4
4
|
Summary: Autonomous context & instruction manager for AI coding assistants
|
|
5
5
|
Author: Arghya Biswas
|
|
6
6
|
License: MIT
|
|
@@ -20,7 +20,7 @@ Description-Content-Type: text/markdown
|
|
|
20
20
|
|
|
21
21
|
[](https://pypi.org/project/auto-context-cli/)
|
|
22
22
|
[](https://pypi.org/project/auto-context-cli/)
|
|
23
|
-
[](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.
|
|
23
|
+
[](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.7)
|
|
24
24
|
[](https://opensource.org/licenses/MIT)
|
|
25
25
|
[](#-quick-one-line-install)
|
|
26
26
|
[](#-supported-ai-assistants)
|
|
@@ -83,7 +83,7 @@ Auto-Context supports both modern subcommands (`init-context <command>`) and sta
|
|
|
83
83
|
| :--- | :--- | :--- |
|
|
84
84
|
| `init-context init [DIR]` | `init-context [DIR]` | Scaffolds 5-tier context in active or specified directory. |
|
|
85
85
|
| `init-context scan [DIR]` | `init-context --scan` | Stack-adaptive codebase scanner: generates satellites (.agents/context/). |
|
|
86
|
-
| `init-context rule <name>` | `init-context -r <name
|
|
86
|
+
| `init-context rule <name>` | `init-context -r <name> [-a]` | Scaffolds a rule or appends to a domain with `registry.json` duplicate protection. |
|
|
87
87
|
| `init-context skill <name>` | `init-context -s <name>` | Scaffolds a new agent skill directory with triggers & runbook. |
|
|
88
88
|
| `init-context promote <name>` | — | Promotes local workspace rule/skill to Global Plugin & Central Memory. |
|
|
89
89
|
| `init-context update` | — | Modular, non-breaking update for CLI, global plugin & system rules. |
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
[](https://pypi.org/project/auto-context-cli/)
|
|
8
8
|
[](https://pypi.org/project/auto-context-cli/)
|
|
9
|
-
[](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.
|
|
9
|
+
[](https://github.com/Cyber-arghya/auto-context/releases/tag/v1.0.7)
|
|
10
10
|
[](https://opensource.org/licenses/MIT)
|
|
11
11
|
[](#-quick-one-line-install)
|
|
12
12
|
[](#-supported-ai-assistants)
|
|
@@ -69,7 +69,7 @@ Auto-Context supports both modern subcommands (`init-context <command>`) and sta
|
|
|
69
69
|
| :--- | :--- | :--- |
|
|
70
70
|
| `init-context init [DIR]` | `init-context [DIR]` | Scaffolds 5-tier context in active or specified directory. |
|
|
71
71
|
| `init-context scan [DIR]` | `init-context --scan` | Stack-adaptive codebase scanner: generates satellites (.agents/context/). |
|
|
72
|
-
| `init-context rule <name>` | `init-context -r <name
|
|
72
|
+
| `init-context rule <name>` | `init-context -r <name> [-a]` | Scaffolds a rule or appends to a domain with `registry.json` duplicate protection. |
|
|
73
73
|
| `init-context skill <name>` | `init-context -s <name>` | Scaffolds a new agent skill directory with triggers & runbook. |
|
|
74
74
|
| `init-context promote <name>` | — | Promotes local workspace rule/skill to Global Plugin & Central Memory. |
|
|
75
75
|
| `init-context update` | — | Modular, non-breaking update for CLI, global plugin & system rules. |
|
|
@@ -167,6 +167,10 @@ def init(
|
|
|
167
167
|
for rule_file in (templates / "rules").glob("*.md"):
|
|
168
168
|
_copy_if_missing(rule_file, rules_dest / rule_file.name, force=force, dry_run=dry_run)
|
|
169
169
|
|
|
170
|
+
reg_tmpl = templates / "rules" / "registry.json"
|
|
171
|
+
if reg_tmpl.exists():
|
|
172
|
+
_copy_if_missing(reg_tmpl, rules_dest / "registry.json", force=force, dry_run=dry_run)
|
|
173
|
+
|
|
170
174
|
maintain_tmpl = templates / "maintain_context.template.md"
|
|
171
175
|
if maintain_tmpl.exists():
|
|
172
176
|
content = _render(maintain_tmpl, variables)
|
|
@@ -234,14 +238,116 @@ def init(
|
|
|
234
238
|
|
|
235
239
|
# ── rule command ──────────────────────────────────────────────────────────────
|
|
236
240
|
|
|
241
|
+
def _load_registry(registry_file: Path) -> dict:
|
|
242
|
+
if registry_file.exists():
|
|
243
|
+
try:
|
|
244
|
+
import json
|
|
245
|
+
return json.loads(registry_file.read_text(encoding="utf-8"))
|
|
246
|
+
except Exception:
|
|
247
|
+
pass
|
|
248
|
+
tmpl = get_templates_dir() / "rules" / "registry.json"
|
|
249
|
+
if tmpl.exists():
|
|
250
|
+
try:
|
|
251
|
+
import json
|
|
252
|
+
return json.loads(tmpl.read_text(encoding="utf-8"))
|
|
253
|
+
except Exception:
|
|
254
|
+
pass
|
|
255
|
+
return {"version": "1.0.0", "domains": {}}
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _find_duplicate_rule(registry: dict, text_or_title: str) -> Optional[tuple[str, str, str]]:
|
|
259
|
+
import re
|
|
260
|
+
clean_query = re.sub(r"[^a-zA-Z0-9\s]", "", text_or_title).lower().strip()
|
|
261
|
+
query_words = set(w for w in clean_query.split() if len(w) > 3)
|
|
262
|
+
|
|
263
|
+
for d_key, domain in registry.get("domains", {}).items():
|
|
264
|
+
d_file = domain.get("file", f"{d_key}.md")
|
|
265
|
+
for r in domain.get("rules", []):
|
|
266
|
+
r_title = r.get("title", "")
|
|
267
|
+
r_id = r.get("id", "")
|
|
268
|
+
clean_title = re.sub(r"[^a-zA-Z0-9\s]", "", r_title).lower().strip()
|
|
269
|
+
|
|
270
|
+
if clean_query == clean_title or (len(clean_query) > 6 and clean_query in clean_title) or (len(clean_title) > 6 and clean_title in clean_query):
|
|
271
|
+
return d_key, r_title, d_file
|
|
272
|
+
if r_id and r_id in clean_query.replace(" ", "-"):
|
|
273
|
+
return d_key, r_title, d_file
|
|
274
|
+
|
|
275
|
+
r_keywords = set(k.lower() for k in r.get("keywords", []))
|
|
276
|
+
if query_words and len(query_words.intersection(r_keywords)) >= 2:
|
|
277
|
+
return d_key, r_title, d_file
|
|
278
|
+
|
|
279
|
+
return None
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def _register_rule_in_registry(registry_file: Path, domain_key: str, rule_title: str, file_name: str) -> None:
|
|
283
|
+
import json
|
|
284
|
+
import re
|
|
285
|
+
from datetime import date
|
|
286
|
+
|
|
287
|
+
registry = _load_registry(registry_file)
|
|
288
|
+
if "domains" not in registry:
|
|
289
|
+
registry["domains"] = {}
|
|
290
|
+
|
|
291
|
+
if domain_key not in registry["domains"]:
|
|
292
|
+
registry["domains"][domain_key] = {
|
|
293
|
+
"file": file_name,
|
|
294
|
+
"name": domain_key.replace("-", " ").title(),
|
|
295
|
+
"description": f"Domain rules for {domain_key}",
|
|
296
|
+
"rules": []
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
clean_first_line = rule_title.strip().splitlines()[0].strip("* ").strip()
|
|
300
|
+
slug = re.sub(r"[^a-zA-Z0-9\s-]", "", clean_first_line).strip().lower().replace(" ", "-")
|
|
301
|
+
clean_words = [w for w in re.sub(r"[^a-zA-Z0-9\s]", "", clean_first_line).lower().split() if len(w) > 3]
|
|
302
|
+
|
|
303
|
+
existing_ids = [r.get("id") for r in registry["domains"][domain_key].get("rules", [])]
|
|
304
|
+
if slug not in existing_ids:
|
|
305
|
+
registry["domains"][domain_key]["rules"].append({
|
|
306
|
+
"id": slug,
|
|
307
|
+
"title": clean_first_line,
|
|
308
|
+
"keywords": clean_words
|
|
309
|
+
})
|
|
310
|
+
registry["last_updated"] = date.today().isoformat()
|
|
311
|
+
registry_file.parent.mkdir(parents=True, exist_ok=True)
|
|
312
|
+
registry_file.write_text(json.dumps(registry, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def _append_guideline_to_file(dest_file: Path, text_to_append: str) -> None:
|
|
316
|
+
import re
|
|
317
|
+
content = dest_file.read_text(encoding="utf-8")
|
|
318
|
+
existing_nums = [int(m) for m in re.findall(r"(?m)^(\d+)\.\s+\*", content)]
|
|
319
|
+
next_num = (max(existing_nums) + 1) if existing_nums else 1
|
|
320
|
+
|
|
321
|
+
clean_guideline = text_to_append.strip()
|
|
322
|
+
if not re.match(r"^\d+\.\s+", clean_guideline):
|
|
323
|
+
if not clean_guideline.startswith("**"):
|
|
324
|
+
lines = clean_guideline.splitlines()
|
|
325
|
+
title = lines[0]
|
|
326
|
+
rest = lines[1:] if len(lines) > 1 else []
|
|
327
|
+
entry = f"{next_num}. **{title}**\n"
|
|
328
|
+
for r in rest:
|
|
329
|
+
entry += f" {r}\n"
|
|
330
|
+
else:
|
|
331
|
+
entry = f"{next_num}. {clean_guideline}\n"
|
|
332
|
+
else:
|
|
333
|
+
entry = f"{clean_guideline}\n"
|
|
334
|
+
|
|
335
|
+
if not content.endswith("\n"):
|
|
336
|
+
content += "\n"
|
|
337
|
+
content += entry
|
|
338
|
+
dest_file.write_text(content, encoding="utf-8")
|
|
339
|
+
|
|
340
|
+
|
|
237
341
|
def new_rule(
|
|
238
342
|
name: Annotated[str, typer.Argument(help="Rule name (e.g. code-standards).")],
|
|
239
343
|
target: Annotated[Optional[Path], typer.Option("--target", "-t")] = None,
|
|
240
344
|
global_: Annotated[bool, typer.Option("--global", "-g", help="Install into global plugin.")] = False,
|
|
241
345
|
force: Annotated[bool, typer.Option("--force", "-f")] = False,
|
|
346
|
+
append: Annotated[bool, typer.Option("--append", "-a", help="Append guideline to existing rule domain.")] = False,
|
|
347
|
+
guideline: Annotated[Optional[str], typer.Option("--guideline", help="Guideline text to append to rule.")] = None,
|
|
242
348
|
dry_run: Annotated[bool, typer.Option("--dry-run", "-d")] = False,
|
|
243
349
|
) -> None:
|
|
244
|
-
"""Scaffold a new agent rule file."""
|
|
350
|
+
"""Scaffold a new agent rule file or append to an existing domain rule with duplicate guard."""
|
|
245
351
|
clean_name = name.lower().replace(" ", "-").replace("_", "-").removesuffix(".md")
|
|
246
352
|
title = clean_name.replace("-", " ").title()
|
|
247
353
|
|
|
@@ -251,9 +357,43 @@ def new_rule(
|
|
|
251
357
|
else (target or Path.cwd()).resolve() / AGENTS_SUBDIR / "rules"
|
|
252
358
|
)
|
|
253
359
|
dest_file = dest_dir / f"{clean_name}.md"
|
|
360
|
+
registry_file = dest_dir / "registry.json"
|
|
254
361
|
|
|
255
362
|
if dest_file.exists() and not force:
|
|
256
|
-
|
|
363
|
+
if append or guideline:
|
|
364
|
+
text_to_append = guideline or "New domain constraint and best practice."
|
|
365
|
+
|
|
366
|
+
# Check duplicate against registry
|
|
367
|
+
dup = _find_duplicate_rule(_load_registry(registry_file), text_to_append)
|
|
368
|
+
if dup:
|
|
369
|
+
dup_domain, dup_title, dup_file = dup
|
|
370
|
+
console.print(Panel(
|
|
371
|
+
f"[bold yellow]⚠️ Duplicate Rule Detected — Skipped![/]\n"
|
|
372
|
+
f"[white]The guideline '[cyan]{text_to_append}[/]' matches existing rule:\n"
|
|
373
|
+
f"[green]'{dup_title}'[/] inside [yellow]{dup_file}[/] (Domain: [cyan]{dup_domain}[/]).\n\n"
|
|
374
|
+
f"[dim]Registry checked: {registry_file}[/]",
|
|
375
|
+
border_style="yellow",
|
|
376
|
+
))
|
|
377
|
+
return
|
|
378
|
+
|
|
379
|
+
if not dry_run:
|
|
380
|
+
_append_guideline_to_file(dest_file, text_to_append)
|
|
381
|
+
_register_rule_in_registry(registry_file, clean_name, text_to_append, dest_file.name)
|
|
382
|
+
if global_ and config.MEMORY_DIR.exists():
|
|
383
|
+
mem_dest = config.MEMORY_DIR / "rules" / f"{clean_name}.md"
|
|
384
|
+
if mem_dest.exists():
|
|
385
|
+
_append_guideline_to_file(mem_dest, text_to_append)
|
|
386
|
+
_register_rule_in_registry(config.MEMORY_DIR / "rules" / "registry.json", clean_name, text_to_append, dest_file.name)
|
|
387
|
+
console.print(Panel(
|
|
388
|
+
f"[bold green]✨ Rule Domain Updated & Registered![/]\n"
|
|
389
|
+
f"[yellow] Rule:[/] {clean_name}\n"
|
|
390
|
+
f"[cyan] File:[/] {dest_file}\n"
|
|
391
|
+
f"[cyan] Registry:[/] {registry_file}\n"
|
|
392
|
+
f"[green] Added:[/] {text_to_append}",
|
|
393
|
+
border_style="green",
|
|
394
|
+
))
|
|
395
|
+
return
|
|
396
|
+
console.print(f"[yellow][!] Rule already exists:[/] {dest_file}\n Use --append (-a) with --guideline to add to this domain, or --force to overwrite.")
|
|
257
397
|
raise typer.Exit(1)
|
|
258
398
|
|
|
259
399
|
tmpl = get_templates_dir() / "rule.template.md"
|
|
@@ -237,10 +237,20 @@ def update_global_plugin() -> int:
|
|
|
237
237
|
core_files = [
|
|
238
238
|
("plugin.json", plugin_dir / "plugin.json"),
|
|
239
239
|
("plugin/rules/AGENTS.md", rules_dir / "AGENTS.md"),
|
|
240
|
+
("plugin/rules/code-standards.md", rules_dir / "code-standards.md"),
|
|
241
|
+
("plugin/rules/security-boundaries.md", rules_dir / "security-boundaries.md"),
|
|
242
|
+
("plugin/rules/hub-satellite-architecture.md", rules_dir / "hub-satellite-architecture.md"),
|
|
243
|
+
("plugin/rules/readme-docs-sync.md", rules_dir / "readme-docs-sync.md"),
|
|
244
|
+
("plugin/rules/registry.json", rules_dir / "registry.json"),
|
|
240
245
|
("plugin/skills/auto-context/SKILL.md", skills_dir / "SKILL.md"),
|
|
246
|
+
("plugin/skills/browser-testing/SKILL.md", plugin_dir / "skills" / "browser-testing" / "SKILL.md"),
|
|
247
|
+
("plugin/skills/docker-ops/SKILL.md", plugin_dir / "skills" / "docker-ops" / "SKILL.md"),
|
|
248
|
+
("plugin/skills/git-workflow/SKILL.md", plugin_dir / "skills" / "git-workflow" / "SKILL.md"),
|
|
249
|
+
("plugin/skills/server-diagnostics/SKILL.md", plugin_dir / "skills" / "server-diagnostics" / "SKILL.md"),
|
|
241
250
|
]
|
|
242
251
|
|
|
243
252
|
for rel_path, dest_path in core_files:
|
|
253
|
+
dest_path.parent.mkdir(parents=True, exist_ok=True)
|
|
244
254
|
url = f"{config.RAW_GITHUB_BASE}/{rel_path}"
|
|
245
255
|
content = _download_text(url)
|
|
246
256
|
if content:
|
|
@@ -252,10 +262,16 @@ def update_global_plugin() -> int:
|
|
|
252
262
|
tmpl_dir = config.get_templates_dir()
|
|
253
263
|
fallback_map = {
|
|
254
264
|
"AGENTS.md": tmpl_dir / "AGENTS.template.md",
|
|
255
|
-
"SKILL.md": tmpl_dir / "skill.template.md",
|
|
265
|
+
"SKILL.md": tmpl_dir / "skills" / dest_path.parent.name / "SKILL.md" if (tmpl_dir / "skills" / dest_path.parent.name / "SKILL.md").exists() else tmpl_dir / "skill.template.md",
|
|
266
|
+
"code-standards.md": tmpl_dir / "rules" / "code-standards.md",
|
|
267
|
+
"security-boundaries.md": tmpl_dir / "rules" / "security-boundaries.md",
|
|
268
|
+
"hub-satellite-architecture.md": tmpl_dir / "rules" / "hub-satellite-architecture.md",
|
|
269
|
+
"readme-docs-sync.md": tmpl_dir / "rules" / "readme-docs-sync.md",
|
|
270
|
+
"registry.json": tmpl_dir / "rules" / "registry.json",
|
|
256
271
|
}
|
|
257
|
-
|
|
258
|
-
|
|
272
|
+
fb = fallback_map.get(dest_path.name)
|
|
273
|
+
if fb and fb.exists():
|
|
274
|
+
shutil.copy2(fb, dest_path)
|
|
259
275
|
console.print(f" [green][✓] Restored from bundled template:[/] {dest_path.name}")
|
|
260
276
|
updated_count += 1
|
|
261
277
|
|
|
@@ -54,6 +54,8 @@ def root(
|
|
|
54
54
|
env: Annotated[Optional[str], typer.Option("--env", help="Environment variables (KEY=val,KEY2=val2).")] = None,
|
|
55
55
|
global_: Annotated[bool, typer.Option("--global", "-g", help="Target global plugin scope.")] = False,
|
|
56
56
|
force: Annotated[bool, typer.Option("--force", "-f", help="Overwrite existing files.")] = False,
|
|
57
|
+
append: Annotated[bool, typer.Option("--append", "-a", help="Append to existing domain rule.")] = False,
|
|
58
|
+
guideline: Annotated[Optional[str], typer.Option("--guideline", help="Guideline text to append to rule.")] = None,
|
|
57
59
|
dry_run: Annotated[bool, typer.Option("--dry-run", "-d", help="Preview without writing.")] = False,
|
|
58
60
|
scan: Annotated[bool, typer.Option("--scan", help="Run stack-adaptive scanner on target directory.")] = False,
|
|
59
61
|
version: bool = typer.Option(False, "--version", "-v", help="Show version and exit."),
|
|
@@ -69,7 +71,7 @@ def root(
|
|
|
69
71
|
try:
|
|
70
72
|
v = pkg_version("auto-context")
|
|
71
73
|
except Exception:
|
|
72
|
-
v = "1.0.
|
|
74
|
+
v = "1.0.7"
|
|
73
75
|
console.print(f"init-context v{v}")
|
|
74
76
|
raise typer.Exit()
|
|
75
77
|
|
|
@@ -78,7 +80,7 @@ def root(
|
|
|
78
80
|
|
|
79
81
|
# ── Legacy flag routing ────────────────────────────────────────────────────
|
|
80
82
|
if new_rule:
|
|
81
|
-
init_cmd.new_rule(name=new_rule, target=target, global_=global_, force=force, dry_run=dry_run)
|
|
83
|
+
init_cmd.new_rule(name=new_rule, target=target, global_=global_, force=force, append=append, guideline=guideline, dry_run=dry_run)
|
|
82
84
|
return
|
|
83
85
|
|
|
84
86
|
if new_skill:
|
{auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/AGENTS.template.md
RENAMED
|
@@ -45,3 +45,8 @@ Never blindly delete or truncate context:
|
|
|
45
45
|
- `init-context -s <name> [-g]`: Create skill.
|
|
46
46
|
- `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
|
|
47
47
|
- `init-context memory push`: Push updates to central memory.
|
|
48
|
+
|
|
49
|
+
### 7. First-Principles Gatekeeper: Idempotency, KISS, DRY & The Brutal Truth Filter
|
|
50
|
+
- **Strict Idempotency Proof ($f(f(x)) = f(x)$):** All code generation, filesystem operations, and context sync commands must be 100% idempotent. Running them once or 100 times must yield the exact same deterministic state without duplication or side-effects.
|
|
51
|
+
- **Modular, KISS & DRY:** Maintain clean separation of concerns. Prohibit copy-paste duplication, unnecessary abstractions, and monolithic bloat across all project code and context.
|
|
52
|
+
- **The Brutal Truth Filter:** Every idea, design proposal, or architectural suggestion must pass first-principles scrutiny. If an idea or approach fails "The Brutal Truth Filter" (adds needless complexity, breaks DRY/KISS, or solves the wrong problem), **immediately DROP the idea** and proactively notify the user with clear technical rationale instead of blindly building flawed requests.
|
{auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/GEMINI.template.md
RENAMED
|
@@ -45,3 +45,8 @@ Never blindly delete or truncate context:
|
|
|
45
45
|
- `init-context -s <name> [-g]`: Create skill.
|
|
46
46
|
- `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
|
|
47
47
|
- `init-context memory push`: Push updates to central memory.
|
|
48
|
+
|
|
49
|
+
### 7. First-Principles Gatekeeper: Idempotency, KISS, DRY & The Brutal Truth Filter
|
|
50
|
+
- **Strict Idempotency Proof ($f(f(x)) = f(x)$):** All code generation, filesystem operations, and context sync commands must be 100% idempotent. Running them once or 100 times must yield the exact same deterministic state without duplication or side-effects.
|
|
51
|
+
- **Modular, KISS & DRY:** Maintain clean separation of concerns. Prohibit copy-paste duplication, unnecessary abstractions, and monolithic bloat across all project code and context.
|
|
52
|
+
- **The Brutal Truth Filter:** Every idea, design proposal, or architectural suggestion must pass first-principles scrutiny. If an idea or approach fails "The Brutal Truth Filter" (adds needless complexity, breaks DRY/KISS, or solves the wrong problem), **immediately DROP the idea** and proactively notify the user with clear technical rationale instead of blindly building flawed requests.
|
|
@@ -46,3 +46,8 @@ Never blindly delete or truncate context:
|
|
|
46
46
|
- `init-context scan`: Refresh stack-adaptive satellites (`routes.md`, `schema.md`, `gotchas.md`).
|
|
47
47
|
- `init-context update`: Safely sync public rules and upstream capabilities (non-breaking).
|
|
48
48
|
- `init-context memory push`: Push updates to central memory.
|
|
49
|
+
|
|
50
|
+
### 7. First-Principles Gatekeeper: Idempotency, KISS, DRY & The Brutal Truth Filter
|
|
51
|
+
- **Strict Idempotency Proof ($f(f(x)) = f(x)$):** All code generation, filesystem operations, and context sync commands must be 100% idempotent. Running them once or 100 times must yield the exact same deterministic state without duplication or side-effects.
|
|
52
|
+
- **Modular, KISS & DRY:** Maintain clean separation of concerns. Prohibit copy-paste duplication, unnecessary abstractions, and monolithic bloat across all project code and context.
|
|
53
|
+
- **The Brutal Truth Filter:** Every idea, design proposal, or architectural suggestion must pass first-principles scrutiny. If an idea or approach fails "The Brutal Truth Filter" (adds needless complexity, breaks DRY/KISS, or solves the wrong problem), **immediately DROP the idea** and proactively notify the user with clear technical rationale instead of blindly building flawed requests.
|
{auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rules/code-standards.md
RENAMED
|
@@ -22,3 +22,9 @@ Maintain readable, maintainable, modular, and type-safe codebases with clear err
|
|
|
22
22
|
- Log actionable error messages that include relevant context (e.g. invalid inputs, resource identifiers).
|
|
23
23
|
4. **Conventional Git Commits:**
|
|
24
24
|
- Write semantic commit messages (`feat:`, `fix:`, `docs:`, `refactor:`, `chore:`).
|
|
25
|
+
5. **Static Type Annotations & Null Safety:**
|
|
26
|
+
- Enforce explicit type annotations for public functions, parameters, and return types.
|
|
27
|
+
- Prohibit unchecked null / undefined dereferencing.
|
|
28
|
+
6. **Named Constants Over Magic Values:**
|
|
29
|
+
- Replace literal strings and magic numbers with descriptive, uppercase module-level constants.
|
|
30
|
+
7. **Immutable Data Structures**
|
|
@@ -23,8 +23,8 @@ Prevent monolithic context file bloat, eliminate token waste, ensure 100% idempo
|
|
|
23
23
|
- User-written notes, secrets, and manual entries outside anchored zones must remain 100% untouched.
|
|
24
24
|
- Check content hashes before disk writes to avoid unnecessary I/O.
|
|
25
25
|
|
|
26
|
-
3. **The Brutal Truth Filter (Zero Dead Logs):**
|
|
27
|
-
- If an idea, log entry, or feature fails first-principles scrutiny,
|
|
26
|
+
3. **The Brutal Truth Filter (Zero Dead Logs & Flawed Ideas):**
|
|
27
|
+
- If an idea, design approach, log entry, or feature proposal fails first-principles scrutiny, breaks KISS/DRY principles, or does not pass 'The Brutal Truth Filter', **immediately drop the idea and notify the user** with honest technical reasons.
|
|
28
28
|
- Prohibit chronological bug cemeteries (`history.md` dumps of trivial solved bugs).
|
|
29
29
|
- In their place, maintain **`gotchas.md`**: high-impact institutional knowledge, non-obvious architecture traps, port collisions, and edge-case invariants.
|
|
30
30
|
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"last_updated": "2026-11-02",
|
|
4
|
+
"description": "Registry of unique rules and guidelines to prevent duplicates and enforce domain consolidation.",
|
|
5
|
+
"domains": {
|
|
6
|
+
"code-standards": {
|
|
7
|
+
"file": "code-standards.md",
|
|
8
|
+
"name": "Code Quality & Architecture Standards",
|
|
9
|
+
"description": "Clean code, defensive programming, typing, naming, and error handling",
|
|
10
|
+
"rules": [
|
|
11
|
+
{
|
|
12
|
+
"id": "defensive-coding-early-return",
|
|
13
|
+
"title": "Defensive Coding & Early Return",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"guard clauses",
|
|
16
|
+
"early return",
|
|
17
|
+
"nested indentation",
|
|
18
|
+
"input validation",
|
|
19
|
+
"defensive coding"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "clean-code-srp",
|
|
24
|
+
"title": "Clean Code & Self-Documenting Logic",
|
|
25
|
+
"keywords": [
|
|
26
|
+
"single responsibility",
|
|
27
|
+
"srp",
|
|
28
|
+
"clean code",
|
|
29
|
+
"variable names",
|
|
30
|
+
"docstrings"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "structured-error-handling",
|
|
35
|
+
"title": "Structured Error Handling",
|
|
36
|
+
"keywords": [
|
|
37
|
+
"exception handling",
|
|
38
|
+
"empty catch",
|
|
39
|
+
"error logging",
|
|
40
|
+
"try catch"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "conventional-git-commits",
|
|
45
|
+
"title": "Conventional Git Commits",
|
|
46
|
+
"keywords": [
|
|
47
|
+
"commit messages",
|
|
48
|
+
"feat",
|
|
49
|
+
"fix",
|
|
50
|
+
"docs",
|
|
51
|
+
"chore",
|
|
52
|
+
"refactor"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "static-type-annotations",
|
|
57
|
+
"title": "Static Type Annotations & Null Safety",
|
|
58
|
+
"keywords": [
|
|
59
|
+
"type hints",
|
|
60
|
+
"type annotations",
|
|
61
|
+
"null safety",
|
|
62
|
+
"typing",
|
|
63
|
+
"null pointer"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": "named-constants-over-magic-values",
|
|
68
|
+
"title": "Named Constants Over Magic Values",
|
|
69
|
+
"keywords": [
|
|
70
|
+
"magic numbers",
|
|
71
|
+
"literal strings",
|
|
72
|
+
"constants",
|
|
73
|
+
"magic values"
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "immutable-data-structures",
|
|
78
|
+
"title": "Immutable Data Structures",
|
|
79
|
+
"keywords": [
|
|
80
|
+
"immutable",
|
|
81
|
+
"data",
|
|
82
|
+
"structures"
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
"security-boundaries": {
|
|
88
|
+
"file": "security-boundaries.md",
|
|
89
|
+
"name": "Security Boundaries & Secret Safety",
|
|
90
|
+
"description": "Secret protection, API keys, sandbox isolation, and network exposure",
|
|
91
|
+
"rules": [
|
|
92
|
+
{
|
|
93
|
+
"id": "zero-hardcoded-secrets",
|
|
94
|
+
"title": "Zero Hardcoded Secrets",
|
|
95
|
+
"keywords": [
|
|
96
|
+
"api keys",
|
|
97
|
+
"passwords",
|
|
98
|
+
"tokens",
|
|
99
|
+
"private keys",
|
|
100
|
+
"secrets",
|
|
101
|
+
".env"
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "local-sandbox-test-data-isolation",
|
|
106
|
+
"title": "Local Sandbox Test Data Isolation",
|
|
107
|
+
"keywords": [
|
|
108
|
+
"context.local.md",
|
|
109
|
+
"mock credentials",
|
|
110
|
+
"dummy logins",
|
|
111
|
+
"test accounts",
|
|
112
|
+
"git-ignored"
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"id": "public-exposure-boundaries",
|
|
117
|
+
"title": "Public Exposure Boundaries",
|
|
118
|
+
"keywords": [
|
|
119
|
+
"port binding",
|
|
120
|
+
"127.0.0.1",
|
|
121
|
+
"localhost",
|
|
122
|
+
"exposure",
|
|
123
|
+
"tunneling"
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
"hub-satellite-architecture": {
|
|
129
|
+
"file": "hub-satellite-architecture.md",
|
|
130
|
+
"name": "Hub & Satellite Modular Architecture & Idempotency Proof",
|
|
131
|
+
"description": "Context budget, satelittes, deterministic idempotency, and gotchas invariants",
|
|
132
|
+
"rules": [
|
|
133
|
+
{
|
|
134
|
+
"id": "hub-satellite-token-budget",
|
|
135
|
+
"title": "Hub & Satellite Pattern (Strict Token Budget)",
|
|
136
|
+
"keywords": [
|
|
137
|
+
"context.md",
|
|
138
|
+
"satellites",
|
|
139
|
+
"routes.md",
|
|
140
|
+
"schema.md",
|
|
141
|
+
"gotchas.md",
|
|
142
|
+
"token budget"
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"id": "strict-idempotency-proof",
|
|
147
|
+
"title": "Strict Idempotency Proof",
|
|
148
|
+
"keywords": [
|
|
149
|
+
"idempotency",
|
|
150
|
+
"anchored blocks",
|
|
151
|
+
"re-running",
|
|
152
|
+
"deterministic",
|
|
153
|
+
"hash check"
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "brutal-truth-filter",
|
|
158
|
+
"title": "The Brutal Truth Filter (Zero Dead Logs)",
|
|
159
|
+
"keywords": [
|
|
160
|
+
"gotchas.md",
|
|
161
|
+
"anti-patterns",
|
|
162
|
+
"dead logs",
|
|
163
|
+
"bug cemeteries",
|
|
164
|
+
"invariants"
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"id": "kiss-dry-heuristics",
|
|
169
|
+
"title": "KISS & DRY Heuristics",
|
|
170
|
+
"keywords": [
|
|
171
|
+
"convention heuristics",
|
|
172
|
+
"graceful degradation",
|
|
173
|
+
"lightweight scanners"
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
"readme-docs-sync": {
|
|
179
|
+
"file": "readme-docs-sync.md",
|
|
180
|
+
"name": "Mandatory README & Documentation Synchronization",
|
|
181
|
+
"description": "Documentation synchronization for CLI commands, options, and workflows",
|
|
182
|
+
"rules": [
|
|
183
|
+
{
|
|
184
|
+
"id": "zero-undocumented-features",
|
|
185
|
+
"title": "Zero Undocumented Features",
|
|
186
|
+
"keywords": [
|
|
187
|
+
"readme",
|
|
188
|
+
"documentation",
|
|
189
|
+
"docs sync",
|
|
190
|
+
"bengali guide",
|
|
191
|
+
"options table"
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"id": "clear-executable-instructions",
|
|
196
|
+
"title": "Clear & Executable Instructions",
|
|
197
|
+
"keywords": [
|
|
198
|
+
"executable commands",
|
|
199
|
+
"cli examples",
|
|
200
|
+
"options tables",
|
|
201
|
+
"syntax"
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"id": "safety-non-breaking-boundaries",
|
|
206
|
+
"title": "Safety & Non-Breaking Boundaries",
|
|
207
|
+
"keywords": [
|
|
208
|
+
"non-breaking",
|
|
209
|
+
"protection guarantees",
|
|
210
|
+
"custom rules preserve"
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"id": "release-version-alignment",
|
|
215
|
+
"title": "Release Version Alignment",
|
|
216
|
+
"keywords": [
|
|
217
|
+
"version bump",
|
|
218
|
+
"pyproject.toml",
|
|
219
|
+
"tags",
|
|
220
|
+
"release badges"
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/context.template.md
RENAMED
|
File without changes
|
|
File without changes
|
{auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/profile.template.md
RENAMED
|
File without changes
|
{auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/rule.template.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{auto_context_cli-1.0.6 → auto_context_cli-1.0.7}/src/auto_context/templates/skill.template.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|