@topolo/cli 0.13.19 → 0.13.21
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.
- package/agent-packs/README.md +421 -1
- package/agent-packs/docs/selected-artifacts.md +47 -0
- package/agent-packs/documentation/cloud-task-state.md +56 -0
- package/agent-packs/domain-contexts/README.md +25 -0
- package/agent-packs/domain-contexts/cicd.json +8 -0
- package/agent-packs/gui/feed-adapter.js +4 -0
- package/agent-packs/gui/index.html +9 -0
- package/agent-packs/gui/studio.css +14 -0
- package/agent-packs/gui/studio.js +121 -0
- package/agent-packs/gui/studio_server.py +355 -0
- package/agent-packs/roles/cicd/CLAUDE.md +24 -0
- package/agent-packs/specializations/cicd--cicd.json +5 -0
- package/agent-packs/specializations/cicd--pipeline-engineering.json +5 -0
- package/agent-packs/specializations/cicd--promotion-deployment.json +5 -0
- package/agent-packs/specializations/cicd--queue-recovery.json +5 -0
- package/agent-packs/specializations/cicd--release-verification.json +5 -0
- package/agent-packs/specializations/cicd--runner-capacity.json +5 -0
- package/agent-packs/specializations/intakes--engineering-02.json +5 -0
- package/agent-packs/specializations/intakes--engineering-03.json +5 -0
- package/agent-packs/specializations/intakes--engineering.json +5 -0
- package/agent-packs/specializations/intakes--operator-01.json +5 -0
- package/agent-packs/specializations/intakes--operator-02.json +5 -0
- package/agent-packs/specializations/operator-skills--audio-and-narration-specialist.json +5 -0
- package/agent-packs/specializations/operator-skills--brand-and-copywriting-specialist.json +5 -0
- package/agent-packs/specializations/operator-skills--capability-research-specialist.json +5 -0
- package/agent-packs/specializations/operator-skills--data-analysis-and-visualization.json +5 -0
- package/agent-packs/specializations/operator-skills--financial-evidence-specialist.json +5 -0
- package/agent-packs/specializations/operator-skills--operating-template-specialist.json +5 -0
- package/agent-packs/specializations/operator-skills--operator-skill-library.json +5 -0
- package/agent-packs/specializations/operator-skills--operator-skills.json +5 -0
- package/agent-packs/specializations/operator-skills--operator-workflow-evaluation.json +5 -0
- package/agent-packs/specializations/operator-skills--privacy-and-agreement-review.json +5 -0
- package/agent-packs/specializations/operator-skills--storytelling-specialist.json +5 -0
- package/agent-packs/specializations/operator-skills--ux-and-accessibility-specialist.json +5 -0
- package/agent-packs/specializations/operator-skills--video-production-specialist.json +5 -0
- package/agent-packs/specializations/operator-skills--visual-design-specialist.json +5 -0
- package/agent-packs/specializations/operator-skills--workflow-integration-specialist.json +5 -0
- package/agent-packs/specializations/operators--access-and-privacy.json +5 -0
- package/agent-packs/specializations/operators--accounting-evidence-review.json +5 -0
- package/agent-packs/specializations/operators--agreement-operations.json +5 -0
- package/agent-packs/specializations/operators--books-operator.json +5 -0
- package/agent-packs/specializations/operators--brand-operator.json +5 -0
- package/agent-packs/specializations/operators--commerce-operations.json +5 -0
- package/agent-packs/specializations/operators--communications-operator.json +5 -0
- package/agent-packs/specializations/operators--content-and-assets-operator.json +5 -0
- package/agent-packs/specializations/operators--customer-operations.json +5 -0
- package/agent-packs/specializations/operators--design-operator.json +5 -0
- package/agent-packs/specializations/operators--design-production-02.json +5 -0
- package/agent-packs/specializations/operators--design-production-03.json +5 -0
- package/agent-packs/specializations/operators--design-production-04.json +5 -0
- package/agent-packs/specializations/operators--device-and-feed-operator.json +5 -0
- package/agent-packs/specializations/operators--director-operator.json +5 -0
- package/agent-packs/specializations/operators--experience-review.json +5 -0
- package/agent-packs/specializations/operators--growth-operations.json +5 -0
- package/agent-packs/specializations/operators--learn-operator.json +5 -0
- package/agent-packs/specializations/operators--localization-operator.json +5 -0
- package/agent-packs/specializations/operators--operators.json +5 -0
- package/agent-packs/specializations/operators--pay-operator.json +5 -0
- package/agent-packs/specializations/operators--research-and-intelligence.json +5 -0
- package/agent-packs/specializations/operators--roadmap-operator.json +5 -0
- package/agent-packs/specializations/operators--social-content-operator.json +5 -0
- package/agent-packs/specializations/operators--talent-operations.json +5 -0
- package/agent-packs/specializations/operators--web-operator.json +5 -0
- package/agent-packs/specializations/operators--workflow-operator.json +5 -0
- package/agent-packs/specializations/specialists--adversarial-qa.json +5 -0
- package/agent-packs/specializations/specialists--backlog-dispatch.json +5 -0
- package/agent-packs/specializations/specialists--build-01.json +5 -0
- package/agent-packs/specializations/specialists--build-02.json +5 -0
- package/agent-packs/specializations/specialists--build-03.json +5 -0
- package/agent-packs/specializations/specialists--developer-environment-steward.json +5 -0
- package/agent-packs/specializations/specialists--documentation-knowledge-steward.json +5 -0
- package/agent-packs/specializations/specialists--execution-readiness.json +5 -0
- package/agent-packs/specializations/specialists--incident-triage.json +5 -0
- package/agent-packs/specializations/specialists--platform-package-steward.json +5 -0
- package/agent-packs/specializations/specialists--product-direction-01.json +5 -0
- package/agent-packs/specializations/specialists--product-direction-02.json +5 -0
- package/agent-packs/specializations/specialists--release-recovery.json +5 -0
- package/agent-packs/specializations/specialists--release-watch.json +5 -0
- package/agent-packs/specializations/specialists--roadmap-planning-01.json +5 -0
- package/agent-packs/specializations/specialists--roadmap-planning-02.json +5 -0
- package/agent-packs/specializations/specialists--security-permissions-review.json +5 -0
- package/agent-packs/specializations/specialists--system-architecture-01.json +5 -0
- package/agent-packs/specializations/specialists--system-architecture-02.json +5 -0
- package/agent-packs/specializations/specialists--translation.json +5 -0
- package/agent-packs/specializations/specialists--ux-consistency-review.json +5 -0
- package/agent-packs/specializations/specialists--workflow-improvement.json +5 -0
- package/agent-packs/specializations/specialists--worktree-retirement.json +5 -0
- package/agent-packs/src/topolo_agent_pack/cicd.py +101 -0
- package/agent-packs/src/topolo_agent_pack/claude.py +22 -7
- package/agent-packs/src/topolo_agent_pack/claude_activation.py +157 -0
- package/agent-packs/src/topolo_agent_pack/claude_completion_recovery.py +216 -0
- package/agent-packs/src/topolo_agent_pack/claude_desktop.py +181 -0
- package/agent-packs/src/topolo_agent_pack/claude_dispatch.py +240 -0
- package/agent-packs/src/topolo_agent_pack/claude_prompt.py +74 -0
- package/agent-packs/src/topolo_agent_pack/claude_runner.py +207 -0
- package/agent-packs/src/topolo_agent_pack/claude_service.py +397 -0
- package/agent-packs/src/topolo_agent_pack/cli.py +181 -16
- package/agent-packs/src/topolo_agent_pack/closed_ledger_fence.py +118 -0
- package/agent-packs/src/topolo_agent_pack/cloud_attach.py +128 -0
- package/agent-packs/src/topolo_agent_pack/cloud_cutover.py +134 -0
- package/agent-packs/src/topolo_agent_pack/cloud_delta.py +162 -0
- package/agent-packs/src/topolo_agent_pack/cloud_migrate.py +142 -0
- package/agent-packs/src/topolo_agent_pack/cloud_recovery.py +42 -0
- package/agent-packs/src/topolo_agent_pack/cloud_work.py +126 -0
- package/agent-packs/src/topolo_agent_pack/coordinator_activity.py +27 -0
- package/agent-packs/src/topolo_agent_pack/coordinator_context.py +91 -0
- package/agent-packs/src/topolo_agent_pack/coordinator_refresh.py +116 -0
- package/agent-packs/src/topolo_agent_pack/desktop_acceptance.py +45 -0
- package/agent-packs/src/topolo_agent_pack/desktop_launcher.py +114 -0
- package/agent-packs/src/topolo_agent_pack/domain_context.py +38 -0
- package/agent-packs/src/topolo_agent_pack/execution.py +103 -6
- package/agent-packs/src/topolo_agent_pack/frontdoor.py +23 -0
- package/agent-packs/src/topolo_agent_pack/linked_task_context.py +80 -0
- package/agent-packs/src/topolo_agent_pack/live.py +285 -18
- package/agent-packs/src/topolo_agent_pack/native.py +160 -4
- package/agent-packs/src/topolo_agent_pack/review_context.py +33 -0
- package/agent-packs/src/topolo_agent_pack/role_catalog.py +137 -0
- package/agent-packs/src/topolo_agent_pack/role_context.py +63 -0
- package/agent-packs/src/topolo_agent_pack/role_refresh.py +50 -0
- package/agent-packs/src/topolo_agent_pack/topolo.py +7 -1
- package/agent-packs/src/topolo_agent_pack/work.py +322 -0
- package/agent-packs/src/topolo_agent_pack/work_adoption.py +122 -0
- package/agent-packs/src/topolo_agent_pack/work_artifacts.py +84 -0
- package/agent-packs/src/topolo_agent_pack/work_context.py +77 -0
- package/agent-packs/src/topolo_agent_pack/work_gui.py +51 -0
- package/agent-packs/src/topolo_agent_pack/work_native.py +414 -0
- package/agent-packs/src/topolo_agent_pack/work_wait.py +151 -0
- package/agent-packs/templates/topolo-coordinators/AGENTS.md +7 -0
- package/agent-packs/templates/topolo-coordinators/agents/intakes/cicd/AGENTS.md +6 -0
- package/agent-packs/templates/topolo-coordinators/agents/intakes/cicd/config.json +4 -0
- package/agent-packs/templates/topolo-coordinators/agents/intakes/engineering/AGENTS.md +3 -0
- package/agent-packs/templates/topolo-coordinators/agents/intakes/engineering/config.json +4 -0
- package/agent-packs/templates/topolo-coordinators/agents/intakes/operator-01/AGENTS.md +3 -0
- package/agent-packs/templates/topolo-coordinators/agents/intakes/operator-01/config.json +4 -0
- package/agent-packs/templates/topolo-coordinators/pack.json +56 -0
- package/dist/chunk-NYDIAYVY.js +144 -0
- package/dist/{claude-pack-backend-YEVPAOID.js → chunk-UY5LEU5C.js} +1659 -21
- package/dist/claude-desktop-profile-JCQKSY3K.js +13 -0
- package/dist/claude-pack-activation-Q25MCEPU.js +506 -0
- package/dist/claude-pack-backend-HUTKGIDS.js +90 -0
- package/dist/index.js +89 -10
- package/package.json +4 -4
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/build-03",
|
|
4
|
+
"instructions": "# Build 03\n\n## Specialization\nExecute one explicitly dispatched contained source task at a time. Verify ownership and use an isolated worktree under repository policy. Complete validated source and accepted owning-controller handoff before releasing custody.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/developer-environment-steward",
|
|
4
|
+
"instructions": "# Developer Environment Steward\n\n## Specialization\nRead-only local tooling, runtime PATH, dependency and capacity inventory; prepare contained environment proposals.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/documentation-knowledge-steward",
|
|
4
|
+
"instructions": "# Documentation & Knowledge Steward\n\n## Specialization\nAuthor documentation and maintain durable evidence-backed knowledge, source provenance and concise handovers.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/execution-readiness",
|
|
4
|
+
"instructions": "# Execution Readiness\n\n## Specialization\nTurn observations into bounded clarification/reproduction briefs; check scope, acceptance, dependencies, ownership and recorded authority before Backlog claims. No implementation or permission invented.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/incident-triage",
|
|
4
|
+
"instructions": "# Incident Triage\n\n## Specialization\nBounded symptom reproduction, impact classification and incident evidence; route release/controller failures to Release Recovery and local tool issues to Environment. No takeover of current recovery owners.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/platform-package-steward",
|
|
4
|
+
"instructions": "# Platform & Package Steward\n\n## Specialization\nSteward canonical package currency, versions, lockfiles, consumer impact and shared platform contracts. Architecture retains system design; release and recovery owners retain their custody.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/product-direction-01",
|
|
4
|
+
"instructions": "# Product Direction 01\n\n## Specialization\nOwn product direction, product design, user research, landing-page experience and inspected visual review packets.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/product-direction-02",
|
|
4
|
+
"instructions": "# Product Direction 02\n\n## Specialization\nProvide an independent Product Direction lane for bounded product, design and research briefs. Avoid duplicating an existing owner.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/release-recovery",
|
|
4
|
+
"instructions": "# Release Recovery\n\n## Specialization\nDiagnose controller and release failures and explicitly assigned recovery. Preserve current owners, exact pauses, uncertainty and effects. Separate containment, source repair, environment promotion and runtime proof.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/release-watch",
|
|
4
|
+
"instructions": "# Release Watch\n\n## Specialization\nRead-only controller monitoring, dependency/proof tracking and delivery reconciliation. Report meaningful transitions, precise blockers and current evidence. Accepted/pushed/published is not deployed; source promotion is not runtime activation. Never retry, sign, deploy, change priority/config, steal leases, or alter controller-owned trains. Route corrective proposals to Release Recovery and the hub.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/roadmap-planning-01",
|
|
4
|
+
"instructions": "# Roadmap Planning 01\n\n## Specialization\nTranslate an authorized brief into the existing production Roadmapper project and item structure. Reuse canonical IDs and dependency edges; leave dates, assignees, effort and budgets unknown unless supported by evidence. Operational planning content follows its own authorization; code and deployment require the engineering release process.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/roadmap-planning-02",
|
|
4
|
+
"instructions": "# Roadmap Planning 02\n\n## Specialization\nProvide independent bounded roadmap planning. Preserve canonical IDs and unknown estimates; no canonical mutation or implementation without applicable authority/proof.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/security-permissions-review",
|
|
4
|
+
"instructions": "# Security & Permissions Review\n\n## Specialization\nReview credential, tenant, permission and signed authority boundaries. Prepare evidence and recommendations; never widen scopes or infer protected action approval.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/system-architecture-01",
|
|
4
|
+
"instructions": "# System Architecture 01\n\n## Specialization\nOwn system architecture and cross-service contracts. Preserve catalog, localization and icon contract requirements. Route canonical package implementation to Platform & Package Steward.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/system-architecture-02",
|
|
4
|
+
"instructions": "# System Architecture 02\n\n## Specialization\nProvide independent bounded system and contract architecture review. No duplicate current source owner; packages belong to Platform & Package Steward.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/translation",
|
|
4
|
+
"instructions": "# Topolo Translation\n\n## Specialization\nTranslate source-bound English content with exact source/version, keys/namespaces, locales and terminology. Validate structure and supported Localize response schemas. Deliver artifacts to the Localization Operator; the parent owner retains source/release custody and upload/publication requires its own authority.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/ux-consistency-review",
|
|
4
|
+
"instructions": "# UX Consistency Review\n\n## Specialization\nIndependently review UX journeys, responsive behavior, accessibility, locale and shared design consistency against concrete supplied evidence.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/workflow-improvement",
|
|
4
|
+
"instructions": "# Workflow Improvement\n\n## Specialization\nImprove intake, ownership, responsiveness, lane capacity and economical role use through scoped proposals and evidence.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "topolo-role-specialization-v1",
|
|
3
|
+
"logicalId": "specialists/worktree-retirement",
|
|
4
|
+
"instructions": "# Topolo Worktree Retirement\n\n## Specialization\nQualify task worktrees for supported recoverable retirement after verified production and original-owner completion. Check current processes, leases, claims, trains, dependencies and preserved local data; never force removal or infer branch deletion authority.\n\n## Working method\nRead the current assignment, repository or resource contracts and exact existing checkpoint before acting. Identify the narrowest relevant evidence, affected boundaries, dependencies and acceptance checks. Perform only the assigned phase; preserve the substantive source/release owner. Return the actual outcome, checks, evidence pointers and next supported action.\n\n## Task context and output\nLoad only the task-specific Docs/Bytes references supplied with this assignment. Request a missing exact reference instead of scanning every task, exporting the workspace or reading old chats. Reusable instructions are not task state. Return a concise outcome, inspected evidence, material limitations, remaining owner and next action; record progress on the same task for the GUI.\n\n## Boundaries\nA fresh worker inherits no task lease or effect authority. Preserve current owners, holds, pauses and uncertain outcomes. Never replay a mutation because a response was lost. No peer messaging, scheduling, extra worker creation or production effect is authorized by this role definition. Use the current task-based model/effort selection; the Agent hosted model is not the Desktop worker model. Stop after the bounded assignment."
|
|
5
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Native Claude task-profile definitions, not persistent worker sessions."""
|
|
2
|
+
import argparse
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
import pathlib
|
|
6
|
+
from .storage import PackError, atomic_json
|
|
7
|
+
from .task_models import default_configuration, _selection
|
|
8
|
+
|
|
9
|
+
DISCIPLINES = {
|
|
10
|
+
'queue-recovery': 'Reconcile existing intents, dependencies, queue age, leases and uncertain effects. Preserve ownership. Never clear holds or replay operations without verified reconciliation.',
|
|
11
|
+
'runner-capacity': 'Diagnose runner eligibility, architecture, admission, locking, utilisation and accepted job evidence. Do not change capacities or restart services without the task authority.',
|
|
12
|
+
'pipeline-engineering': 'Diagnose and repair assigned validation, caching, artifact, provenance or scheduler defects in an isolated dev worktree. Follow the normal review and release process.',
|
|
13
|
+
'promotion-deployment': 'Advance explicitly eligible existing intents through DEV, STG and PROD using the owning release controller. Verify exact SHA and artifact custody. Never create duplicate handoffs or bypass a train.',
|
|
14
|
+
'release-verification': 'Independently inspect exact release intent, deployment revision and actual environment proof. Do not implement source changes or perform deployment effects during verification.'}
|
|
15
|
+
PROFILES = {'trivial': ('claude-haiku-5-5','low'), 'routine': ('claude-sonnet-5-5','low'), 'standard': ('claude-sonnet-5-5','medium'), 'deep': ('claude-opus-5-5','high')}
|
|
16
|
+
RELEASE_RISK_TYPES = frozenset({'production-deployment','effect-reconciliation','signing-custody','concurrency-repair'})
|
|
17
|
+
COMMON = '''Execute only the bounded assignment, then return its checkpoint and stop. Do not spawn other agents, resume old workers, create schedules or send peer messages. Topolo Agent contains reusable specialization only. Load current task context from the referenced Topolo Docs/Bytes packet, preserving canonical task, intent, owner and effect identities. An empty local workspace grants no permission to repeat work. Local task packets are disposable caches. Refuse missing context or unresolved effects; never silently invent completion. Record outcome, next action and evidence in the existing task/GUI through supported mechanisms. A missing cloud or feed capability is a blocker, not permission to substitute chat history. No production mutation is authorized by this definition alone.'''
|
|
18
|
+
from .coordinator_context import CONTRACT as COORDINATOR
|
|
19
|
+
|
|
20
|
+
def definitions():
|
|
21
|
+
result={}
|
|
22
|
+
for discipline,prompt in DISCIPLINES.items():
|
|
23
|
+
for profile,(model,effort) in PROFILES.items():
|
|
24
|
+
name='cicd-'+discipline+'-'+profile
|
|
25
|
+
result[name]={'description':discipline+'; '+profile+' task profile. Select using context/CICD-DISPATCH.md.', 'model':model,'effort':effort,'maxTurns':24,'permissionMode':'bypassPermissions','disallowedTools':['Agent'],'prompt':prompt+'\n\n'+COMMON}
|
|
26
|
+
if profile=='trivial':result[name]['tools']=['Read','Glob','Grep']
|
|
27
|
+
return result
|
|
28
|
+
|
|
29
|
+
def select(discipline,task):
|
|
30
|
+
if discipline not in DISCIPLINES:
|
|
31
|
+
raise PackError('Unknown CI/CD discipline')
|
|
32
|
+
config=default_configuration();constraints={'allowedModels':sorted({v[0] for v in PROFILES.values()}),'allowedEfforts':['low','medium','high']}
|
|
33
|
+
selection=_selection(config,task,'claude',constraints)
|
|
34
|
+
if task['type'] in RELEASE_RISK_TYPES and selection['rule']['profile']!='deep':
|
|
35
|
+
raise PackError('Release-risk tasks require a deep profile')
|
|
36
|
+
return 'cicd-'+discipline+'-'+selection['rule']['profile']
|
|
37
|
+
|
|
38
|
+
def install(workspace):
|
|
39
|
+
workspace=pathlib.Path(workspace).expanduser().resolve()
|
|
40
|
+
if not (workspace/'CLAUDE.md').is_file():
|
|
41
|
+
raise PackError('Existing coordinator CLAUDE.md required')
|
|
42
|
+
rows=definitions(); files={}
|
|
43
|
+
for name,row in rows.items():
|
|
44
|
+
header={k:v for k,v in row.items() if k!='prompt'};header={'name':name,**header}
|
|
45
|
+
# JSON values are valid YAML scalars and avoid implicit YAML conversions.
|
|
46
|
+
body='---\n'+'\n'.join(k+': '+json.dumps(v) for k,v in header.items())+'\n---\n\n'+row['prompt']+'\n'
|
|
47
|
+
files[workspace/'.claude/agents'/(name+'.md')]=body
|
|
48
|
+
guide='''# CI/CD dispatch contract
|
|
49
|
+
|
|
50
|
+
Use one fresh native Agent invocation per bounded task. Never resume a completed worker. These files are reusable templates, not sidebar sessions. Select the discipline and task profile before dispatch; pass task identity, canonical Docs/Bytes references, current owner, exact release intent, scope, acceptance and effect authority in the invocation. If an existing owner holds the task, reconcile rather than replace them.
|
|
51
|
+
|
|
52
|
+
Task profiles: trivial = Haiku 5.5 low, only low-risk format/extract-fields/reference-lookup/status-read; routine = Sonnet 5.5 low; standard = Sonnet 5.5 medium; complex or security-critical = Opus 5.5 high. Ordinary implementation is never trivial. Production effects, uncertain recovery, signing/custody and concurrency require deep. Choose the matching cicd-<discipline>-<profile> subagent_type; do not override its model or inherit the coordinator effort. Native model rejection is a visible blocker, never a silent fallback.
|
|
53
|
+
|
|
54
|
+
Disciplines: queue-recovery, runner-capacity, pipeline-engineering, promotion-deployment, release-verification. For simple read-only status extraction use queue-recovery-trivial. Before mutations read the current owning controller records, current signed authority and unresolved operations. Do not duplicate existing intents. Independent release verification uses a fresh release-verification worker. Completed model turns do not prove delivery.
|
|
55
|
+
|
|
56
|
+
Dispatch may run independent bounded tasks concurrently subject to current admitted capacity and disjoint ownership. Coordinator remains available for human input. Publish each meaningful checkpoint once to the existing canonical task and GUI; missing platform persistence or dispatch must be reported explicitly. Do not claim cross-machine duplicate protection from a local lock.
|
|
57
|
+
'''
|
|
58
|
+
files[workspace/'context/CICD-DISPATCH.md']=guide
|
|
59
|
+
# Reject unowned conflicting files before any write.
|
|
60
|
+
receipt_path=workspace/'.claude/cicd-installation.json'
|
|
61
|
+
prior=json.loads(receipt_path.read_text()) if receipt_path.exists() else {'files':{}}
|
|
62
|
+
for path,body in files.items():
|
|
63
|
+
if path.is_symlink():
|
|
64
|
+
raise PackError('Symlinked CI/CD definition')
|
|
65
|
+
if path.exists() and path.read_text()!=body and hashlib.sha256(path.read_bytes()).hexdigest()!=prior['files'].get(str(path.relative_to(workspace))):
|
|
66
|
+
raise PackError('Changed definition requires reconciliation: '+str(path))
|
|
67
|
+
for path,body in files.items():path.parent.mkdir(parents=True,exist_ok=True);path.write_text(body);path.chmod(0o600)
|
|
68
|
+
marker='\n\n## Native CI/CD specialist dispatch\nRead context/CICD-DISPATCH.md before assigning release work. Use the project cicd-* native subagents with explicit task profiles.\n'
|
|
69
|
+
charter=workspace/'CLAUDE.md'
|
|
70
|
+
# Older generated coordinators accidentally carried the worker-only contract.
|
|
71
|
+
# Replace only that exact known prefix; preserve the remaining role charter.
|
|
72
|
+
body=charter.read_text()
|
|
73
|
+
if body.startswith(COMMON):
|
|
74
|
+
charter.write_text(COORDINATOR+body[len(COMMON):])
|
|
75
|
+
if marker not in charter.read_text():
|
|
76
|
+
with charter.open('a') as stream:stream.write(marker)
|
|
77
|
+
receipt={'format':'topolo-cicd-specialists','schemaVersion':1,'profiles':PROFILES,'files':{str(p.relative_to(workspace)):hashlib.sha256(p.read_bytes()).hexdigest() for p in files},'workersCreated':0,'activationVerified':False}
|
|
78
|
+
atomic_json(receipt_path,receipt);return receipt
|
|
79
|
+
|
|
80
|
+
def main():
|
|
81
|
+
parser=argparse.ArgumentParser();sub=parser.add_subparsers(dest='action',required=True)
|
|
82
|
+
p=sub.add_parser('install');p.add_argument('workspace')
|
|
83
|
+
p=sub.add_parser('select');p.add_argument('discipline',choices=DISCIPLINES);p.add_argument('--task',required=True)
|
|
84
|
+
args=parser.parse_args();print(json.dumps(install(args.workspace) if args.action=='install' else {'subagent':select(args.discipline,json.loads(args.task))},indent=2))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def configure_profile(config):
|
|
88
|
+
"""Set the pack-owned user scope; project scope cannot enable bypass."""
|
|
89
|
+
config=pathlib.Path(config).expanduser().resolve()
|
|
90
|
+
config.mkdir(parents=True,exist_ok=True,mode=0o700)
|
|
91
|
+
path=config/'settings.json'
|
|
92
|
+
if path.is_symlink():
|
|
93
|
+
raise PackError('Symlinked Claude user settings')
|
|
94
|
+
settings=json.loads(path.read_text()) if path.exists() else {}
|
|
95
|
+
settings.setdefault('permissions',{})['defaultMode']='bypassPermissions'
|
|
96
|
+
settings['model']='claude-sonnet-5-5'
|
|
97
|
+
settings.setdefault('modelSettings',{}).setdefault('claude-sonnet-5-5',{})['effortLevel']='low'
|
|
98
|
+
atomic_json(path,settings)
|
|
99
|
+
return {'path':str(path),'settingsReadback':json.loads(path.read_text()),'existingDesktopSessionsVerified':False}
|
|
100
|
+
|
|
101
|
+
if __name__=='__main__':main()
|
|
@@ -10,6 +10,7 @@ import json
|
|
|
10
10
|
import os
|
|
11
11
|
import pathlib
|
|
12
12
|
import pty
|
|
13
|
+
import re
|
|
13
14
|
import select as io_select
|
|
14
15
|
import shutil
|
|
15
16
|
import subprocess
|
|
@@ -28,19 +29,21 @@ def find_binary():
|
|
|
28
29
|
return shutil.which('claude')
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
def handoff(binary, directory, session_id):
|
|
32
|
+
def handoff(binary, directory, session_id, env=None):
|
|
32
33
|
"""Native --desktop requires a TTY. No prompt, model call or shell is used."""
|
|
33
34
|
if not binary:
|
|
34
35
|
raise PackError('Claude Code 2.1.285+ is required; install Claude Desktop or Claude Code.')
|
|
35
36
|
version = subprocess.run([binary, '--version'], capture_output=True, text=True, timeout=10)
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
release = re.match(r'^(\d+)\.(\d+)\.(\d+)\s+\(Claude Code\)', version.stdout)
|
|
38
|
+
if version.returncode or release is None or tuple(map(int, release.groups())) < (2, 1, 285):
|
|
39
|
+
raise PackError('Native import requires the Desktop handoff capability introduced in Claude Code 2.1.285; selected binary: ' + version.stdout.strip())
|
|
38
40
|
master, slave = pty.openpty()
|
|
39
41
|
process = None
|
|
40
42
|
output = bytearray()
|
|
41
43
|
try:
|
|
42
44
|
process = subprocess.Popen([binary, '--desktop', '--resume', session_id],
|
|
43
|
-
cwd=directory, stdin=slave, stdout=slave, stderr=slave
|
|
45
|
+
cwd=directory, stdin=slave, stdout=slave, stderr=slave,
|
|
46
|
+
**({'env':env} if env is not None else {}))
|
|
44
47
|
os.close(slave)
|
|
45
48
|
slave = None
|
|
46
49
|
deadline = time.monotonic() + 20
|
|
@@ -105,6 +108,10 @@ def materialize(lib, name, selected, config):
|
|
|
105
108
|
if record['sourceRevision'] != revision:
|
|
106
109
|
raise PackError('Existing Claude agent uses a different revision; build a new named pack to preserve its context.')
|
|
107
110
|
if record['importState'] != 'preparing':
|
|
111
|
+
if agent['id'] == 'cicd':
|
|
112
|
+
from .cicd import install, configure_profile
|
|
113
|
+
install(record['workspace'])
|
|
114
|
+
configure_profile(config)
|
|
108
115
|
records.append(record)
|
|
109
116
|
continue
|
|
110
117
|
else:
|
|
@@ -139,12 +146,19 @@ def materialize(lib, name, selected, config):
|
|
|
139
146
|
if relative.as_posix() == 'AGENTS.md':
|
|
140
147
|
relative = pathlib.Path('CLAUDE.md')
|
|
141
148
|
write_new(workspace / relative, lib.object(resource['content']).read_bytes())
|
|
149
|
+
if agent['id'] == 'cicd':
|
|
150
|
+
from .cicd import install, configure_profile
|
|
151
|
+
install(workspace)
|
|
152
|
+
configure_profile(config)
|
|
142
153
|
session_id = record['cliSessionId']
|
|
143
154
|
transcript = pathlib.Path(record['transcript'])
|
|
144
155
|
note = (agent['title'] + '. You are this Topolo Agent Pack role in Claude Desktop. '
|
|
145
156
|
'Read CLAUDE.md and relevant context/ files before work. '
|
|
146
157
|
'This is starting context only; no assignment, claim or prior conversation is inherited. '
|
|
147
|
-
'Await a new human request.
|
|
158
|
+
'Await a new human request. A human request authorizes the necessary bounded specialist dispatch '
|
|
159
|
+
'within its scope; do not ask for that authorization again. Preserve existing owners, holds '
|
|
160
|
+
'and action-specific approval requirements. Use the configured dispatch adapter and canonical '
|
|
161
|
+
'task records; do not substitute coordinator execution when dispatch is unavailable.')
|
|
148
162
|
rows = [{'parentUuid': None, 'isSidechain': False, 'userType': 'external',
|
|
149
163
|
'cwd': str(workspace), 'sessionId': session_id, 'version': '2.1.289',
|
|
150
164
|
'type': 'user', 'message': {'role': 'user', 'content': note},
|
|
@@ -214,7 +228,8 @@ def main(argv):
|
|
|
214
228
|
if args.command in {'status', 'doctor', 'recover', 'list'}:
|
|
215
229
|
proof = readback(state['agents'], app_data)
|
|
216
230
|
active_path = lib.root / 'claude/active.json'
|
|
217
|
-
pending_path = lib.root / 'claude/
|
|
231
|
+
pending_path = lib.root / ('claude/startup-operation.json' if
|
|
232
|
+
(lib.root / 'claude/startup-operation.json').exists() else 'claude/native-operation.json')
|
|
218
233
|
result = {**state, 'adoptionProof': proof, 'verifiedAgents': sum(p['verified'] for p in proof),
|
|
219
234
|
'fullPackSwitchSupported': False, 'sidebarGroupsAndPinsVerified': False,
|
|
220
235
|
'nativeRecordsRewritten': False, 'modelIdentityResponseVerified': False,
|
|
@@ -224,7 +239,7 @@ def main(argv):
|
|
|
224
239
|
'nativeRecoveryReplayed': False,
|
|
225
240
|
'verificationBoundary': 'read-only adoption records; use the explicit native connection for current settings or recovery'}
|
|
226
241
|
else:
|
|
227
|
-
if (lib.root / 'claude/native-operation.json'
|
|
242
|
+
if any((lib.root / ('claude/'+name)).exists() for name in ['native-operation.json','startup-operation.json','activation-operation.json','launch-operation.json']):
|
|
228
243
|
raise PackError('An unresolved native Claude operation blocks imports and preparation. Use topolo agent-packs recover with the explicit native connection; no effects are replayed.')
|
|
229
244
|
manifest, revision = lib.load(args.source)
|
|
230
245
|
chosen = select(manifest, args.sets, args.agents)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""Read-only cloud and service evidence for the exact installed Desktop roster."""
|
|
2
|
+
import hashlib,json,os,time,fcntl
|
|
3
|
+
from .storage import Library,read_json,PackError,canonical
|
|
4
|
+
from .work import require
|
|
5
|
+
from .cloud_work import CloudStore
|
|
6
|
+
from .work_artifacts import read_checkpoint
|
|
7
|
+
from .claude_service import ensure_running,verify_retired_binding
|
|
8
|
+
from .live import request
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def observe(root,qualification_task=None,previous=None,connection=None,start_service=False,native_proof=False,wait_retired_service=False,require_native_idle=False,successor_connection=None,warm_connection=None):
|
|
12
|
+
lib=Library(root);store=CloudStore(root);version,state=store.load()
|
|
13
|
+
if warm_connection is not None:
|
|
14
|
+
require(previous is None and connection is None and not start_service and not wait_retired_service and not require_native_idle and not native_proof and qualification_task is None and successor_connection is None,'Warm restore cannot change lifecycle custody')
|
|
15
|
+
binding=read_json(lib.root/'work/claude-frontdoors.json')
|
|
16
|
+
require(isinstance(warm_connection,dict) and set(warm_connection)=={'pid','runtime','identity','socket','secretPath'} and binding.get('nativeConnection')==warm_connection and binding.get('desktopPid')==warm_connection['pid'] and warm_connection['runtime']==str(lib.root/'claude/task-runtime'),'Current warm binding differs')
|
|
17
|
+
ensure_running(lib)
|
|
18
|
+
service=request(lib,'status',{})
|
|
19
|
+
require(service.get('harness')=='claude' and service.get('cloudDispatchReady') is True and service.get('desktopPid')==warm_connection['pid'] and service.get('runtime')==warm_connection['runtime'] and isinstance(service.get('activeTurns'),list) and all(isinstance(w,str) for w in service['activeTurns']) and len(set(service['activeTurns']))==len(service['activeTurns']),'Authenticated warm service differs')
|
|
20
|
+
from .claude_desktop import call
|
|
21
|
+
status=call(warm_connection,{'kind':'status'})
|
|
22
|
+
require(status.get('harness')=='claude-desktop' and status.get('pid')==warm_connection['pid'] and status.get('identity')==warm_connection['identity'] and status.get('qualified') is True and type(status.get('workers')) is int and status['workers']>=0,'Qualified warm native control differs')
|
|
23
|
+
return {'warmOwner':True,'nativeInputsSent':False,'workerCustodyPreserved':True,'service':service,'binding':store.binding}
|
|
24
|
+
if successor_connection is not None:
|
|
25
|
+
require(previous is None and connection is None and not start_service and not wait_retired_service and not require_native_idle and not native_proof and qualification_task is None,'Exact successor observation cannot change lifecycle custody')
|
|
26
|
+
binding=read_json(lib.root/'work/claude-frontdoors.json')
|
|
27
|
+
require(isinstance(successor_connection,dict) and set(successor_connection)=={'pid','runtime','identity','socket','secretPath'} and binding.get('nativeConnection')==successor_connection and binding.get('desktopPid')==successor_connection['pid'] and successor_connection['runtime']==str(lib.root/'claude/task-runtime'),'Current successor binding differs')
|
|
28
|
+
try:service=request(lib,'status',{})
|
|
29
|
+
except (OSError,PackError):return {'existingSuccessor':False,'serviceStarted':False,'nativeInputsSent':False}
|
|
30
|
+
require(service.get('harness')=='claude' and service.get('cloudDispatchReady') is True and service.get('desktopPid')==successor_connection['pid'] and service.get('runtime')==successor_connection['runtime'] and isinstance(service.get('activeTurns'),list) and all(isinstance(w,str) for w in service['activeTurns']) and len(set(service['activeTurns']))==len(service['activeTurns']),'Authenticated successor service differs; preserve its ownership')
|
|
31
|
+
from .claude_desktop import call
|
|
32
|
+
status=call(successor_connection,{'kind':'status'})
|
|
33
|
+
require(status.get('harness')=='claude-desktop' and status.get('pid')==successor_connection['pid'] and status.get('identity')==successor_connection['identity'] and status.get('qualified') is True and type(status.get('workers')) is int and status['workers']>=0,'Qualified successor native control differs')
|
|
34
|
+
native=call(successor_connection,{'kind':'frontdoors'})
|
|
35
|
+
require(native.get('state')=='installed-frontdoors-verified' and native.get('nativeInputsSent') is False,'Native successor front doors differ')
|
|
36
|
+
return {'existingSuccessor':True,'serviceStarted':False,'workerCustodyPreserved':True,'nativeInputsSent':False,'native':native,'service':service,'binding':store.binding,'versionId':version,'generation':state['generation']}
|
|
37
|
+
if previous is not None:
|
|
38
|
+
if connection is not None:
|
|
39
|
+
verify_retired_binding(lib,previous,connection)
|
|
40
|
+
else:
|
|
41
|
+
old=previous['nativeConnection']
|
|
42
|
+
try:os.kill(old['pid'],0)
|
|
43
|
+
except ProcessLookupError:pass
|
|
44
|
+
else:raise ValueError('Previous native owner remains alive')
|
|
45
|
+
tasks={row[0]:json.loads(row[2]) for row in state['tables']['tasks']}
|
|
46
|
+
for row in state['tables']['workers']:
|
|
47
|
+
worker=json.loads(row[2]);cwd=worker.get('nativePlan',{}).get('cwd','')
|
|
48
|
+
if cwd==old['runtime'] or cwd.startswith(old['runtime']+os.sep):
|
|
49
|
+
require(cwd!=old['runtime'] and os.path.normpath(cwd)==cwd,'Ambiguous previous native workspace path')
|
|
50
|
+
if not cwd.startswith(old['runtime']+os.sep):
|
|
51
|
+
if tasks.get(worker['taskId'],{}).get('ownerInstallationId')==store.binding['installationId']:
|
|
52
|
+
require(worker['state']=='archived' and worker.get('nativeArchived') is True or worker['state']=='failed' and not worker.get('turnId') and (not worker.get('nativeId') or worker.get('nativeArchived') is True),'Historical worker remains active or UNKNOWN')
|
|
53
|
+
continue
|
|
54
|
+
require(worker.get('resolution',{}).get('harness')=='claude','Previous runtime worker harness custody differs')
|
|
55
|
+
if worker['state']=='failed' and not worker.get('turnId') and (not worker.get('nativeId') or worker.get('nativeArchived') is True):continue
|
|
56
|
+
require(worker['state']=='archived' and worker.get('nativeArchived') is True and worker.get('checkpoint') and worker.get('turnId'),'Previous native worker remains active or UNKNOWN')
|
|
57
|
+
payload=read_checkpoint(store.root,worker['checkpoint'],worker['taskId'],worker['id'],client=store.client);receipt=payload['nativeReceipt']
|
|
58
|
+
require(payload['phase']==worker['phase'] and receipt['threadId']==worker['nativeId'] and receipt['turnId']==worker['turnId'] and receipt['status'] in {'completed','failed','cancelled'},'Previous terminal checkpoint differs')
|
|
59
|
+
if wait_retired_service:
|
|
60
|
+
require(previous is not None,'Exact retired service owner required')
|
|
61
|
+
for _ in range(50):
|
|
62
|
+
try:status=request(lib,'status',{})
|
|
63
|
+
except (OSError,PackError):
|
|
64
|
+
bridge=read_json(lib.root/'live-bridge.json',{})
|
|
65
|
+
if bridge:
|
|
66
|
+
require(bridge.get('harness')=='claude' and type(bridge.get('pid')) is int and bridge['pid']>1,'Prior service process custody is unverified')
|
|
67
|
+
try:os.kill(bridge['pid'],0)
|
|
68
|
+
except ProcessLookupError:pass
|
|
69
|
+
else:
|
|
70
|
+
time.sleep(.1)
|
|
71
|
+
continue
|
|
72
|
+
with (lib.root/'work/claude-service-owner.lock').open('a') as owner:
|
|
73
|
+
try:fcntl.flock(owner,fcntl.LOCK_EX|fcntl.LOCK_NB)
|
|
74
|
+
except BlockingIOError:pass
|
|
75
|
+
else:break
|
|
76
|
+
time.sleep(.1)
|
|
77
|
+
continue
|
|
78
|
+
require(status.get('harness')=='claude' and status.get('desktopPid')==previous['nativeConnection']['pid'],'Another service owns this installation')
|
|
79
|
+
time.sleep(.1)
|
|
80
|
+
else:raise ValueError('Previous native service has not finished its owned shutdown')
|
|
81
|
+
task=None
|
|
82
|
+
if qualification_task is not None:
|
|
83
|
+
tasks=[json.loads(row[2]) for row in state['tables']['tasks'] if row[0]==qualification_task]
|
|
84
|
+
require(len(tasks)==1,'Qualification task is not in the current cloud authority')
|
|
85
|
+
task=tasks[0]
|
|
86
|
+
require(task['state']=='completed' and task.get('ownerInstallationId')==store.binding['installationId']
|
|
87
|
+
and task.get('verification',{}).get('verdict')=='completed','Independent cloud qualification is incomplete or belongs to another installation')
|
|
88
|
+
workers=[json.loads(row[2]) for row in state['tables']['workers'] if row[1]==qualification_task]
|
|
89
|
+
attempt=[w for w in workers if w.get('attempt',1)==task.get('attempt',1)]
|
|
90
|
+
generation=task.get('reviewGeneration',0);history=task.get('reviewHistory',[])
|
|
91
|
+
require(type(generation) is int and generation>=0 and isinstance(history,list) and len(history)==generation,'Authorized review generation history differs')
|
|
92
|
+
execution=[w for w in attempt if w['phase']!='review'];reviews=[w for w in attempt if w['phase']=='review']
|
|
93
|
+
require(len(execution)==2 and {w['phase'] for w in execution}=={'route','execute'} and len(reviews)==generation+1
|
|
94
|
+
and all(type(w.get('reviewGeneration',0)) is int for w in reviews)
|
|
95
|
+
and sorted(w.get('reviewGeneration',0) for w in reviews)==list(range(generation+1)),
|
|
96
|
+
'Original execution and unique authorized review generations are required')
|
|
97
|
+
latest=next(w for w in reviews if w.get('reviewGeneration',0)==generation)
|
|
98
|
+
current=execution+[latest];verification_by_worker={latest['id']:task['verification']}
|
|
99
|
+
require(all(w['state']=='archived' and w.get('nativeArchived') is True for w in attempt)
|
|
100
|
+
and task['verification'].get('nativeCheckpoint')==latest.get('checkpoint'),
|
|
101
|
+
'Current Claude qualification phase receipts are incomplete')
|
|
102
|
+
result=task.get('result',{});executed=next(w for w in execution if w['phase']=='execute')
|
|
103
|
+
require(result.get('workerId')==executed['id'] and result.get('checkpoint')==executed.get('checkpoint'),'Qualification must preserve the exact original execution result')
|
|
104
|
+
for index,entry in enumerate(history):
|
|
105
|
+
rejected=next(w for w in reviews if w.get('reviewGeneration',0)==index)
|
|
106
|
+
require(isinstance(entry,dict) and set(entry)=={'reviewWorkerId','generation','verification','continuation'}
|
|
107
|
+
and type(entry['generation']) is int and entry['generation']==index and entry['reviewWorkerId']==rejected['id']
|
|
108
|
+
and isinstance(entry['verification'],dict)
|
|
109
|
+
and entry['verification'].get('verdict') in {'blocked','needs_input'}
|
|
110
|
+
and entry['verification'].get('nativeCheckpoint')==rejected.get('checkpoint'),
|
|
111
|
+
'Prior rejected review identity and checkpoint must remain preserved')
|
|
112
|
+
continuation=entry['continuation']
|
|
113
|
+
require(isinstance(continuation,dict) and set(continuation)=={'requestId','taskId','revision','reviewWorkerId','reviewCheckpoint','note'}
|
|
114
|
+
and continuation['taskId']==task['id'] and continuation['reviewWorkerId']==rejected['id']
|
|
115
|
+
and continuation['reviewCheckpoint']==rejected.get('checkpoint')
|
|
116
|
+
and type(continuation['revision']) is int and continuation['revision']<task['revision']
|
|
117
|
+
and isinstance(continuation['note'],str) and bool(continuation['note'])
|
|
118
|
+
and [continuation['requestId'],hashlib.sha256(canonical(continuation)).hexdigest(),task['id']] in state['tables']['responses'],
|
|
119
|
+
'Review continuation must have its exact canonical authorization receipt')
|
|
120
|
+
verification_by_worker[rejected['id']]=entry['verification']
|
|
121
|
+
for worker in workers:
|
|
122
|
+
if worker['state']=='failed' and not worker.get('turnId') and (not worker.get('nativeId') or worker.get('nativeArchived') is True):continue
|
|
123
|
+
require(worker['state']=='archived' and worker.get('nativeArchived') is True and worker.get('checkpoint') and worker.get('turnId'),'Qualification worker closure is unresolved')
|
|
124
|
+
if worker not in current and worker.get('resolution',{}).get('harness')!='claude':continue
|
|
125
|
+
payload=read_checkpoint(store.root,worker['checkpoint'],qualification_task,worker['id'],client=store.client)
|
|
126
|
+
receipt=payload['nativeReceipt']
|
|
127
|
+
require(payload['phase']==worker['phase'] and receipt['threadId']==worker['nativeId'] and receipt['turnId']==worker['turnId'] and receipt['status'] in {'completed','failed','cancelled'},'Qualification checkpoint identity differs')
|
|
128
|
+
if worker['id'] in verification_by_worker:
|
|
129
|
+
expected=verification_by_worker[worker['id']]
|
|
130
|
+
require(payload.get('outputError') is None and json.loads(payload['output'])=={k:expected[k] for k in ['verdict','summary','evidence']},'Review verification differs from its immutable checkpoint')
|
|
131
|
+
if worker in current:
|
|
132
|
+
resolution=worker.get('resolution',{});role=worker.get('roleSource',{})
|
|
133
|
+
require(receipt['status']=='completed' and resolution.get('harness')=='claude'
|
|
134
|
+
and isinstance(resolution.get('nativeACK'),dict) and resolution['nativeACK']==resolution.get('resolved')
|
|
135
|
+
and bool(resolution['nativeACK'].get('model')) and bool(resolution['nativeACK'].get('effort'))
|
|
136
|
+
and role.get('source')=='topolo-agent-definition' and role.get('rolesLoaded')==1
|
|
137
|
+
and role.get('wholePackExportLoaded') is False and role.get('memoryLoaded') is False
|
|
138
|
+
and bool(role.get('agentId')) and bool(role.get('instructionsSHA256'))
|
|
139
|
+
and payload.get('resolution')==resolution and payload.get('roleSource')==role,
|
|
140
|
+
'Current qualification must prove selected Claude Agent context and native settings ACK')
|
|
141
|
+
native=None
|
|
142
|
+
if native_proof:
|
|
143
|
+
from .claude_desktop import call
|
|
144
|
+
binding=read_json(lib.root/'work/claude-frontdoors.json')
|
|
145
|
+
if require_native_idle:
|
|
146
|
+
status=call(binding['nativeConnection'],{'kind':'status'})
|
|
147
|
+
require(status.get('harness')=='claude-desktop' and status.get('pid')==binding['desktopPid'] and status.get('identity')==binding['nativeConnection']['identity'] and status.get('workers')==0 and status.get('qualified') is True,'Exact idle native control is required')
|
|
148
|
+
native=call(binding['nativeConnection'],{'kind':'frontdoors'})
|
|
149
|
+
require(native.get('state')=='installed-frontdoors-verified' and native.get('nativeInputsSent') is False,'Native front doors are unverified')
|
|
150
|
+
if start_service:ensure_running(lib)
|
|
151
|
+
service=request(lib,'status',{}) if start_service or qualification_task is not None else None
|
|
152
|
+
if service is not None:
|
|
153
|
+
binding=read_json(lib.root/'work/claude-frontdoors.json')
|
|
154
|
+
require(service.get('harness')=='claude' and service.get('cloudDispatchReady') is True and service.get('desktopPid')==binding['desktopPid'],'Current Claude dispatcher is not ready')
|
|
155
|
+
return {'native':native,'format':'topolo-claude-cloud-activation-proof-v1','binding':store.binding,'versionId':version,
|
|
156
|
+
'generation':state['generation'],'qualificationTaskId':qualification_task,
|
|
157
|
+
'qualificationRevision':task['revision'] if task else None,'service':service,'activated':True}
|