yjcli 0.0.2__tar.gz → 0.0.4__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 (90) hide show
  1. yjcli-0.0.4/PKG-INFO +115 -0
  2. yjcli-0.0.4/README.md +90 -0
  3. {yjcli-0.0.2 → yjcli-0.0.4}/pyproject.toml +1 -1
  4. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/__init__.py +0 -2
  5. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/cli.py +16 -2
  6. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/commands/add.py +4 -1
  7. yjcli-0.0.4/src/yjcli/commands/sync.py +75 -0
  8. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/AGENTS.md +14 -1
  9. yjcli-0.0.4/src/yjcli/data/templates/TOOLS.md +168 -0
  10. yjcli-0.0.4/src/yjcli/services/sync.py +68 -0
  11. yjcli-0.0.4/src/yjcli/services/wiring.py +42 -0
  12. yjcli-0.0.2/PKG-INFO +0 -60
  13. yjcli-0.0.2/README.md +0 -35
  14. yjcli-0.0.2/src/yjcli/services/wiring.py +0 -61
  15. {yjcli-0.0.2 → yjcli-0.0.4}/.gitignore +0 -0
  16. {yjcli-0.0.2 → yjcli-0.0.4}/LICENSE +0 -0
  17. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/__main__.py +0 -0
  18. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/commands/__init__.py +0 -0
  19. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/commands/init_cmd.py +0 -0
  20. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/__init__.py +0 -0
  21. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/claude-rules/output-discipline.md +0 -0
  22. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/claude-rules/skill-backend-msa.md +0 -0
  23. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/claude-rules/skill-backend-service.md +0 -0
  24. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/claude-rules/skill-browser-extension.md +0 -0
  25. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/claude-rules/skill-cli.md +0 -0
  26. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/claude-rules/skill-frontend.md +0 -0
  27. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/claude-rules/skill-mobile-app.md +0 -0
  28. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/claude-rules/skill-pc-app.md +0 -0
  29. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/claude-rules/yj-arch-core.md +0 -0
  30. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/cursor-rules/output-discipline.mdc +0 -0
  31. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/cursor-rules/skill-backend-msa.mdc +0 -0
  32. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/cursor-rules/skill-backend-service.mdc +0 -0
  33. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/cursor-rules/skill-browser-extension.mdc +0 -0
  34. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/cursor-rules/skill-cli.mdc +0 -0
  35. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/cursor-rules/skill-frontend.mdc +0 -0
  36. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/cursor-rules/skill-mobile-app.mdc +0 -0
  37. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/cursor-rules/skill-pc-app.mdc +0 -0
  38. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/cursor-rules/yj-arch-core.mdc +0 -0
  39. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/skills/yj-arch-core/SKILL.md +0 -0
  40. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/skills/yj-backend-msa/SKILL.md +0 -0
  41. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/skills/yj-backend-service/SKILL.md +0 -0
  42. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/skills/yj-browser-extension/SKILL.md +0 -0
  43. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/skills/yj-cli/SKILL.md +0 -0
  44. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/skills/yj-frontend/SKILL.md +0 -0
  45. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/skills/yj-mobile-app/SKILL.md +0 -0
  46. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/skills/yj-pc-app/SKILL.md +0 -0
  47. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/.gitignore +0 -0
  48. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/Makefile +0 -0
  49. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/make.bat +0 -0
  50. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/backend/.env.development +0 -0
  51. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/backend/.env.examples +0 -0
  52. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/backend/.env.local-dev +0 -0
  53. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/backend/.env.production +0 -0
  54. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/backend-service/.env.development +0 -0
  55. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/backend-service/.env.examples +0 -0
  56. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/backend-service/.env.local-dev +0 -0
  57. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/backend-service/.env.production +0 -0
  58. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/browser-extension/.env.development +0 -0
  59. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/browser-extension/.env.examples +0 -0
  60. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/browser-extension/.env.local-dev +0 -0
  61. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/browser-extension/.env.production +0 -0
  62. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/cli/.env.development +0 -0
  63. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/cli/.env.examples +0 -0
  64. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/cli/.env.local-dev +0 -0
  65. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/cli/.env.production +0 -0
  66. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/frontend/.env.development +0 -0
  67. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/frontend/.env.examples +0 -0
  68. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/frontend/.env.local-dev +0 -0
  69. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/frontend/.env.production +0 -0
  70. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/frontend/package.json +0 -0
  71. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/frontend/vite.config.ts +0 -0
  72. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/mobile-app/.env.development +0 -0
  73. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/mobile-app/.env.examples +0 -0
  74. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/mobile-app/.env.local-dev +0 -0
  75. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/mobile-app/.env.production +0 -0
  76. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/pc-app/.env.development +0 -0
  77. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/pc-app/.env.examples +0 -0
  78. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/pc-app/.env.local-dev +0 -0
  79. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/pc-app/.env.production +0 -0
  80. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/scripts/run.bat +0 -0
  81. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/platform/scripts/run.sh +0 -0
  82. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/data/templates/settings.json +0 -0
  83. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/modules/__init__.py +0 -0
  84. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/modules/constants.py +0 -0
  85. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/modules/fsutil.py +0 -0
  86. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/modules/paths.py +0 -0
  87. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/modules/prompt.py +0 -0
  88. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/services/__init__.py +0 -0
  89. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/services/scaffold.py +0 -0
  90. {yjcli-0.0.2 → yjcli-0.0.4}/src/yjcli/services/status.py +0 -0
yjcli-0.0.4/PKG-INFO ADDED
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: yjcli
3
+ Version: 0.0.4
4
+ Summary: Scaffold platforms, services, and AI agent wiring (Cursor/Claude) for YJ architecture repos.
5
+ Project-URL: Homepage, https://github.com/yseiren87/yjcli
6
+ Project-URL: Repository, https://github.com/yseiren87/yjcli
7
+ Project-URL: Issues, https://github.com/yseiren87/yjcli/issues
8
+ Author: yseiren87
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,claude,cli,cursor,scaffold
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Code Generators
21
+ Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.12
23
+ Requires-Dist: typer>=0.12
24
+ Description-Content-Type: text/markdown
25
+
26
+ # yjcli
27
+
28
+ CLI that scaffolds YJ platform folders, services, and Cursor/Claude agent wiring.
29
+
30
+ Templates, skills, and rules ship inside the package and are **copied** into the target repo.
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ uv tool install yjcli
36
+ # pin a version:
37
+ uv tool install yjcli==0.0.3
38
+
39
+ yjcli --version
40
+ yjcli -h
41
+ ```
42
+
43
+ Upgrade / remove:
44
+
45
+ ```bash
46
+ uv tool upgrade yjcli
47
+ uv tool uninstall yjcli
48
+ ```
49
+
50
+ ## Quick start
51
+
52
+ ```bash
53
+ uv tool install yjcli
54
+ cd /path/to/your-repo
55
+ yjcli init --all
56
+ # edit AGENTS.md, then:
57
+ yjcli sync agents
58
+ ```
59
+
60
+ ## Platforms
61
+
62
+ Use with `-p` / `--platform` (repeatable):
63
+
64
+ `backend` · `backend-service` · `frontend` · `mobile-app` · `pc-app` · `cli` · `browser-extension`
65
+
66
+ ## What `init` creates
67
+
68
+ - `AGENTS.md`, `CLAUDE.md` (mirror of `AGENTS.md`)
69
+ - `.cursor/` / `.claude/` skills, rules, and Claude `settings.json`
70
+ - Root `Makefile`, `make.bat`, `TOOLS.md`, `.gitignore`
71
+ - Selected platform roots (and shared `scripts/` helpers)
72
+
73
+ ## Sync
74
+
75
+ | Command | When |
76
+ |---------|------|
77
+ | `yjcli sync agents` | After editing `AGENTS.md` — refreshes `CLAUDE.md` |
78
+ | `yjcli sync skills` | Refresh packaged skills only |
79
+ | `yjcli sync rules` | Refresh packaged rules only |
80
+ | `yjcli sync all` | After upgrading `yjcli` — agents + skills + rules |
81
+
82
+ Edit `AGENTS.md` only; do not edit `CLAUDE.md` by hand.
83
+
84
+ ## Options
85
+
86
+ - `--path <dir>` — target repo root (default: current directory). Works on `init`, `add`, `sync`.
87
+ - `--force` / `-f` — overwrite existing root/agent files without prompting (`init`, `add`).
88
+
89
+ ## Notes
90
+
91
+ - `add service` needs the platform root first (`init` or `add platform`).
92
+ - Non-interactive use requires flags (`-p` / `-n` / `--all`, etc.); omit them only in a TTY prompt.
93
+ - `doctor` checks the **installed package** assets, not your target repo.
94
+
95
+ ## Commands
96
+
97
+ ```bash
98
+ yjcli init
99
+ yjcli init --all
100
+ yjcli init -p backend -p frontend
101
+ yjcli init --force
102
+
103
+ yjcli add platform
104
+ yjcli add platform --all
105
+ yjcli add platform -p cli
106
+
107
+ yjcli add service
108
+ yjcli add service -p backend -n api
109
+
110
+ yjcli sync agents
111
+ yjcli sync skills
112
+ yjcli sync rules
113
+ yjcli sync all
114
+ yjcli doctor
115
+ ```
yjcli-0.0.4/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # yjcli
2
+
3
+ CLI that scaffolds YJ platform folders, services, and Cursor/Claude agent wiring.
4
+
5
+ Templates, skills, and rules ship inside the package and are **copied** into the target repo.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ uv tool install yjcli
11
+ # pin a version:
12
+ uv tool install yjcli==0.0.3
13
+
14
+ yjcli --version
15
+ yjcli -h
16
+ ```
17
+
18
+ Upgrade / remove:
19
+
20
+ ```bash
21
+ uv tool upgrade yjcli
22
+ uv tool uninstall yjcli
23
+ ```
24
+
25
+ ## Quick start
26
+
27
+ ```bash
28
+ uv tool install yjcli
29
+ cd /path/to/your-repo
30
+ yjcli init --all
31
+ # edit AGENTS.md, then:
32
+ yjcli sync agents
33
+ ```
34
+
35
+ ## Platforms
36
+
37
+ Use with `-p` / `--platform` (repeatable):
38
+
39
+ `backend` · `backend-service` · `frontend` · `mobile-app` · `pc-app` · `cli` · `browser-extension`
40
+
41
+ ## What `init` creates
42
+
43
+ - `AGENTS.md`, `CLAUDE.md` (mirror of `AGENTS.md`)
44
+ - `.cursor/` / `.claude/` skills, rules, and Claude `settings.json`
45
+ - Root `Makefile`, `make.bat`, `TOOLS.md`, `.gitignore`
46
+ - Selected platform roots (and shared `scripts/` helpers)
47
+
48
+ ## Sync
49
+
50
+ | Command | When |
51
+ |---------|------|
52
+ | `yjcli sync agents` | After editing `AGENTS.md` — refreshes `CLAUDE.md` |
53
+ | `yjcli sync skills` | Refresh packaged skills only |
54
+ | `yjcli sync rules` | Refresh packaged rules only |
55
+ | `yjcli sync all` | After upgrading `yjcli` — agents + skills + rules |
56
+
57
+ Edit `AGENTS.md` only; do not edit `CLAUDE.md` by hand.
58
+
59
+ ## Options
60
+
61
+ - `--path <dir>` — target repo root (default: current directory). Works on `init`, `add`, `sync`.
62
+ - `--force` / `-f` — overwrite existing root/agent files without prompting (`init`, `add`).
63
+
64
+ ## Notes
65
+
66
+ - `add service` needs the platform root first (`init` or `add platform`).
67
+ - Non-interactive use requires flags (`-p` / `-n` / `--all`, etc.); omit them only in a TTY prompt.
68
+ - `doctor` checks the **installed package** assets, not your target repo.
69
+
70
+ ## Commands
71
+
72
+ ```bash
73
+ yjcli init
74
+ yjcli init --all
75
+ yjcli init -p backend -p frontend
76
+ yjcli init --force
77
+
78
+ yjcli add platform
79
+ yjcli add platform --all
80
+ yjcli add platform -p cli
81
+
82
+ yjcli add service
83
+ yjcli add service -p backend -n api
84
+
85
+ yjcli sync agents
86
+ yjcli sync skills
87
+ yjcli sync rules
88
+ yjcli sync all
89
+ yjcli doctor
90
+ ```
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "yjcli"
3
- version = "0.0.2"
3
+ version = "0.0.4"
4
4
  description = "Scaffold platforms, services, and AI agent wiring (Cursor/Claude) for YJ architecture repos."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -1,3 +1 @@
1
1
  """yjcli — platform/service scaffold and agent wiring."""
2
-
3
- __version__ = "0.0.1"
@@ -2,25 +2,38 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from importlib.metadata import PackageNotFoundError, version
5
6
  from typing import Optional
6
7
 
7
8
  import typer
8
9
 
9
- from yjcli import __version__
10
10
  from yjcli.commands import add
11
+ from yjcli.commands import sync
11
12
  from yjcli.commands.init_cmd import init_cmd
12
13
  from yjcli.services import status
13
14
 
15
+
16
+ def package_version() -> str:
17
+ """Installed package version from pyproject metadata (single source)."""
18
+ try:
19
+ return version("yjcli")
20
+ except PackageNotFoundError:
21
+ return "0.0.0+local"
22
+
23
+
24
+ _HELP_CONTEXT = {"help_option_names": ["-h", "--help"]}
25
+
14
26
  app = typer.Typer(
15
27
  name="yjcli",
16
28
  help="Scaffold YJ platforms/services and Cursor/Claude agent wiring.",
17
29
  no_args_is_help=True,
30
+ context_settings=_HELP_CONTEXT,
18
31
  )
19
32
 
20
33
 
21
34
  def _version_callback(value: bool) -> None:
22
35
  if value:
23
- typer.echo(__version__)
36
+ typer.echo(package_version())
24
37
  raise typer.Exit()
25
38
 
26
39
 
@@ -40,6 +53,7 @@ def main(
40
53
 
41
54
  app.command("init")(init_cmd)
42
55
  app.add_typer(add.app, name="add")
56
+ app.add_typer(sync.app, name="sync")
43
57
 
44
58
 
45
59
  @app.command("doctor")
@@ -10,7 +10,10 @@ import typer
10
10
  from yjcli.modules.constants import PLATFORMS
11
11
  from yjcli.services import scaffold
12
12
 
13
- app = typer.Typer(help="Add a platform or service to the current repo.")
13
+ app = typer.Typer(
14
+ help="Add a platform or service to the current repo.",
15
+ context_settings={"help_option_names": ["-h", "--help"]},
16
+ )
14
17
 
15
18
 
16
19
  @app.command("platform")
@@ -0,0 +1,75 @@
1
+ """yjcli sync <what> — refresh agent docs / skills / rules."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import typer
8
+
9
+ from yjcli.services import sync as sync_svc
10
+
11
+ app = typer.Typer(
12
+ help="Sync AGENTS.md mirror, skills, or rules into the target repo.",
13
+ no_args_is_help=True,
14
+ context_settings={"help_option_names": ["-h", "--help"]},
15
+ )
16
+
17
+
18
+ @app.command("agents")
19
+ def sync_agents(
20
+ path: Path = typer.Option(
21
+ Path("."),
22
+ "--path",
23
+ help="Target repository root (default: cwd).",
24
+ file_okay=False,
25
+ dir_okay=True,
26
+ resolve_path=True,
27
+ ),
28
+ ) -> None:
29
+ """Overwrite CLAUDE.md from AGENTS.md (edit AGENTS.md only)."""
30
+ sync_svc.sync_agents(path)
31
+
32
+
33
+ @app.command("skills")
34
+ def sync_skills(
35
+ path: Path = typer.Option(
36
+ Path("."),
37
+ "--path",
38
+ help="Target repository root (default: cwd).",
39
+ file_okay=False,
40
+ dir_okay=True,
41
+ resolve_path=True,
42
+ ),
43
+ ) -> None:
44
+ """Overwrite .cursor/.claude skills from the yjcli package."""
45
+ sync_svc.sync_skills(path, force=True)
46
+
47
+
48
+ @app.command("rules")
49
+ def sync_rules(
50
+ path: Path = typer.Option(
51
+ Path("."),
52
+ "--path",
53
+ help="Target repository root (default: cwd).",
54
+ file_okay=False,
55
+ dir_okay=True,
56
+ resolve_path=True,
57
+ ),
58
+ ) -> None:
59
+ """Overwrite .cursor/.claude rules from the yjcli package."""
60
+ sync_svc.sync_rules(path, force=True)
61
+
62
+
63
+ @app.command("all")
64
+ def sync_all(
65
+ path: Path = typer.Option(
66
+ Path("."),
67
+ "--path",
68
+ help="Target repository root (default: cwd).",
69
+ file_okay=False,
70
+ dir_okay=True,
71
+ resolve_path=True,
72
+ ),
73
+ ) -> None:
74
+ """Sync AGENTS.md → CLAUDE.md, skills, and rules together."""
75
+ sync_svc.sync_all(path, force=True)
@@ -10,9 +10,21 @@
10
10
 
11
11
  ## 2. Repository layout
12
12
 
13
+ Paths from `yjcli init` are fixed; add platform/app rows with `<path>` / `<role>` as needed.
14
+
13
15
  | Path | Role |
14
16
  |------|------|
15
- | `<path>/` | `<role>` |
17
+ | `AGENTS.md` | Agent / contributor guide (this file) |
18
+ | `CLAUDE.md` | Mirror of `AGENTS.md` — do not edit; refresh with `yjcli sync agents` |
19
+ | `TOOLS.md` | Release-tools feature spec (version / deploy / git) |
20
+ | `Makefile` | Root run entry (`make run PLATFORM=… NAME=…`) |
21
+ | `make.bat` | Windows counterpart of root Makefile |
22
+ | `.gitignore` | Canonical ignore rules |
23
+ | `.cursor/skills/` | Cursor skills (copied from package) |
24
+ | `.cursor/rules/` | Cursor rules (copied from package) |
25
+ | `.claude/skills/` | Claude skills (copied from package) |
26
+ | `.claude/rules/` | Claude rules (copied from package) |
27
+ | `.claude/settings.json` | Claude settings |
16
28
  | `<path>/` | `<role>` |
17
29
  | `<path>/` | `<role>` |
18
30
 
@@ -105,5 +117,6 @@
105
117
 
106
118
  | Kind | Location |
107
119
  |------|----------|
120
+ | Release tools spec | `TOOLS.md` |
108
121
  | `<kind>` | `<path>` |
109
122
  | `<kind>` | `<path>` |
@@ -0,0 +1,168 @@
1
+ # TOOLS.md — Release tools (feature spec)
2
+
3
+ Language-agnostic **feature specification** for local release tooling.
4
+ Not an architecture diary and not tied to a specific stack.
5
+
6
+ **How to use**
7
+
8
+ 1. Keep or copy this file into a repo.
9
+ 2. Fill project-specific facts in §0 (inputs).
10
+ 3. Ask an agent/dev: *Implement TOOLS.md using \<language/toolchain\>.*
11
+ 4. Implementation may be Make + scripts, a small CLI, CI jobs, etc. — as long as behaviors below are met.
12
+
13
+ ---
14
+
15
+ ## 0. Project inputs (fill before implement)
16
+
17
+ | ID | Input | Value |
18
+ |----|--------|--------|
19
+ | I1 | Product / package name | `<name>` |
20
+ | I2 | Canonical version location | `<file + field>` — semver `X.Y.Z` |
21
+ | I3 | Other version mirrors (optional) | `<paths or none>` |
22
+ | I4 | Git root | `<path>` |
23
+ | I5 | Default branch | `<branch>` |
24
+ | I6 | Git remote name + URL | `<origin + url>` |
25
+ | I7 | Production publish target | `<registry/host + package id>` |
26
+ | I8 | Staging publish target (optional) | `<or none>` |
27
+ | I9 | Secrets store | `<e.g. ignored .env path>` |
28
+ | I10 | Secret: publish token name(s) | `<ENV keys>` |
29
+ | I11 | Secret: git push token name (if HTTPS PAT) | `<ENV key or none if SSH>` |
30
+ | I12 | Version tag pattern | `<e.g. vX.Y.Z or release/X.Y.Z>` |
31
+ | I13 | Preferred invoke style | `<make / cli / npm scripts / …>` |
32
+
33
+ ---
34
+
35
+ ## 1. Goals
36
+
37
+ Provide three capabilities, invocable from a single local entry surface (I13):
38
+
39
+ | ID | Capability | Intent |
40
+ |----|------------|--------|
41
+ | C1 | **Version** | Read/bump canonical semver; keep mirrors in sync if any |
42
+ | C2 | **Deploy** | Build and publish artifacts to configured targets |
43
+ | C3 | **Git release** | Commit (optional), tag, push using non-interactive auth when scripted |
44
+
45
+ Out of scope: app business logic, scaffold of product code, editor agent rules (see `AGENTS.md`).
46
+
47
+ ---
48
+
49
+ ## 2. Shared requirements
50
+
51
+ | ID | Requirement |
52
+ |----|-------------|
53
+ | S1 | No secrets in git. Tokens only via I9/I10/I11. |
54
+ | S2 | Destructive steps (publish, push, tag) require explicit confirmation, default **No**. |
55
+ | S3 | User can abort the whole flow with a clear cancel word (recommend `exit`) on any prompt. |
56
+ | S4 | Steps are logged with clear section boundaries (readable in a terminal). |
57
+ | S5 | Missing config/secrets → fail with actionable message (what to set, where). |
58
+ | S6 | Do not force-overwrite existing git tags matching I12 unless the project explicitly opts in (default: **fail**). |
59
+
60
+ ---
61
+
62
+ ## 3. C1 — Version management
63
+
64
+ ### 3.1 Behaviors
65
+
66
+ | ID | Behavior |
67
+ |----|----------|
68
+ | V1 | Read version from I2; must match `X.Y.Z`. |
69
+ | V2 | Support bumps: `major` → `X+1.0.0`, `minor` → `X.Y+1.0`, `fix` → `X.Y.Z+1`. |
70
+ | V3 | After bump, write I2; if I3 is non-empty, update those to the same version. |
71
+ | V4 | Optional: show latest version from production target I7 when query is possible; if unavailable, warn and continue. |
72
+ | V5 | Interactive bump: ask whether to bump; if yes, ask `major`/`minor`/`fix` (invalid/empty → re-ask; cancel per S3). |
73
+ | V6 | Non-interactive mode (optional): accept bump kind via flags/env; do not hang on stdin. |
74
+
75
+ ### 3.2 Acceptance
76
+
77
+ - Given I2 = `1.2.3`, bump `fix` → I2 (and I3) become `1.2.4`.
78
+ - Invalid version string in I2 → hard fail before publish/tag.
79
+
80
+ ---
81
+
82
+ ## 4. C2 — Deploy / publish
83
+
84
+ ### 4.1 Behaviors
85
+
86
+ | ID | Behavior |
87
+ |----|----------|
88
+ | D1 | **Test**: run project-defined verification before publish (unit/smoke/e2e — project chooses). Fail stops the pipeline. |
89
+ | D2 | **Build**: produce publishable artifact(s) for I7 (and I8 if used). |
90
+ | D3 | **Validate** (recommended): dry-run or registry check when the ecosystem supports it. |
91
+ | D4 | **Confirm** then **Publish** to I7 using I10. Default confirm = No. |
92
+ | D5 | Provide a **staging path** when I8 exists: publish to I8 without requiring a version bump or git push (unless project opts in). |
93
+ | D6 | Production path may optionally chain into C3 after successful publish (project chooses). |
94
+
95
+ ### 4.2 Acceptance
96
+
97
+ - Failed D1 or D2 → no publish.
98
+ - Declined confirm → no publish, exit cleanly.
99
+ - Missing I10 → fail per S5.
100
+
101
+ ---
102
+
103
+ ## 5. C3 — Git release (push / tag)
104
+
105
+ ### 5.1 Behaviors
106
+
107
+ | ID | Behavior |
108
+ |----|----------|
109
+ | G1 | Operate only on git root I4. |
110
+ | G2 | Show status: branch, remote I6, current version (I2), whether tag I12(version) exists. |
111
+ | G3 | **Commit** (optional): if working tree dirty, ask to commit; require non-empty message; cancel per S3. If clean, skip. |
112
+ | G4 | **Tag**: create tag from I12 + current I2 version; if exists → fail (S6). |
113
+ | G5 | **Push**: push current branch + new tag to I6. |
114
+ | G6 | Auth: non-interactive for scripted use (PAT from I11 for HTTPS, or SSH agent). Do not open browser login flows in the happy path. |
115
+ | G7 | Never persist raw tokens into remote URLs in git config. |
116
+
117
+ ### 5.2 Acceptance
118
+
119
+ - Clean tree + new version tag → tag created and pushed when confirmed.
120
+ - Existing tag → fail, no force-push by default.
121
+ - Missing I11 when HTTPS PAT is required → fail per S5.
122
+
123
+ ---
124
+
125
+ ## 6. Suggested entry surface (names are free)
126
+
127
+ Implementers pick I13 names; map behaviors roughly like:
128
+
129
+ | Entry | Calls |
130
+ |-------|--------|
131
+ | Help | List entries |
132
+ | Version / bump | C1 |
133
+ | Deploy production | C1 (optional ask) → C2 → optional C3 |
134
+ | Deploy staging | C2 against I8 (usually skip C1 bump & C3) |
135
+ | Git release only | C3 |
136
+
137
+ Exact command names are **not** part of this spec.
138
+
139
+ ---
140
+
141
+ ## 7. Non-goals
142
+
143
+ - Mandating Python/Node/Go/Make/etc.
144
+ - Mandating a `tools/` directory layout.
145
+ - Replacing product CI; this spec may be implemented as CI, local scripts, or both.
146
+ - Defining app platforms, scaffolds, or agent skills.
147
+
148
+ ---
149
+
150
+ ## 8. Implementation notes for agents
151
+
152
+ When asked to implement this file:
153
+
154
+ 1. Read §0 values; if empty, ask the user for I1–I13 before coding.
155
+ 2. Choose toolchain from the user’s language request + existing repo norms.
156
+ 3. Implement C1→C2→C3 against the IDs above; keep secrets out of the repo.
157
+ 4. Add a short “Implemented by” note under §9 (paths to scripts/workflows only).
158
+
159
+ ---
160
+
161
+ ## 9. Implemented by (fill after coding)
162
+
163
+ | Capability | Entry / path |
164
+ |------------|----------------|
165
+ | C1 Version | `<…>` |
166
+ | C2 Deploy | `<…>` |
167
+ | C3 Git release | `<…>` |
168
+ | Secrets example | `<…>` |
@@ -0,0 +1,68 @@
1
+ """Sync agent docs / skills / rules into a target repo."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import typer
8
+
9
+ from yjcli.modules import paths
10
+ from yjcli.modules.fsutil import copy_file, copy_tree, ensure_real_dir
11
+ from yjcli.modules.prompt import abort
12
+
13
+
14
+ def sync_agents(root: Path) -> None:
15
+ """Overwrite CLAUDE.md from AGENTS.md (AGENTS.md is the source of truth)."""
16
+ agents = root / "AGENTS.md"
17
+ claude = root / "CLAUDE.md"
18
+ if not agents.is_file():
19
+ abort(f"missing {agents} (edit AGENTS.md first)")
20
+ copy_file(agents, claude, force=True)
21
+ typer.echo("synced: AGENTS.md -> CLAUDE.md")
22
+
23
+
24
+ def sync_skills(root: Path, *, force: bool = True) -> None:
25
+ """Copy packaged skills into .cursor/skills and .claude/skills."""
26
+ cursor_skills = root / ".cursor" / "skills"
27
+ claude_skills = root / ".claude" / "skills"
28
+ ensure_real_dir(cursor_skills)
29
+ ensure_real_dir(claude_skills)
30
+
31
+ skills_root = paths.skills_dir()
32
+ if not skills_root.is_dir():
33
+ abort(f"missing packaged skills: {skills_root}")
34
+
35
+ for skill_dir in sorted(p for p in skills_root.iterdir() if p.is_dir()):
36
+ name = skill_dir.name
37
+ copy_tree(skill_dir, cursor_skills / name, force=force)
38
+ copy_tree(skill_dir, claude_skills / name, force=force)
39
+ typer.echo("synced: packaged skills -> .cursor/skills, .claude/skills")
40
+
41
+
42
+ def sync_rules(root: Path, *, force: bool = True) -> None:
43
+ """Copy packaged rules into .cursor/rules and .claude/rules."""
44
+ cursor_rules = root / ".cursor" / "rules"
45
+ claude_rules = root / ".claude" / "rules"
46
+ ensure_real_dir(cursor_rules)
47
+ ensure_real_dir(claude_rules)
48
+
49
+ cursor_src = paths.cursor_rules_dir()
50
+ claude_src = paths.claude_rules_dir()
51
+ if not cursor_src.is_dir() and not claude_src.is_dir():
52
+ abort("missing packaged cursor/claude rules")
53
+
54
+ for rule_file in sorted(cursor_src.glob("*")):
55
+ if rule_file.is_file():
56
+ copy_file(rule_file, cursor_rules / rule_file.name, force=force)
57
+
58
+ for rule_file in sorted(claude_src.glob("*")):
59
+ if rule_file.is_file():
60
+ copy_file(rule_file, claude_rules / rule_file.name, force=force)
61
+ typer.echo("synced: packaged rules -> .cursor/rules, .claude/rules")
62
+
63
+
64
+ def sync_all(root: Path, *, force: bool = True) -> None:
65
+ """Sync AGENTS.md mirror, skills, and rules in one shot."""
66
+ sync_agents(root)
67
+ sync_skills(root, force=force)
68
+ sync_rules(root, force=force)
@@ -0,0 +1,42 @@
1
+ """Copy packaged Cursor/Claude skills & rules into a target repo."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import typer
8
+
9
+ from yjcli.modules import paths
10
+ from yjcli.modules.fsutil import copy_file
11
+ from yjcli.services import sync as sync_svc
12
+
13
+
14
+ def ensure_agent_wiring(root: Path, *, force: bool = False) -> None:
15
+ """Install AGENTS docs, skills, rules, and Claude settings; mirror CLAUDE.md."""
16
+ templates = paths.templates_dir()
17
+ agents_src = templates / "AGENTS.md"
18
+ settings_src = templates / "settings.json"
19
+ if not agents_src.is_file():
20
+ raise FileNotFoundError(f"missing template: {agents_src}")
21
+ if not settings_src.is_file():
22
+ raise FileNotFoundError(f"missing template: {settings_src}")
23
+
24
+ copy_file(agents_src, root / "AGENTS.md", force=force)
25
+ # CLAUDE.md is always a mechanical mirror of AGENTS.md (never edited by hand).
26
+ if (root / "AGENTS.md").is_file():
27
+ sync_svc.sync_agents(root)
28
+
29
+ sync_svc.sync_skills(root, force=force)
30
+ sync_svc.sync_rules(root, force=force)
31
+ copy_file(settings_src, root / ".claude" / "settings.json", force=force)
32
+
33
+
34
+ def ensure_root_from_templates(root: Path, *, force: bool = False) -> None:
35
+ """Copy root Makefile / TOOLS.md / .gitignore / make.bat from packaged templates."""
36
+ templates = paths.templates_dir()
37
+ for name in (".gitignore", "Makefile", "make.bat", "TOOLS.md"):
38
+ src = templates / name
39
+ if not src.is_file():
40
+ typer.echo(f"warn: missing template: {src}", err=True)
41
+ continue
42
+ copy_file(src, root / name, force=force)
yjcli-0.0.2/PKG-INFO DELETED
@@ -1,60 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: yjcli
3
- Version: 0.0.2
4
- Summary: Scaffold platforms, services, and AI agent wiring (Cursor/Claude) for YJ architecture repos.
5
- Project-URL: Homepage, https://github.com/yseiren87/yjcli
6
- Project-URL: Repository, https://github.com/yseiren87/yjcli
7
- Project-URL: Issues, https://github.com/yseiren87/yjcli/issues
8
- Author: yseiren87
9
- License-Expression: MIT
10
- License-File: LICENSE
11
- Keywords: agent,claude,cli,cursor,scaffold
12
- Classifier: Development Status :: 3 - Alpha
13
- Classifier: Environment :: Console
14
- Classifier: Intended Audience :: Developers
15
- Classifier: License :: OSI Approved :: MIT License
16
- Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.12
18
- Classifier: Programming Language :: Python :: 3.13
19
- Classifier: Programming Language :: Python :: 3.14
20
- Classifier: Topic :: Software Development :: Code Generators
21
- Classifier: Topic :: Utilities
22
- Requires-Python: >=3.12
23
- Requires-Dist: typer>=0.12
24
- Description-Content-Type: text/markdown
25
-
26
- # yjcli
27
-
28
- CLI that scaffolds YJ platform folders, services, and Cursor/Claude agent wiring.
29
-
30
- Templates, skills, and rules ship inside the package (`src/yjcli/data/`) and are **copied** into the target repo (no `.agent` / symlink).
31
-
32
- ## Develop
33
-
34
- ```bash
35
- uv sync
36
- uv run yjcli --help
37
- uv run yjcli --version
38
- ```
39
-
40
- Version: `pyproject.toml` / `src/yjcli/__init__.py`.
41
-
42
- ## Commands
43
-
44
- ```bash
45
- # Bootstrap: AGENTS.md/CLAUDE.md, .cursor/.claude skills+rules,
46
- # root Makefile/.gitignore, selected platform roots.
47
- uv run yjcli init
48
- uv run yjcli init --all
49
- uv run yjcli init -p backend -p frontend
50
- uv run yjcli init --force # overwrite existing agent assets
51
-
52
- uv run yjcli add platform # interactive: add missing platforms
53
- uv run yjcli add platform --all
54
- uv run yjcli add platform -p cli
55
-
56
- uv run yjcli add service # interactive
57
- uv run yjcli add service -p backend -n api
58
-
59
- uv run yjcli doctor # packaged asset sanity check
60
- ```
yjcli-0.0.2/README.md DELETED
@@ -1,35 +0,0 @@
1
- # yjcli
2
-
3
- CLI that scaffolds YJ platform folders, services, and Cursor/Claude agent wiring.
4
-
5
- Templates, skills, and rules ship inside the package (`src/yjcli/data/`) and are **copied** into the target repo (no `.agent` / symlink).
6
-
7
- ## Develop
8
-
9
- ```bash
10
- uv sync
11
- uv run yjcli --help
12
- uv run yjcli --version
13
- ```
14
-
15
- Version: `pyproject.toml` / `src/yjcli/__init__.py`.
16
-
17
- ## Commands
18
-
19
- ```bash
20
- # Bootstrap: AGENTS.md/CLAUDE.md, .cursor/.claude skills+rules,
21
- # root Makefile/.gitignore, selected platform roots.
22
- uv run yjcli init
23
- uv run yjcli init --all
24
- uv run yjcli init -p backend -p frontend
25
- uv run yjcli init --force # overwrite existing agent assets
26
-
27
- uv run yjcli add platform # interactive: add missing platforms
28
- uv run yjcli add platform --all
29
- uv run yjcli add platform -p cli
30
-
31
- uv run yjcli add service # interactive
32
- uv run yjcli add service -p backend -n api
33
-
34
- uv run yjcli doctor # packaged asset sanity check
35
- ```
@@ -1,61 +0,0 @@
1
- """Copy packaged Cursor/Claude skills & rules into a target repo."""
2
-
3
- from __future__ import annotations
4
-
5
- from pathlib import Path
6
-
7
- import typer
8
-
9
- from yjcli.modules import paths
10
- from yjcli.modules.fsutil import copy_file, copy_tree, ensure_real_dir
11
-
12
-
13
- def ensure_agent_wiring(root: Path, *, force: bool = False) -> None:
14
- """Install AGENTS/CLAUDE docs, skills, rules, and Claude settings."""
15
- templates = paths.templates_dir()
16
- agents_src = templates / "AGENTS.md"
17
- settings_src = templates / "settings.json"
18
- if not agents_src.is_file():
19
- raise FileNotFoundError(f"missing template: {agents_src}")
20
- if not settings_src.is_file():
21
- raise FileNotFoundError(f"missing template: {settings_src}")
22
-
23
- copy_file(agents_src, root / "AGENTS.md", force=force)
24
- copy_file(agents_src, root / "CLAUDE.md", force=force)
25
-
26
- cursor_skills = root / ".cursor" / "skills"
27
- claude_skills = root / ".claude" / "skills"
28
- cursor_rules = root / ".cursor" / "rules"
29
- claude_rules = root / ".claude" / "rules"
30
- ensure_real_dir(cursor_skills)
31
- ensure_real_dir(claude_skills)
32
- ensure_real_dir(cursor_rules)
33
- ensure_real_dir(claude_rules)
34
-
35
- skills_root = paths.skills_dir()
36
- if skills_root.is_dir():
37
- for skill_dir in sorted(p for p in skills_root.iterdir() if p.is_dir()):
38
- name = skill_dir.name
39
- copy_tree(skill_dir, cursor_skills / name, force=force)
40
- copy_tree(skill_dir, claude_skills / name, force=force)
41
-
42
- for rule_file in sorted(paths.cursor_rules_dir().glob("*")):
43
- if rule_file.is_file():
44
- copy_file(rule_file, cursor_rules / rule_file.name, force=force)
45
-
46
- for rule_file in sorted(paths.claude_rules_dir().glob("*")):
47
- if rule_file.is_file():
48
- copy_file(rule_file, claude_rules / rule_file.name, force=force)
49
-
50
- copy_file(settings_src, root / ".claude" / "settings.json", force=force)
51
-
52
-
53
- def ensure_root_from_templates(root: Path, *, force: bool = False) -> None:
54
- """Copy root Makefile / .gitignore / make.bat from packaged templates."""
55
- templates = paths.templates_dir()
56
- for name in (".gitignore", "Makefile", "make.bat"):
57
- src = templates / name
58
- if not src.is_file():
59
- typer.echo(f"warn: missing template: {src}", err=True)
60
- continue
61
- copy_file(src, root / name, force=force)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes