pathly-adapters 2.1.0__tar.gz → 2.3.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.
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/PKG-INFO +1 -1
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/README.md +8 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/pyproject.toml +1 -1
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/install_cli/codex_plugin_config.py +170 -170
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/install_cli/detect.py +21 -21
- pathly_adapters-2.3.0/src/install_cli/materialize.py +285 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/install_cli/resources.py +42 -38
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/install_cli/setup_command.py +225 -168
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/install_cli/stitch.py +78 -75
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_adapters.egg-info/PKG-INFO +1 -1
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_adapters.egg-info/SOURCES.txt +4 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/.claude-plugin/plugin.json +1 -1
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/architect.yaml +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/director.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/explorer.yaml +5 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/orchestrator.yaml +12 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/pathly_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/planner.yaml +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/po.yaml +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/quick.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/reviewer.yaml +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/scout-path_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/scout.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/team-build_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/team-discover_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/team-plan_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/team-retro_skill.yaml +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/team-review_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/team-test_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/tester.yaml +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/web-researcher.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/.codex-plugin/plugin.json +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/README.md +21 -21
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/architect.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/director.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/explorer.yaml +4 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/install.yaml +13 -9
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/orchestrator.yaml +11 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/pathly_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/planner.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/po.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/quick.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/reviewer.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/scout-path_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/scout.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/team-build_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/team-discover_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/team-plan_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/team-retro_skill.yaml +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/team-review_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/team-test_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/tester.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/web-researcher.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/architect.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/builder.yaml +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/director.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/explorer.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/install.yaml +14 -9
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/orchestrator.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/pathly_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/planner.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/po.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/quick.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/reviewer.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/scout-path_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/scout.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/team-build_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/team-discover_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/team-plan_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/team-retro_skill.yaml +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/team-review_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/team-test_skill.yaml +3 -3
- {pathly_adapters-2.1.0/src/pathly_data/adapters/codex → pathly_adapters-2.3.0/src/pathly_data/adapters/copilot}/_meta/team_skill.yaml +3 -3
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/tester.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/web-researcher.yaml +4 -4
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/SKILLS_OVERVIEW.md +883 -883
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/builder.md +26 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/explorer.md +130 -103
- pathly_adapters-2.3.0/src/pathly_data/core/agents/orchestrator.md +159 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/planner.md +40 -32
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/po.md +30 -30
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/tester.md +35 -12
- pathly_adapters-2.3.0/src/pathly_data/core/flows/debug.flow.yaml +37 -0
- pathly_adapters-2.3.0/src/pathly_data/core/flows/explore.flow.yaml +30 -0
- pathly_adapters-2.3.0/src/pathly_data/core/flows/team.flow.yaml +73 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/archive.md +83 -83
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/build.md +3 -4
- pathly_adapters-2.3.0/src/pathly_data/core/skills/debug.md +76 -0
- pathly_adapters-2.3.0/src/pathly_data/core/skills/explore.md +75 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/meet.md +303 -303
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/pathly.md +358 -358
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/pause.md +43 -43
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/po.md +146 -146
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/prd-import.md +196 -196
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/review.md +4 -1
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/scout-path.md +85 -83
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/team/build.md +128 -131
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/team/discover.md +193 -192
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/team/plan.md +20 -6
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/team/review.md +166 -167
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/team/test.md +128 -127
- pathly_adapters-2.3.0/src/pathly_data/core/skills/team.md +104 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/test.md +139 -140
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/FEATURE_INDEX.template.md +61 -61
- pathly_adapters-2.3.0/src/pathly_data/schemas/pathly-meta.schema.json +116 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_hooks/__init__.py +5 -5
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_hooks/classify_feedback.py +73 -73
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_hooks/inject_feedback_ttl.py +81 -81
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_orchestrator/__init__.py +8 -8
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_orchestrator/events.py +83 -83
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_orchestrator/state.py +13 -2
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_telemetry/__init__.py +1 -1
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_telemetry/__main__.py +14 -14
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_telemetry/report.py +80 -80
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_telemetry/storage.py +28 -28
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/tests/test_codex_plugin_config.py +122 -122
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/tests/test_feedback_protocol.py +15 -15
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/tests/test_hooks.py +40 -40
- pathly_adapters-2.3.0/tests/test_materialize_hooks.py +116 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/tests/test_orchestrator.py +7 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/tests/test_setup.py +23 -23
- pathly_adapters-2.1.0/src/install_cli/materialize.py +0 -107
- pathly_adapters-2.1.0/src/pathly_data/core/agents/orchestrator.md +0 -116
- pathly_adapters-2.1.0/src/pathly_data/core/skills/debug.md +0 -238
- pathly_adapters-2.1.0/src/pathly_data/core/skills/explore.md +0 -171
- pathly_adapters-2.1.0/src/pathly_data/core/skills/team.md +0 -216
- pathly_adapters-2.1.0/src/pathly_data/schemas/pathly-meta.schema.json +0 -40
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/setup.cfg +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/install_cli/__init__.py +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/install_cli/__main__.py +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/install_cli/mcp_config.py +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_adapters.egg-info/dependency_links.txt +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_adapters.egg-info/entry_points.txt +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_adapters.egg-info/requires.txt +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_adapters.egg-info/top_level.txt +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/__init__.py +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/.claude-plugin/marketplace.json +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/README.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/archive_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/build_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/builder.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/debug_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/end_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/explore_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/go_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/help_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/install.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/lessons_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/meet_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/pause_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/plan_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/po_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/prd-import_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/retro_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/review_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/start_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/storm_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/team_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/test_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/claude/_meta/verify-state_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/archive_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/build_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/builder.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/debug_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/end_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/explore_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/go_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/help_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/lessons_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/meet_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/pause_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/plan_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/po_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/prd-import_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/retro_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/review_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/start_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/storm_skill.yaml +0 -0
- {pathly_adapters-2.1.0/src/pathly_data/adapters/copilot → pathly_adapters-2.3.0/src/pathly_data/adapters/codex}/_meta/team_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/test_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/codex/_meta/verify-state_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/README.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/archive_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/build_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/debug_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/end_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/explore_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/go_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/help_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/lessons_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/meet_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/pause_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/plan_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/po_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/prd-import_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/retro_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/review_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/start_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/storm_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/test_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/adapters/copilot/_meta/verify-state_skill.yaml +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/README.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/README_routing.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/architect.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/director.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/quick.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/reviewer.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/scout.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/agents/web-researcher.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/end.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/go.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/help.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/lessons.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/plan.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/retro.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/start.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/storm.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/team/retro.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/skills/verify-state.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/README.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/pipeline-walkthrough/01-PIPELINE-FLOW.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/pipeline-walkthrough/02-TOKEN-USAGE.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/pipeline-walkthrough/03-ARTIFACT-MAP.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/pipeline-walkthrough/README.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/ARCHITECTURE_PROPOSAL.template.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/CONVERSATION_PROMPTS.template.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/EDGE_CASES.template.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/FLOW_DIAGRAM.template.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/HAPPY_FLOW.template.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/IMPLEMENTATION_PLAN.template.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/MERMAID_DIAGRAM.template.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/PROGRESS.template.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_data/core/templates/plan/USER_STORIES.template.md +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_orchestrator/eventlog.py +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/src/pathly_telemetry/server.py +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/tests/test_mcp_config.py +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/tests/test_stitch.py +0 -0
- {pathly_adapters-2.1.0 → pathly_adapters-2.3.0}/tests/test_stitch_skill.py +0 -0
|
@@ -37,7 +37,9 @@ Then open Claude Code in your project directory and start:
|
|
|
37
37
|
/pathly end ← retro + archive
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
All commands go through `/pathly`. See
|
|
40
|
+
All commands go through `/pathly`. See [docs/FLOW_DIAGRAM.md](docs/FLOW_DIAGRAM.md) for the full command reference.
|
|
41
|
+
|
|
42
|
+
> **Tip:** `/start` and `/pathly start` are equivalent. `/pathly` dispatches to the same skill; direct invocation skips the dispatcher.
|
|
41
43
|
|
|
42
44
|
## All commands
|
|
43
45
|
|
|
@@ -61,14 +63,14 @@ pathly-state <feature> # print current FSM state for a feature
|
|
|
61
63
|
|
|
62
64
|
| Host | Detected by | Installed locations |
|
|
63
65
|
|------|-------------|---------------------|
|
|
64
|
-
| `claude` | `~/.claude/` directory exists | `~/.claude/agents/`
|
|
66
|
+
| `claude` | `~/.claude/` directory exists | `~/.claude/agents/` (behavioral contracts)<br>`~/.claude/skills/` (skill folders) |
|
|
65
67
|
| `codex` | Codex config directory exists | `~/.codex/agents/` + `~/.codex/skills/` + local plugin marketplace |
|
|
66
|
-
| `copilot` | VS Code + Copilot detected |
|
|
68
|
+
| `copilot` | VS Code + Copilot detected | `~/.vscode/extensions/pathly/agents/`<br>`~/.vscode/extensions/pathly/skills/` |
|
|
67
69
|
|
|
68
70
|
## How It Works
|
|
69
71
|
|
|
70
72
|
1. **Detect** — scans for installed hosts on the current machine.
|
|
71
|
-
2. **Stitch** — combines `core/agents/` and `core/skills/` content with adapter-specific `_meta
|
|
73
|
+
2. **Stitch** — combines `core/agents/` and `core/skills/` content with adapter-specific `_meta/<name>.yaml` to produce deployable agent and skill files (frontmatter + body + spawn section).
|
|
72
74
|
3. **Materialize** — writes stitched files to the host config location. A manifest tracks Pathly-owned files; `--repair` overwrites owned files, `--force` overwrites everything. Install is atomic — if anything fails, already-written files are rolled back.
|
|
73
75
|
4. **Register Codex plugin** - for Codex installs, writes `~/.codex/pathly-marketplace`, enables `pathly@pathly-local`, and refreshes the marketplace through the Codex CLI when available.
|
|
74
76
|
|
|
@@ -122,3 +124,5 @@ Stable (1.0.0). Core install path (`--dry-run`, `--apply`, `--uninstall`) is ver
|
|
|
122
124
|
- **Hook path validation requires Python 3.9+** — hook scripts use `Path.is_relative_to()`, introduced in Python 3.9. The project already requires Python 3.11+, so this is always satisfied.
|
|
123
125
|
|
|
124
126
|
- **Hooks require `PATHLY_PROJECT_ROOT`** — hook scripts (`classify_feedback.py`, `inject_feedback_ttl.py`) read the `PATHLY_PROJECT_ROOT` environment variable to locate the active project's `plans/` directory. If this variable is not set, hooks exit immediately without performing any action.
|
|
127
|
+
|
|
128
|
+
- **Hook parity gap** — Pathly hooks run automatically only under Claude Code. Codex and Copilot VS Code require manual install; see [Hook surface coverage](docs/SECURITY.md#hook-surface-coverage).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pathly-adapters"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.3.0"
|
|
8
8
|
description = "Pathly adapter installer — stitches and deploys agent files to AI host tools."
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
dependencies = ["pyyaml>=6.0"]
|
|
@@ -1,170 +1,170 @@
|
|
|
1
|
-
"""Install/remove Pathly's Codex local marketplace registration."""
|
|
2
|
-
from __future__ import annotations
|
|
3
|
-
|
|
4
|
-
import json
|
|
5
|
-
import re
|
|
6
|
-
import shutil
|
|
7
|
-
import subprocess
|
|
8
|
-
import sys
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
|
|
11
|
-
MARKETPLACE_NAME = "pathly-local"
|
|
12
|
-
PLUGIN_NAME = "pathly"
|
|
13
|
-
|
|
14
|
-
_CODEX_CONFIG = Path.home() / ".codex" / "config.toml"
|
|
15
|
-
_MARKETPLACE_ROOT = Path.home() / ".codex" / "pathly-marketplace"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def install_codex_plugin(
|
|
19
|
-
plugin_files: dict[str, str],
|
|
20
|
-
*,
|
|
21
|
-
dry_run: bool = False,
|
|
22
|
-
config_path: Path | None = None,
|
|
23
|
-
marketplace_root: Path | None = None,
|
|
24
|
-
codex_command: str | None = None,
|
|
25
|
-
) -> None:
|
|
26
|
-
"""Create a real local marketplace and enable the Pathly plugin."""
|
|
27
|
-
config_path = config_path or _CODEX_CONFIG
|
|
28
|
-
marketplace_root = marketplace_root or _MARKETPLACE_ROOT
|
|
29
|
-
|
|
30
|
-
if dry_run:
|
|
31
|
-
print(f" [dry-run] Would write Codex marketplace to {marketplace_root}")
|
|
32
|
-
print(f" [dry-run] Would enable plugin '{PLUGIN_NAME}@{MARKETPLACE_NAME}' in {config_path}")
|
|
33
|
-
print(" [dry-run] Would refresh Codex local marketplace registration if the codex CLI is available")
|
|
34
|
-
return
|
|
35
|
-
|
|
36
|
-
using_default_paths = config_path == _CODEX_CONFIG and marketplace_root == _MARKETPLACE_ROOT
|
|
37
|
-
plugin_root = marketplace_root / "plugins" / PLUGIN_NAME
|
|
38
|
-
if plugin_root.exists():
|
|
39
|
-
shutil.rmtree(plugin_root)
|
|
40
|
-
plugin_root.mkdir(parents=True, exist_ok=True)
|
|
41
|
-
|
|
42
|
-
for name, content in sorted(plugin_files.items()):
|
|
43
|
-
target = plugin_root / name
|
|
44
|
-
if not target.resolve().is_relative_to(plugin_root.resolve()):
|
|
45
|
-
raise ValueError(f"Path traversal detected in plugin file: {name!r}")
|
|
46
|
-
target.parent.mkdir(parents=True, exist_ok=True)
|
|
47
|
-
target.write_text(content, encoding="utf-8")
|
|
48
|
-
|
|
49
|
-
_write_marketplace_json(marketplace_root)
|
|
50
|
-
refreshed = _refresh_codex_marketplace(
|
|
51
|
-
marketplace_root,
|
|
52
|
-
codex_command=codex_command,
|
|
53
|
-
discover_cli=using_default_paths,
|
|
54
|
-
)
|
|
55
|
-
if not refreshed:
|
|
56
|
-
_enable_in_codex_config(config_path, marketplace_root)
|
|
57
|
-
print(f"[codex] Registered local plugin marketplace at {marketplace_root}")
|
|
58
|
-
print('[codex] Restart Codex and start a new thread. Try: "Use Pathly help"')
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def uninstall_codex_plugin(
|
|
62
|
-
*,
|
|
63
|
-
dry_run: bool = False,
|
|
64
|
-
config_path: Path | None = None,
|
|
65
|
-
marketplace_root: Path | None = None,
|
|
66
|
-
) -> None:
|
|
67
|
-
config_path = config_path or _CODEX_CONFIG
|
|
68
|
-
marketplace_root = marketplace_root or _MARKETPLACE_ROOT
|
|
69
|
-
|
|
70
|
-
if dry_run:
|
|
71
|
-
print(f" [dry-run] Would remove plugin '{PLUGIN_NAME}@{MARKETPLACE_NAME}' from {config_path}")
|
|
72
|
-
print(f" [dry-run] Would remove Codex marketplace at {marketplace_root}")
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
_disable_in_codex_config(config_path)
|
|
76
|
-
if marketplace_root.exists():
|
|
77
|
-
shutil.rmtree(marketplace_root)
|
|
78
|
-
print(f"[codex] Removed local plugin marketplace at {marketplace_root}")
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def _write_marketplace_json(root: Path) -> None:
|
|
82
|
-
path = root / ".agents" / "plugins" / "marketplace.json"
|
|
83
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
84
|
-
data = {
|
|
85
|
-
"name": MARKETPLACE_NAME,
|
|
86
|
-
"interface": {"displayName": "Pathly Local"},
|
|
87
|
-
"plugins": [
|
|
88
|
-
{
|
|
89
|
-
"name": PLUGIN_NAME,
|
|
90
|
-
"source": {"source": "local", "path": f"./plugins/{PLUGIN_NAME}"},
|
|
91
|
-
"policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"},
|
|
92
|
-
"category": "Developer Tools",
|
|
93
|
-
}
|
|
94
|
-
],
|
|
95
|
-
}
|
|
96
|
-
path.write_text(json.dumps(data, indent=2), encoding="utf-8")
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def _refresh_codex_marketplace(
|
|
100
|
-
marketplace_root: Path,
|
|
101
|
-
*,
|
|
102
|
-
codex_command: str | None = None,
|
|
103
|
-
discover_cli: bool = True,
|
|
104
|
-
) -> bool:
|
|
105
|
-
command = codex_command
|
|
106
|
-
if command is None and discover_cli:
|
|
107
|
-
command = shutil.which("codex")
|
|
108
|
-
if command is None:
|
|
109
|
-
print("[codex] Codex CLI not found; config.toml was updated directly.")
|
|
110
|
-
return False
|
|
111
|
-
|
|
112
|
-
remove = subprocess.run(
|
|
113
|
-
[command, "plugin", "marketplace", "remove", MARKETPLACE_NAME],
|
|
114
|
-
capture_output=True,
|
|
115
|
-
text=True,
|
|
116
|
-
timeout=60,
|
|
117
|
-
)
|
|
118
|
-
if remove.returncode != 0:
|
|
119
|
-
print(f"[codex] Marketplace remove skipped: {remove.stderr.strip() or remove.stdout.strip()}")
|
|
120
|
-
|
|
121
|
-
add = subprocess.run(
|
|
122
|
-
[command, "plugin", "marketplace", "add", str(marketplace_root)],
|
|
123
|
-
capture_output=True,
|
|
124
|
-
text=True,
|
|
125
|
-
timeout=60,
|
|
126
|
-
)
|
|
127
|
-
if add.returncode != 0:
|
|
128
|
-
print(f"[codex] Codex CLI marketplace refresh failed: {add.stderr.strip() or add.stdout.strip()}", file=sys.stderr)
|
|
129
|
-
print("[codex] Falling back to direct config.toml registration.", file=sys.stderr)
|
|
130
|
-
return False
|
|
131
|
-
|
|
132
|
-
print("[codex] Refreshed Codex local marketplace registration via codex CLI.")
|
|
133
|
-
return True
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def _enable_in_codex_config(path: Path, marketplace_root: Path) -> None:
|
|
137
|
-
content = _read_config(path)
|
|
138
|
-
content = _remove_pathly_blocks(content)
|
|
139
|
-
block = (
|
|
140
|
-
f"\n[marketplaces.{MARKETPLACE_NAME}]\n"
|
|
141
|
-
'last_updated = "1970-01-01T00:00:00Z"\n'
|
|
142
|
-
'source_type = "local"\n'
|
|
143
|
-
f"source = '{marketplace_root}'\n"
|
|
144
|
-
f'[plugins."{PLUGIN_NAME}@{MARKETPLACE_NAME}"]\n'
|
|
145
|
-
"enabled = true\n"
|
|
146
|
-
)
|
|
147
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
148
|
-
path.write_text(content.rstrip() + "\n" + block, encoding="utf-8")
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def _disable_in_codex_config(path: Path) -> None:
|
|
152
|
-
content = _read_config(path)
|
|
153
|
-
cleaned = _remove_pathly_blocks(content)
|
|
154
|
-
if cleaned != content:
|
|
155
|
-
path.write_text(cleaned.rstrip() + "\n", encoding="utf-8")
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
def _read_config(path: Path) -> str:
|
|
159
|
-
if not path.exists():
|
|
160
|
-
print(f" [warn] Codex config not found at {path}; creating it.", file=sys.stderr)
|
|
161
|
-
return ""
|
|
162
|
-
return path.read_text(encoding="utf-8")
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def _remove_pathly_blocks(content: str) -> str:
|
|
166
|
-
marketplace = rf"\n?\[marketplaces\.{re.escape(MARKETPLACE_NAME)}\].*?(?=\n\[|\Z)"
|
|
167
|
-
plugin = rf"\n?\[plugins\.\"{re.escape(PLUGIN_NAME)}@{re.escape(MARKETPLACE_NAME)}\"\].*?(?=\n\[|\Z)"
|
|
168
|
-
content = re.sub(marketplace, "", content, flags=re.DOTALL)
|
|
169
|
-
content = re.sub(plugin, "", content, flags=re.DOTALL)
|
|
170
|
-
return content
|
|
1
|
+
"""Install/remove Pathly's Codex local marketplace registration."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import re
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
MARKETPLACE_NAME = "pathly-local"
|
|
12
|
+
PLUGIN_NAME = "pathly"
|
|
13
|
+
|
|
14
|
+
_CODEX_CONFIG = Path.home() / ".codex" / "config.toml"
|
|
15
|
+
_MARKETPLACE_ROOT = Path.home() / ".codex" / "pathly-marketplace"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def install_codex_plugin(
|
|
19
|
+
plugin_files: dict[str, str],
|
|
20
|
+
*,
|
|
21
|
+
dry_run: bool = False,
|
|
22
|
+
config_path: Path | None = None,
|
|
23
|
+
marketplace_root: Path | None = None,
|
|
24
|
+
codex_command: str | None = None,
|
|
25
|
+
) -> None:
|
|
26
|
+
"""Create a real local marketplace and enable the Pathly plugin."""
|
|
27
|
+
config_path = config_path or _CODEX_CONFIG
|
|
28
|
+
marketplace_root = marketplace_root or _MARKETPLACE_ROOT
|
|
29
|
+
|
|
30
|
+
if dry_run:
|
|
31
|
+
print(f" [dry-run] Would write Codex marketplace to {marketplace_root}")
|
|
32
|
+
print(f" [dry-run] Would enable plugin '{PLUGIN_NAME}@{MARKETPLACE_NAME}' in {config_path}")
|
|
33
|
+
print(" [dry-run] Would refresh Codex local marketplace registration if the codex CLI is available")
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
using_default_paths = config_path == _CODEX_CONFIG and marketplace_root == _MARKETPLACE_ROOT
|
|
37
|
+
plugin_root = marketplace_root / "plugins" / PLUGIN_NAME
|
|
38
|
+
if plugin_root.exists():
|
|
39
|
+
shutil.rmtree(plugin_root)
|
|
40
|
+
plugin_root.mkdir(parents=True, exist_ok=True)
|
|
41
|
+
|
|
42
|
+
for name, content in sorted(plugin_files.items()):
|
|
43
|
+
target = plugin_root / name
|
|
44
|
+
if not target.resolve().is_relative_to(plugin_root.resolve()):
|
|
45
|
+
raise ValueError(f"Path traversal detected in plugin file: {name!r}")
|
|
46
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
target.write_text(content, encoding="utf-8")
|
|
48
|
+
|
|
49
|
+
_write_marketplace_json(marketplace_root)
|
|
50
|
+
refreshed = _refresh_codex_marketplace(
|
|
51
|
+
marketplace_root,
|
|
52
|
+
codex_command=codex_command,
|
|
53
|
+
discover_cli=using_default_paths,
|
|
54
|
+
)
|
|
55
|
+
if not refreshed:
|
|
56
|
+
_enable_in_codex_config(config_path, marketplace_root)
|
|
57
|
+
print(f"[codex] Registered local plugin marketplace at {marketplace_root}")
|
|
58
|
+
print('[codex] Restart Codex and start a new thread. Try: "Use Pathly help"')
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def uninstall_codex_plugin(
|
|
62
|
+
*,
|
|
63
|
+
dry_run: bool = False,
|
|
64
|
+
config_path: Path | None = None,
|
|
65
|
+
marketplace_root: Path | None = None,
|
|
66
|
+
) -> None:
|
|
67
|
+
config_path = config_path or _CODEX_CONFIG
|
|
68
|
+
marketplace_root = marketplace_root or _MARKETPLACE_ROOT
|
|
69
|
+
|
|
70
|
+
if dry_run:
|
|
71
|
+
print(f" [dry-run] Would remove plugin '{PLUGIN_NAME}@{MARKETPLACE_NAME}' from {config_path}")
|
|
72
|
+
print(f" [dry-run] Would remove Codex marketplace at {marketplace_root}")
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
_disable_in_codex_config(config_path)
|
|
76
|
+
if marketplace_root.exists():
|
|
77
|
+
shutil.rmtree(marketplace_root)
|
|
78
|
+
print(f"[codex] Removed local plugin marketplace at {marketplace_root}")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _write_marketplace_json(root: Path) -> None:
|
|
82
|
+
path = root / ".agents" / "plugins" / "marketplace.json"
|
|
83
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
84
|
+
data = {
|
|
85
|
+
"name": MARKETPLACE_NAME,
|
|
86
|
+
"interface": {"displayName": "Pathly Local"},
|
|
87
|
+
"plugins": [
|
|
88
|
+
{
|
|
89
|
+
"name": PLUGIN_NAME,
|
|
90
|
+
"source": {"source": "local", "path": f"./plugins/{PLUGIN_NAME}"},
|
|
91
|
+
"policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"},
|
|
92
|
+
"category": "Developer Tools",
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
}
|
|
96
|
+
path.write_text(json.dumps(data, indent=2), encoding="utf-8")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _refresh_codex_marketplace(
|
|
100
|
+
marketplace_root: Path,
|
|
101
|
+
*,
|
|
102
|
+
codex_command: str | None = None,
|
|
103
|
+
discover_cli: bool = True,
|
|
104
|
+
) -> bool:
|
|
105
|
+
command = codex_command
|
|
106
|
+
if command is None and discover_cli:
|
|
107
|
+
command = shutil.which("codex")
|
|
108
|
+
if command is None:
|
|
109
|
+
print("[codex] Codex CLI not found; config.toml was updated directly.")
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
remove = subprocess.run(
|
|
113
|
+
[command, "plugin", "marketplace", "remove", MARKETPLACE_NAME],
|
|
114
|
+
capture_output=True,
|
|
115
|
+
text=True,
|
|
116
|
+
timeout=60,
|
|
117
|
+
)
|
|
118
|
+
if remove.returncode != 0:
|
|
119
|
+
print(f"[codex] Marketplace remove skipped: {remove.stderr.strip() or remove.stdout.strip()}")
|
|
120
|
+
|
|
121
|
+
add = subprocess.run(
|
|
122
|
+
[command, "plugin", "marketplace", "add", str(marketplace_root)],
|
|
123
|
+
capture_output=True,
|
|
124
|
+
text=True,
|
|
125
|
+
timeout=60,
|
|
126
|
+
)
|
|
127
|
+
if add.returncode != 0:
|
|
128
|
+
print(f"[codex] Codex CLI marketplace refresh failed: {add.stderr.strip() or add.stdout.strip()}", file=sys.stderr)
|
|
129
|
+
print("[codex] Falling back to direct config.toml registration.", file=sys.stderr)
|
|
130
|
+
return False
|
|
131
|
+
|
|
132
|
+
print("[codex] Refreshed Codex local marketplace registration via codex CLI.")
|
|
133
|
+
return True
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _enable_in_codex_config(path: Path, marketplace_root: Path) -> None:
|
|
137
|
+
content = _read_config(path)
|
|
138
|
+
content = _remove_pathly_blocks(content)
|
|
139
|
+
block = (
|
|
140
|
+
f"\n[marketplaces.{MARKETPLACE_NAME}]\n"
|
|
141
|
+
'last_updated = "1970-01-01T00:00:00Z"\n'
|
|
142
|
+
'source_type = "local"\n'
|
|
143
|
+
f"source = '{marketplace_root}'\n"
|
|
144
|
+
f'[plugins."{PLUGIN_NAME}@{MARKETPLACE_NAME}"]\n'
|
|
145
|
+
"enabled = true\n"
|
|
146
|
+
)
|
|
147
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
148
|
+
path.write_text(content.rstrip() + "\n" + block, encoding="utf-8")
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _disable_in_codex_config(path: Path) -> None:
|
|
152
|
+
content = _read_config(path)
|
|
153
|
+
cleaned = _remove_pathly_blocks(content)
|
|
154
|
+
if cleaned != content:
|
|
155
|
+
path.write_text(cleaned.rstrip() + "\n", encoding="utf-8")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _read_config(path: Path) -> str:
|
|
159
|
+
if not path.exists():
|
|
160
|
+
print(f" [warn] Codex config not found at {path}; creating it.", file=sys.stderr)
|
|
161
|
+
return ""
|
|
162
|
+
return path.read_text(encoding="utf-8")
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _remove_pathly_blocks(content: str) -> str:
|
|
166
|
+
marketplace = rf"\n?\[marketplaces\.{re.escape(MARKETPLACE_NAME)}\].*?(?=\n\[|\Z)"
|
|
167
|
+
plugin = rf"\n?\[plugins\.\"{re.escape(PLUGIN_NAME)}@{re.escape(MARKETPLACE_NAME)}\"\].*?(?=\n\[|\Z)"
|
|
168
|
+
content = re.sub(marketplace, "", content, flags=re.DOTALL)
|
|
169
|
+
content = re.sub(plugin, "", content, flags=re.DOTALL)
|
|
170
|
+
return content
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
_HOST_MARKERS: dict[str, list[Path]] = {
|
|
4
|
-
"claude": [
|
|
5
|
-
Path.home() / ".claude",
|
|
6
|
-
],
|
|
7
|
-
"codex": [
|
|
8
|
-
Path.home() / ".codex",
|
|
9
|
-
Path.home() / ".openai-codex",
|
|
10
|
-
],
|
|
11
|
-
"copilot": [
|
|
12
|
-
Path.home() / "AppData" / "Roaming" / "Code", # Windows
|
|
13
|
-
Path.home() / ".config" / "Code", # Linux
|
|
14
|
-
Path.home() / "Library" / "Application Support" / "Code", # macOS
|
|
15
|
-
Path.home() / ".vscode",
|
|
16
|
-
],
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def detect_hosts() -> list[str]:
|
|
21
|
-
return [host for host, paths in _HOST_MARKERS.items() if any(p.exists() for p in paths)]
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
_HOST_MARKERS: dict[str, list[Path]] = {
|
|
4
|
+
"claude": [
|
|
5
|
+
Path.home() / ".claude",
|
|
6
|
+
],
|
|
7
|
+
"codex": [
|
|
8
|
+
Path.home() / ".codex",
|
|
9
|
+
Path.home() / ".openai-codex",
|
|
10
|
+
],
|
|
11
|
+
"copilot": [
|
|
12
|
+
Path.home() / "AppData" / "Roaming" / "Code", # Windows
|
|
13
|
+
Path.home() / ".config" / "Code", # Linux
|
|
14
|
+
Path.home() / "Library" / "Application Support" / "Code", # macOS
|
|
15
|
+
Path.home() / ".vscode",
|
|
16
|
+
],
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def detect_hosts() -> list[str]:
|
|
21
|
+
return [host for host, paths in _HOST_MARKERS.items() if any(p.exists() for p in paths)]
|