crewly 1.20.302 → 1.20.304
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/config/roles/developer/prompt.md +7 -0
- package/config/roles/fullstack-dev/prompt.md +7 -0
- package/config/roles/product-manager/prompt.md +7 -0
- package/config/skills/orchestrator/move-team/SKILL.md +53 -0
- package/config/skills/orchestrator/move-team/execute.sh +42 -0
- package/config/skills/orchestrator/usage-categories/SKILL.md +59 -0
- package/config/skills/orchestrator/usage-categories/execute.sh +81 -0
- package/config/skills/orchestrator/usage-categories/execute.test.sh +45 -0
- package/config/skills/orchestrator/usage-report/SKILL.md +71 -0
- package/config/skills/orchestrator/usage-report/execute.sh +84 -0
- package/config/skills/orchestrator/usage-report/execute.test.sh +39 -0
- package/config/skills/team-leader/usage-report/SKILL.md +71 -0
- package/config/skills/team-leader/usage-report/execute.sh +84 -0
- package/config/skills/team-leader/usage-report/execute.test.sh +39 -0
- package/dist/backend/backend/src/constants.d.ts +80 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +80 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.d.ts +45 -0
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.js +214 -0
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.controller.d.ts +36 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.controller.js +158 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.routes.d.ts +15 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.routes.js +26 -0
- package/dist/backend/backend/src/controllers/usage-ledger/usage-ledger.routes.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts +10 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +97 -20
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +6 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/follow-through.wiring.d.ts +32 -0
- package/dist/backend/backend/src/services/agent/follow-through.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/follow-through.wiring.js +42 -1
- package/dist/backend/backend/src/services/agent/follow-through.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts +26 -6
- package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode.service.js +59 -5
- package/dist/backend/backend/src/services/agent/resource-mode.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.d.ts +18 -0
- package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.js +16 -0
- package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts +19 -0
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.js +46 -0
- package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/agent-turn-state.d.ts +35 -0
- package/dist/backend/backend/src/services/monitoring/agent-turn-state.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/agent-turn-state.js +101 -0
- package/dist/backend/backend/src/services/monitoring/agent-turn-state.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/background-work-watchdog.d.ts +58 -0
- package/dist/backend/backend/src/services/monitoring/background-work-watchdog.d.ts.map +1 -0
- package/dist/backend/backend/src/services/monitoring/background-work-watchdog.js +100 -0
- package/dist/backend/backend/src/services/monitoring/background-work-watchdog.js.map +1 -0
- package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js +3 -0
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts +7 -0
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +15 -0
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +2 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +9 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +25 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +24 -0
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +63 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +41 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-archive.d.ts +122 -0
- package/dist/backend/backend/src/services/team-move/team-move-archive.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-archive.js +202 -0
- package/dist/backend/backend/src/services/team-move/team-move-archive.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts +59 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.js +133 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.d.ts +102 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.js +217 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.d.ts +102 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.js +348 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.d.ts +209 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.js +504 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts +156 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.js +462 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.d.ts +157 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.js +298 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.d.ts +69 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.js +198 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts +121 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.js +462 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.d.ts +110 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.js +198 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.d.ts +71 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.js +102 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts +29 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.js +173 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.d.ts +50 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.js +96 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.d.ts +94 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.js +124 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.d.ts +46 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.js +202 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.d.ts +269 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.js +44 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.js.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-context.service.d.ts +42 -2
- package/dist/backend/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/trace/trace-context.service.js +66 -5
- package/dist/backend/backend/src/services/trace/trace-context.service.js.map +1 -1
- package/dist/backend/backend/src/services/trace/trace-recorder.d.ts.map +1 -1
- package/dist/backend/backend/src/services/trace/trace-recorder.js +11 -0
- package/dist/backend/backend/src/services/trace/trace-recorder.js.map +1 -1
- package/dist/backend/backend/src/services/usage-ledger/categories-param.d.ts +28 -0
- package/dist/backend/backend/src/services/usage-ledger/categories-param.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/categories-param.js +67 -0
- package/dist/backend/backend/src/services/usage-ledger/categories-param.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/excerpt.d.ts +37 -0
- package/dist/backend/backend/src/services/usage-ledger/excerpt.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/excerpt.js +49 -0
- package/dist/backend/backend/src/services/usage-ledger/excerpt.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/index.d.ts +14 -0
- package/dist/backend/backend/src/services/usage-ledger/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/index.js +14 -0
- package/dist/backend/backend/src/services/usage-ledger/index.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-hooks.d.ts +44 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-hooks.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-hooks.js +52 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-hooks.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-rollup.d.ts +100 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-rollup.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-rollup.js +189 -0
- package/dist/backend/backend/src/services/usage-ledger/ledger-rollup.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/owner-spans.d.ts +41 -0
- package/dist/backend/backend/src/services/usage-ledger/owner-spans.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/owner-spans.js +71 -0
- package/dist/backend/backend/src/services/usage-ledger/owner-spans.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/team-directory.d.ts +47 -0
- package/dist/backend/backend/src/services/usage-ledger/team-directory.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/team-directory.js +106 -0
- package/dist/backend/backend/src/services/usage-ledger/team-directory.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/unit-classifier.d.ts +101 -0
- package/dist/backend/backend/src/services/usage-ledger/unit-classifier.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/unit-classifier.js +263 -0
- package/dist/backend/backend/src/services/usage-ledger/unit-classifier.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-categories.store.d.ts +96 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-categories.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-categories.store.js +166 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-categories.store.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.backfill.d.ts +90 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.backfill.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.backfill.js +294 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.backfill.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.recorder.d.ts +102 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.recorder.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.recorder.js +314 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.recorder.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.runtime.d.ts +62 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.runtime.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.runtime.js +106 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.runtime.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.store.d.ts +52 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.store.js +95 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.store.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.types.d.ts +127 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.types.js +19 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-ledger.types.js.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-report.service.d.ts +124 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-report.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-report.service.js +372 -0
- package/dist/backend/backend/src/services/usage-ledger/usage-report.service.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +80 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +80 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts +26 -6
- package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/resource-mode.service.js +59 -5
- package/dist/cli/backend/src/services/agent/resource-mode.service.js.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.d.ts +18 -0
- package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.js +16 -0
- package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts +19 -0
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.js +46 -0
- package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/cli/backend/src/services/monitoring/agent-turn-state.d.ts +35 -0
- package/dist/cli/backend/src/services/monitoring/agent-turn-state.d.ts.map +1 -1
- package/dist/cli/backend/src/services/monitoring/agent-turn-state.js +101 -0
- package/dist/cli/backend/src/services/monitoring/agent-turn-state.js.map +1 -1
- package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/monitoring/token-usage.service.js +3 -0
- package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +9 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +25 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +24 -0
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +63 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +41 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-context.service.d.ts +42 -2
- package/dist/cli/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-context.service.js +66 -5
- package/dist/cli/backend/src/services/trace/trace-context.service.js.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-recorder.d.ts.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-recorder.js +11 -0
- package/dist/cli/backend/src/services/trace/trace-recorder.js.map +1 -1
- package/dist/cli/backend/src/services/usage-ledger/ledger-hooks.d.ts +44 -0
- package/dist/cli/backend/src/services/usage-ledger/ledger-hooks.d.ts.map +1 -0
- package/dist/cli/backend/src/services/usage-ledger/ledger-hooks.js +52 -0
- package/dist/cli/backend/src/services/usage-ledger/ledger-hooks.js.map +1 -0
- package/dist/cli/cli/src/commands/team-move.d.ts +68 -0
- package/dist/cli/cli/src/commands/team-move.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/team-move.js +155 -0
- package/dist/cli/cli/src/commands/team-move.js.map +1 -0
- package/dist/cli/cli/src/index.js +33 -0
- package/dist/cli/cli/src/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -406,6 +406,13 @@ Default tier: **Fast Path** (greenfield, internal tools, prototypes). Escalate t
|
|
|
406
406
|
- The Owner is consulted only for goal change, scope change, customer-facing commitment, irreversible expense, or strategic direction.
|
|
407
407
|
|
|
408
408
|
|
|
409
|
+
## Long Builds and Background Forks
|
|
410
|
+
|
|
411
|
+
- Do long multi-step builds (rendering, video, large refactors) in the foreground of your own turn. That is the default.
|
|
412
|
+
- A background subagent or fork can die silently, and then nobody delivers what you promised. If you do use one, keep its description specific, tell the owner only what you can verify, and check on it: look at its output or transcript yourself within a few minutes, and do not end the turn on "it will report back" without a plan for when you look.
|
|
413
|
+
- Crewly tells you when a background task made no progress for about 10 minutes (`[BACKGROUND TASK STALLED]`). When you see it, inspect what it produced and continue the work yourself in the foreground.
|
|
414
|
+
- A promise to the owner ("starting now, will post here") stays yours until the result is posted, whoever does the work.
|
|
415
|
+
|
|
409
416
|
## Lazy Behavior Anti-Patterns
|
|
410
417
|
|
|
411
418
|
You are failing the task if you:
|
|
@@ -186,6 +186,13 @@ Default tier: **Fast Path** (greenfield, internal tools, prototypes). Escalate t
|
|
|
186
186
|
- The Owner is consulted only for goal change, scope change, customer-facing commitment, irreversible expense, or strategic direction.
|
|
187
187
|
|
|
188
188
|
|
|
189
|
+
## Long Builds and Background Forks
|
|
190
|
+
|
|
191
|
+
- Do long multi-step builds (rendering, video, large refactors) in the foreground of your own turn. That is the default.
|
|
192
|
+
- A background subagent or fork can die silently, and then nobody delivers what you promised. If you do use one, keep its description specific, tell the owner only what you can verify, and check on it: look at its output or transcript yourself within a few minutes, and do not end the turn on "it will report back" without a plan for when you look.
|
|
193
|
+
- Crewly tells you when a background task made no progress for about 10 minutes (`[BACKGROUND TASK STALLED]`). When you see it, inspect what it produced and continue the work yourself in the foreground.
|
|
194
|
+
- A promise to the owner ("starting now, will post here") stays yours until the result is posted, whoever does the work.
|
|
195
|
+
|
|
189
196
|
## Lazy Behavior Anti-Patterns
|
|
190
197
|
|
|
191
198
|
You are failing the task if you:
|
|
@@ -296,6 +296,13 @@ Default tier: **Standard Path** (customer-facing or coordination work). Drop to
|
|
|
296
296
|
- The Owner is consulted only for goal change, scope change, customer-facing commitment, irreversible expense, or strategic direction.
|
|
297
297
|
|
|
298
298
|
|
|
299
|
+
## Long Builds and Background Forks
|
|
300
|
+
|
|
301
|
+
- Do long multi-step builds (rendering, video, large refactors) in the foreground of your own turn. That is the default.
|
|
302
|
+
- A background subagent or fork can die silently, and then nobody delivers what you promised. If you do use one, keep its description specific, tell the owner only what you can verify, and check on it: look at its output or transcript yourself within a few minutes, and do not end the turn on "it will report back" without a plan for when you look.
|
|
303
|
+
- Crewly tells you when a background task made no progress for about 10 minutes (`[BACKGROUND TASK STALLED]`). When you see it, inspect what it produced and continue the work yourself in the foreground.
|
|
304
|
+
- A promise to the owner ("starting now, will post here") stays yours until the result is posted, whoever does the work.
|
|
305
|
+
|
|
299
306
|
## Lazy Behavior Anti-Patterns
|
|
300
307
|
|
|
301
308
|
You are failing the task if you:
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Move Team
|
|
3
|
+
description: Move a whole team (members, memory, tickets, wiki, schedules, Slack identity) to another machine of the owner's account. Use only after the owner said yes to a specific team and machine.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: management
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- orchestrator
|
|
9
|
+
triggers:
|
|
10
|
+
- move team
|
|
11
|
+
- move the team to
|
|
12
|
+
- move to the other machine
|
|
13
|
+
- move to my Air
|
|
14
|
+
- migrate team to another machine
|
|
15
|
+
tags:
|
|
16
|
+
- team
|
|
17
|
+
- machines
|
|
18
|
+
- migration
|
|
19
|
+
execution:
|
|
20
|
+
type: script
|
|
21
|
+
script:
|
|
22
|
+
file: execute.sh
|
|
23
|
+
interpreter: bash
|
|
24
|
+
timeoutMs: 60000
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# Move Team
|
|
28
|
+
|
|
29
|
+
The owner's Mac runs out of CPU or memory; another machine of the same account has room. "Move team CE to the Air" moves the whole team: members, prompts, memory and handover notes, tickets, wiki, schedules, open decisions, channels, and the agents' Slack identity. Code is cloned on the target from its git remote. Credentials and logins do not move; the owner gets a short list to reconnect. Crewly Cloud only carries an encrypted package.
|
|
30
|
+
|
|
31
|
+
## Steps (the owner is on their phone: never ask for a terminal step)
|
|
32
|
+
|
|
33
|
+
1. List the machines: `bash {{ORCHESTRATOR_SKILLS_PATH}}/move-team/execute.sh '{"action":"machines"}'`
|
|
34
|
+
2. If the owner did not name the machine, or the name is ambiguous, ask which one (show the names).
|
|
35
|
+
3. Check what would block it: `... '{"action":"check","team":"CE"}'`. If a repository has unpushed or uncommitted work, tell the owner in one sentence what to push (the lines it returns) and stop. Never move with `allowDirty` unless the owner says to move without that work.
|
|
36
|
+
4. Ask the owner for approval in your own words, in the owner's thread: team, from which machine to which machine, and that the team stops here and starts there. Wait for a yes. A move without a yes in chat is refused by the backend.
|
|
37
|
+
5. Start it: `... '{"action":"start","team":"CE","to":"Air"}'`. It returns a move id and runs in the background.
|
|
38
|
+
6. Do not narrate progress in the owner's thread. Crewly Cloud sends the owner one summary (what moved, what to reconnect, a rollback link) when it is done.
|
|
39
|
+
|
|
40
|
+
## Actions
|
|
41
|
+
|
|
42
|
+
| Parameter | Used by | Description |
|
|
43
|
+
|-----------|---------|-------------|
|
|
44
|
+
| `action` | all | `machines`, `check`, `start`, `status`, `moves` |
|
|
45
|
+
| `team` | check, start | Team name or id on this machine |
|
|
46
|
+
| `to` | start | Target machine name (from `machines`) |
|
|
47
|
+
| `moveId` | status | A move id |
|
|
48
|
+
| `allowDirty` | start | `true` only on the owner's word: move although a repo has unpushed work (that work stays here) |
|
|
49
|
+
| `skipFlagged` | start | `true` to leave out notes that hold credentials instead of stopping |
|
|
50
|
+
|
|
51
|
+
## Rollback
|
|
52
|
+
|
|
53
|
+
Within 7 days the owner can undo a move from the portal ("Moves") or by asking you. Rolling back is the owner's call: it needs the owner's tap, not yours.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Move a team to another machine of the owner's account
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
source "${SCRIPT_DIR}/../_common/lib.sh"
|
|
6
|
+
|
|
7
|
+
INPUT=$(read_json_input "${1:-}")
|
|
8
|
+
[ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"action\":\"machines|check|start|status|moves\",\"team\":\"CE\",\"to\":\"Air\"}'"
|
|
9
|
+
|
|
10
|
+
ACTION=$(printf '%s' "$INPUT" | jq -r '.action // empty')
|
|
11
|
+
require_param "action" "$ACTION"
|
|
12
|
+
|
|
13
|
+
case "$ACTION" in
|
|
14
|
+
machines)
|
|
15
|
+
api_call GET "/team-moves/machines"
|
|
16
|
+
;;
|
|
17
|
+
moves)
|
|
18
|
+
api_call GET "/team-moves"
|
|
19
|
+
;;
|
|
20
|
+
status)
|
|
21
|
+
MOVE_ID=$(printf '%s' "$INPUT" | jq -r '.moveId // empty')
|
|
22
|
+
require_param "moveId" "$MOVE_ID"
|
|
23
|
+
api_call GET "/team-moves/${MOVE_ID}"
|
|
24
|
+
;;
|
|
25
|
+
check)
|
|
26
|
+
TEAM=$(printf '%s' "$INPUT" | jq -r '.team // empty')
|
|
27
|
+
require_param "team" "$TEAM"
|
|
28
|
+
BODY=$(jq -n --arg t "$TEAM" '{teamName: $t}')
|
|
29
|
+
api_call POST "/team-moves/check" "$BODY"
|
|
30
|
+
;;
|
|
31
|
+
start)
|
|
32
|
+
TEAM=$(printf '%s' "$INPUT" | jq -r '.team // empty')
|
|
33
|
+
TO=$(printf '%s' "$INPUT" | jq -r '.to // empty')
|
|
34
|
+
require_param "team" "$TEAM"
|
|
35
|
+
require_param "to" "$TO"
|
|
36
|
+
BODY=$(printf '%s' "$INPUT" | jq -c --arg t "$TEAM" --arg to "$TO" '{teamName: $t, targetName: $to, allowDirty: (.allowDirty // false), skipFlagged: (.skipFlagged // false)}')
|
|
37
|
+
api_call POST "/team-moves" "$BODY"
|
|
38
|
+
;;
|
|
39
|
+
*)
|
|
40
|
+
error_exit "Unknown action: ${ACTION}. Use machines | check | start | status | moves"
|
|
41
|
+
;;
|
|
42
|
+
esac
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Usage Categories
|
|
3
|
+
description: Save, list or remove the owner's own categories for usage reports (for example "self-media" and "book"). Categories are optional and only change how reports group tickets; they never alter ticket facts.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: monitoring
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- orchestrator
|
|
9
|
+
triggers:
|
|
10
|
+
- usage categories
|
|
11
|
+
- track time by category
|
|
12
|
+
- split usage into
|
|
13
|
+
- count self-media separately
|
|
14
|
+
tags:
|
|
15
|
+
- usage
|
|
16
|
+
- categories
|
|
17
|
+
- report
|
|
18
|
+
execution:
|
|
19
|
+
type: script
|
|
20
|
+
script:
|
|
21
|
+
file: execute.sh
|
|
22
|
+
interpreter: bash
|
|
23
|
+
timeoutMs: 20000
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Usage Categories
|
|
27
|
+
|
|
28
|
+
The owner decides how usage should be grouped ("how much on self-media vs the book?"). Turn what they say into a category and save it. Nothing is required: with no categories, reports group by team.
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bash execute.sh list
|
|
34
|
+
|
|
35
|
+
# The description doubles as the keyword list when it is comma separated
|
|
36
|
+
bash execute.sh set --name self-media --description "Xiaohongshu, Substack, LinkedIn, videos"
|
|
37
|
+
|
|
38
|
+
# Explicit hints: keywords match ticket titles and text; teams / projects match by name
|
|
39
|
+
bash execute.sh set --name book --keywords "chapter,manuscript,Bible study book" --teams "Writers"
|
|
40
|
+
|
|
41
|
+
bash execute.sh remove --name book
|
|
42
|
+
bash execute.sh clear
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## How a ticket gets its category
|
|
46
|
+
|
|
47
|
+
At report time, in this order:
|
|
48
|
+
|
|
49
|
+
1. Keywords (case-insensitive), then team and project hints. The best score wins.
|
|
50
|
+
2. If nothing matched and a small model is available, one batched question for the unmatched tickets.
|
|
51
|
+
3. Otherwise `other`.
|
|
52
|
+
|
|
53
|
+
The result is cached per ticket and category set, and changes the moment a definition changes. Tickets themselves are never modified, so redefining categories re-slices all past usage.
|
|
54
|
+
|
|
55
|
+
## Etiquette
|
|
56
|
+
|
|
57
|
+
- Use the owner's own words for names. Do not invent categories they did not ask for.
|
|
58
|
+
- After saving, offer to run `usage-report --by category` so they see the split.
|
|
59
|
+
- `other` is reserved and cannot be defined.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# The owner's report categories ("self-media", "book", ...).
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# execute.sh list
|
|
6
|
+
# execute.sh set --name self-media --description "Xiaohongshu, Substack, LinkedIn, videos" \
|
|
7
|
+
# [--keywords a,b,c] [--teams "Marketing,Media"] [--projects "Site,Newsletter"]
|
|
8
|
+
# execute.sh remove --name self-media
|
|
9
|
+
# execute.sh clear
|
|
10
|
+
# execute.sh '{"command":"set","name":"book","keywords":["chapter","manuscript"]}'
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
source "${SCRIPT_DIR}/../_common/lib.sh"
|
|
14
|
+
|
|
15
|
+
COMMAND=""
|
|
16
|
+
NAME=""
|
|
17
|
+
DESCRIPTION=""
|
|
18
|
+
KEYWORDS=""
|
|
19
|
+
TEAMS=""
|
|
20
|
+
PROJECTS=""
|
|
21
|
+
INPUT_JSON=""
|
|
22
|
+
|
|
23
|
+
if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
24
|
+
INPUT_JSON="$1"
|
|
25
|
+
shift || true
|
|
26
|
+
elif [[ $# -gt 0 && ${1:0:2} != '--' ]]; then
|
|
27
|
+
COMMAND="$1"
|
|
28
|
+
shift || true
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
while [[ $# -gt 0 ]]; do
|
|
32
|
+
case "$1" in
|
|
33
|
+
--name) NAME="$2"; shift 2 ;;
|
|
34
|
+
--description) DESCRIPTION="$2"; shift 2 ;;
|
|
35
|
+
--keywords) KEYWORDS="$2"; shift 2 ;;
|
|
36
|
+
--teams) TEAMS="$2"; shift 2 ;;
|
|
37
|
+
--projects) PROJECTS="$2"; shift 2 ;;
|
|
38
|
+
--help|-h)
|
|
39
|
+
echo "Usage: execute.sh list | set --name N [--description D] [--keywords a,b] [--teams a,b] [--projects a,b] | remove --name N | clear"
|
|
40
|
+
exit 0 ;;
|
|
41
|
+
*) shift ;;
|
|
42
|
+
esac
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
if [[ -n "$INPUT_JSON" ]]; then
|
|
46
|
+
[[ -z "$COMMAND" ]] && COMMAND=$(echo "$INPUT_JSON" | jq -r '.command // empty' 2>/dev/null || true)
|
|
47
|
+
[[ -z "$NAME" ]] && NAME=$(echo "$INPUT_JSON" | jq -r '.name // empty' 2>/dev/null || true)
|
|
48
|
+
[[ -z "$DESCRIPTION" ]] && DESCRIPTION=$(echo "$INPUT_JSON" | jq -r '.description // empty' 2>/dev/null || true)
|
|
49
|
+
[[ -z "$KEYWORDS" ]] && KEYWORDS=$(echo "$INPUT_JSON" | jq -r '.keywords // empty | if type == "array" then join(",") else . end' 2>/dev/null || true)
|
|
50
|
+
[[ -z "$TEAMS" ]] && TEAMS=$(echo "$INPUT_JSON" | jq -r '.teams // empty | if type == "array" then join(",") else . end' 2>/dev/null || true)
|
|
51
|
+
[[ -z "$PROJECTS" ]] && PROJECTS=$(echo "$INPUT_JSON" | jq -r '.projects // empty | if type == "array" then join(",") else . end' 2>/dev/null || true)
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
require_param "command (list|set|remove|clear)" "$COMMAND"
|
|
55
|
+
|
|
56
|
+
case "$COMMAND" in
|
|
57
|
+
list)
|
|
58
|
+
api_call GET "/usage-ledger/categories"
|
|
59
|
+
;;
|
|
60
|
+
set)
|
|
61
|
+
require_param "name" "$NAME"
|
|
62
|
+
BODY=$(jq -n --arg name "$NAME" --arg description "$DESCRIPTION" --arg keywords "$KEYWORDS" --arg teams "$TEAMS" --arg projects "$PROJECTS" '
|
|
63
|
+
def list($s): $s | split(",") | map(gsub("^\\s+|\\s+$"; "")) | map(select(length > 0));
|
|
64
|
+
{ name: $name }
|
|
65
|
+
+ (if $description != "" then { description: $description } else {} end)
|
|
66
|
+
+ (if $keywords != "" then { keywords: list($keywords) } else {} end)
|
|
67
|
+
+ (if $teams != "" then { teams: list($teams) } else {} end)
|
|
68
|
+
+ (if $projects != "" then { projects: list($projects) } else {} end)')
|
|
69
|
+
api_call POST "/usage-ledger/categories" "$BODY"
|
|
70
|
+
;;
|
|
71
|
+
remove)
|
|
72
|
+
require_param "name" "$NAME"
|
|
73
|
+
api_call DELETE "/usage-ledger/categories/$(jq -rn --arg n "$NAME" '$n|@uri')"
|
|
74
|
+
;;
|
|
75
|
+
clear)
|
|
76
|
+
api_call PUT "/usage-ledger/categories" '{"categories":[]}'
|
|
77
|
+
;;
|
|
78
|
+
*)
|
|
79
|
+
error_exit "Unknown command: $COMMAND (use list, set, remove or clear)"
|
|
80
|
+
;;
|
|
81
|
+
esac
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for usage-categories — run with: bash execute.test.sh
|
|
3
|
+
set -u
|
|
4
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
PASS=0; FAIL=0
|
|
6
|
+
check() { local name="$1"; local got="$2"; local want="$3"; if [ "$got" = "$want" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $name"; echo " want: $want"; echo " got: $got"; fi; }
|
|
7
|
+
|
|
8
|
+
TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
|
|
9
|
+
mkdir -p "$TMP/skills/orchestrator/usage-categories" "$TMP/skills/orchestrator/_common"
|
|
10
|
+
cp "$HERE/execute.sh" "$TMP/skills/orchestrator/usage-categories/execute.sh"
|
|
11
|
+
REAL_LIB="$(cd "$HERE/../../_common" && pwd)/lib.sh"
|
|
12
|
+
cat > "$TMP/skills/orchestrator/_common/lib.sh" <<'STUB'
|
|
13
|
+
source "$REAL_LIB"
|
|
14
|
+
api_call() { printf '%s|%s|%s' "$1" "$2" "${3:-}" > "$CALL_LOG"; echo '{"success":true}'; }
|
|
15
|
+
STUB
|
|
16
|
+
export REAL_LIB CALL_LOG="$TMP/call"
|
|
17
|
+
|
|
18
|
+
run() { CODE=0; OUT=$(env -u CREWLY_SESSION_NAME bash "$TMP/skills/orchestrator/usage-categories/execute.sh" "$@" 2>"$TMP/err") || CODE=$?; }
|
|
19
|
+
|
|
20
|
+
run list
|
|
21
|
+
check "list" "$(cat "$CALL_LOG")" "GET|/usage-ledger/categories|"
|
|
22
|
+
|
|
23
|
+
run set --name self-media --description "Xiaohongshu, Substack, LinkedIn" --keywords "videos, shorts" --teams "Marketing"
|
|
24
|
+
LOG=$(cat "$CALL_LOG"); M=${LOG%%|*}; REST=${LOG#*|}; P=${REST%%|*}; B=${REST#*|}
|
|
25
|
+
check "set uses POST" "$M $P" "POST /usage-ledger/categories"
|
|
26
|
+
check "set body" "$(printf '%s' "$B" | jq -c '.')" '{"name":"self-media","description":"Xiaohongshu, Substack, LinkedIn","keywords":["videos","shorts"],"teams":["Marketing"]}'
|
|
27
|
+
|
|
28
|
+
run '{"command":"set","name":"book","keywords":["chapter","manuscript"]}'
|
|
29
|
+
LOG=$(cat "$CALL_LOG"); B=${LOG#*|*|}
|
|
30
|
+
check "JSON input set body" "$(printf '%s' "$B" | jq -c '.')" '{"name":"book","keywords":["chapter","manuscript"]}'
|
|
31
|
+
|
|
32
|
+
run remove --name "Bible study"
|
|
33
|
+
check "remove encodes the name" "$(cat "$CALL_LOG")" "DELETE|/usage-ledger/categories/Bible%20study|"
|
|
34
|
+
|
|
35
|
+
run clear
|
|
36
|
+
check "clear" "$(cat "$CALL_LOG")" 'PUT|/usage-ledger/categories|{"categories":[]}'
|
|
37
|
+
|
|
38
|
+
run set
|
|
39
|
+
check "set needs a name" "$CODE" "1"
|
|
40
|
+
|
|
41
|
+
run frobnicate
|
|
42
|
+
check "unknown command" "$CODE" "1"
|
|
43
|
+
|
|
44
|
+
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
45
|
+
[ "$FAIL" -eq 0 ]
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Usage Report
|
|
3
|
+
description: How much owner time, agent time and tokens went into each category, team, project, agent or ticket (for example self-media vs the book). Computed from the immutable ticket ledger; categories are applied at report time.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: monitoring
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- orchestrator
|
|
9
|
+
triggers:
|
|
10
|
+
- usage report
|
|
11
|
+
- how much time did we spend
|
|
12
|
+
- how many tokens
|
|
13
|
+
- time and tokens per project
|
|
14
|
+
- where did the tokens go
|
|
15
|
+
tags:
|
|
16
|
+
- usage
|
|
17
|
+
- tokens
|
|
18
|
+
- time
|
|
19
|
+
- cost
|
|
20
|
+
- report
|
|
21
|
+
execution:
|
|
22
|
+
type: script
|
|
23
|
+
script:
|
|
24
|
+
file: execute.sh
|
|
25
|
+
interpreter: bash
|
|
26
|
+
timeoutMs: 60000
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
# Usage Report
|
|
30
|
+
|
|
31
|
+
Answers "how much time and how many tokens went into X?". Every ticket's facts (agent busy time, tokens and estimated cost per model, owner active minutes) are recorded as they happen and never change. This skill adds them up for a window and groups them the way the owner asks.
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Last 7 days by category (the owner's categories, else by team)
|
|
37
|
+
bash execute.sh --since 7d --by category
|
|
38
|
+
|
|
39
|
+
# Just the short text to read out or post to Slack
|
|
40
|
+
bash execute.sh --since 30d --by category --text
|
|
41
|
+
|
|
42
|
+
# Compare two of the owner's categories
|
|
43
|
+
bash execute.sh --since 14d --by category --categories "self-media,book"
|
|
44
|
+
|
|
45
|
+
# One-off categories (not saved): name:keyword,keyword;name:keyword
|
|
46
|
+
bash execute.sh --since 7d --categories "media:xiaohongshu,substack,linkedin;book:chapter,bible"
|
|
47
|
+
|
|
48
|
+
# Other groupings
|
|
49
|
+
bash execute.sh --since 7d --by team
|
|
50
|
+
bash execute.sh --since 7d --by project
|
|
51
|
+
bash execute.sh --since 7d --by agent
|
|
52
|
+
bash execute.sh --since 2d --by ticket --limit 10
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`--since` takes `24h`, `7d`, `2w` or a date. Figures are summed per UTC hour, so a window edge is accurate to the hour.
|
|
56
|
+
|
|
57
|
+
## Categories
|
|
58
|
+
|
|
59
|
+
Categories are never required and never stored on tickets. If the owner has defined categories (see the `usage-categories` skill) the report uses them. If not, tickets are grouped by team (then project). A ticket that matches no category is `other`; usage that happened outside any ticket is `(no ticket)`.
|
|
60
|
+
|
|
61
|
+
When the owner asks for a new grouping ("how much on self-media vs the book?"), either pass `--categories` for one report or save it with `usage-categories set`.
|
|
62
|
+
|
|
63
|
+
## Output
|
|
64
|
+
|
|
65
|
+
Each group has: owner minutes, agent busy minutes, tokens (cost-weighted: cache reads count 0.1x), raw tokens, estimated cost in USD, ticket count and its top 5 tickets. `summary` is a short text suitable for speech or Slack. `notes` lists caveats (for example tickets rebuilt from history are marked inferred).
|
|
66
|
+
|
|
67
|
+
## Reading the numbers to the owner
|
|
68
|
+
|
|
69
|
+
- Lead with the summary line, then the two or three biggest groups.
|
|
70
|
+
- Owner minutes are an estimate from message times (messages on one ticket within 10 minutes form one span).
|
|
71
|
+
- Say "about" for cost; it is an API-price estimate, not a bill.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Usage report: where the owner's time and the agents' tokens went.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# execute.sh [--since 7d] [--until 2026-10-11] [--by category|team|project|agent|ticket]
|
|
6
|
+
# [--categories "book,self-media" | "media:linkedin,substack;book:chapter"]
|
|
7
|
+
# [--limit 10] [--text]
|
|
8
|
+
# execute.sh '{"since":"7d","by":"category"}'
|
|
9
|
+
#
|
|
10
|
+
# --text prints only the short summary (good to read out or post to Slack).
|
|
11
|
+
# Read-only: it changes nothing.
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
source "${SCRIPT_DIR}/../_common/lib.sh"
|
|
15
|
+
|
|
16
|
+
SINCE=""
|
|
17
|
+
UNTIL=""
|
|
18
|
+
BY=""
|
|
19
|
+
CATEGORIES=""
|
|
20
|
+
LIMIT=""
|
|
21
|
+
TEXT="false"
|
|
22
|
+
INPUT_JSON=""
|
|
23
|
+
|
|
24
|
+
if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
25
|
+
INPUT_JSON="$1"
|
|
26
|
+
shift || true
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
while [[ $# -gt 0 ]]; do
|
|
30
|
+
case "$1" in
|
|
31
|
+
--since) SINCE="$2"; shift 2 ;;
|
|
32
|
+
--until) UNTIL="$2"; shift 2 ;;
|
|
33
|
+
--by) BY="$2"; shift 2 ;;
|
|
34
|
+
--categories) CATEGORIES="$2"; shift 2 ;;
|
|
35
|
+
--limit) LIMIT="$2"; shift 2 ;;
|
|
36
|
+
--text) TEXT="true"; shift ;;
|
|
37
|
+
--help|-h)
|
|
38
|
+
echo "Usage: execute.sh [--since 7d] [--until DATE] [--by category|team|project|agent|ticket] [--categories NAMES_OR_DEFS] [--limit N] [--text]"
|
|
39
|
+
exit 0 ;;
|
|
40
|
+
*) shift ;;
|
|
41
|
+
esac
|
|
42
|
+
done
|
|
43
|
+
|
|
44
|
+
if [[ -n "$INPUT_JSON" ]]; then
|
|
45
|
+
[[ -z "$SINCE" ]] && SINCE=$(echo "$INPUT_JSON" | jq -r '.since // empty' 2>/dev/null || true)
|
|
46
|
+
[[ -z "$UNTIL" ]] && UNTIL=$(echo "$INPUT_JSON" | jq -r '.until // empty' 2>/dev/null || true)
|
|
47
|
+
[[ -z "$BY" ]] && BY=$(echo "$INPUT_JSON" | jq -r '.by // empty' 2>/dev/null || true)
|
|
48
|
+
[[ -z "$CATEGORIES" ]] && CATEGORIES=$(echo "$INPUT_JSON" | jq -r '.categories // empty | if type == "array" then tojson else . end' 2>/dev/null || true)
|
|
49
|
+
[[ -z "$LIMIT" ]] && LIMIT=$(echo "$INPUT_JSON" | jq -r '.limit // empty' 2>/dev/null || true)
|
|
50
|
+
if [[ "$TEXT" != "true" ]]; then TEXT=$(echo "$INPUT_JSON" | jq -r '.text // false' 2>/dev/null || echo false); fi
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
QUERY=$(jq -rn \
|
|
54
|
+
--arg since "${SINCE:-7d}" --arg until "$UNTIL" --arg by "${BY:-category}" \
|
|
55
|
+
--arg categories "$CATEGORIES" --arg limit "$LIMIT" \
|
|
56
|
+
'[ "since=" + ($since|@uri), "by=" + ($by|@uri),
|
|
57
|
+
(if $until != "" then "until=" + ($until|@uri) else empty end),
|
|
58
|
+
(if $categories != "" then "categories=" + ($categories|@uri) else empty end),
|
|
59
|
+
(if $limit != "" then "limit=" + ($limit|@uri) else empty end) ] | join("&")')
|
|
60
|
+
|
|
61
|
+
if ! RESP=$(api_call_full GET "/usage-ledger/report?${QUERY}"); then
|
|
62
|
+
error_exit "Could not fetch the usage report"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
if [[ "$TEXT" == "true" ]]; then
|
|
66
|
+
printf '%s' "$RESP" | jq -r '.data.summary // .error // "No report"'
|
|
67
|
+
exit 0
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# Compact: the full body has every token kind for every group.
|
|
71
|
+
printf '%s' "$RESP" | jq '
|
|
72
|
+
if .success then
|
|
73
|
+
{ summary: .data.summary,
|
|
74
|
+
window: .data.window,
|
|
75
|
+
by: .data.by,
|
|
76
|
+
categories: .data.categories,
|
|
77
|
+
totals: { ownerMinutes: .data.totals.ownerMinutes, agentBusyMinutes: .data.totals.agentBusyMinutes,
|
|
78
|
+
tokens: .data.totals.tokens.budget, rawTokens: .data.totals.tokens.total,
|
|
79
|
+
costUsd: .data.totals.costUsd, tickets: .data.totals.ticketCount },
|
|
80
|
+
groups: [ .data.groups[] | { key, ownerMinutes, agentBusyMinutes, tokens: .tokens.budget, rawTokens: .tokens.total,
|
|
81
|
+
costUsd, tickets: .ticketCount,
|
|
82
|
+
topTickets: [ .topTickets[] | { ticketId, title, ownerMinutes, agentBusyMinutes, tokens, costUsd } ] } ],
|
|
83
|
+
notes: .data.notes }
|
|
84
|
+
else . end'
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for usage-report — run with: bash execute.test.sh
|
|
3
|
+
set -u
|
|
4
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
PASS=0; FAIL=0
|
|
6
|
+
check() { local name="$1"; local got="$2"; local want="$3"; if [ "$got" = "$want" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $name"; echo " want: $want"; echo " got: $got"; fi; }
|
|
7
|
+
|
|
8
|
+
TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
|
|
9
|
+
mkdir -p "$TMP/skills/orchestrator/usage-report" "$TMP/skills/orchestrator/_common"
|
|
10
|
+
cp "$HERE/execute.sh" "$TMP/skills/orchestrator/usage-report/execute.sh"
|
|
11
|
+
REAL_LIB="$(cd "$HERE/../../_common" && pwd)/lib.sh"
|
|
12
|
+
REPORT='{"success":true,"data":{"summary":"Usage, last 7 days: 3 tickets","window":{},"by":"category","categories":null,
|
|
13
|
+
"totals":{"ownerMinutes":6,"agentBusyMinutes":30,"tokens":{"budget":5000,"total":9000},"costUsd":1.5,"ticketCount":3},
|
|
14
|
+
"groups":[{"key":"book","ownerMinutes":6,"agentBusyMinutes":30,"tokens":{"budget":5000,"total":9000},"costUsd":1.5,"ticketCount":3,
|
|
15
|
+
"topTickets":[{"ticketId":"TKT-1","title":"Chapter","ownerMinutes":6,"agentBusyMinutes":30,"tokens":5000,"costUsd":1.5,"inferred":false}]}],"notes":[]}}'
|
|
16
|
+
cat > "$TMP/skills/orchestrator/_common/lib.sh" <<'STUB'
|
|
17
|
+
source "$REAL_LIB"
|
|
18
|
+
api_call() { echo "$1 $2" > "$CALL_LOG"; printf '%s' "$REPORT"; }
|
|
19
|
+
STUB
|
|
20
|
+
export REAL_LIB REPORT CALL_LOG="$TMP/call"
|
|
21
|
+
|
|
22
|
+
run() { CODE=0; OUT=$(env -u CREWLY_SESSION_NAME bash "$TMP/skills/orchestrator/usage-report/execute.sh" "$@" 2>"$TMP/err") || CODE=$?; }
|
|
23
|
+
|
|
24
|
+
run
|
|
25
|
+
check "default window and grouping" "$(cat "$CALL_LOG")" "GET /usage-ledger/report?since=7d&by=category"
|
|
26
|
+
check "compact groups" "$(printf '%s' "$OUT" | jq -c '.groups[0] | [.key, .tokens, .topTickets[0].ticketId]')" '["book",5000,"TKT-1"]'
|
|
27
|
+
check "totals flattened" "$(printf '%s' "$OUT" | jq -c '.totals.tickets')" "3"
|
|
28
|
+
|
|
29
|
+
run --since 30d --by team --limit 5 --categories "media:linkedin,substack;book"
|
|
30
|
+
check "flags in the query, encoded" "$(cat "$CALL_LOG")" "GET /usage-ledger/report?since=30d&by=team&categories=media%3Alinkedin%2Csubstack%3Bbook&limit=5"
|
|
31
|
+
|
|
32
|
+
run '{"since":"2w","by":"project"}'
|
|
33
|
+
check "JSON input" "$(cat "$CALL_LOG")" "GET /usage-ledger/report?since=2w&by=project"
|
|
34
|
+
|
|
35
|
+
run --text
|
|
36
|
+
check "--text prints the summary only" "$OUT" "Usage, last 7 days: 3 tickets"
|
|
37
|
+
|
|
38
|
+
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
39
|
+
[ "$FAIL" -eq 0 ]
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Usage Report
|
|
3
|
+
description: How much owner time, agent time and tokens went into each category, team, project, agent or ticket (for example self-media vs the book). Computed from the immutable ticket ledger; categories are applied at report time.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: monitoring
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- team-leader
|
|
9
|
+
triggers:
|
|
10
|
+
- usage report
|
|
11
|
+
- how much time did we spend
|
|
12
|
+
- how many tokens
|
|
13
|
+
- time and tokens per project
|
|
14
|
+
- where did the tokens go
|
|
15
|
+
tags:
|
|
16
|
+
- usage
|
|
17
|
+
- tokens
|
|
18
|
+
- time
|
|
19
|
+
- cost
|
|
20
|
+
- report
|
|
21
|
+
execution:
|
|
22
|
+
type: script
|
|
23
|
+
script:
|
|
24
|
+
file: execute.sh
|
|
25
|
+
interpreter: bash
|
|
26
|
+
timeoutMs: 60000
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
# Usage Report
|
|
30
|
+
|
|
31
|
+
Answers "how much time and how many tokens went into X?". Every ticket's facts (agent busy time, tokens and estimated cost per model, owner active minutes) are recorded as they happen and never change. This skill adds them up for a window and groups them the way the owner asks.
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Last 7 days by category (the owner's categories, else by team)
|
|
37
|
+
bash execute.sh --since 7d --by category
|
|
38
|
+
|
|
39
|
+
# Just the short text to read out or post to Slack
|
|
40
|
+
bash execute.sh --since 30d --by category --text
|
|
41
|
+
|
|
42
|
+
# Compare two of the owner's categories
|
|
43
|
+
bash execute.sh --since 14d --by category --categories "self-media,book"
|
|
44
|
+
|
|
45
|
+
# One-off categories (not saved): name:keyword,keyword;name:keyword
|
|
46
|
+
bash execute.sh --since 7d --categories "media:xiaohongshu,substack,linkedin;book:chapter,bible"
|
|
47
|
+
|
|
48
|
+
# Other groupings
|
|
49
|
+
bash execute.sh --since 7d --by team
|
|
50
|
+
bash execute.sh --since 7d --by project
|
|
51
|
+
bash execute.sh --since 7d --by agent
|
|
52
|
+
bash execute.sh --since 2d --by ticket --limit 10
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`--since` takes `24h`, `7d`, `2w` or a date. Figures are summed per UTC hour, so a window edge is accurate to the hour.
|
|
56
|
+
|
|
57
|
+
## Categories
|
|
58
|
+
|
|
59
|
+
Categories are never required and never stored on tickets. If the owner has defined categories (see the `usage-categories` skill) the report uses them. If not, tickets are grouped by team (then project). A ticket that matches no category is `other`; usage that happened outside any ticket is `(no ticket)`.
|
|
60
|
+
|
|
61
|
+
When the owner asks for a new grouping ("how much on self-media vs the book?"), either pass `--categories` for one report or save it with `usage-categories set`.
|
|
62
|
+
|
|
63
|
+
## Output
|
|
64
|
+
|
|
65
|
+
Each group has: owner minutes, agent busy minutes, tokens (cost-weighted: cache reads count 0.1x), raw tokens, estimated cost in USD, ticket count and its top 5 tickets. `summary` is a short text suitable for speech or Slack. `notes` lists caveats (for example tickets rebuilt from history are marked inferred).
|
|
66
|
+
|
|
67
|
+
## Reading the numbers to the owner
|
|
68
|
+
|
|
69
|
+
- Lead with the summary line, then the two or three biggest groups.
|
|
70
|
+
- Owner minutes are an estimate from message times (messages on one ticket within 10 minutes form one span).
|
|
71
|
+
- Say "about" for cost; it is an API-price estimate, not a bill.
|