codex-coach 0.1.0 → 0.1.3

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-coach",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "Local-first Codex usage coach that analyzes logs and suggests workflow improvements.",
5
5
  "author": {
6
6
  "name": "Codex Coach Contributors"
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Codex Coach
2
2
 
3
- ![Codex Coach logo](https://cdn.jsdelivr.net/npm/codex-coach@0.1.0/assets/brand/codex-coach-logo.png)
3
+ ![Codex Coach banner](assets/brand/codex-coach-banner.png)
4
4
 
5
5
  Codex Coach is a local-first usage coach for Codex users. It reads Codex session logs on your machine, generates redacted habit reports, and suggests reviewable improvements to your Codex configuration and project instructions.
6
6
 
@@ -48,6 +48,9 @@ codex-coach scan --since 7d
48
48
  codex-coach report --since 7d
49
49
  codex-coach report --since 7d --mode expert
50
50
  codex-coach suggest-config
51
+ codex-coach instructions scan --since 30d
52
+ codex-coach instructions report --since 30d
53
+ codex-coach instructions suggest --since 30d
51
54
  codex-coach lint-prompt "fix the failing auth test and verify pytest passes"
52
55
  ```
53
56
 
@@ -71,6 +74,7 @@ Suggest custom instruction changes
71
74
  - `~/.codex-coach/reports/latest.md`
72
75
  - `~/.codex-coach/reports/weekly-YYYY-MM-DD.md`
73
76
  - `~/.codex-coach/facts/latest.json`
77
+ - `~/.codex-coach/instructions/index.json`
74
78
  - `~/.codex-coach/suggestions/*.patch.md`
75
79
 
76
80
  ## Coaching Features
@@ -81,17 +85,10 @@ Suggest custom instruction changes
81
85
  - Beginner and expert report modes.
82
86
  - Skill opportunities: repeated workflow patterns that may deserve a reusable Codex skill.
83
87
  - Real-time prompt linting through `codex-coach lint-prompt`.
84
-
85
- ## Visual Examples
86
-
87
- ![How Codex Coach works](https://cdn.jsdelivr.net/npm/codex-coach@0.1.0/assets/examples/how-it-works.png)
88
-
89
- ![Prompt lint example](https://cdn.jsdelivr.net/npm/codex-coach@0.1.0/assets/examples/prompt-lint.png)
90
-
91
- ![Project capsules example](https://cdn.jsdelivr.net/npm/codex-coach@0.1.0/assets/examples/project-capsules.png)
88
+ - Instruction Playbook Audit: review global custom instructions and project `AGENTS.md` files for stale mode locks, scope leaks, missing verification rules, secrets, and active projects without a playbook.
92
89
 
93
90
  ## Brand Assets
94
91
 
95
- - Wide logo: `assets/brand/codex-coach-logo.png`
92
+ - Main README banner: `assets/brand/codex-coach-banner.png`
93
+ - Wide logo/social preview: `assets/brand/codex-coach-logo.png`
96
94
  - Square icon: `assets/brand/codex-coach-icon.png`
97
- - Editable SVG sources live beside each PNG.
Binary file
Binary file
package/package.json CHANGED
@@ -1,9 +1,17 @@
1
1
  {
2
2
  "name": "codex-coach",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "Local-first Codex usage coach and plugin",
5
5
  "license": "MIT",
6
6
  "author": "Codex Coach Contributors",
7
+ "homepage": "https://github.com/johnvouros/codexcoach#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/johnvouros/codexcoach.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/johnvouros/codexcoach/issues"
14
+ },
7
15
  "type": "commonjs",
8
16
  "bin": {
9
17
  "codex-coach": "bin/codex-coach.js"
@@ -12,6 +20,9 @@
12
20
  "assets/",
13
21
  "bin/",
14
22
  "src/",
23
+ "!src/**/__pycache__/**",
24
+ "!src/**/*.pyc",
25
+ "!src/**/*.pyo",
15
26
  "skills/",
16
27
  ".codex-plugin/",
17
28
  "install.sh",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "codex-coach"
7
- version = "0.1.0"
7
+ version = "0.1.3"
8
8
  description = "Local-first Codex usage coach and plugin"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -13,6 +13,11 @@ authors = [{ name = "Codex Coach Contributors" }]
13
13
  keywords = ["codex", "ai", "developer-tools", "analytics", "prompting"]
14
14
  dependencies = []
15
15
 
16
+ [project.urls]
17
+ Homepage = "https://github.com/johnvouros/codexcoach"
18
+ Repository = "https://github.com/johnvouros/codexcoach"
19
+ Issues = "https://github.com/johnvouros/codexcoach/issues"
20
+
16
21
  [project.scripts]
17
22
  codex-coach = "codex_coach.cli:main"
18
23
 
@@ -36,13 +36,20 @@ codex-coach report --since 7d --mode expert
36
36
  codex-coach suggest-config --since 7d
37
37
  ```
38
38
 
39
- 6. For a prompt the user is drafting, lint it directly:
39
+ 6. For custom instructions or `AGENTS.md` health, run the playbook audit:
40
+
41
+ ```sh
42
+ codex-coach instructions report --since 30d
43
+ codex-coach instructions suggest --since 30d
44
+ ```
45
+
46
+ 7. For a prompt the user is drafting, lint it directly:
40
47
 
41
48
  ```sh
42
49
  codex-coach lint-prompt "fix the login bug"
43
50
  ```
44
51
 
45
- 7. Explain that suggestions are reviewable and are not applied automatically.
52
+ 8. Explain that suggestions are reviewable and are not applied automatically.
46
53
 
47
54
  ## User Modes
48
55
 
@@ -56,6 +63,7 @@ codex-coach lint-prompt "fix the login bug"
56
63
  - Prompt rewrites: show the redacted preview and the safer template, not the raw original prompt.
57
64
  - Confidence: keep low-confidence suggestions tentative; high-confidence suggestions can be presented as the next best habit.
58
65
  - Skill opportunities: if the report flags a repeated workflow, suggest a small user skill with trigger, context to gather, verification commands, and resume rules.
66
+ - Instruction Playbook: surface stale mode locks, project-specific global rules, missing project playbooks, missing verification cues, and secret-shaped values without quoting raw instruction text.
59
67
 
60
68
  ## Guardrails
61
69
 
@@ -33,3 +33,13 @@ For repeated workflows, prefer a user skill over a long global instruction:
33
33
  ```md
34
34
  When this workflow appears, gather [project context], follow [steps], verify with [commands], and resume from [ledger/checklist] after interruption.
35
35
  ```
36
+
37
+ Instruction Playbook Audit checks:
38
+
39
+ - Stale mode locks: standing rules such as "research only" or "do not implement" that may belong to a temporary task mode.
40
+ - Scope leaks: stack, UI style, or command rules in global custom instructions that should live in a project `AGENTS.md`.
41
+ - Missing verification cues: active projects with implementation-heavy usage but no test/build/lint/verify guidance.
42
+ - Missing playbooks: active project directories with no discovered nearby `AGENTS.md`.
43
+ - Safety issues: secret-shaped values or credentials in instruction files.
44
+
45
+ Suggested edits should be small, reversible, and phrased as snippets for the user to review.
@@ -6,13 +6,14 @@ Default inputs:
6
6
 
7
7
  - `~/.codex/sessions/**/*.jsonl`
8
8
  - `~/.codex/archived_sessions/*.jsonl`
9
- - Optional Codex config and project metadata only when a user asks for deeper recommendations.
9
+ - Optional Codex config, global instruction files, and project `AGENTS.md` metadata for Instruction Playbook Audit.
10
10
 
11
11
  Default outputs:
12
12
 
13
13
  - `~/.codex-coach/facts/latest.json`
14
14
  - `~/.codex-coach/reports/latest.md`
15
15
  - `~/.codex-coach/reports/weekly-YYYY-MM-DD.md`
16
+ - `~/.codex-coach/instructions/index.json`
16
17
  - `~/.codex-coach/suggestions/*.patch.md`
17
18
 
18
19
  Default redaction:
@@ -23,3 +24,4 @@ Default redaction:
23
24
  - Prompt rewrites are generated as generic templates and do not include raw private details.
24
25
  - Project capsules use redacted project labels instead of full local paths.
25
26
  - Config suggestions are written as review files and are not applied automatically.
27
+ - Instruction audits store hashes, sizes, categories, and suggested snippets; they do not write raw instruction file bodies to reports or facts.
@@ -6,11 +6,19 @@ import sys
6
6
  from datetime import UTC, datetime
7
7
  from pathlib import Path
8
8
 
9
+ from .instruction_audit import analyze_instructions
9
10
  from .install import install_from_source, uninstall
10
11
  from .parser import iter_log_paths, scan_logs
11
12
  from .paths import default_paths
12
13
  from .prompts import score_prompt
13
- from .reports import render_markdown_report, write_json_facts, write_markdown_report, write_suggestion_files
14
+ from .reports import (
15
+ render_instruction_report,
16
+ render_markdown_report,
17
+ write_instruction_suggestion_files,
18
+ write_json_facts,
19
+ write_markdown_report,
20
+ write_suggestion_files,
21
+ )
14
22
  from .timeutil import parse_since
15
23
 
16
24
 
@@ -34,6 +42,15 @@ def main(argv: list[str] | None = None) -> int:
34
42
  suggest = sub.add_parser("suggest-config", help="Write reviewable config suggestion files")
35
43
  suggest.add_argument("--since", default="7d")
36
44
 
45
+ instructions = sub.add_parser("instructions", help="Audit Codex custom instructions and project AGENTS.md files")
46
+ instructions_sub = instructions.add_subparsers(dest="instructions_command", required=True)
47
+ instructions_scan = instructions_sub.add_parser("scan", help="Write instruction audit facts")
48
+ instructions_scan.add_argument("--since", default="30d")
49
+ instructions_report = instructions_sub.add_parser("report", help="Write an instruction playbook report")
50
+ instructions_report.add_argument("--since", default="30d")
51
+ instructions_suggest = instructions_sub.add_parser("suggest", help="Write reviewable instruction suggestion files")
52
+ instructions_suggest.add_argument("--since", default="30d")
53
+
37
54
  lint = sub.add_parser("lint-prompt", help="Score one prompt and suggest a safer rewrite")
38
55
  lint.add_argument("prompt", nargs="*", help="Prompt text. Reads stdin when omitted.")
39
56
  lint.add_argument("--json", action="store_true", help="Write machine-readable JSON")
@@ -68,6 +85,8 @@ def main(argv: list[str] | None = None) -> int:
68
85
  for path in written:
69
86
  print(f"Wrote suggestion {path}")
70
87
  return 0
88
+ if args.command == "instructions":
89
+ return _instructions(paths, args.instructions_command, args.since)
71
90
  if args.command == "lint-prompt":
72
91
  prompt_text = " ".join(args.prompt).strip() if args.prompt else sys.stdin.read().strip()
73
92
  return _lint_prompt(prompt_text, as_json=args.json)
@@ -94,11 +113,47 @@ def _scan(paths, since: str) -> dict:
94
113
  since_dt = parse_since(since)
95
114
  paths.ensure_output_dirs()
96
115
  facts = scan_logs(paths.codex_home, since_dt=since_dt, since_label=since)
116
+ facts["instruction_audit"] = analyze_instructions(
117
+ paths.home,
118
+ paths.codex_home,
119
+ since_dt=since_dt,
120
+ since_label=since,
121
+ usage_facts=facts,
122
+ )
97
123
  facts["generated_at"] = datetime.now(UTC).isoformat(timespec="seconds")
98
124
  write_json_facts(facts, paths.facts_dir / "latest.json")
125
+ write_json_facts(facts["instruction_audit"], paths.instructions_dir / "index.json")
99
126
  return facts
100
127
 
101
128
 
129
+ def _instructions(paths, command: str, since: str) -> int:
130
+ facts = _scan(paths, since)
131
+ audit = facts.get("instruction_audit", {})
132
+ if command == "scan":
133
+ print(f"Wrote instruction audit to {paths.instructions_dir / 'index.json'}")
134
+ return 0
135
+ if command == "report":
136
+ generated_at = datetime.now(UTC)
137
+ report_text = render_instruction_report(audit, generated_at=generated_at)
138
+ paths.reports_dir.mkdir(parents=True, exist_ok=True)
139
+ latest = paths.reports_dir / "instructions-latest.md"
140
+ weekly = paths.reports_dir / f"instructions-{generated_at.date().isoformat()}.md"
141
+ latest.write_text(report_text, encoding="utf-8")
142
+ weekly.write_text(report_text, encoding="utf-8")
143
+ print(f"Wrote instruction report to {latest}")
144
+ print(f"Wrote dated copy to {weekly}")
145
+ return 0
146
+ if command == "suggest":
147
+ written = write_instruction_suggestion_files(audit, paths.suggestions_dir)
148
+ if written:
149
+ for path in written:
150
+ print(f"Wrote instruction suggestion {path}")
151
+ else:
152
+ print("No instruction suggestions found")
153
+ return 0
154
+ raise ValueError(f"unknown instructions command: {command}")
155
+
156
+
102
157
  def _doctor(paths) -> int:
103
158
  log_paths = iter_log_paths(paths.codex_home)
104
159
  print(f"home: {paths.home}")
@@ -106,6 +161,7 @@ def _doctor(paths) -> int:
106
161
  print(f"coach_home: {paths.coach_home}")
107
162
  print(f"log_files: {len(log_paths)}")
108
163
  print(f"reports_dir: {paths.reports_dir}")
164
+ print(f"instructions_dir: {paths.instructions_dir}")
109
165
  command = paths.home / ".local" / "bin" / "codex-coach"
110
166
  print(f"command: {command} {'OK' if command.exists() else 'not installed'}")
111
167
  plugin = paths.home / "plugins" / "codex-coach" / ".codex-plugin" / "plugin.json"
@@ -15,7 +15,8 @@ def install_from_source(source_root: Path, paths: CoachPaths, *, schedule: str =
15
15
  paths.ensure_output_dirs()
16
16
  paths.coach_home.mkdir(parents=True, exist_ok=True)
17
17
  _write_default_config(paths, schedule=schedule)
18
- _copy_app(source_root, paths.app_dir)
18
+ if source_root != paths.app_dir.resolve():
19
+ _copy_app(source_root, paths.app_dir)
19
20
  _install_command(paths)
20
21
  plugin_path = _install_plugin(source_root, paths.home)
21
22
  skill_paths = _install_user_skills(source_root, paths.home)