pactkit-codex 2.10.2__tar.gz → 2.17.0__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.
- {pactkit_codex-2.10.2/src/pactkit_codex.egg-info → pactkit_codex-2.17.0}/PKG-INFO +2 -2
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/pyproject.toml +2 -2
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/src/pactkit_codex/deployer.py +51 -129
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0/src/pactkit_codex.egg-info}/PKG-INFO +2 -2
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/src/pactkit_codex.egg-info/requires.txt +1 -1
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/LICENSE +0 -0
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/README.md +0 -0
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/setup.cfg +0 -0
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/src/pactkit_codex/__init__.py +0 -0
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/src/pactkit_codex.egg-info/SOURCES.txt +0 -0
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/src/pactkit_codex.egg-info/dependency_links.txt +0 -0
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/src/pactkit_codex.egg-info/entry_points.txt +0 -0
- {pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/src/pactkit_codex.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pactkit-codex
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.17.0
|
|
4
4
|
Summary: PactKit adapter for OpenAI Codex CLI
|
|
5
5
|
Author: Slim
|
|
6
6
|
License: MIT
|
|
@@ -21,7 +21,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
-
Requires-Dist: pactkit>=2.
|
|
24
|
+
Requires-Dist: pactkit>=2.17.0
|
|
25
25
|
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
|
|
26
26
|
Dynamic: license-file
|
|
27
27
|
|
|
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pactkit-codex"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.17.0"
|
|
8
8
|
description = "PactKit adapter for OpenAI Codex CLI"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
11
11
|
requires-python = ">=3.10"
|
|
12
12
|
dependencies = [
|
|
13
|
-
"pactkit>=2.
|
|
13
|
+
"pactkit>=2.17.0",
|
|
14
14
|
"tomli>=1.1.0; python_version < '3.11'",
|
|
15
15
|
]
|
|
16
16
|
|
|
@@ -14,10 +14,6 @@ Codex-specific features:
|
|
|
14
14
|
import re
|
|
15
15
|
from pathlib import Path
|
|
16
16
|
|
|
17
|
-
try:
|
|
18
|
-
import tomllib
|
|
19
|
-
except ModuleNotFoundError:
|
|
20
|
-
import tomli as tomllib # Python 3.10 fallback
|
|
21
17
|
from pactkit import __version__, prompts
|
|
22
18
|
from pactkit.config import (
|
|
23
19
|
VALID_SKILLS,
|
|
@@ -35,7 +31,6 @@ from pactkit.prompts.rules import (
|
|
|
35
31
|
CREDENTIAL_SAFETY_FILE,
|
|
36
32
|
RULES_FILES,
|
|
37
33
|
)
|
|
38
|
-
from pactkit.skills import load_script
|
|
39
34
|
from pactkit.utils import atomic_write
|
|
40
35
|
|
|
41
36
|
# Commands excluded from Codex deployment (require multi-agent capabilities)
|
|
@@ -130,6 +125,11 @@ class CodexDeployer(DeployerBase):
|
|
|
130
125
|
|
|
131
126
|
self.write_version_marker(codex_root)
|
|
132
127
|
|
|
128
|
+
# STORY-slim-139 R2: machine-readable deployment manifest
|
|
129
|
+
from pactkit.deploy_manifest import write_deploy_manifest
|
|
130
|
+
|
|
131
|
+
write_deploy_manifest(codex_root, "codex", cfg)
|
|
132
|
+
|
|
133
133
|
print(
|
|
134
134
|
f"\n✅ Codex CLI: {n_skills} Skills, {n_commands} Commands → {codex_root}"
|
|
135
135
|
)
|
|
@@ -168,6 +168,7 @@ class CodexDeployer(DeployerBase):
|
|
|
168
168
|
content = content.replace(pattern, "~/.codex/")
|
|
169
169
|
content = CodexDeployer.strip_model_references(content)
|
|
170
170
|
content = DeployerBase.strip_excluded_command_references(content, profile)
|
|
171
|
+
content = _replace_cli_with_scripts(content)
|
|
171
172
|
atomic_write(rules_dir / filename, content + "\n")
|
|
172
173
|
|
|
173
174
|
cred_path = rules_dir / CREDENTIAL_SAFETY_FILE
|
|
@@ -286,7 +287,7 @@ class CodexDeployer(DeployerBase):
|
|
|
286
287
|
content = _replace_cli_with_scripts(content)
|
|
287
288
|
|
|
288
289
|
# Build SKILL.md with frontmatter + @references + content
|
|
289
|
-
rule_keys = COMMAND_RULES_MAP.get(cmd_name, ["
|
|
290
|
+
rule_keys = COMMAND_RULES_MAP.get(cmd_name, ["pactkit", "credential"])
|
|
290
291
|
refs = []
|
|
291
292
|
for key in rule_keys:
|
|
292
293
|
if key == "credential":
|
|
@@ -306,48 +307,32 @@ class CodexDeployer(DeployerBase):
|
|
|
306
307
|
|
|
307
308
|
@staticmethod
|
|
308
309
|
def generate_codex_config_toml(codex_root):
|
|
309
|
-
"""
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
310
|
+
"""Create config.toml for Codex CLI — but NEVER modify an existing one.
|
|
311
|
+
|
|
312
|
+
config.toml carries the user's providers, MCP servers, project trust
|
|
313
|
+
and other sensitive state. PactKit's share is two scalar defaults and
|
|
314
|
+
one MCP entry — not worth any write risk. Policy (2026-08-13, user
|
|
315
|
+
directive after two wipe incidents):
|
|
316
|
+
- File exists -> leave it BYTE-IDENTICAL, print the recommended
|
|
317
|
+
settings for the user to add by hand.
|
|
318
|
+
- File missing -> create it with the PactKit-managed sections.
|
|
315
319
|
"""
|
|
316
320
|
config_path = codex_root / "config.toml"
|
|
317
321
|
|
|
318
|
-
pactkit_defaults = {
|
|
319
|
-
"sandbox_mode": "workspace-write",
|
|
320
|
-
"approval_policy": "on-request",
|
|
321
|
-
}
|
|
322
|
-
pactkit_mcp = {
|
|
323
|
-
"context7": {"url": "https://mcp.context7.com/mcp"},
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
FORBIDDEN_KEYS = {"api_key", "OPENAI_API_KEY", "organization"}
|
|
327
|
-
|
|
328
322
|
if config_path.exists():
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
except Exception:
|
|
332
|
-
# User-edited config may have non-standard TOML; preserve it
|
|
333
|
-
existing = {}
|
|
334
|
-
for key, value in pactkit_defaults.items():
|
|
335
|
-
if key not in existing:
|
|
336
|
-
existing[key] = value
|
|
337
|
-
if "mcp_servers" not in existing:
|
|
338
|
-
existing["mcp_servers"] = {}
|
|
339
|
-
for name, cfg in pactkit_mcp.items():
|
|
340
|
-
if name not in existing["mcp_servers"]:
|
|
341
|
-
existing["mcp_servers"][name] = cfg
|
|
342
|
-
merged = existing
|
|
343
|
-
else:
|
|
344
|
-
merged = dict(pactkit_defaults)
|
|
345
|
-
merged["mcp_servers"] = dict(pactkit_mcp)
|
|
346
|
-
|
|
347
|
-
for key in FORBIDDEN_KEYS:
|
|
348
|
-
merged.pop(key, None)
|
|
323
|
+
print(" ℹ️ config.toml exists — left untouched (PactKit never modifies it)")
|
|
324
|
+
return
|
|
349
325
|
|
|
350
|
-
|
|
326
|
+
lines = [
|
|
327
|
+
"# [pactkit:managed]",
|
|
328
|
+
'sandbox_mode = "workspace-write"',
|
|
329
|
+
'approval_policy = "on-request"',
|
|
330
|
+
"",
|
|
331
|
+
"# [pactkit:managed]",
|
|
332
|
+
"[mcp_servers.context7]",
|
|
333
|
+
'url = "https://mcp.context7.com/mcp"',
|
|
334
|
+
]
|
|
335
|
+
atomic_write(config_path, chr(10).join(lines) + chr(10))
|
|
351
336
|
|
|
352
337
|
@staticmethod
|
|
353
338
|
def generate_codex_project_files(project_root):
|
|
@@ -397,67 +382,32 @@ class CodexDeployer(DeployerBase):
|
|
|
397
382
|
"""Deploy skills with Codex-specific path replacement in scripts."""
|
|
398
383
|
_prefix = profile.skills_path_var
|
|
399
384
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
"script_source": load_script("visualize.py"),
|
|
406
|
-
},
|
|
407
|
-
{
|
|
408
|
-
"name": "pactkit-board",
|
|
409
|
-
"skill_md": prompts.SKILL_BOARD_MD,
|
|
410
|
-
"script_name": "board.py",
|
|
411
|
-
"script_source": load_script("board.py"),
|
|
412
|
-
},
|
|
413
|
-
{
|
|
414
|
-
"name": "pactkit-scaffold",
|
|
415
|
-
"skill_md": prompts.SKILL_SCAFFOLD_MD,
|
|
416
|
-
"script_name": "scaffold.py",
|
|
417
|
-
"script_source": load_script("scaffold.py"),
|
|
418
|
-
},
|
|
419
|
-
]
|
|
420
|
-
|
|
421
|
-
prompt_only_skill_defs = [
|
|
422
|
-
{"name": "pactkit-trace", "skill_md": prompts.SKILL_TRACE_MD},
|
|
423
|
-
{"name": "pactkit-draw", "skill_md": prompts.SKILL_DRAW_MD},
|
|
424
|
-
{"name": "pactkit-status", "skill_md": prompts.SKILL_STATUS_MD},
|
|
425
|
-
{"name": "pactkit-doctor", "skill_md": prompts.SKILL_DOCTOR_MD},
|
|
426
|
-
{"name": "pactkit-review", "skill_md": prompts.SKILL_REVIEW_MD},
|
|
427
|
-
{"name": "pactkit-release", "skill_md": prompts.SKILL_RELEASE_MD},
|
|
428
|
-
{"name": "pactkit-analyze", "skill_md": prompts.SKILL_ANALYZE_MD},
|
|
429
|
-
]
|
|
385
|
+
# STORY-slim-139 R4: consume the core SKILL_MANIFEST — no local
|
|
386
|
+
# hardcoded skill list (the old 10-item snapshot silently dropped
|
|
387
|
+
# garden/audit/report when core added them).
|
|
388
|
+
from pactkit.generators.deployer import _render_skill_md
|
|
389
|
+
from pactkit.prompts.skills import get_skill_manifest
|
|
430
390
|
|
|
431
391
|
enabled_set = set(enabled_skills)
|
|
432
392
|
deployed = 0
|
|
433
393
|
|
|
434
|
-
for sd in
|
|
435
|
-
if sd["name"] not in enabled_set:
|
|
436
|
-
continue
|
|
437
|
-
skill_dir = skills_dir / sd["name"]
|
|
438
|
-
scripts_dir = skill_dir / "scripts"
|
|
439
|
-
scripts_dir.mkdir(parents=True, exist_ok=True)
|
|
440
|
-
|
|
441
|
-
from pactkit.generators.deployer import _render_skill_md
|
|
442
|
-
skill_md = _render_skill_md(sd, profile, _prefix)
|
|
443
|
-
skill_md = _replace_cli_with_scripts(skill_md)
|
|
444
|
-
atomic_write(skill_dir / "SKILL.md", skill_md)
|
|
445
|
-
script_content = sd["script_source"]
|
|
446
|
-
script_content = script_content.replace("~/.claude/", f"{profile.global_config_dir}/")
|
|
447
|
-
script_content = script_content.replace("~/.config/opencode/", f"{profile.global_config_dir}/")
|
|
448
|
-
atomic_write(scripts_dir / sd["script_name"], script_content)
|
|
449
|
-
deployed += 1
|
|
450
|
-
|
|
451
|
-
for sd in prompt_only_skill_defs:
|
|
394
|
+
for sd in get_skill_manifest():
|
|
452
395
|
if sd["name"] not in enabled_set:
|
|
453
396
|
continue
|
|
454
397
|
skill_dir = skills_dir / sd["name"]
|
|
455
398
|
skill_dir.mkdir(parents=True, exist_ok=True)
|
|
456
399
|
|
|
457
|
-
from pactkit.generators.deployer import _render_skill_md
|
|
458
400
|
skill_md = _render_skill_md(sd, profile, _prefix)
|
|
459
401
|
skill_md = _replace_cli_with_scripts(skill_md)
|
|
402
|
+
skill_md = CodexDeployer.strip_model_references(skill_md)
|
|
460
403
|
atomic_write(skill_dir / "SKILL.md", skill_md)
|
|
404
|
+
if sd["script_name"]:
|
|
405
|
+
scripts_dir = skill_dir / "scripts"
|
|
406
|
+
scripts_dir.mkdir(exist_ok=True)
|
|
407
|
+
script_content = sd["script_source"]
|
|
408
|
+
script_content = script_content.replace("~/.claude/", f"{profile.global_config_dir}/")
|
|
409
|
+
script_content = script_content.replace("~/.config/opencode/", f"{profile.global_config_dir}/")
|
|
410
|
+
atomic_write(scripts_dir / sd["script_name"], script_content)
|
|
461
411
|
deployed += 1
|
|
462
412
|
|
|
463
413
|
return deployed
|
|
@@ -594,7 +544,9 @@ _SCAFFOLD_SCRIPT = "python3 ~/.codex/skills/pactkit-scaffold/scripts/scaffold.py
|
|
|
594
544
|
_CLI_TO_SCRIPT = [
|
|
595
545
|
# visualize variants (order matters: longer patterns first)
|
|
596
546
|
("Run `pactkit visualize --lazy`", f"Run `{_VIZ_SCRIPT}` (file, `--mode class`, `--mode call` if source changed)"),
|
|
547
|
+
("`pactkit visualize --lazy`", f"`{_VIZ_SCRIPT}` (file, `--mode class`, `--mode call` if source changed)"),
|
|
597
548
|
("Run `pactkit visualize", f"Run `{_VIZ_SCRIPT}"),
|
|
549
|
+
("`pactkit visualize", f"`{_VIZ_SCRIPT}"),
|
|
598
550
|
("Run `visualize --focus", f"Run `{_VIZ_SCRIPT} --focus"),
|
|
599
551
|
("Run `visualize --mode", f"Run `{_VIZ_SCRIPT} --mode"),
|
|
600
552
|
("Run `visualize`", f"Run `{_VIZ_SCRIPT}`"),
|
|
@@ -602,8 +554,14 @@ _CLI_TO_SCRIPT = [
|
|
|
602
554
|
("Run `python3 ~/.codex/skills/pactkit-board/scripts/board.py", f"Run `{_BOARD_SCRIPT}"),
|
|
603
555
|
# scaffold
|
|
604
556
|
("Run `python3 ~/.codex/skills/pactkit-scaffold/scripts/scaffold.py", f"Run `{_SCAFFOLD_SCRIPT}"),
|
|
605
|
-
# pactkit CLI → manual fallback
|
|
557
|
+
# pactkit CLI → manual fallback hints (for commands without script equivalents)
|
|
606
558
|
("Run `pactkit clean`", "Run language-specific cleanup (e.g., `find . -name '__pycache__' -exec rm -rf {} +` for Python)"),
|
|
559
|
+
("`pactkit update", "run `pactkit init --format codex` to reinstall"),
|
|
560
|
+
("`pactkit lint", "run your language linter directly (e.g., `ruff check src/ tests/` for Python)"),
|
|
561
|
+
("`pactkit regression", "run the full test suite directly (e.g., `python3 -m pytest tests/ -v`)"),
|
|
562
|
+
("`pactkit context", "update `docs/product/context.md` manually"),
|
|
563
|
+
("`pactkit guard", "run your linter and test suite directly"),
|
|
564
|
+
("`pactkit doctor", "check project files and structure manually"),
|
|
607
565
|
]
|
|
608
566
|
|
|
609
567
|
|
|
@@ -624,42 +582,6 @@ def _replace_cli_with_scripts(content):
|
|
|
624
582
|
return content
|
|
625
583
|
|
|
626
584
|
|
|
627
|
-
def _write_toml_with_markers(path, data):
|
|
628
|
-
"""Write a dict as TOML with [pactkit:managed] comment markers."""
|
|
629
|
-
lines = ["# [pactkit:managed]"]
|
|
630
|
-
|
|
631
|
-
for key, value in sorted(data.items()):
|
|
632
|
-
if isinstance(value, dict):
|
|
633
|
-
continue
|
|
634
|
-
lines.append(f'{key} = {_toml_value(value)}')
|
|
635
|
-
|
|
636
|
-
lines.append("")
|
|
637
|
-
|
|
638
|
-
for key, value in sorted(data.items()):
|
|
639
|
-
if not isinstance(value, dict):
|
|
640
|
-
continue
|
|
641
|
-
if key == "mcp_servers":
|
|
642
|
-
lines.append("# [pactkit:managed]")
|
|
643
|
-
for sub_key, sub_val in sorted(value.items()):
|
|
644
|
-
quoted_sub = _toml_key(sub_key)
|
|
645
|
-
if isinstance(sub_val, dict):
|
|
646
|
-
lines.append(f"[{key}.{quoted_sub}]")
|
|
647
|
-
for k, v in sorted(sub_val.items()):
|
|
648
|
-
lines.append(f'{_toml_key(k)} = {_toml_value(v)}')
|
|
649
|
-
else:
|
|
650
|
-
lines.append(f"[{key}]")
|
|
651
|
-
lines.append(f'{quoted_sub} = {_toml_value(sub_val)}')
|
|
652
|
-
lines.append("")
|
|
653
|
-
|
|
654
|
-
atomic_write(path, "\n".join(lines) + "\n")
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
def _toml_key(key):
|
|
658
|
-
"""Quote a TOML key if it contains characters outside [A-Za-z0-9_-]."""
|
|
659
|
-
if re.fullmatch(r'[A-Za-z0-9_-]+', key):
|
|
660
|
-
return key
|
|
661
|
-
return f'"{key}"'
|
|
662
|
-
|
|
663
585
|
|
|
664
586
|
def _toml_value(value):
|
|
665
587
|
"""Format a Python value as a TOML value string."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pactkit-codex
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.17.0
|
|
4
4
|
Summary: PactKit adapter for OpenAI Codex CLI
|
|
5
5
|
Author: Slim
|
|
6
6
|
License: MIT
|
|
@@ -21,7 +21,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
-
Requires-Dist: pactkit>=2.
|
|
24
|
+
Requires-Dist: pactkit>=2.17.0
|
|
25
25
|
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
|
|
26
26
|
Dynamic: license-file
|
|
27
27
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pactkit_codex-2.10.2 → pactkit_codex-2.17.0}/src/pactkit_codex.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|