crewly 1.15.0 → 1.17.0
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/README.md +39 -5
- package/config/roles/developer/prompt.md +1 -1
- package/config/roles/orchestrator/prompt.md +20 -5
- package/config/runtime_scripts/runtime-config.json +7 -0
- package/config/skills/agent/core/calendar-create/SKILL.md +62 -0
- package/config/skills/agent/core/calendar-create/execute.sh +91 -0
- package/config/skills/agent/core/calendar-create/execute.test.sh +80 -0
- package/config/skills/agent/core/calendar-list/SKILL.md +58 -0
- package/config/skills/agent/core/calendar-list/execute.sh +88 -0
- package/config/skills/agent/core/calendar-list/execute.test.sh +71 -0
- package/config/skills/agent/core/count-json/SKILL.md +61 -0
- package/config/skills/agent/core/count-json/execute.sh +52 -0
- package/config/skills/agent/core/count-json/execute.test.sh +35 -0
- package/config/skills/agent/core/gmail-read/SKILL.md +61 -0
- package/config/skills/agent/core/gmail-read/execute.sh +62 -0
- package/config/skills/agent/core/gmail-read/execute.test.sh +68 -0
- package/config/skills/agent/core/gmail-search/SKILL.md +64 -0
- package/config/skills/agent/core/gmail-search/execute.sh +70 -0
- package/config/skills/agent/core/gmail-search/execute.test.sh +67 -0
- package/config/skills/agent/core/gmail-send/SKILL.md +69 -0
- package/config/skills/agent/core/gmail-send/execute.sh +114 -0
- package/config/skills/agent/core/gmail-send/execute.test.sh +83 -0
- package/config/skills/agent/core/record-prediction/SKILL.md +61 -0
- package/config/skills/agent/core/record-prediction/execute.sh +90 -0
- package/config/skills/agent/core/record-prediction/execute.test.sh +67 -0
- package/config/skills/agent/core/resolve-prediction/SKILL.md +61 -0
- package/config/skills/agent/core/resolve-prediction/execute.sh +87 -0
- package/config/skills/agent/core/resolve-prediction/execute.test.sh +74 -0
- package/config/skills/agent/core/set-focus/SKILL.md +64 -0
- package/config/skills/agent/core/set-focus/execute.sh +73 -0
- package/config/skills/agent/core/set-focus/execute.test.sh +67 -0
- package/config/skills/agent/core/suppress-noise/SKILL.md +59 -0
- package/config/skills/agent/core/suppress-noise/execute.sh +68 -0
- package/config/skills/agent/core/suppress-noise/execute.test.sh +58 -0
- package/config/skills/orchestrator/list-missions/SKILL.md +47 -0
- package/config/skills/orchestrator/list-missions/execute.sh +34 -0
- package/config/skills/orchestrator/list-missions/execute.test.sh +33 -0
- package/config/slack-master-app-manifest.json +64 -0
- package/dist/backend/backend/src/constants.d.ts +186 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +196 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/agent-self-improvement/agent-self-improvement.controller.d.ts +76 -0
- package/dist/backend/backend/src/controllers/agent-self-improvement/agent-self-improvement.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/agent-self-improvement/agent-self-improvement.controller.js +262 -0
- package/dist/backend/backend/src/controllers/agent-self-improvement/agent-self-improvement.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +3 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.controller.d.ts +100 -0
- package/dist/backend/backend/src/controllers/google/google.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/google/google.controller.js +293 -0
- package/dist/backend/backend/src/controllers/google/google.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/google/google.routes.d.ts +26 -0
- package/dist/backend/backend/src/controllers/google/google.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/google/google.routes.js +38 -0
- package/dist/backend/backend/src/controllers/google/google.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.js +31 -0
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/request-types.d.ts +6 -2
- package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js +209 -2
- package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +4 -0
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +1 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +92 -8
- 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 +10 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +10 -0
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +32 -4
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/opencode-runtime.service.d.ts +114 -0
- package/dist/backend/backend/src/services/agent/opencode-runtime.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/opencode-runtime.service.js +185 -0
- package/dist/backend/backend/src/services/agent/opencode-runtime.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +22 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +15 -3
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-service.factory.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-service.factory.js +9 -0
- package/dist/backend/backend/src/services/agent/runtime-service.factory.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +23 -0
- package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js +45 -0
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts +43 -3
- package/dist/backend/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/memory-reference.module.js +85 -4
- package/dist/backend/backend/src/services/ai/prompt-modules/memory-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +2 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +6 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/ai/self-improvement/agent-memory-provider.d.ts +45 -0
- package/dist/backend/backend/src/services/ai/self-improvement/agent-memory-provider.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/agent-memory-provider.js +59 -0
- package/dist/backend/backend/src/services/ai/self-improvement/agent-memory-provider.js.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/consolidation-scheduler.service.d.ts +137 -0
- package/dist/backend/backend/src/services/ai/self-improvement/consolidation-scheduler.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/consolidation-scheduler.service.js +216 -0
- package/dist/backend/backend/src/services/ai/self-improvement/consolidation-scheduler.service.js.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/prediction-calibration.service.d.ts +4 -1
- package/dist/backend/backend/src/services/ai/self-improvement/prediction-calibration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/self-improvement/prediction-calibration.service.js +3 -1
- package/dist/backend/backend/src/services/ai/self-improvement/prediction-calibration.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts +8 -0
- package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-initializer.js +25 -0
- package/dist/backend/backend/src/services/cloud/cloud-initializer.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/google/calendar.service.d.ts +98 -0
- package/dist/backend/backend/src/services/google/calendar.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/google/calendar.service.js +125 -0
- package/dist/backend/backend/src/services/google/calendar.service.js.map +1 -0
- package/dist/backend/backend/src/services/google/gmail.service.d.ts +165 -0
- package/dist/backend/backend/src/services/google/gmail.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/google/gmail.service.js +296 -0
- package/dist/backend/backend/src/services/google/gmail.service.js.map +1 -0
- package/dist/backend/backend/src/services/google/google-api.client.d.ts +44 -0
- package/dist/backend/backend/src/services/google/google-api.client.d.ts.map +1 -0
- package/dist/backend/backend/src/services/google/google-api.client.js +104 -0
- package/dist/backend/backend/src/services/google/google-api.client.js.map +1 -0
- package/dist/backend/backend/src/services/google/google-workspace-token.service.d.ts +159 -0
- package/dist/backend/backend/src/services/google/google-workspace-token.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/google/google-workspace-token.service.js +274 -0
- package/dist/backend/backend/src/services/google/google-workspace-token.service.js.map +1 -0
- package/dist/backend/backend/src/services/mcp-tool-definitions.d.ts +1 -1
- package/dist/backend/backend/src/services/mcp-tool-definitions.js +1 -1
- package/dist/backend/backend/src/services/mcp-tool-definitions.js.map +1 -1
- package/dist/backend/backend/src/services/runtime-adapter.d.ts +10 -1
- package/dist/backend/backend/src/services/runtime-adapter.d.ts.map +1 -1
- package/dist/backend/backend/src/services/runtime-adapter.js +12 -1
- package/dist/backend/backend/src/services/runtime-adapter.js.map +1 -1
- package/dist/backend/backend/src/services/settings/settings.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/settings/settings.service.js +1 -0
- package/dist/backend/backend/src/services/settings/settings.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-identity.service.d.ts +12 -1
- package/dist/backend/backend/src/services/slack/slack-agent-identity.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-identity.service.js +30 -0
- package/dist/backend/backend/src/services/slack/slack-agent-identity.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-cloud-config.service.d.ts +186 -0
- package/dist/backend/backend/src/services/slack/slack-cloud-config.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-cloud-config.service.js +409 -0
- package/dist/backend/backend/src/services/slack/slack-cloud-config.service.js.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts +95 -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 +284 -4
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-instance-registry.service.d.ts +178 -0
- package/dist/backend/backend/src/services/slack/slack-instance-registry.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-instance-registry.service.js +392 -0
- package/dist/backend/backend/src/services/slack/slack-instance-registry.service.js.map +1 -0
- package/dist/backend/backend/src/services/slack/slack.service.d.ts +76 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.js +234 -47
- package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/fallback-trigger-cleanup.subscriber.d.ts +78 -0
- package/dist/backend/backend/src/services/v3/fallback-trigger-cleanup.subscriber.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/fallback-trigger-cleanup.subscriber.js +129 -0
- package/dist/backend/backend/src/services/v3/fallback-trigger-cleanup.subscriber.js.map +1 -0
- package/dist/backend/backend/src/services/v3/kr-skill-measurer.service.d.ts +117 -0
- package/dist/backend/backend/src/services/v3/kr-skill-measurer.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/kr-skill-measurer.service.js +214 -0
- package/dist/backend/backend/src/services/v3/kr-skill-measurer.service.js.map +1 -0
- package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts +6 -0
- package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/mission-reminder.service.js +33 -0
- package/dist/backend/backend/src/services/v3/mission-reminder.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/okr-owner-guidance.service.d.ts +116 -0
- package/dist/backend/backend/src/services/v3/okr-owner-guidance.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/okr-owner-guidance.service.js +254 -0
- package/dist/backend/backend/src/services/v3/okr-owner-guidance.service.js.map +1 -0
- package/dist/backend/backend/src/types/index.d.ts +11 -1
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/backend/src/types/settings.types.d.ts +1 -1
- package/dist/backend/backend/src/types/settings.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/settings.types.js +7 -0
- package/dist/backend/backend/src/types/settings.types.js.map +1 -1
- package/dist/backend/backend/src/types/slack.types.d.ts +141 -2
- package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/slack.types.js.map +1 -1
- package/dist/backend/backend/src/types/team-template.types.d.ts +2 -2
- package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/team-template.types.js +1 -1
- package/dist/backend/backend/src/types/team-template.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/mission.types.d.ts +2 -0
- package/dist/backend/backend/src/types/v2/mission.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/mission.types.js.map +1 -1
- package/dist/backend/backend/src/utils/terminal-string-ops.d.ts +2 -0
- package/dist/backend/backend/src/utils/terminal-string-ops.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/terminal-string-ops.js +14 -0
- package/dist/backend/backend/src/utils/terminal-string-ops.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +186 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +196 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +10 -0
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.js +32 -4
- package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/opencode-runtime.service.d.ts +114 -0
- package/dist/cli/backend/src/services/agent/opencode-runtime.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/agent/opencode-runtime.service.js +185 -0
- package/dist/cli/backend/src/services/agent/opencode-runtime.service.js.map +1 -0
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js +22 -1
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts +1 -1
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js +15 -3
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-service.factory.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-service.factory.js +9 -0
- package/dist/cli/backend/src/services/agent/runtime-service.factory.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-builder.service.d.ts +23 -0
- package/dist/cli/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-builder.service.js +45 -0
- package/dist/cli/backend/src/services/ai/prompt-builder.service.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts +43 -3
- package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.js +85 -4
- package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +2 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +6 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/cli/backend/src/services/ai/self-improvement/agent-memory-provider.d.ts +45 -0
- package/dist/cli/backend/src/services/ai/self-improvement/agent-memory-provider.d.ts.map +1 -0
- package/dist/cli/backend/src/services/ai/self-improvement/agent-memory-provider.js +59 -0
- package/dist/cli/backend/src/services/ai/self-improvement/agent-memory-provider.js.map +1 -0
- package/dist/cli/backend/src/services/ai/self-improvement/attention.service.d.ts +74 -0
- package/dist/cli/backend/src/services/ai/self-improvement/attention.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/ai/self-improvement/attention.service.js +132 -0
- package/dist/cli/backend/src/services/ai/self-improvement/attention.service.js.map +1 -0
- package/dist/cli/backend/src/services/ai/self-improvement/memory-consolidation.service.d.ts +107 -0
- package/dist/cli/backend/src/services/ai/self-improvement/memory-consolidation.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/ai/self-improvement/memory-consolidation.service.js +183 -0
- package/dist/cli/backend/src/services/ai/self-improvement/memory-consolidation.service.js.map +1 -0
- package/dist/cli/backend/src/services/ai/self-improvement/prediction-calibration.service.d.ts +100 -0
- package/dist/cli/backend/src/services/ai/self-improvement/prediction-calibration.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/ai/self-improvement/prediction-calibration.service.js +130 -0
- package/dist/cli/backend/src/services/ai/self-improvement/prediction-calibration.service.js.map +1 -0
- 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/mcp-tool-definitions.d.ts +1 -1
- package/dist/cli/backend/src/services/mcp-tool-definitions.js +1 -1
- package/dist/cli/backend/src/services/mcp-tool-definitions.js.map +1 -1
- package/dist/cli/backend/src/services/settings/settings.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/settings/settings.service.js +1 -0
- package/dist/cli/backend/src/services/settings/settings.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-identity.service.d.ts +12 -1
- package/dist/cli/backend/src/services/slack/slack-agent-identity.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-identity.service.js +30 -0
- package/dist/cli/backend/src/services/slack/slack-agent-identity.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts +76 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.js +234 -47
- package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +11 -1
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/dist/cli/backend/src/types/settings.types.d.ts +1 -1
- package/dist/cli/backend/src/types/settings.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/settings.types.js +7 -0
- package/dist/cli/backend/src/types/settings.types.js.map +1 -1
- package/dist/cli/backend/src/types/slack.types.d.ts +141 -2
- package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/slack.types.js.map +1 -1
- package/dist/cli/backend/src/types/team-template.types.d.ts +2 -2
- package/dist/cli/backend/src/types/team-template.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/team-template.types.js +1 -1
- package/dist/cli/backend/src/types/team-template.types.js.map +1 -1
- package/dist/cli/backend/src/types/v2/mission.types.d.ts +2 -0
- package/dist/cli/backend/src/types/v2/mission.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/mission.types.js.map +1 -1
- package/dist/cli/backend/src/utils/terminal-string-ops.d.ts +2 -0
- package/dist/cli/backend/src/utils/terminal-string-ops.d.ts.map +1 -1
- package/dist/cli/backend/src/utils/terminal-string-ops.js +14 -0
- package/dist/cli/backend/src/utils/terminal-string-ops.js.map +1 -1
- package/dist/cli/cli/src/commands/onboard.d.ts +2 -2
- package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/onboard.js +15 -7
- package/dist/cli/cli/src/commands/onboard.js.map +1 -1
- package/frontend/dist/assets/{index-203224f9.js → index-c87332bf.js} +278 -278
- package/frontend/dist/assets/index-f6b4230e.css +42 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- package/frontend/dist/assets/index-dcaf6c88.css +0 -42
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# gmail-send — Send an email from the owner's Gmail
|
|
4
|
+
#
|
|
5
|
+
# Backed by POST /api/google/gmail/send. Refuses without --to and --subject.
|
|
6
|
+
# With --dry-run or CREWLY_GMAIL_SEND_DRY_RUN=1 nothing is sent and no
|
|
7
|
+
# request is made: the message preview is printed instead.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# bash execute.sh --to a@b.c --subject "Hi" --text "Hello" [--cc x@y.z]
|
|
11
|
+
# [--thread-id <id>] [--in-reply-to "<msgid>"] [--dry-run]
|
|
12
|
+
# bash execute.sh '{"to":"a@b.c","subject":"Hi","text":"Hello"}'
|
|
13
|
+
# =============================================================================
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
source "${SCRIPT_DIR}/../../_common/lib.sh"
|
|
17
|
+
|
|
18
|
+
print_usage() {
|
|
19
|
+
cat <<'EOF_USAGE'
|
|
20
|
+
Usage:
|
|
21
|
+
bash execute.sh --to a@b.c --subject "Hi" --text "Hello" [--cc x@y.z]
|
|
22
|
+
[--thread-id <gmail thread id>] [--in-reply-to "<message-id>"] [--dry-run]
|
|
23
|
+
bash execute.sh '{"to":"a@b.c","subject":"Hi","text":"Hello"}'
|
|
24
|
+
|
|
25
|
+
Options:
|
|
26
|
+
--to Recipient(s), comma-separated (required)
|
|
27
|
+
--subject Subject (required)
|
|
28
|
+
--text Plain-text body (or --text-file <path>)
|
|
29
|
+
--text-file Read the body from a file
|
|
30
|
+
--cc Cc recipient(s)
|
|
31
|
+
--thread-id Reply inside this Gmail thread
|
|
32
|
+
--in-reply-to Message-ID being answered (sets In-Reply-To / References)
|
|
33
|
+
--dry-run Preview only; nothing is sent (also: CREWLY_GMAIL_SEND_DRY_RUN=1)
|
|
34
|
+
--help | -h Show this help
|
|
35
|
+
EOF_USAGE
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
INPUT_JSON=""
|
|
39
|
+
TO=""; CC=""; SUBJECT=""; TEXT=""; TEXT_FILE=""; THREAD_ID=""; IN_REPLY_TO=""
|
|
40
|
+
DRY_RUN="${CREWLY_GMAIL_SEND_DRY_RUN:-}"
|
|
41
|
+
|
|
42
|
+
if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
43
|
+
INPUT_JSON="$1"
|
|
44
|
+
shift || true
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
while [[ $# -gt 0 ]]; do
|
|
48
|
+
case "$1" in
|
|
49
|
+
--to) [ $# -ge 2 ] || error_exit "--to requires a value"; TO="$2"; shift 2 ;;
|
|
50
|
+
--cc) [ $# -ge 2 ] || error_exit "--cc requires a value"; CC="$2"; shift 2 ;;
|
|
51
|
+
--subject) [ $# -ge 2 ] || error_exit "--subject requires a value"; SUBJECT="$2"; shift 2 ;;
|
|
52
|
+
--text|--body) [ $# -ge 2 ] || error_exit "--text requires a value"; TEXT="$2"; shift 2 ;;
|
|
53
|
+
--text-file) [ $# -ge 2 ] || error_exit "--text-file requires a value"; TEXT_FILE="$2"; shift 2 ;;
|
|
54
|
+
--thread-id) [ $# -ge 2 ] || error_exit "--thread-id requires a value"; THREAD_ID="$2"; shift 2 ;;
|
|
55
|
+
--in-reply-to) [ $# -ge 2 ] || error_exit "--in-reply-to requires a value"; IN_REPLY_TO="$2"; shift 2 ;;
|
|
56
|
+
--dry-run) DRY_RUN=1; shift ;;
|
|
57
|
+
--help|-h) print_usage; exit 0 ;;
|
|
58
|
+
*) error_exit "Unknown option: $1" ;;
|
|
59
|
+
esac
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
if [ -n "$INPUT_JSON" ]; then
|
|
63
|
+
INPUT=$(read_json_input "$INPUT_JSON")
|
|
64
|
+
[ -z "$TO" ] && TO=$(printf '%s' "$INPUT" | jq -r '.to // empty')
|
|
65
|
+
[ -z "$CC" ] && CC=$(printf '%s' "$INPUT" | jq -r '.cc // empty')
|
|
66
|
+
[ -z "$SUBJECT" ] && SUBJECT=$(printf '%s' "$INPUT" | jq -r '.subject // empty')
|
|
67
|
+
[ -z "$TEXT" ] && TEXT=$(printf '%s' "$INPUT" | jq -r '.text // .body // empty')
|
|
68
|
+
[ -z "$THREAD_ID" ] && THREAD_ID=$(printf '%s' "$INPUT" | jq -r '.threadId // empty')
|
|
69
|
+
[ -z "$IN_REPLY_TO" ] && IN_REPLY_TO=$(printf '%s' "$INPUT" | jq -r '.inReplyTo // empty')
|
|
70
|
+
[ -z "$DRY_RUN" ] && DRY_RUN=$(printf '%s' "$INPUT" | jq -r 'if .dryRun == true then "1" else "" end')
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
if [ -n "$TEXT_FILE" ]; then
|
|
74
|
+
[ -f "$TEXT_FILE" ] || error_exit "text file not found: $TEXT_FILE"
|
|
75
|
+
TEXT=$(cat "$TEXT_FILE")
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
require_param "to (--to)" "$TO"
|
|
79
|
+
require_param "subject (--subject)" "$SUBJECT"
|
|
80
|
+
require_param "text (--text or --text-file)" "$TEXT"
|
|
81
|
+
|
|
82
|
+
# Dry run: no request leaves this machine. Print a readable preview of the
|
|
83
|
+
# headers and body exactly as they will be sent.
|
|
84
|
+
if [ "$DRY_RUN" = "1" ]; then
|
|
85
|
+
PREVIEW="To: ${TO}"
|
|
86
|
+
[ -n "$CC" ] && PREVIEW="${PREVIEW}
|
|
87
|
+
Cc: ${CC}"
|
|
88
|
+
PREVIEW="${PREVIEW}
|
|
89
|
+
Subject: ${SUBJECT}"
|
|
90
|
+
[ -n "$IN_REPLY_TO" ] && PREVIEW="${PREVIEW}
|
|
91
|
+
In-Reply-To: ${IN_REPLY_TO}"
|
|
92
|
+
[ -n "$THREAD_ID" ] && PREVIEW="${PREVIEW}
|
|
93
|
+
X-Gmail-Thread: ${THREAD_ID}"
|
|
94
|
+
PREVIEW="${PREVIEW}
|
|
95
|
+
|
|
96
|
+
${TEXT}"
|
|
97
|
+
jq -cn --arg p "$PREVIEW" '{success: true, dryRun: true, preview: $p}'
|
|
98
|
+
exit 0
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
BODY=$(jq -cn --arg to "$TO" --arg cc "$CC" --arg subject "$SUBJECT" --arg text "$TEXT" \
|
|
102
|
+
--arg threadId "$THREAD_ID" --arg inReplyTo "$IN_REPLY_TO" \
|
|
103
|
+
'{to: $to, subject: $subject, text: $text}
|
|
104
|
+
+ (if $cc != "" then {cc: $cc} else {} end)
|
|
105
|
+
+ (if $threadId != "" then {threadId: $threadId} else {} end)
|
|
106
|
+
+ (if $inReplyTo != "" then {inReplyTo: $inReplyTo} else {} end)')
|
|
107
|
+
|
|
108
|
+
RESPONSE=$(api_call POST "/google/gmail/send" "$BODY" 2>&1) || {
|
|
109
|
+
printf '%s' "$RESPONSE" | jq -c '{success: false, reason: (.details.error // .details // .error // "unknown"), hint: (.details.hint // ""), message: (.details.message // "")}' 2>/dev/null \
|
|
110
|
+
|| jq -n --arg r "$RESPONSE" '{success: false, reason: $r}'
|
|
111
|
+
exit 1
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
printf '%s' "$RESPONSE" | jq -c '{success: (.success // false), id: .data.id, threadId: .data.threadId}'
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for gmail-send — run with: bash execute.test.sh
|
|
3
|
+
# Spins up a python HTTP stub as the backend, asserts the request body the
|
|
4
|
+
# skill sends, the JSON it prints, and that dry-run makes NO request.
|
|
5
|
+
set -u
|
|
6
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
EXEC="$HERE/execute.sh"
|
|
8
|
+
PASS=0; FAIL=0
|
|
9
|
+
check() {
|
|
10
|
+
local name="$1"; local got="$2"; local want="$3"
|
|
11
|
+
if [ "$got" = "$want" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $name"; echo " want: $want"; echo " got: $got"; fi
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
PORT=18803
|
|
15
|
+
STUB_LOG="$(mktemp)"; export STUB_LOG; export STUB_PORT="$PORT"
|
|
16
|
+
python3 -u <<'PY' >/dev/null 2>&1 &
|
|
17
|
+
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
18
|
+
import json, os
|
|
19
|
+
LOG = os.environ['STUB_LOG']; PORT = int(os.environ['STUB_PORT'])
|
|
20
|
+
class H(BaseHTTPRequestHandler):
|
|
21
|
+
def do_POST(self):
|
|
22
|
+
n = int(self.headers.get('content-length', '0')); body = self.rfile.read(n).decode() if n else ''
|
|
23
|
+
data = json.loads(body or '{}')
|
|
24
|
+
open(LOG, 'w').write(json.dumps({'method': 'POST', 'path': self.path, 'body': data}))
|
|
25
|
+
if data.get('to') == 'no-grant@example.com':
|
|
26
|
+
self.send_response(409); self.send_header('Content-Type', 'application/json'); self.end_headers()
|
|
27
|
+
self.wfile.write(json.dumps({'success': False, 'error': 'not_connected', 'message': 'no grant', 'hint': 'https://cloud/start?token=j'}).encode()); return
|
|
28
|
+
self.send_response(200); self.send_header('Content-Type', 'application/json'); self.end_headers()
|
|
29
|
+
self.wfile.write(json.dumps({'success': True, 'data': {'id': 's1', 'threadId': data.get('threadId', 'tNew'), 'labelIds': ['SENT']}}).encode())
|
|
30
|
+
def log_message(self, *a, **k): pass
|
|
31
|
+
HTTPServer(('127.0.0.1', PORT), H).serve_forever()
|
|
32
|
+
PY
|
|
33
|
+
STUB_PID=$!
|
|
34
|
+
disown "$STUB_PID" 2>/dev/null || true
|
|
35
|
+
trap 'kill "$STUB_PID" >/dev/null 2>&1; rm -f "$STUB_LOG"' EXIT
|
|
36
|
+
for i in $(seq 1 30); do curl -s -o /dev/null -m 0.2 "http://127.0.0.1:${PORT}/" 2>/dev/null && break; sleep 0.1; done
|
|
37
|
+
|
|
38
|
+
run() { CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_GMAIL_SEND_DRY_RUN="" bash "$EXEC" "$@" 2>/dev/null; }
|
|
39
|
+
run_err() { CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_GMAIL_SEND_DRY_RUN="" bash "$EXEC" "$@" 2>&1 >/dev/null | jq -r '.error' 2>/dev/null; }
|
|
40
|
+
|
|
41
|
+
# --- send with all fields ---
|
|
42
|
+
OUT=$(run --to ann@example.com --cc bob@example.com --subject "Re: 第三季度" --text "Looks good" --thread-id t1 --in-reply-to "<abc@x>")
|
|
43
|
+
check "send: output" "$OUT" '{"success":true,"id":"s1","threadId":"t1"}'
|
|
44
|
+
check "send: path" "$(jq -r .path "$STUB_LOG")" "/api/google/gmail/send"
|
|
45
|
+
check "send: body" "$(jq -c .body "$STUB_LOG")" '{"to":"ann@example.com","subject":"Re: 第三季度","text":"Looks good","cc":"bob@example.com","threadId":"t1","inReplyTo":"<abc@x>"}'
|
|
46
|
+
|
|
47
|
+
# --- minimal + JSON input + text file ---
|
|
48
|
+
TMP=$(mktemp); printf 'line one\nline two' > "$TMP"
|
|
49
|
+
OUT=$(run '{"to":"a@b.c","subject":"Hi"}' --text-file "$TMP"); rm -f "$TMP"
|
|
50
|
+
check "json+file: output" "$OUT" '{"success":true,"id":"s1","threadId":"tNew"}'
|
|
51
|
+
check "json+file: body omits optional keys" "$(jq -c .body "$STUB_LOG")" '{"to":"a@b.c","subject":"Hi","text":"line one\nline two"}'
|
|
52
|
+
|
|
53
|
+
# --- dry run via env: no request, preview printed ---
|
|
54
|
+
: > "$STUB_LOG"
|
|
55
|
+
OUT=$(CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_GMAIL_SEND_DRY_RUN=1 bash "$EXEC" --to a@b.c --cc c@d.e --subject "Hi" --text "hello" --in-reply-to "<m@x>" 2>/dev/null); RC=$?
|
|
56
|
+
check "env dry-run: exit 0" "$RC" "0"
|
|
57
|
+
check "env dry-run: preview" "$OUT" '{"success":true,"dryRun":true,"preview":"To: a@b.c\nCc: c@d.e\nSubject: Hi\nIn-Reply-To: <m@x>\n\nhello"}'
|
|
58
|
+
check "env dry-run: no request made" "$(cat "$STUB_LOG")" ""
|
|
59
|
+
|
|
60
|
+
# --- dry run via flag ---
|
|
61
|
+
OUT=$(run --to a@b.c --subject "Hi" --text "x" --dry-run)
|
|
62
|
+
check "flag dry-run: preview" "$OUT" '{"success":true,"dryRun":true,"preview":"To: a@b.c\nSubject: Hi\n\nx"}'
|
|
63
|
+
check "flag dry-run: no request made" "$(cat "$STUB_LOG")" ""
|
|
64
|
+
|
|
65
|
+
# --- dry run still validates ---
|
|
66
|
+
check "dry-run without --to refuses" "$(CREWLY_GMAIL_SEND_DRY_RUN=1 run_err --subject Hi --text x)" "Missing required parameter: to (--to)"
|
|
67
|
+
|
|
68
|
+
# --- backend 409 ---
|
|
69
|
+
OUT=$(CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_GMAIL_SEND_DRY_RUN="" bash "$EXEC" --to no-grant@example.com --subject Hi --text x 2>/dev/null); RC=$?
|
|
70
|
+
check "409: exit code" "$RC" "1"
|
|
71
|
+
check "409: reason + hint" "$OUT" '{"success":false,"reason":"not_connected","hint":"https://cloud/start?token=j","message":"no grant"}'
|
|
72
|
+
|
|
73
|
+
# --- validation (nothing sent) ---
|
|
74
|
+
: > "$STUB_LOG"
|
|
75
|
+
check "missing to errors" "$(run_err --subject Hi --text x)" "Missing required parameter: to (--to)"
|
|
76
|
+
check "missing subject errors" "$(run_err --to a@b.c --text x)" "Missing required parameter: subject (--subject)"
|
|
77
|
+
check "missing text errors" "$(run_err --to a@b.c --subject Hi)" "Missing required parameter: text (--text or --text-file)"
|
|
78
|
+
check "missing text file errors" "$(run_err --to a@b.c --subject Hi --text-file /nonexistent/x.txt)" "text file not found: /nonexistent/x.txt"
|
|
79
|
+
check "validation: no request made" "$(cat "$STUB_LOG")" ""
|
|
80
|
+
check "unknown option errors" "$(run_err --bogus 1)" "Unknown option: --bogus"
|
|
81
|
+
|
|
82
|
+
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
83
|
+
[ "$FAIL" -eq 0 ]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Record Prediction
|
|
3
|
+
description: Record a prediction with a confidence level so your calibration can be measured once it resolves.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: memory
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- developer
|
|
9
|
+
- qa
|
|
10
|
+
- tpm
|
|
11
|
+
- designer
|
|
12
|
+
- frontend-developer
|
|
13
|
+
- backend-developer
|
|
14
|
+
- fullstack-dev
|
|
15
|
+
- qa-engineer
|
|
16
|
+
- product-manager
|
|
17
|
+
- architect
|
|
18
|
+
- generalist
|
|
19
|
+
- sales
|
|
20
|
+
- support
|
|
21
|
+
- orchestrator
|
|
22
|
+
triggers:
|
|
23
|
+
- record prediction
|
|
24
|
+
- I predict
|
|
25
|
+
- confidence
|
|
26
|
+
- estimate
|
|
27
|
+
tags:
|
|
28
|
+
- memory
|
|
29
|
+
- calibration
|
|
30
|
+
- self-improvement
|
|
31
|
+
execution:
|
|
32
|
+
type: script
|
|
33
|
+
script:
|
|
34
|
+
file: execute.sh
|
|
35
|
+
interpreter: bash
|
|
36
|
+
timeoutMs: 15000
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
# Record Prediction
|
|
40
|
+
|
|
41
|
+
Write down a falsifiable prediction ("this PR lands today", "the flaky test is a race in the mock") with a confidence between 0 and 1. Later, close it with `resolve-prediction`. Your calibration score (how well confidence tracks reality) is shown in your prompt once predictions resolve, with guidance when you are over- or under-confident.
|
|
42
|
+
|
|
43
|
+
## Parameters
|
|
44
|
+
|
|
45
|
+
| Flag | JSON Field | Required | Description |
|
|
46
|
+
|------|-----------|----------|-------------|
|
|
47
|
+
| `--statement` / `-p` | `statement` | Yes | What you predict will happen |
|
|
48
|
+
| `--confidence` / `-c` | `confidence` | Yes | 0–1 (e.g. `0.7`) |
|
|
49
|
+
| `--resolve-by` | `resolveBy` | No | ISO date by which it should be resolved |
|
|
50
|
+
| `--session` / `-s` | `sessionName` | No | Your session name — defaults to `$CREWLY_SESSION_NAME` |
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
bash execute.sh --statement "checkout PR merges before Friday" --confidence 0.7 --resolve-by 2026-10-03
|
|
56
|
+
bash execute.sh '{"statement":"checkout PR merges before Friday","confidence":0.7}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Output
|
|
60
|
+
|
|
61
|
+
`{ "success": true, "id": "pred-...", "prediction": {...} }` — keep the `id`; you need it to resolve.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# record-prediction — Record a prediction with a confidence level
|
|
4
|
+
#
|
|
5
|
+
# Backed by POST /api/agents/:sessionName/self-improvement/predictions.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# bash execute.sh --statement "PR lands today" --confidence 0.7 [--resolve-by 2026-10-01] [--session crewly-dev-1]
|
|
9
|
+
# bash execute.sh '{"statement":"PR lands today","confidence":0.7,"resolveBy":"2026-10-01"}'
|
|
10
|
+
# =============================================================================
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
source "${SCRIPT_DIR}/../../_common/lib.sh"
|
|
14
|
+
|
|
15
|
+
print_usage() {
|
|
16
|
+
cat <<'EOF_USAGE'
|
|
17
|
+
Usage:
|
|
18
|
+
bash execute.sh --statement "PR lands today" --confidence 0.7 [--resolve-by 2026-10-01] [--session crewly-dev-1]
|
|
19
|
+
bash execute.sh '{"statement":"PR lands today","confidence":0.7}'
|
|
20
|
+
|
|
21
|
+
Options:
|
|
22
|
+
--statement | -p What you predict (required)
|
|
23
|
+
--confidence | -c Confidence 0-1 (required)
|
|
24
|
+
--resolve-by ISO date the prediction should be resolved by (optional)
|
|
25
|
+
--session | -s Session name (defaults to $CREWLY_SESSION_NAME)
|
|
26
|
+
--help | -h Show this help
|
|
27
|
+
EOF_USAGE
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
INPUT_JSON=""
|
|
31
|
+
SESSION_NAME=""
|
|
32
|
+
STATEMENT=""
|
|
33
|
+
CONFIDENCE=""
|
|
34
|
+
RESOLVE_BY=""
|
|
35
|
+
|
|
36
|
+
if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
37
|
+
INPUT_JSON="$1"
|
|
38
|
+
shift || true
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
while [[ $# -gt 0 ]]; do
|
|
42
|
+
case "$1" in
|
|
43
|
+
--statement|-p)
|
|
44
|
+
[ $# -ge 2 ] || error_exit "--statement requires a value"
|
|
45
|
+
STATEMENT="$2"; shift 2 ;;
|
|
46
|
+
--confidence|-c)
|
|
47
|
+
[ $# -ge 2 ] || error_exit "--confidence requires a value"
|
|
48
|
+
CONFIDENCE="$2"; shift 2 ;;
|
|
49
|
+
--resolve-by)
|
|
50
|
+
[ $# -ge 2 ] || error_exit "--resolve-by requires a value"
|
|
51
|
+
RESOLVE_BY="$2"; shift 2 ;;
|
|
52
|
+
--session|-s)
|
|
53
|
+
[ $# -ge 2 ] || error_exit "--session requires a value"
|
|
54
|
+
SESSION_NAME="$2"; shift 2 ;;
|
|
55
|
+
--help|-h) print_usage; exit 0 ;;
|
|
56
|
+
*) error_exit "Unknown option: $1" ;;
|
|
57
|
+
esac
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
if [ -n "$INPUT_JSON" ]; then
|
|
61
|
+
INPUT=$(read_json_input "$INPUT_JSON")
|
|
62
|
+
[ -z "$SESSION_NAME" ] && SESSION_NAME=$(printf '%s' "$INPUT" | jq -r '.sessionName // .agentId // empty')
|
|
63
|
+
[ -z "$STATEMENT" ] && STATEMENT=$(printf '%s' "$INPUT" | jq -r '.statement // .prediction // empty')
|
|
64
|
+
[ -z "$CONFIDENCE" ] && CONFIDENCE=$(printf '%s' "$INPUT" | jq -r 'if .confidence == null then empty else (.confidence | tostring) end')
|
|
65
|
+
[ -z "$RESOLVE_BY" ] && RESOLVE_BY=$(printf '%s' "$INPUT" | jq -r '.resolveBy // empty')
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
[ -z "$SESSION_NAME" ] && SESSION_NAME="${CREWLY_SESSION_NAME:-}"
|
|
69
|
+
require_param "sessionName (--session or CREWLY_SESSION_NAME)" "$SESSION_NAME"
|
|
70
|
+
require_param "statement (--statement)" "$STATEMENT"
|
|
71
|
+
require_param "confidence (--confidence)" "$CONFIDENCE"
|
|
72
|
+
|
|
73
|
+
# Validate locally so a typo fails fast with a readable message.
|
|
74
|
+
if ! printf '%s' "$CONFIDENCE" | grep -Eq '^(0(\.[0-9]+)?|1(\.0+)?)$'; then
|
|
75
|
+
error_exit "confidence must be a number between 0 and 1 (got: $CONFIDENCE)"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
if [ -n "$RESOLVE_BY" ]; then
|
|
79
|
+
BODY=$(jq -cn --arg s "$STATEMENT" --argjson c "$CONFIDENCE" --arg r "$RESOLVE_BY" '{statement: $s, confidence: $c, resolveBy: $r}')
|
|
80
|
+
else
|
|
81
|
+
BODY=$(jq -cn --arg s "$STATEMENT" --argjson c "$CONFIDENCE" '{statement: $s, confidence: $c}')
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
RESPONSE=$(api_call POST "/agents/${SESSION_NAME}/self-improvement/predictions" "$BODY" 2>&1) || {
|
|
85
|
+
ERROR_MSG=$(printf '%s' "$RESPONSE" | jq -r '.details.error // .details // .error // "Unknown error"' 2>/dev/null || echo "$RESPONSE")
|
|
86
|
+
jq -n --arg reason "$ERROR_MSG" '{success: false, reason: $reason}'
|
|
87
|
+
exit 1
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
printf '%s' "$RESPONSE" | jq -c '{success: (.success // false), id: (.data.prediction.id // null), prediction: (.data.prediction // null)}'
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for record-prediction — run with: bash execute.test.sh
|
|
3
|
+
# Spins up a python HTTP stub as the backend, asserts the request path/body
|
|
4
|
+
# the skill sends and the JSON it prints. Exit 0 on pass.
|
|
5
|
+
set -u
|
|
6
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
EXEC="$HERE/execute.sh"
|
|
8
|
+
PASS=0; FAIL=0
|
|
9
|
+
check() {
|
|
10
|
+
local name="$1"; local got="$2"; local want="$3"
|
|
11
|
+
if [ "$got" = "$want" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $name"; echo " want: $want"; echo " got: $got"; fi
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
PORT=18793
|
|
15
|
+
STUB_LOG="$(mktemp)"; export STUB_LOG; export STUB_PORT="$PORT"
|
|
16
|
+
python3 -u <<'PY' >/dev/null 2>&1 &
|
|
17
|
+
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
18
|
+
import json, os
|
|
19
|
+
LOG = os.environ['STUB_LOG']; PORT = int(os.environ['STUB_PORT'])
|
|
20
|
+
class H(BaseHTTPRequestHandler):
|
|
21
|
+
def do_POST(self):
|
|
22
|
+
n = int(self.headers.get('content-length', '0')); body = self.rfile.read(n).decode() if n else ''
|
|
23
|
+
data = json.loads(body or '{}')
|
|
24
|
+
open(LOG, 'w').write(json.dumps({'path': self.path, 'body': data}))
|
|
25
|
+
if data.get('resolveBy') == 'soon':
|
|
26
|
+
self.send_response(400); self.send_header('Content-Type', 'application/json'); self.end_headers()
|
|
27
|
+
self.wfile.write(b'{"success":false,"error":"resolveBy must be an ISO date string"}'); return
|
|
28
|
+
pred = {'id': 'pred-1-abc', 'prediction': data.get('statement'), 'confidence': data.get('confidence'), 'madeAt': '2026-09-18'}
|
|
29
|
+
if 'resolveBy' in data: pred['resolveBy'] = data['resolveBy']
|
|
30
|
+
self.send_response(201); self.send_header('Content-Type', 'application/json'); self.end_headers()
|
|
31
|
+
self.wfile.write(json.dumps({'success': True, 'data': {'prediction': pred}}).encode())
|
|
32
|
+
def log_message(self, *a, **k): pass
|
|
33
|
+
HTTPServer(('127.0.0.1', PORT), H).serve_forever()
|
|
34
|
+
PY
|
|
35
|
+
STUB_PID=$!
|
|
36
|
+
disown "$STUB_PID" 2>/dev/null || true
|
|
37
|
+
trap 'kill "$STUB_PID" >/dev/null 2>&1; rm -f "$STUB_LOG"' EXIT
|
|
38
|
+
for i in $(seq 1 30); do curl -s -o /dev/null -m 0.2 "http://127.0.0.1:${PORT}/" 2>/dev/null && break; sleep 0.1; done
|
|
39
|
+
|
|
40
|
+
run() { CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_SESSION_NAME="crewly-dev-1" bash "$EXEC" "$@" 2>/dev/null; }
|
|
41
|
+
run_err() { CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_SESSION_NAME="" bash "$EXEC" "$@" 2>&1 >/dev/null | jq -r '.error' 2>/dev/null; }
|
|
42
|
+
|
|
43
|
+
OUT=$(run --statement "PR lands today" --confidence 0.7 --resolve-by 2026-10-01)
|
|
44
|
+
check "flags: output id" "$(printf '%s' "$OUT" | jq -r .id)" "pred-1-abc"
|
|
45
|
+
check "flags: output success" "$(printf '%s' "$OUT" | jq -r .success)" "true"
|
|
46
|
+
check "flags: path" "$(jq -r .path "$STUB_LOG")" "/api/agents/crewly-dev-1/self-improvement/predictions"
|
|
47
|
+
check "flags: body (confidence is numeric, resolveBy present)" "$(jq -c .body "$STUB_LOG")" '{"statement":"PR lands today","confidence":0.7,"resolveBy":"2026-10-01"}'
|
|
48
|
+
|
|
49
|
+
run '{"statement":"no deadline","confidence":1,"sessionName":"crewly-qa-9"}' >/dev/null
|
|
50
|
+
check "json: body omits resolveBy when absent" "$(jq -c .body "$STUB_LOG")" '{"statement":"no deadline","confidence":1}'
|
|
51
|
+
check "json: explicit session in path" "$(jq -r .path "$STUB_LOG")" "/api/agents/crewly-qa-9/self-improvement/predictions"
|
|
52
|
+
|
|
53
|
+
run '{"prediction":"legacy field name","confidence":"0.25"}' >/dev/null
|
|
54
|
+
check "json: accepts legacy 'prediction' key and string confidence" "$(jq -c .body "$STUB_LOG")" '{"statement":"legacy field name","confidence":0.25}'
|
|
55
|
+
|
|
56
|
+
OUT=$(CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_SESSION_NAME="crewly-dev-1" bash "$EXEC" --statement x --confidence 0.5 --resolve-by soon 2>/dev/null); RC=$?
|
|
57
|
+
check "backend 400: exit code" "$RC" "1"
|
|
58
|
+
check "backend 400: reason" "$(printf '%s' "$OUT" | jq -r .reason)" "resolveBy must be an ISO date string"
|
|
59
|
+
|
|
60
|
+
check "confidence > 1 rejected locally" "$(run_err --session s --statement x --confidence 1.5)" "confidence must be a number between 0 and 1 (got: 1.5)"
|
|
61
|
+
check "non-numeric confidence rejected locally" "$(run_err --session s --statement x --confidence abc)" "confidence must be a number between 0 and 1 (got: abc)"
|
|
62
|
+
check "missing statement errors" "$(run_err --session s --confidence 0.5)" "Missing required parameter: statement (--statement)"
|
|
63
|
+
check "missing confidence errors" "$(run_err --session s --statement x)" "Missing required parameter: confidence (--confidence)"
|
|
64
|
+
check "missing session errors" "$(run_err --statement x --confidence 0.5)" "Missing required parameter: sessionName (--session or CREWLY_SESSION_NAME)"
|
|
65
|
+
|
|
66
|
+
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
67
|
+
[ "$FAIL" -eq 0 ]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Resolve Prediction
|
|
3
|
+
description: Close a recorded prediction with what actually happened so your calibration score updates.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: memory
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- developer
|
|
9
|
+
- qa
|
|
10
|
+
- tpm
|
|
11
|
+
- designer
|
|
12
|
+
- frontend-developer
|
|
13
|
+
- backend-developer
|
|
14
|
+
- fullstack-dev
|
|
15
|
+
- qa-engineer
|
|
16
|
+
- product-manager
|
|
17
|
+
- architect
|
|
18
|
+
- generalist
|
|
19
|
+
- sales
|
|
20
|
+
- support
|
|
21
|
+
- orchestrator
|
|
22
|
+
triggers:
|
|
23
|
+
- resolve prediction
|
|
24
|
+
- prediction outcome
|
|
25
|
+
- was I right
|
|
26
|
+
tags:
|
|
27
|
+
- memory
|
|
28
|
+
- calibration
|
|
29
|
+
- self-improvement
|
|
30
|
+
execution:
|
|
31
|
+
type: script
|
|
32
|
+
script:
|
|
33
|
+
file: execute.sh
|
|
34
|
+
interpreter: bash
|
|
35
|
+
timeoutMs: 15000
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
# Resolve Prediction
|
|
39
|
+
|
|
40
|
+
Record the outcome of a prediction made with `record-prediction`. Pass `--accurate true|false`; if you only pass an outcome, a plain verdict such as `correct`, `wrong`, `yes`, `no` is understood — anything else needs the explicit flag. The response includes your updated calibration score.
|
|
41
|
+
|
|
42
|
+
## Parameters
|
|
43
|
+
|
|
44
|
+
| Flag | JSON Field | Required | Description |
|
|
45
|
+
|------|-----------|----------|-------------|
|
|
46
|
+
| `--id` | `id` | Yes | Prediction id (`pred-...`) |
|
|
47
|
+
| `--outcome` / `-o` | `outcome` | Yes | What actually happened |
|
|
48
|
+
| `--accurate` / `-a` | `accurate` | No* | `true` / `false` — required unless outcome is a plain verdict |
|
|
49
|
+
| `--session` / `-s` | `sessionName` | No | Your session name — defaults to `$CREWLY_SESSION_NAME` |
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bash execute.sh --id pred-1718000000-ab12cd --outcome "merged Thursday" --accurate true
|
|
55
|
+
bash execute.sh --id pred-1718000000-ab12cd --outcome wrong
|
|
56
|
+
bash execute.sh '{"id":"pred-1718000000-ab12cd","outcome":"slipped a week","accurate":false}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Output
|
|
60
|
+
|
|
61
|
+
`{ "success": true, "prediction": {...}, "calibrationScore": 0.82 }`
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# resolve-prediction — Close a prediction with its actual outcome
|
|
4
|
+
#
|
|
5
|
+
# Backed by POST /api/agents/:sessionName/self-improvement/predictions/:id/resolve.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# bash execute.sh --id pred-123 --outcome "merged Thursday" --accurate true [--session crewly-dev-1]
|
|
9
|
+
# bash execute.sh --id pred-123 --outcome wrong
|
|
10
|
+
# bash execute.sh '{"id":"pred-123","outcome":"slipped","accurate":false}'
|
|
11
|
+
# =============================================================================
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
source "${SCRIPT_DIR}/../../_common/lib.sh"
|
|
15
|
+
|
|
16
|
+
print_usage() {
|
|
17
|
+
cat <<'EOF_USAGE'
|
|
18
|
+
Usage:
|
|
19
|
+
bash execute.sh --id pred-123 --outcome "merged Thursday" --accurate true [--session crewly-dev-1]
|
|
20
|
+
bash execute.sh --id pred-123 --outcome wrong
|
|
21
|
+
bash execute.sh '{"id":"pred-123","outcome":"slipped","accurate":false}'
|
|
22
|
+
|
|
23
|
+
Options:
|
|
24
|
+
--id Prediction id (required)
|
|
25
|
+
--outcome | -o What actually happened (required)
|
|
26
|
+
--accurate | -a true|false (required unless outcome is a plain verdict like "correct"/"wrong")
|
|
27
|
+
--session | -s Session name (defaults to $CREWLY_SESSION_NAME)
|
|
28
|
+
--help | -h Show this help
|
|
29
|
+
EOF_USAGE
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
INPUT_JSON=""
|
|
33
|
+
SESSION_NAME=""
|
|
34
|
+
PRED_ID=""
|
|
35
|
+
OUTCOME=""
|
|
36
|
+
ACCURATE=""
|
|
37
|
+
|
|
38
|
+
if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
39
|
+
INPUT_JSON="$1"
|
|
40
|
+
shift || true
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
while [[ $# -gt 0 ]]; do
|
|
44
|
+
case "$1" in
|
|
45
|
+
--id)
|
|
46
|
+
[ $# -ge 2 ] || error_exit "--id requires a value"
|
|
47
|
+
PRED_ID="$2"; shift 2 ;;
|
|
48
|
+
--outcome|-o)
|
|
49
|
+
[ $# -ge 2 ] || error_exit "--outcome requires a value"
|
|
50
|
+
OUTCOME="$2"; shift 2 ;;
|
|
51
|
+
--accurate|-a)
|
|
52
|
+
[ $# -ge 2 ] || error_exit "--accurate requires a value"
|
|
53
|
+
ACCURATE="$2"; shift 2 ;;
|
|
54
|
+
--session|-s)
|
|
55
|
+
[ $# -ge 2 ] || error_exit "--session requires a value"
|
|
56
|
+
SESSION_NAME="$2"; shift 2 ;;
|
|
57
|
+
--help|-h) print_usage; exit 0 ;;
|
|
58
|
+
*) error_exit "Unknown option: $1" ;;
|
|
59
|
+
esac
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
if [ -n "$INPUT_JSON" ]; then
|
|
63
|
+
INPUT=$(read_json_input "$INPUT_JSON")
|
|
64
|
+
[ -z "$SESSION_NAME" ] && SESSION_NAME=$(printf '%s' "$INPUT" | jq -r '.sessionName // .agentId // empty')
|
|
65
|
+
[ -z "$PRED_ID" ] && PRED_ID=$(printf '%s' "$INPUT" | jq -r '.id // .predictionId // empty')
|
|
66
|
+
[ -z "$OUTCOME" ] && OUTCOME=$(printf '%s' "$INPUT" | jq -r '.outcome // empty')
|
|
67
|
+
[ -z "$ACCURATE" ] && ACCURATE=$(printf '%s' "$INPUT" | jq -r 'if .accurate == null then empty else (.accurate | tostring) end')
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
[ -z "$SESSION_NAME" ] && SESSION_NAME="${CREWLY_SESSION_NAME:-}"
|
|
71
|
+
require_param "sessionName (--session or CREWLY_SESSION_NAME)" "$SESSION_NAME"
|
|
72
|
+
require_param "id (--id)" "$PRED_ID"
|
|
73
|
+
require_param "outcome (--outcome)" "$OUTCOME"
|
|
74
|
+
|
|
75
|
+
case "$ACCURATE" in
|
|
76
|
+
"") BODY=$(jq -cn --arg o "$OUTCOME" '{outcome: $o}') ;;
|
|
77
|
+
true|false) BODY=$(jq -cn --arg o "$OUTCOME" --argjson a "$ACCURATE" '{outcome: $o, accurate: $a}') ;;
|
|
78
|
+
*) error_exit "accurate must be true or false (got: $ACCURATE)" ;;
|
|
79
|
+
esac
|
|
80
|
+
|
|
81
|
+
RESPONSE=$(api_call POST "/agents/${SESSION_NAME}/self-improvement/predictions/${PRED_ID}/resolve" "$BODY" 2>&1) || {
|
|
82
|
+
ERROR_MSG=$(printf '%s' "$RESPONSE" | jq -r '.details.error // .details // .error // "Unknown error"' 2>/dev/null || echo "$RESPONSE")
|
|
83
|
+
jq -n --arg reason "$ERROR_MSG" '{success: false, reason: $reason}'
|
|
84
|
+
exit 1
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
printf '%s' "$RESPONSE" | jq -c '{success: (.success // false), prediction: (.data.prediction // null), calibrationScore: (.data.calibrationScore // null)}'
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for resolve-prediction — run with: bash execute.test.sh
|
|
3
|
+
# Spins up a python HTTP stub as the backend, asserts the request path/body
|
|
4
|
+
# the skill sends and the JSON it prints. Exit 0 on pass.
|
|
5
|
+
set -u
|
|
6
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
EXEC="$HERE/execute.sh"
|
|
8
|
+
PASS=0; FAIL=0
|
|
9
|
+
check() {
|
|
10
|
+
local name="$1"; local got="$2"; local want="$3"
|
|
11
|
+
if [ "$got" = "$want" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $name"; echo " want: $want"; echo " got: $got"; fi
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
PORT=18794
|
|
15
|
+
STUB_LOG="$(mktemp)"; export STUB_LOG; export STUB_PORT="$PORT"
|
|
16
|
+
python3 -u <<'PY' >/dev/null 2>&1 &
|
|
17
|
+
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
18
|
+
import json, os
|
|
19
|
+
LOG = os.environ['STUB_LOG']; PORT = int(os.environ['STUB_PORT'])
|
|
20
|
+
class H(BaseHTTPRequestHandler):
|
|
21
|
+
def do_POST(self):
|
|
22
|
+
n = int(self.headers.get('content-length', '0')); body = self.rfile.read(n).decode() if n else ''
|
|
23
|
+
data = json.loads(body or '{}')
|
|
24
|
+
open(LOG, 'w').write(json.dumps({'path': self.path, 'body': data}))
|
|
25
|
+
self.send_header_json = lambda code: (self.send_response(code), self.send_header('Content-Type', 'application/json'), self.end_headers())
|
|
26
|
+
if '/pred-missing/' in self.path:
|
|
27
|
+
self.send_header_json(404); self.wfile.write(b'{"success":false,"error":"Prediction pred-missing not found"}'); return
|
|
28
|
+
if 'accurate' not in data and data.get('outcome') not in ('correct', 'wrong'):
|
|
29
|
+
self.send_header_json(400); self.wfile.write(b'{"success":false,"error":"accurate (boolean) is required"}'); return
|
|
30
|
+
acc = data.get('accurate', data.get('outcome') == 'correct')
|
|
31
|
+
pred = {'id': 'pred-1-abc', 'prediction': 'x', 'confidence': 0.9, 'madeAt': '2026-09-18', 'outcome': data.get('outcome'), 'accurate': acc, 'resolvedAt': '2026-09-18'}
|
|
32
|
+
self.send_header_json(200)
|
|
33
|
+
self.wfile.write(json.dumps({'success': True, 'data': {'prediction': pred, 'calibrationScore': 0.82}}).encode())
|
|
34
|
+
def log_message(self, *a, **k): pass
|
|
35
|
+
HTTPServer(('127.0.0.1', PORT), H).serve_forever()
|
|
36
|
+
PY
|
|
37
|
+
STUB_PID=$!
|
|
38
|
+
disown "$STUB_PID" 2>/dev/null || true
|
|
39
|
+
trap 'kill "$STUB_PID" >/dev/null 2>&1; rm -f "$STUB_LOG"' EXIT
|
|
40
|
+
for i in $(seq 1 30); do curl -s -o /dev/null -m 0.2 "http://127.0.0.1:${PORT}/" 2>/dev/null && break; sleep 0.1; done
|
|
41
|
+
|
|
42
|
+
run() { CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_SESSION_NAME="crewly-dev-1" bash "$EXEC" "$@" 2>/dev/null; }
|
|
43
|
+
run_err() { CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_SESSION_NAME="" bash "$EXEC" "$@" 2>&1 >/dev/null | jq -r '.error' 2>/dev/null; }
|
|
44
|
+
|
|
45
|
+
OUT=$(run --id pred-1-abc --outcome "merged Thursday" --accurate true)
|
|
46
|
+
check "flags: success + calibration" "$(printf '%s' "$OUT" | jq -c '{success, calibrationScore}')" '{"success":true,"calibrationScore":0.82}'
|
|
47
|
+
check "flags: prediction accurate" "$(printf '%s' "$OUT" | jq -r .prediction.accurate)" "true"
|
|
48
|
+
check "flags: path includes id" "$(jq -r .path "$STUB_LOG")" "/api/agents/crewly-dev-1/self-improvement/predictions/pred-1-abc/resolve"
|
|
49
|
+
check "flags: body (accurate is boolean)" "$(jq -c .body "$STUB_LOG")" '{"outcome":"merged Thursday","accurate":true}'
|
|
50
|
+
|
|
51
|
+
run --id pred-1-abc --outcome wrong >/dev/null
|
|
52
|
+
check "verdict-only outcome omits accurate" "$(jq -c .body "$STUB_LOG")" '{"outcome":"wrong"}'
|
|
53
|
+
|
|
54
|
+
run '{"id":"pred-1-abc","outcome":"slipped","accurate":false,"sessionName":"crewly-qa-9"}' >/dev/null
|
|
55
|
+
check "json: body" "$(jq -c .body "$STUB_LOG")" '{"outcome":"slipped","accurate":false}'
|
|
56
|
+
check "json: explicit session in path" "$(jq -r .path "$STUB_LOG")" "/api/agents/crewly-qa-9/self-improvement/predictions/pred-1-abc/resolve"
|
|
57
|
+
|
|
58
|
+
run '{"predictionId":"pred-1-abc","outcome":"correct"}' >/dev/null
|
|
59
|
+
check "json: accepts legacy predictionId key" "$(jq -r .path "$STUB_LOG")" "/api/agents/crewly-dev-1/self-improvement/predictions/pred-1-abc/resolve"
|
|
60
|
+
|
|
61
|
+
OUT=$(CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_SESSION_NAME="crewly-dev-1" bash "$EXEC" --id pred-missing --outcome correct 2>/dev/null); RC=$?
|
|
62
|
+
check "backend 404: exit code" "$RC" "1"
|
|
63
|
+
check "backend 404: reason" "$(printf '%s' "$OUT" | jq -r .reason)" "Prediction pred-missing not found"
|
|
64
|
+
|
|
65
|
+
OUT=$(CREWLY_API_URL="http://127.0.0.1:${PORT}" CREWLY_SESSION_NAME="crewly-dev-1" bash "$EXEC" --id pred-1-abc --outcome "took a while" 2>/dev/null); RC=$?
|
|
66
|
+
check "backend 400 (ambiguous outcome): reason" "$(printf '%s' "$OUT" | jq -r .reason)" "accurate (boolean) is required"
|
|
67
|
+
|
|
68
|
+
check "bad accurate value rejected locally" "$(run_err --session s --id p --outcome x --accurate maybe)" "accurate must be true or false (got: maybe)"
|
|
69
|
+
check "missing id errors" "$(run_err --session s --outcome x)" "Missing required parameter: id (--id)"
|
|
70
|
+
check "missing outcome errors" "$(run_err --session s --id p)" "Missing required parameter: outcome (--outcome)"
|
|
71
|
+
check "missing session errors" "$(run_err --id p --outcome x)" "Missing required parameter: sessionName (--session or CREWLY_SESSION_NAME)"
|
|
72
|
+
|
|
73
|
+
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
74
|
+
[ "$FAIL" -eq 0 ]
|