runops 0.2.1__tar.gz → 0.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.
- {runops-0.2.1 → runops-0.3.0}/.claude/rules/commands.md +2 -2
- {runops-0.2.1 → runops-0.3.0}/.claude/rules/dev-workflow.md +9 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/rules/gotchas.md +11 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/settings.json +7 -0
- runops-0.3.0/.claude/skills/release/SKILL.md +104 -0
- runops-0.3.0/.claude/skills/triage/SKILL.md +106 -0
- runops-0.3.0/.claude/skills/update-docs/SKILL.md +73 -0
- {runops-0.2.1 → runops-0.3.0}/CLAUDE.md +2 -2
- {runops-0.2.1 → runops-0.3.0}/PKG-INFO +1 -1
- {runops-0.2.1 → runops-0.3.0}/docs/agent-user-guide.md +1 -1
- {runops-0.2.1 → runops-0.3.0}/docs/toml-reference.md +2 -0
- {runops-0.2.1 → runops-0.3.0}/pyproject.toml +1 -1
- {runops-0.2.1 → runops-0.3.0}/src/runops/__init__.py +1 -1
- {runops-0.2.1 → runops-0.3.0}/src/runops/adapters/contrib/beach.py +1 -1
- {runops-0.2.1 → runops-0.3.0}/src/runops/adapters/contrib/emses.py +6 -2
- {runops-0.2.1 → runops-0.3.0}/src/runops/adapters/generic.py +4 -2
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/knowledge.py +2 -2
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/status.py +35 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/submit.py +27 -4
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/update_harness.py +20 -2
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/update_refs.py +1 -1
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/actions.py +6 -3
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/case.py +3 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/knowledge.py +1 -1
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/run_creation.py +2 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/jobgen/generator.py +4 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/sites/camphor.md +19 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/agent.md +2 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/rules/runops-workflow.md +2 -1
- runops-0.3.0/src/runops/templates/skills/feedback/SKILL.md +116 -0
- runops-0.3.0/src/runops/templates/skills/release/SKILL.md +107 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/beach.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/emses.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/implement-adapter.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/implement-cli.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/implement-core.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/implement-launcher.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/implement-slurm.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/scaffold.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/spec-reviewer.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/agents/test-writer.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/rules/architecture.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/rules/knowledge-layer.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/skills/check/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/skills/improve-harness/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.claude/skills/test-module/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/.dockerignore +0 -0
- {runops-0.2.1 → runops-0.3.0}/.gitattributes +0 -0
- {runops-0.2.1 → runops-0.3.0}/.github/workflows/ci.yml +0 -0
- {runops-0.2.1 → runops-0.3.0}/.github/workflows/publish.yml +0 -0
- {runops-0.2.1 → runops-0.3.0}/.gitignore +0 -0
- {runops-0.2.1 → runops-0.3.0}/.pre-commit-config.yaml +0 -0
- {runops-0.2.1 → runops-0.3.0}/AGENTS.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/Dockerfile.diagrams +0 -0
- {runops-0.2.1 → runops-0.3.0}/LICENSE +0 -0
- {runops-0.2.1 → runops-0.3.0}/README.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/SKILLS.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/SPEC.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/architecture.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/extending.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/figures/agent-project-flow/human-gates.png +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/figures/agent-project-flow/init-world.png +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/figures/agent-project-flow/operation-loop.png +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/figures/src-structure/overview.png +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/figures/src-structure/run-creation-resolution.png +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/figures/src-structure/site-resolution.png +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/get-started-with-agent.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/knowledge-layer.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/project-flow.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/simulator-kb-spec.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/docs/src-structure.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/entrypoints.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/beach/campaign.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/beach/cases/periodic2_basic/beach_template.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/beach/cases/periodic2_basic/case.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/beach/launchers.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/beach/simulators.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/beach/surveys/density_scan/survey.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/emses/campaign.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/emses/cases/flat_surface/case.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/emses/cases/flat_surface/plasma.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/emses/launchers.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/emses/simulators.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/examples/emses/surveys/mag_angle_scan/survey.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/schemas/campaign.json +0 -0
- {runops-0.2.1 → runops-0.3.0}/schemas/case.json +0 -0
- {runops-0.2.1 → runops-0.3.0}/schemas/launchers.json +0 -0
- {runops-0.2.1 → runops-0.3.0}/schemas/manifest.json +0 -0
- {runops-0.2.1 → runops-0.3.0}/schemas/runops.json +0 -0
- {runops-0.2.1 → runops-0.3.0}/schemas/simulators.json +0 -0
- {runops-0.2.1 → runops-0.3.0}/schemas/survey.json +0 -0
- {runops-0.2.1 → runops-0.3.0}/scripts/diagram_utils.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/scripts/generate_agent_project_flow.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/scripts/generate_architecture_diagrams.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/scripts/render_diagrams_in_docker.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/adapters/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/adapters/_utils/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/adapters/_utils/toml_utils.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/adapters/base.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/adapters/contrib/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/adapters/registry.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/analyze.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/clone.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/config.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/context.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/create.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/dashboard.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/extend.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/history.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/init.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/jobs.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/list.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/log.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/main.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/manage.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/new.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/notes.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/run_lookup.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/setup.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/cli/update.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/analysis.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/campaign.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/context.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/discovery.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/environment.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/exceptions.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/knowledge_source.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/manifest.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/project.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/provenance.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/retry.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/run.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/site.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/state.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/survey.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/core/validation.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/harness/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/harness/builder.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/harness/claude.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/jobgen/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/launchers/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/launchers/base.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/launchers/mpiexec.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/launchers/mpirun.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/launchers/srun.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/sites/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/sites/camphor.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/slurm/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/slurm/query.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/slurm/submit.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/beach/agent_guide.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/beach/beach.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/beach/case.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/beach/summarize.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/emses/agent_guide.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/emses/case.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/emses/plasma.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/emses/summarize.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/generic/case.toml.j2 +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/adapters/generic/summarize.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/rules/cookbook.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/campaign.toml.j2 +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/cases_claude.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/facts.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/gitignore.txt +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/notes/README.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/rules/plan-before-act.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/rules/upstream-feedback.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/runs_claude.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/scaffold/vscode_settings.json +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/analyze/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/check-status/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/cleanup/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/create-run/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/debug-failed/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/learn/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/new-case/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/note/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/run-all/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/runops-reference/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/setup-campaign/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/setup-env/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/survey-design/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/skills/update-runops/SKILL.md +0 -0
- {runops-0.2.1 → runops-0.3.0}/src/runops/templates/survey.toml.j2 +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/conftest.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/fixtures/sample_case.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/fixtures/sample_launchers.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/fixtures/sample_manifest.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/fixtures/sample_runops.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/fixtures/sample_simulators.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/fixtures/sample_survey.toml +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_adapters/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_adapters/test_beach.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_adapters/test_emses.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_adapters/test_generic.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_adapters/test_registry.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_adapters/test_toml_utils.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_analyze.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_clone.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_config.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_context_cli.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_create.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_dashboard.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_extend.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_history.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_init.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_jobs.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_knowledge.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_list.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_log.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_main.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_manage.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_new.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_notes.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_setup.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_status.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_submit.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_update.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_update_harness.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_cli/test_update_refs.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_action_contract.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_actions.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_analysis.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_case.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_context.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_discovery.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_knowledge_source.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_manifest.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_project.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_provenance.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_retry.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_run.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_run_creation.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_site.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_state.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_core/test_survey.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_e2e/test_bootstrap.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_harness/test_claude.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_launchers/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_launchers/test_launcher_base.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_launchers/test_mpiexec.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_launchers/test_mpirun.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_launchers/test_srun.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_slurm/__init__.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_slurm/test_jobgen.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_slurm/test_slurm_query.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/tests/test_slurm/test_slurm_submit.py +0 -0
- {runops-0.2.1 → runops-0.3.0}/uv.lock +0 -0
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
| `runops case new CASE [--minimal] [--survey]` | case のスキャフォールド生成 |
|
|
24
24
|
| `runops runs create CASE` | case から単一 run を生成 |
|
|
25
25
|
| `runops runs sweep [DIR] [--dry-run]` | survey.toml からパラメータ直積で全 run 生成 |
|
|
26
|
-
| `runops runs submit [RUN]` | run を sbatch で投入 (`-qn`, `--afterok` 対応) |
|
|
26
|
+
| `runops runs submit [RUN]` | run を sbatch で投入 (`-qn`, `--qos`, `--afterok` 対応) |
|
|
27
27
|
| `runops runs submit --all [DIR]` | created な run を一括投入 |
|
|
28
28
|
| `runops runs clone` | run 複製・派生 |
|
|
29
29
|
| `runops runs extend` | スナップショットから継続 run 生成 |
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
| コマンド | 説明 |
|
|
34
34
|
|---------|------|
|
|
35
35
|
| `runops runs status [RUNS...]` | run 状態確認 (複数指定可) |
|
|
36
|
-
| `runops runs sync [RUNS...]` | Slurm 状態を manifest に反映 |
|
|
36
|
+
| `runops runs sync [RUNS...]` | Slurm 状態を manifest に反映 (複数 run 時はサマリ表示) |
|
|
37
37
|
| `runops runs log [RUN]` | 最新 job の stdout/stderr 表示 + 進捗% |
|
|
38
38
|
| `runops runs jobs [PATH] [--watch SECS]` | 実行中ジョブ一覧 |
|
|
39
39
|
| `runops runs dashboard [TARGETS...] [--watch SECS]` | 複数 run の進捗表 |
|
|
@@ -37,3 +37,12 @@ CI でも同じチェックが走る。ruff format 違反は自動修正可 (`uv
|
|
|
37
37
|
- commit message は英語推奨 (`fix:`, `feat:`, `refactor:`, `test:`, `docs:`)
|
|
38
38
|
- `--no-verify` / `--force` は使わない
|
|
39
39
|
- PR は main ブランチへ
|
|
40
|
+
|
|
41
|
+
## リリース
|
|
42
|
+
|
|
43
|
+
`/release` スキルで実施する。手順の概要:
|
|
44
|
+
|
|
45
|
+
1. 品質ゲート通過を確認
|
|
46
|
+
2. `pyproject.toml` と `src/runops/__init__.py` のバージョンを **同時に** 更新
|
|
47
|
+
3. `git commit -m "chore: bump version to X.Y.Z"` + `git tag vX.Y.Z`
|
|
48
|
+
4. `git push origin main --tags` で CI が PyPI にパブリッシュ
|
|
@@ -35,6 +35,17 @@ local が team を **マージ上書き** する。同じキーを両方に書
|
|
|
35
35
|
Adapter が返すリストは **累積** (重複排除) される。
|
|
36
36
|
同じ package を複数 adapter が返しても 1 回だけ install される。
|
|
37
37
|
|
|
38
|
+
## バージョン二重管理
|
|
39
|
+
|
|
40
|
+
`pyproject.toml` の `version` と `src/runops/__init__.py` の `__version__` は
|
|
41
|
+
**必ず同時に更新する**。片方だけ変えるとランタイム (`runops --version`) と
|
|
42
|
+
PyPI パッケージのバージョンがずれる。`/release` スキルを使えば自動で両方更新される。
|
|
43
|
+
|
|
44
|
+
## read_text() の encoding
|
|
45
|
+
|
|
46
|
+
`Path.read_text()` は `encoding` 引数を省略するとシステムロケール依存になる。
|
|
47
|
+
日本語を含むファイルを読むときは必ず `encoding="utf-8"` を明示する。
|
|
48
|
+
|
|
38
49
|
## ハーネス lock
|
|
39
50
|
|
|
40
51
|
`harness.lock` は **テンプレートの hash** を記録する。
|
|
@@ -13,7 +13,14 @@
|
|
|
13
13
|
"Bash(git branch*)",
|
|
14
14
|
"Bash(git checkout*)",
|
|
15
15
|
"Bash(git stash*)",
|
|
16
|
+
"Bash(git add *)",
|
|
17
|
+
"Bash(git tag *)",
|
|
18
|
+
"Bash(gh issue *)",
|
|
19
|
+
"Bash(gh pr *)",
|
|
20
|
+
"Bash(gh run *)",
|
|
21
|
+
"Bash(mkdir *)",
|
|
16
22
|
"Bash(python -c *)",
|
|
23
|
+
"Bash(uv run python *)",
|
|
17
24
|
"Bash(wc -l *)",
|
|
18
25
|
"Bash(ls *)",
|
|
19
26
|
"Edit(src/**)",
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release
|
|
3
|
+
description: "Prepare and publish a new runops release. Bump version, sync __init__.py, generate changelog, create commit and tag, and push to trigger PyPI publish."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# runops リリース
|
|
7
|
+
|
|
8
|
+
`/release` は新しいバージョンの runops をリリースするスキル。
|
|
9
|
+
|
|
10
|
+
## 使い方
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
/release patch # 0.2.1 -> 0.2.2
|
|
14
|
+
/release minor # 0.2.1 -> 0.3.0
|
|
15
|
+
/release major # 0.2.1 -> 1.0.0
|
|
16
|
+
/release 0.3.0 # 明示的にバージョン指定
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
引数なしで呼んだ場合は、変更内容から bump レベルを自動判定し、
|
|
20
|
+
確認 → リリースまで一気通貫で実行する。
|
|
21
|
+
|
|
22
|
+
## 手順
|
|
23
|
+
|
|
24
|
+
### 1. リリース可否を確認する
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# 未コミットの変更がないか
|
|
28
|
+
git status --porcelain
|
|
29
|
+
|
|
30
|
+
# テストが全て通るか
|
|
31
|
+
uv run pytest tests/ -x -q
|
|
32
|
+
|
|
33
|
+
# lint / type check
|
|
34
|
+
uv run ruff check src/ tests/
|
|
35
|
+
uv run mypy src/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
品質ゲートが通らなければリリースを中止する。
|
|
39
|
+
|
|
40
|
+
### 2. 変更内容を把握する
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# 前回リリースタグからの変更
|
|
44
|
+
git log $(git describe --tags --abbrev=0 2>/dev/null || echo HEAD~20)..HEAD --oneline
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
commit message から以下を分類する:
|
|
48
|
+
|
|
49
|
+
- **Breaking changes** (`feat!:`, `BREAKING CHANGE`) → major bump 候補
|
|
50
|
+
- **New features** (`feat:`) → minor bump 候補
|
|
51
|
+
- **Bug fixes** (`fix:`) → patch bump 候補
|
|
52
|
+
- **Other** (`refactor:`, `test:`, `docs:`, `chore:`)
|
|
53
|
+
|
|
54
|
+
### 3. バージョンを決定する
|
|
55
|
+
|
|
56
|
+
引数で指定されていればそれを使う。なければ以下のルールで自動判定する:
|
|
57
|
+
|
|
58
|
+
- `feat!:` or `BREAKING CHANGE` あり → **major**
|
|
59
|
+
- `feat:` あり → **minor**
|
|
60
|
+
- `fix:` のみ → **patch**
|
|
61
|
+
- `docs:` / `chore:` のみ → **patch**
|
|
62
|
+
|
|
63
|
+
### 4. バージョンを更新する
|
|
64
|
+
|
|
65
|
+
2 箇所を同時に更新する (**ずれ防止**):
|
|
66
|
+
|
|
67
|
+
1. `pyproject.toml` の `version = "X.Y.Z"` — pip / PyPI が参照する正本
|
|
68
|
+
2. `src/runops/__init__.py` の `__version__ = "X.Y.Z"` — ランタイム参照
|
|
69
|
+
|
|
70
|
+
### 5. コミットとタグ
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
git add pyproject.toml src/runops/__init__.py
|
|
74
|
+
git commit -m "chore: bump version to X.Y.Z"
|
|
75
|
+
git tag vX.Y.Z
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 6. push してリリース
|
|
79
|
+
|
|
80
|
+
ユーザーの確認を得てから push する:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
git push origin main
|
|
84
|
+
git push origin vX.Y.Z
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`v*` タグの push により `.github/workflows/publish.yml` が起動し、
|
|
88
|
+
CI が自動で PyPI にパブリッシュする。
|
|
89
|
+
|
|
90
|
+
### 7. 確認
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
gh run list --workflow=publish.yml --limit 1
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 引数なしの場合
|
|
97
|
+
|
|
98
|
+
変更内容を分類し、bump レベルを自動判定して、リリースまで実行する。
|
|
99
|
+
具体的には:
|
|
100
|
+
|
|
101
|
+
1. 前回タグからのコミットを分類 (breaking / feat / fix / other)
|
|
102
|
+
2. bump レベルを自動判定
|
|
103
|
+
3. 変更サマリとバージョンをユーザーに提示して確認
|
|
104
|
+
4. 確認が取れたら手順 4〜7 を順に実行 (バージョン更新 → コミット → タグ → push)
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: triage
|
|
3
|
+
description: "Triage open GitHub issues: review new issues, assess priority, filter spam/malicious content, suggest which to tackle, and close resolved or invalid issues."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Issue トリアージ
|
|
7
|
+
|
|
8
|
+
`/triage` は runops リポジトリの GitHub issue を一括レビューし、
|
|
9
|
+
対応方針を提案するスキル。
|
|
10
|
+
|
|
11
|
+
## 手順
|
|
12
|
+
|
|
13
|
+
### 1. Open issue を一覧取得
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
gh issue list --state open --limit 30
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 2. 各 issue を評価
|
|
20
|
+
|
|
21
|
+
issue ごとに以下の観点で評価する:
|
|
22
|
+
|
|
23
|
+
| 観点 | 判定 |
|
|
24
|
+
|------|------|
|
|
25
|
+
| **正当性** | 悪意・スパム・無関係な内容でないか |
|
|
26
|
+
| **再現性** | バグなら再現手順があるか、実際にコードベースで確認できるか |
|
|
27
|
+
| **影響度** | 影響を受けるユーザー・ワークフローの範囲 |
|
|
28
|
+
| **難易度** | 修正の複雑さ (軽微 / 中 / 大) |
|
|
29
|
+
| **重複** | 既存の issue や実装済み機能と重複していないか |
|
|
30
|
+
|
|
31
|
+
### 3. 悪意ある issue のフィルタリング
|
|
32
|
+
|
|
33
|
+
以下に該当する issue は close を提案する:
|
|
34
|
+
|
|
35
|
+
- スパム (無関係な宣伝、bot 投稿)
|
|
36
|
+
- 悪意のあるコード・リンクを含む
|
|
37
|
+
- プロジェクトと無関係な内容
|
|
38
|
+
- 個人攻撃・ハラスメント
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
gh issue close <NUMBER> --comment "Closed: <理由>"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 4. 優先度付けと対応方針の提案
|
|
45
|
+
|
|
46
|
+
ユーザーに以下の形式で報告する:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
## トリアージ結果
|
|
50
|
+
|
|
51
|
+
### 対応推奨 (高)
|
|
52
|
+
- #N: <タイトル> — <理由・工数見積>
|
|
53
|
+
|
|
54
|
+
### 対応推奨 (中)
|
|
55
|
+
- #N: <タイトル> — <理由・工数見積>
|
|
56
|
+
|
|
57
|
+
### 保留 / 要議論
|
|
58
|
+
- #N: <タイトル> — <保留理由>
|
|
59
|
+
|
|
60
|
+
### Close 推奨
|
|
61
|
+
- #N: <タイトル> — <close 理由>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 5. ユーザー判断を仰ぐ
|
|
65
|
+
|
|
66
|
+
トリアージ結果を提示した後、ユーザーに以下を確認する:
|
|
67
|
+
|
|
68
|
+
- どの issue に取り掛かるか
|
|
69
|
+
- close してよい issue はどれか
|
|
70
|
+
- 追加情報が必要な issue はあるか
|
|
71
|
+
|
|
72
|
+
## 対応完了時の処理
|
|
73
|
+
|
|
74
|
+
issue に対応した後は以下の手順で close する:
|
|
75
|
+
|
|
76
|
+
### コミットでの紐づけ
|
|
77
|
+
|
|
78
|
+
commit message に `Closes #N` を含めると、push 時に自動 close される:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
feat: add --qos option to runs submit
|
|
82
|
+
|
|
83
|
+
Closes #15
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 手動 close
|
|
87
|
+
|
|
88
|
+
push 前に close する場合や、コミットに紐づけない場合:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
gh issue close <NUMBER> --comment "Fixed in <commit-hash> — <概要>"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 対応しないと決めた issue
|
|
95
|
+
|
|
96
|
+
理由を明記して close する:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
gh issue close <NUMBER> --comment "Won't fix: <理由>"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 注意事項
|
|
103
|
+
|
|
104
|
+
- ユーザーの確認なしに issue を close しない (スパム除く)
|
|
105
|
+
- close 時は必ずコメントで理由を残す
|
|
106
|
+
- 対応済み issue は対応コミットのハッシュを記載する
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: update-docs
|
|
3
|
+
description: "Reflect code changes into documentation. Scan recent commits or staged changes, identify which docs need updating, and apply the updates. Use after implementing features, fixing bugs, or adding skills/commands."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ドキュメント反映
|
|
7
|
+
|
|
8
|
+
`/update-docs` はコード変更に伴うドキュメント更新を行うスキル。
|
|
9
|
+
機能追加・修正・スキル追加の後に呼ぶことで、ドキュメントの整合性を保つ。
|
|
10
|
+
|
|
11
|
+
## 対象ドキュメント
|
|
12
|
+
|
|
13
|
+
### このリポジトリ (runops 開発者向け)
|
|
14
|
+
|
|
15
|
+
| ファイル | 内容 | 更新タイミング |
|
|
16
|
+
|---------|------|---------------|
|
|
17
|
+
| `CLAUDE.md` | プロジェクト概要・主要コマンド表 | コマンド追加・変更時 |
|
|
18
|
+
| `.claude/rules/commands.md` | 全コマンド一覧 | CLI 引数追加・変更時 |
|
|
19
|
+
| `.claude/rules/dev-workflow.md` | 開発ワークフロー | ビルド手順・品質ゲート変更時 |
|
|
20
|
+
| `.claude/rules/architecture.md` | アーキテクチャ原則 | レイヤ構造変更時 |
|
|
21
|
+
| `docs/toml-reference.md` | TOML 設定リファレンス | case.toml / survey.toml 等のフィールド追加時 |
|
|
22
|
+
| `docs/extending.md` | 拡張ガイド | Adapter / Launcher の追加方法変更時 |
|
|
23
|
+
| `docs/project-flow.md` | プロジェクトフロー | ワークフロー変更時 |
|
|
24
|
+
| `src/runops/sites/*.md` | サイト固有ドキュメント | サイト機能追加・制限事項更新時 |
|
|
25
|
+
|
|
26
|
+
### プロジェクト側ハーネス (runops ユーザー向け)
|
|
27
|
+
|
|
28
|
+
| テンプレート | 内容 | 更新タイミング |
|
|
29
|
+
|------------|------|---------------|
|
|
30
|
+
| `src/runops/templates/agent.md` | プロジェクト側 CLAUDE.md | コマンド体系変更時 |
|
|
31
|
+
| `src/runops/templates/scaffold/rules/runops-workflow.md` | ワークフロー rule | コマンド追加時 |
|
|
32
|
+
| `src/runops/templates/scaffold/rules/cookbook.md` | cookbook | 頻出パターン追加時 |
|
|
33
|
+
|
|
34
|
+
## 手順
|
|
35
|
+
|
|
36
|
+
### 1. 変更内容を把握する
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# 直近のコミットから (デフォルト)
|
|
40
|
+
git log --oneline HEAD~5..HEAD
|
|
41
|
+
|
|
42
|
+
# または未コミットの変更
|
|
43
|
+
git diff --stat
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. 影響するドキュメントを特定する
|
|
47
|
+
|
|
48
|
+
変更の種類と対応するドキュメント:
|
|
49
|
+
|
|
50
|
+
| 変更の種類 | 更新対象 |
|
|
51
|
+
|-----------|---------|
|
|
52
|
+
| CLI オプション追加・変更 | `commands.md`, `CLAUDE.md`, `toml-reference.md` |
|
|
53
|
+
| TOML フィールド追加 | `toml-reference.md` |
|
|
54
|
+
| 新スキル追加 | プロジェクト側テンプレートの CLAUDE.md (スキル一覧があれば) |
|
|
55
|
+
| サイト固有の変更 | `src/runops/sites/<site>.md` |
|
|
56
|
+
| Adapter / Launcher 追加 | `docs/extending.md`, `CLAUDE.md` |
|
|
57
|
+
| アーキテクチャ変更 | `architecture.md` |
|
|
58
|
+
|
|
59
|
+
### 3. ドキュメントを更新する
|
|
60
|
+
|
|
61
|
+
各対象ファイルを読み、変更を反映する。
|
|
62
|
+
|
|
63
|
+
### 4. 整合性チェック
|
|
64
|
+
|
|
65
|
+
- コマンドの `--help` 出力とドキュメントが一致しているか
|
|
66
|
+
- TOML フィールドの型・デフォルト値が正しいか
|
|
67
|
+
- スキルの description がファイル内容と一致しているか
|
|
68
|
+
|
|
69
|
+
## 注意事項
|
|
70
|
+
|
|
71
|
+
- ドキュメントの書き方や文体は既存部分に合わせる
|
|
72
|
+
- 日本語ドキュメントと英語ドキュメントの両方を更新する
|
|
73
|
+
- ハーネス二重構造に注意: 開発者向け (`.claude/`) とプロジェクト側 (`src/runops/templates/`) は別物
|
|
@@ -93,7 +93,7 @@ completed → archived → purged
|
|
|
93
93
|
|---------|------|
|
|
94
94
|
| `runops init` / `setup` / `doctor` | プロジェクト管理 |
|
|
95
95
|
| `runops case new` / `runs create` / `runs sweep` | case / run 生成 |
|
|
96
|
-
| `runops runs submit [--all]` | ジョブ投入 |
|
|
96
|
+
| `runops runs submit [--all] [-qn] [--qos]` | ジョブ投入 |
|
|
97
97
|
| `runops runs status` / `sync` / `log` / `dashboard` | モニタリング |
|
|
98
98
|
| `runops analyze summarize` / `collect` | 解析 |
|
|
99
99
|
| `runops notes append` / `knowledge save` | 知見管理 |
|
|
@@ -109,7 +109,7 @@ completed → archived → purged
|
|
|
109
109
|
- docstring は Google style
|
|
110
110
|
- テスト: Slurm はモック、TOML は fixtures、CLI は CliRunner
|
|
111
111
|
- Git: 1 コミット = 1 論理変更、`--no-verify` / `--force` 禁止
|
|
112
|
-
- release 時は `pyproject.toml` version
|
|
112
|
+
- release 時は `pyproject.toml` + `__init__.py` の version を同時に更新
|
|
113
113
|
|
|
114
114
|
## Adapter 実装時の注意
|
|
115
115
|
|
|
@@ -24,7 +24,7 @@ runops プロジェクトにおける Agent の作業ガイド。
|
|
|
24
24
|
| sweep 内容を確認だけ | `runops runs sweep <survey> --dry-run` |
|
|
25
25
|
| job 投入 | `runops runs submit` |
|
|
26
26
|
| 全 run 一括投入 | `runops runs submit --all` |
|
|
27
|
-
| キュー上書き / 依存ジョブ | `runops runs submit -qn <queue>` / `--afterok <job_id>` |
|
|
27
|
+
| キュー上書き / QOS / 依存ジョブ | `runops runs submit -qn <queue>` / `--qos <qos>` / `--afterok <job_id>` |
|
|
28
28
|
| 状態確認 (単一/複数/survey 一括) | `runops runs status [RUNS...]` |
|
|
29
29
|
| Slurm 同期 (単一/複数/survey 一括) | `runops runs sync [RUNS...]` (bulk: created + terminal state は silent skip) |
|
|
30
30
|
| ログ確認 | `runops runs log` |
|
|
@@ -301,6 +301,7 @@ Slurm job parameters. These become `#SBATCH` directives in `job.sh`.
|
|
|
301
301
|
| Field | Type | Required | Description |
|
|
302
302
|
|-------|------|----------|-------------|
|
|
303
303
|
| `partition` | string | No | Partition/queue name. Can be overridden at submit time with `runops runs submit -qn <name>` |
|
|
304
|
+
| `qos` | string | No | Slurm QOS name. Emits `#SBATCH --qos=<value>`. Can be overridden with `runops runs submit --qos <name>`. Note: camphor では使用不可 (partition 経由で暗黙決定) |
|
|
304
305
|
| `nodes` | integer | No | Number of nodes |
|
|
305
306
|
| `ntasks` | integer | No | Number of MPI tasks |
|
|
306
307
|
| `walltime` | string | Yes | Wall time limit (HH:MM:SS) |
|
|
@@ -312,6 +313,7 @@ Slurm job parameters. These become `#SBATCH` directives in `job.sh`.
|
|
|
312
313
|
| Field | Type | Required | Description |
|
|
313
314
|
|-------|------|----------|-------------|
|
|
314
315
|
| `partition` | string | No | Partition/queue name |
|
|
316
|
+
| `qos` | string | No | Slurm QOS name (camphor では使用不可) |
|
|
315
317
|
| `processes` | integer | No | MPI プロセス数 (`--rsc p=N`) |
|
|
316
318
|
| `threads` | integer | No | プロセスあたりスレッド数 (`--rsc t=T`) |
|
|
317
319
|
| `cores` | integer | No | プロセスあたりコア数 (`--rsc c=C`, ≥ threads) |
|
|
@@ -702,7 +702,7 @@ class BeachAdapter(SimulatorAdapter):
|
|
|
702
702
|
summary_file = output_dir / "summary.txt"
|
|
703
703
|
if summary_file.is_file():
|
|
704
704
|
try:
|
|
705
|
-
for line in summary_file.read_text().split("\n"):
|
|
705
|
+
for line in summary_file.read_text(encoding="utf-8").split("\n"):
|
|
706
706
|
line = line.strip()
|
|
707
707
|
if "=" not in line:
|
|
708
708
|
continue
|
|
@@ -765,7 +765,9 @@ class EmseAdapter(SimulatorAdapter):
|
|
|
765
765
|
nstep = self._get_expected_nstep(run_dir)
|
|
766
766
|
lines = [
|
|
767
767
|
line
|
|
768
|
-
for line in energy_file.read_text(
|
|
768
|
+
for line in energy_file.read_text(encoding="utf-8")
|
|
769
|
+
.strip()
|
|
770
|
+
.split("\n")
|
|
769
771
|
if line.strip()
|
|
770
772
|
]
|
|
771
773
|
if lines and nstep:
|
|
@@ -814,7 +816,9 @@ class EmseAdapter(SimulatorAdapter):
|
|
|
814
816
|
try:
|
|
815
817
|
lines = [
|
|
816
818
|
line
|
|
817
|
-
for line in energy_file.read_text(
|
|
819
|
+
for line in energy_file.read_text(encoding="utf-8")
|
|
820
|
+
.strip()
|
|
821
|
+
.split("\n")
|
|
818
822
|
if line.strip()
|
|
819
823
|
]
|
|
820
824
|
if lines:
|
|
@@ -273,7 +273,7 @@ class GenericAdapter(SimulatorAdapter):
|
|
|
273
273
|
|
|
274
274
|
if exit_code_path.exists():
|
|
275
275
|
try:
|
|
276
|
-
code = int(exit_code_path.read_text().strip())
|
|
276
|
+
code = int(exit_code_path.read_text(encoding="utf-8").strip())
|
|
277
277
|
except (ValueError, OSError):
|
|
278
278
|
return "unknown"
|
|
279
279
|
return "completed" if code == 0 else "failed"
|
|
@@ -316,7 +316,9 @@ class GenericAdapter(SimulatorAdapter):
|
|
|
316
316
|
exit_code_path = run_dir / WORK_DIR / EXIT_CODE_FILE
|
|
317
317
|
if exit_code_path.exists():
|
|
318
318
|
try:
|
|
319
|
-
summary["exit_code"] = int(
|
|
319
|
+
summary["exit_code"] = int(
|
|
320
|
+
exit_code_path.read_text(encoding="utf-8").strip()
|
|
321
|
+
)
|
|
320
322
|
except (ValueError, OSError) as exc:
|
|
321
323
|
errors.append(f"exit_code: {exc}")
|
|
322
324
|
|
|
@@ -265,7 +265,7 @@ def show(
|
|
|
265
265
|
typer.echo(f"Insight not found: {name}", err=True)
|
|
266
266
|
raise typer.Exit(code=1)
|
|
267
267
|
|
|
268
|
-
typer.echo(path.read_text())
|
|
268
|
+
typer.echo(path.read_text(encoding="utf-8"))
|
|
269
269
|
|
|
270
270
|
|
|
271
271
|
def sync(
|
|
@@ -852,7 +852,7 @@ def render() -> None:
|
|
|
852
852
|
rel = imports_path.relative_to(root)
|
|
853
853
|
typer.echo(f"Rendered: {rel}")
|
|
854
854
|
|
|
855
|
-
content = imports_path.read_text().strip()
|
|
855
|
+
content = imports_path.read_text(encoding="utf-8").strip()
|
|
856
856
|
if content:
|
|
857
857
|
for line in content.split("\n"):
|
|
858
858
|
if line.startswith("@"):
|
|
@@ -129,7 +129,13 @@ def sync(
|
|
|
129
129
|
RunState.PURGED.value,
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
from collections import Counter
|
|
133
|
+
|
|
132
134
|
failures = 0
|
|
135
|
+
state_counts: Counter[str] = Counter()
|
|
136
|
+
changed = 0
|
|
137
|
+
total = 0
|
|
138
|
+
|
|
133
139
|
for run_dir in targets:
|
|
134
140
|
try:
|
|
135
141
|
manifest = read_manifest(run_dir)
|
|
@@ -138,11 +144,15 @@ def sync(
|
|
|
138
144
|
failures += 1
|
|
139
145
|
continue
|
|
140
146
|
|
|
147
|
+
total += 1
|
|
148
|
+
|
|
141
149
|
# In multi-target / bulk mode, runs without a job_id are skipped
|
|
142
150
|
# silently — they typically belong to ``created`` runs that haven't
|
|
143
151
|
# been submitted yet.
|
|
144
152
|
if not manifest.job.get("job_id", ""):
|
|
145
153
|
if multi:
|
|
154
|
+
state = str(manifest.run.get("status", "created"))
|
|
155
|
+
state_counts[state] += 1
|
|
146
156
|
continue
|
|
147
157
|
run_id_str = manifest.run.get("id", run_dir.name)
|
|
148
158
|
typer.echo(
|
|
@@ -158,6 +168,7 @@ def sync(
|
|
|
158
168
|
# in bulk mode so the rest of the survey still gets processed.
|
|
159
169
|
current_state = str(manifest.run.get("status", ""))
|
|
160
170
|
if current_state in terminal_states:
|
|
171
|
+
state_counts[current_state] += 1
|
|
161
172
|
if multi:
|
|
162
173
|
continue
|
|
163
174
|
run_id_str = manifest.run.get("id", run_dir.name)
|
|
@@ -174,14 +185,38 @@ def sync(
|
|
|
174
185
|
failures += 1
|
|
175
186
|
continue
|
|
176
187
|
|
|
188
|
+
after = str(result.state_after or current_state)
|
|
189
|
+
state_counts[after] += 1
|
|
190
|
+
|
|
177
191
|
if result.state_before == result.state_after:
|
|
178
192
|
typer.echo(f"{run_id}: state unchanged ({result.state_after})")
|
|
179
193
|
else:
|
|
194
|
+
changed += 1
|
|
180
195
|
msg = f"{run_id}: {result.state_before} -> {result.state_after}"
|
|
181
196
|
failure_reason = str(result.data.get("failure_reason", ""))
|
|
182
197
|
if failure_reason:
|
|
183
198
|
msg += f" (reason: {failure_reason})"
|
|
184
199
|
typer.echo(msg)
|
|
185
200
|
|
|
201
|
+
# Print summary when multiple targets are involved
|
|
202
|
+
if multi and total > 0:
|
|
203
|
+
parts = []
|
|
204
|
+
for state in (
|
|
205
|
+
"completed",
|
|
206
|
+
"running",
|
|
207
|
+
"submitted",
|
|
208
|
+
"created",
|
|
209
|
+
"failed",
|
|
210
|
+
"cancelled",
|
|
211
|
+
"archived",
|
|
212
|
+
"purged",
|
|
213
|
+
):
|
|
214
|
+
count = state_counts.get(state, 0)
|
|
215
|
+
if count:
|
|
216
|
+
parts.append(f"{count} {state}")
|
|
217
|
+
summary_line = ", ".join(parts)
|
|
218
|
+
typer.echo(f"\nSummary: {summary_line} ({total} total)")
|
|
219
|
+
typer.echo(f" {changed} state(s) changed in this sync")
|
|
220
|
+
|
|
186
221
|
if failures:
|
|
187
222
|
raise typer.Exit(code=1)
|