ai-forge-cli 3.0.0__tar.gz → 3.0.2__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.
Files changed (43) hide show
  1. {ai_forge_cli-3.0.0/src/ai_forge_cli.egg-info → ai_forge_cli-3.0.2}/PKG-INFO +1 -1
  2. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/pyproject.toml +1 -1
  3. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2/src/ai_forge_cli.egg-info}/PKG-INFO +1 -1
  4. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/commands/init.py +56 -22
  5. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/tests/test_context.py +14 -8
  6. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/tests/test_crawler.py +2 -2
  7. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/MANIFEST.in +0 -0
  8. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/README.md +0 -0
  9. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/setup.cfg +0 -0
  10. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/setup.py +0 -0
  11. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/ai_forge_cli.egg-info/SOURCES.txt +0 -0
  12. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/ai_forge_cli.egg-info/dependency_links.txt +0 -0
  13. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/ai_forge_cli.egg-info/entry_points.txt +0 -0
  14. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/ai_forge_cli.egg-info/requires.txt +0 -0
  15. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/ai_forge_cli.egg-info/top_level.txt +0 -0
  16. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/__init__.py +0 -0
  17. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/__main__.py +0 -0
  18. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/assets/audit_template.html +0 -0
  19. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/assets/forge_full_logo.drawio.svg +0 -0
  20. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/assets/forge_white_small.drawio.svg +0 -0
  21. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/commands/__init__.py +0 -0
  22. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/commands/audit.py +0 -0
  23. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/commands/base.py +0 -0
  24. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/commands/context.py +0 -0
  25. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/commands/crawl.py +0 -0
  26. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/common.py +0 -0
  27. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/crawler.py +0 -0
  28. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/forge.py +0 -0
  29. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/FRAMEWORK_V4.md +0 -0
  30. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/SCHEMA_REFERENCE_V4.md +0 -0
  31. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-build/SKILL.md +0 -0
  32. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-build/agents/openai.yaml +0 -0
  33. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-business/SKILL.md +0 -0
  34. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-business/agents/openai.yaml +0 -0
  35. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-hydrate/SKILL.md +0 -0
  36. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-hydrate/agents/openai.yaml +0 -0
  37. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-review/SKILL.md +0 -0
  38. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-review/agents/openai.yaml +0 -0
  39. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-schema/SKILL.md +0 -0
  40. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-schema/agents/openai.yaml +0 -0
  41. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-security/SKILL.md +0 -0
  42. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/resources/skills/forge-security/agents/openai.yaml +0 -0
  43. {ai_forge_cli-3.0.0 → ai_forge_cli-3.0.2}/src/cli/yaml_io.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ai-forge-cli
3
- Version: 3.0.0
3
+ Version: 3.0.2
4
4
  Summary: Forge V4 architecture context CLI
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ai-forge-cli"
7
- version = "3.0.0"
7
+ version = "3.0.2"
8
8
  description = "Forge V4 architecture context CLI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ai-forge-cli
3
- Version: 3.0.0
3
+ Version: 3.0.2
4
4
  Summary: Forge V4 architecture context CLI
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -25,6 +25,7 @@ SKILL_SURFACES = [
25
25
  ".claude/skills",
26
26
  ".codex/skills",
27
27
  ".agents/skills",
28
+ ".copilot/skills",
28
29
  ]
29
30
 
30
31
  DOC_FILES = [
@@ -163,6 +164,7 @@ def _scaffold_repository(target_root: Path, system_name: str, system_id: str) ->
163
164
  _copy_skills(forge_root)
164
165
  _rewrite_skill_references(forge_root)
165
166
  _create_surface_skills(target_root, forge_root)
167
+ _create_github_copilot_context(target_root)
166
168
 
167
169
 
168
170
  def _copy_docs(forge_root: Path) -> None:
@@ -227,10 +229,13 @@ def _rewrite_skill_references(forge_root: Path) -> None:
227
229
  for skill_name in SKILL_DIRS:
228
230
  skill_path = forge_root / "skills" / skill_name / "SKILL.md"
229
231
  text = skill_path.read_text(encoding="utf-8")
230
- if "Read before starting:" in text and "../../USING_FORGE.md" not in text:
232
+ text = text.replace("../../SCHEMA_REFERENCE_V4.md", "forge/SCHEMA_REFERENCE_V4.md")
233
+ text = text.replace("../../FRAMEWORK_V4.md", "forge/FRAMEWORK_V4.md")
234
+ text = text.replace("../../USING_FORGE.md", "forge/USING_FORGE.md")
235
+ if "Read before starting:" in text and "forge/USING_FORGE.md" not in text:
231
236
  text = text.replace(
232
237
  "Read before starting:\n",
233
- "Read before starting:\n\n- `../../USING_FORGE.md`\n",
238
+ "Read before starting:\n\n- `forge/USING_FORGE.md`\n",
234
239
  1,
235
240
  )
236
241
  skill_path.write_text(text, encoding="utf-8")
@@ -253,30 +258,31 @@ def _create_surface_skill(surface_root: Path, forge_root: Path, skill_name: str)
253
258
  target_skill.unlink()
254
259
  else:
255
260
  shutil.rmtree(target_skill)
256
- target_skill.mkdir(parents=True, exist_ok=True)
261
+ target_skill.symlink_to(_relative_symlink_target(surface_root, source_skill), target_is_directory=True)
257
262
 
258
- for child in source_skill.iterdir():
259
- if child.name == "SKILL.md":
260
- continue
261
- target_child = target_skill / child.name
262
- if target_child.exists() or target_child.is_symlink():
263
- if target_child.is_symlink() or target_child.is_file():
264
- target_child.unlink()
265
- else:
266
- shutil.rmtree(target_child)
267
- target_child.symlink_to(_relative_symlink_target(target_skill, child), target_is_directory=child.is_dir())
268
263
 
269
- surfaced_skill = _surface_skill_text(source_skill / "SKILL.md")
270
- (target_skill / "SKILL.md").write_text(surfaced_skill, encoding="utf-8")
264
+ def _create_github_copilot_context(target_root: Path) -> None:
265
+ github_root = target_root / ".github"
266
+ instructions_root = github_root / "instructions"
267
+ prompts_root = github_root / "prompts"
268
+ instructions_root.mkdir(parents=True, exist_ok=True)
269
+ prompts_root.mkdir(parents=True, exist_ok=True)
270
+ _write_text(github_root / "copilot-instructions.md", _copilot_instructions_doc())
271
+ _write_text(instructions_root / "forge.instructions.md", _copilot_path_instructions_doc())
272
+ for skill_name in SKILL_DIRS:
273
+ _create_symlink(
274
+ prompts_root / f"{skill_name}.prompt.md",
275
+ target_root / "forge" / "skills" / skill_name / "SKILL.md",
276
+ )
271
277
 
272
278
 
273
- def _surface_skill_text(skill_path: Path) -> str:
274
- text = skill_path.read_text(encoding="utf-8")
275
- return (
276
- text.replace("../../SCHEMA_REFERENCE_V4.md", "../../../forge/SCHEMA_REFERENCE_V4.md")
277
- .replace("../../FRAMEWORK_V4.md", "../../../forge/FRAMEWORK_V4.md")
278
- .replace("../../USING_FORGE.md", "../../../forge/USING_FORGE.md")
279
- )
279
+ def _create_symlink(link_path: Path, destination: Path) -> None:
280
+ if link_path.exists() or link_path.is_symlink():
281
+ if link_path.is_symlink() or link_path.is_file():
282
+ link_path.unlink()
283
+ else:
284
+ shutil.rmtree(link_path)
285
+ link_path.symlink_to(_relative_symlink_target(link_path.parent, destination), target_is_directory=destination.is_dir())
280
286
 
281
287
 
282
288
  def _relative_symlink_target(link_parent: Path, destination: Path) -> Path:
@@ -309,6 +315,34 @@ def _scaffold_gitignore() -> str:
309
315
  )
310
316
 
311
317
 
318
+ def _copilot_instructions_doc() -> str:
319
+ return """# Forge Instructions
320
+
321
+ This repository uses Forge V4. Start with `forge/USING_FORGE.md`, then use the
322
+ skills in `forge/skills` in this order:
323
+
324
+ 1. `forge-business`
325
+ 2. `forge-schema`
326
+ 3. `forge-review`
327
+ 4. `forge-security`
328
+ 5. `forge-build`
329
+
330
+ Treat `forge/skills` as the canonical skill source. Agent-specific skill
331
+ surfaces are symlinked back to that directory.
332
+ """
333
+
334
+
335
+ def _copilot_path_instructions_doc() -> str:
336
+ return """---
337
+ applyTo: "**"
338
+ ---
339
+
340
+ Use the Forge V4 workflow for repository work. Read `forge/USING_FORGE.md`
341
+ before implementation, and prefer the relevant skill in `forge/skills` for the
342
+ current task.
343
+ """
344
+
345
+
312
346
  def _print_init_summary(target_root: Path, system_name: str, system_id: str) -> None:
313
347
  forge_root = target_root / "forge"
314
348
  print(_banner("FORGE INITIALIZED"))
@@ -117,20 +117,26 @@ def test_init_scaffolds_traversable_repo(tmp_path: Path, capsys) -> None:
117
117
  assert "*.egg-info/" in (root / ".gitignore").read_text(encoding="utf-8")
118
118
  codex_skill = root / ".codex" / "skills" / "forge-build"
119
119
  assert codex_skill.is_dir()
120
- assert not codex_skill.is_symlink()
120
+ assert codex_skill.is_symlink()
121
+ assert codex_skill.resolve() == forge_root / "skills" / "forge-build"
121
122
  assert (codex_skill / "SKILL.md").exists()
122
123
  assert (codex_skill / "agents" / "openai.yaml").exists()
123
124
  assert not (codex_skill / "coding_agent_skills_reference").exists()
124
125
  surfaced_skill = (codex_skill / "SKILL.md").read_text(encoding="utf-8")
125
- assert "../../../forge/USING_FORGE.md" in surfaced_skill
126
+ assert "forge/USING_FORGE.md" in surfaced_skill
126
127
  assert "../forge-schema/SKILL.md" in surfaced_skill
127
- assert (root / ".claude" / "skills" / "forge-business" / "SKILL.md").exists()
128
- assert (root / ".claude" / "skills" / "forge-schema" / "SKILL.md").exists()
129
- assert (root / ".claude" / "skills" / "forge-hydrate" / "SKILL.md").exists()
130
- assert (root / ".agents" / "skills" / "forge-review" / "SKILL.md").exists()
128
+ assert (root / ".claude" / "skills" / "forge-business").is_symlink()
129
+ assert (root / ".claude" / "skills" / "forge-schema").is_symlink()
130
+ assert (root / ".claude" / "skills" / "forge-hydrate").is_symlink()
131
+ assert (root / ".agents" / "skills" / "forge-review").is_symlink()
132
+ assert (root / ".copilot" / "skills" / "forge-security").is_symlink()
133
+ assert (root / ".github" / "copilot-instructions.md").exists()
134
+ assert (root / ".github" / "instructions" / "forge.instructions.md").exists()
135
+ assert (root / ".github" / "prompts" / "forge-build.prompt.md").is_symlink()
136
+ assert (root / ".github" / "prompts" / "forge-build.prompt.md").resolve() == forge_root / "skills" / "forge-build" / "SKILL.md"
131
137
  rewritten_skill = (forge_root / "skills" / "forge-schema" / "SKILL.md").read_text(encoding="utf-8")
132
- assert "../../SCHEMA_REFERENCE_V4.md" in rewritten_skill
133
- assert "../../USING_FORGE.md" in rewritten_skill
138
+ assert "forge/SCHEMA_REFERENCE_V4.md" in rewritten_skill
139
+ assert "forge/USING_FORGE.md" in rewritten_skill
134
140
  usage_doc = (forge_root / "USING_FORGE.md").read_text(encoding="utf-8")
135
141
  assert "Forge is **skills-first**." in usage_doc
136
142
  assert "Use Forge In This Order" in usage_doc
@@ -436,8 +436,8 @@ def test_init_scaffolds_v4_project(tmp_path: Path, capsys) -> None:
436
436
  assert (forge_root / "skills" / "forge-schema" / "SKILL.md").exists()
437
437
  assert (forge_root / "skills" / "forge-hydrate" / "SKILL.md").exists()
438
438
  skill_text = (forge_root / "skills" / "forge-schema" / "SKILL.md").read_text(encoding="utf-8")
439
- assert "../../FRAMEWORK_V4.md" in skill_text
440
- assert "../../SCHEMA_REFERENCE_V4.md" in skill_text
439
+ assert "forge/FRAMEWORK_V4.md" in skill_text
440
+ assert "forge/SCHEMA_REFERENCE_V4.md" in skill_text
441
441
  capsys.readouterr()
442
442
  assert main(["crawl", "--project-dir", str(root)]) == 0
443
443
  payload = json.loads(capsys.readouterr().out)
File without changes
File without changes
File without changes
File without changes