crewly 1.15.0 → 1.16.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 +6 -4
- package/config/roles/developer/prompt.md +1 -1
- package/config/runtime_scripts/runtime-config.json +7 -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/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/dist/backend/backend/src/constants.d.ts +61 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +71 -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/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/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 +53 -0
- 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/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/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/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 +2 -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 +16 -0
- package/dist/backend/backend/src/services/v3/mission-reminder.service.js.map +1 -1
- 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/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/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 +61 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +71 -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/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/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/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/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-019817e2.js} +272 -272
- package/frontend/dist/assets/index-a56613e7.css +42 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- package/frontend/dist/assets/index-dcaf6c88.css +0 -42
package/README.md
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
**Website:** [crewlyai.com](https://crewlyai.com/)
|
|
9
9
|
|
|
10
|
-
Crewly is an open-source multi-agent orchestration platform that coordinates AI coding agents (Claude Code, Gemini CLI, Codex) to work together as a team. It provides a web dashboard for real-time monitoring, task management, and team coordination — all running locally on your machine.
|
|
10
|
+
Crewly is an open-source multi-agent orchestration platform that coordinates AI coding agents (Claude Code, Gemini CLI, Codex, OpenCode) to work together as a team. It provides a web dashboard for real-time monitoring, task management, and team coordination — all running locally on your machine.
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
14
|
- **Multi-agent teams** — Create teams with different roles (developer, QA, PM, orchestrator) and watch them collaborate
|
|
15
|
-
- **Multi-runtime support** — Use Claude Code, Gemini CLI,
|
|
15
|
+
- **Multi-runtime support** — Use Claude Code, Gemini CLI, OpenAI Codex, or OpenCode — mix and match per agent
|
|
16
16
|
- **Real-time dashboard** — Monitor all agents through live terminal streams, task boards, and activity feeds
|
|
17
17
|
- **Skill system** — Agents coordinate through bash skills (report status, delegate tasks, manage memory)
|
|
18
18
|
- **Agent memory** — Persistent knowledge that agents build and share across sessions
|
|
@@ -49,8 +49,9 @@ The `init` command walks you through provider selection, installs agent skills,
|
|
|
49
49
|
| **Claude Code** (default) | `npm install -g @anthropic-ai/claude-code` | `claude --version` |
|
|
50
50
|
| **Gemini CLI** | `npm install -g @google/gemini-cli` | `gemini --version` |
|
|
51
51
|
| **Codex (OpenAI)** | `npm install -g @openai/codex` | `codex --version` |
|
|
52
|
+
| **OpenCode** | `npm install -g opencode-ai` | `opencode --version` |
|
|
52
53
|
|
|
53
|
-
**API keys:** Gemini CLI requires `GEMINI_API_KEY`. Codex requires an OpenAI API key. Claude Code authenticates through its own login flow.
|
|
54
|
+
**API keys:** Gemini CLI requires `GEMINI_API_KEY`. Codex requires an OpenAI API key. Claude Code authenticates through its own login flow. OpenCode uses whichever provider you connect via `opencode auth login` (or the `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GEMINI_API_KEY` env vars Crewly already exports to agent sessions).
|
|
54
55
|
|
|
55
56
|
## Architecture
|
|
56
57
|
|
|
@@ -98,7 +99,8 @@ Storage: ~/.crewly/ (global) + project/.crewly/ (per-project)
|
|
|
98
99
|
|---------|-----------------|-------|
|
|
99
100
|
| **Claude Code** | `claude --dangerously-skip-permissions` | Default runtime |
|
|
100
101
|
| **Gemini CLI** | `gemini --yolo` | Requires `GEMINI_API_KEY` |
|
|
101
|
-
| **Codex (OpenAI)** | `codex
|
|
102
|
+
| **Codex (OpenAI)** | `codex -a never -s danger-full-access` | Requires OpenAI API key |
|
|
103
|
+
| **OpenCode** | `opencode --auto` | Any provider/model (`-m provider/model`); reads `AGENTS.md`; auth via `opencode auth login` |
|
|
102
104
|
|
|
103
105
|
You can change the default runtime or customize launch commands in **Settings**.
|
|
104
106
|
|
|
@@ -273,7 +273,7 @@ When you are **idle and have no assigned tasks**, proactively check the Task Poo
|
|
|
273
273
|
|
|
274
274
|
Call the `poll-tasks` skill to query and claim work from the shared Task Pool:
|
|
275
275
|
```bash
|
|
276
|
-
bash {{AGENT_SKILLS_PATH}}/core/poll-tasks/execute.sh '{"sessionName":"{{SESSION_NAME}}","role":"{{ROLE}}","skills":
|
|
276
|
+
bash {{AGENT_SKILLS_PATH}}/core/poll-tasks/execute.sh '{"sessionName":"{{SESSION_NAME}}","role":"{{ROLE}}","skills":{{MEMBER_SKILLS_JSON}},"projectPath":"{{PROJECT_PATH}}"}'
|
|
277
277
|
```
|
|
278
278
|
|
|
279
279
|
### Parameters
|
|
@@ -21,6 +21,13 @@
|
|
|
21
21
|
"timeout": 90000,
|
|
22
22
|
"description": "OpenAI's Codex CLI for advanced code understanding"
|
|
23
23
|
},
|
|
24
|
+
"opencode-cli": {
|
|
25
|
+
"displayName": "OpenCode",
|
|
26
|
+
"initScript": "",
|
|
27
|
+
"welcomeMessage": "Ask anything",
|
|
28
|
+
"timeout": 90000,
|
|
29
|
+
"description": "OpenCode open-source TUI coding agent (opencode.ai), any provider/model"
|
|
30
|
+
},
|
|
24
31
|
"crewly-agent": {
|
|
25
32
|
"displayName": "Crewly Agent",
|
|
26
33
|
"initScript": "",
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Count JSON
|
|
3
|
+
description: Run a command that prints JSON and count the entries matching a field=value filter. Built for skill_output Key Results (e.g. "tickets in review") so a KR can be measured from any board or API that speaks JSON.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: measurement
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- orchestrator
|
|
9
|
+
- team-leader
|
|
10
|
+
- developer
|
|
11
|
+
- devops
|
|
12
|
+
- operations
|
|
13
|
+
- ops
|
|
14
|
+
triggers:
|
|
15
|
+
- count json
|
|
16
|
+
- measure kr
|
|
17
|
+
tags:
|
|
18
|
+
- okr
|
|
19
|
+
- measurement
|
|
20
|
+
- json
|
|
21
|
+
execution:
|
|
22
|
+
type: script
|
|
23
|
+
script:
|
|
24
|
+
file: execute.sh
|
|
25
|
+
interpreter: bash
|
|
26
|
+
timeoutMs: 60000
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
# Count JSON
|
|
30
|
+
|
|
31
|
+
Runs a command, reads the JSON it prints (an array, or an object holding an
|
|
32
|
+
array under `items` / `tickets` / `data`), applies an optional `field=value`
|
|
33
|
+
filter, and prints `{"count": N, "total": M, "filter": "..."}`.
|
|
34
|
+
|
|
35
|
+
Made for `measurementSource: "skill_output"` Key Results:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{ "measurementConfig": { "skill": "count-json",
|
|
39
|
+
"args": { "command": "cd /opt/app/web && make tickets TICKET_ARGS=--json",
|
|
40
|
+
"field": "status", "value": "review" },
|
|
41
|
+
"jsonPath": ".count" } }
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Parameters
|
|
45
|
+
|
|
46
|
+
| Name | Required | Meaning |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `command` | yes | Shell command whose stdout is JSON (or a `file` path instead) |
|
|
49
|
+
| `file` | no | Read JSON from this file instead of running a command |
|
|
50
|
+
| `field` | no | Top-level field to filter on |
|
|
51
|
+
| `value` | no | Value that `field` must equal (string compare) |
|
|
52
|
+
| `arrayPath` | no | jq path to the array when it is nested (default: auto-detect) |
|
|
53
|
+
|
|
54
|
+
## Output
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{"count": 6, "total": 21, "filter": "status=review"}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The command runs with a 50 s timeout; a non-JSON result exits 1 with an error
|
|
61
|
+
object on stderr.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# count-json — run a command (or read a file) that yields JSON, count entries
|
|
3
|
+
# matching field=value. Output: {"count":N,"total":M,"filter":"field=value"}
|
|
4
|
+
#
|
|
5
|
+
# Usage: execute.sh '{"command":"...","field":"status","value":"review"}'
|
|
6
|
+
# execute.sh '{"file":"/tmp/board.json","field":"status","value":"open"}'
|
|
7
|
+
set -uo pipefail
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
source "${SCRIPT_DIR}/../../_common/lib.sh"
|
|
10
|
+
|
|
11
|
+
INPUT="${1:-}"
|
|
12
|
+
[ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"command\":\"...\",\"field\":\"status\",\"value\":\"review\"}'"
|
|
13
|
+
|
|
14
|
+
COMMAND=$(printf '%s' "$INPUT" | jq -r '.command // empty')
|
|
15
|
+
FILE=$(printf '%s' "$INPUT" | jq -r '.file // empty')
|
|
16
|
+
FIELD=$(printf '%s' "$INPUT" | jq -r '.field // empty')
|
|
17
|
+
VALUE=$(printf '%s' "$INPUT" | jq -r '.value // empty')
|
|
18
|
+
ARRAY_PATH=$(printf '%s' "$INPUT" | jq -r '.arrayPath // empty')
|
|
19
|
+
TIMEOUT_S="${COUNT_JSON_TIMEOUT_S:-50}"
|
|
20
|
+
|
|
21
|
+
[ -z "$COMMAND" ] && [ -z "$FILE" ] && error_exit "command or file is required"
|
|
22
|
+
|
|
23
|
+
if [ -n "$FILE" ]; then
|
|
24
|
+
[ -f "$FILE" ] || error_exit "file not found: $FILE"
|
|
25
|
+
RAW=$(cat "$FILE")
|
|
26
|
+
else
|
|
27
|
+
if command -v timeout >/dev/null 2>&1; then
|
|
28
|
+
RAW=$(timeout "$TIMEOUT_S" bash -c "$COMMAND" 2>/dev/null)
|
|
29
|
+
else
|
|
30
|
+
RAW=$(bash -c "$COMMAND" 2>/dev/null)
|
|
31
|
+
fi
|
|
32
|
+
[ $? -ne 0 ] && [ -z "$RAW" ] && error_exit "command failed or produced no output"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Skip any non-JSON preamble (progress lines, banners).
|
|
36
|
+
JSON=$(printf '%s' "$RAW" | awk 'found||/^[[{]/{found=1; print}')
|
|
37
|
+
[ -z "$JSON" ] && error_exit "no JSON found in output"
|
|
38
|
+
|
|
39
|
+
if [ -n "$ARRAY_PATH" ]; then
|
|
40
|
+
SELECT="$ARRAY_PATH"
|
|
41
|
+
else
|
|
42
|
+
SELECT='if type=="array" then . elif (.items|type)=="array" then .items elif (.tickets|type)=="array" then .tickets elif (.data|type)=="array" then .data else [] end'
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if [ -n "$FIELD" ]; then
|
|
46
|
+
printf '%s' "$JSON" | jq -c --arg f "$FIELD" --arg v "$VALUE" \
|
|
47
|
+
"($SELECT) as \$arr | {count: (\$arr | map(select((.[\$f] // \"\" | tostring) == \$v)) | length), total: (\$arr | length), filter: (\$f + \"=\" + \$v)}" \
|
|
48
|
+
|| error_exit "output is not valid JSON"
|
|
49
|
+
else
|
|
50
|
+
printf '%s' "$JSON" | jq -c "($SELECT) as \$arr | {count: (\$arr | length), total: (\$arr | length), filter: \"\"}" \
|
|
51
|
+
|| error_exit "output is not valid JSON"
|
|
52
|
+
fi
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for count-json — run with: bash execute.test.sh
|
|
3
|
+
set -u
|
|
4
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
EXEC="$HERE/execute.sh"
|
|
6
|
+
PASS=0; FAIL=0
|
|
7
|
+
check() {
|
|
8
|
+
local name="$1"; local got="$2"; local want="$3"
|
|
9
|
+
if [ "$got" = "$want" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $name"; echo " want: $want"; echo " got: $got"; fi
|
|
10
|
+
}
|
|
11
|
+
run() { bash "$EXEC" "$1" 2>/dev/null; }
|
|
12
|
+
run_err() { bash "$EXEC" "$1" 2>&1 >/dev/null | jq -r '.error' 2>/dev/null; }
|
|
13
|
+
|
|
14
|
+
TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
|
|
15
|
+
printf '%s' '[{"ticketId":"T1","status":"open"},{"ticketId":"T2","status":"review"},{"ticketId":"T3","status":"review"},{"ticketId":"T4","status":"blocked"}]' > "$TMP/board.json"
|
|
16
|
+
printf '%s' 'fetching...
|
|
17
|
+
{"items":[{"s":"a"},{"s":"b"}]}' > "$TMP/nested.txt"
|
|
18
|
+
|
|
19
|
+
ARGS=$(jq -cn --arg f "$TMP/board.json" '{file:$f, field:"status", value:"review"}')
|
|
20
|
+
check "filter by field=value" "$(run "$ARGS")" '{"count":2,"total":4,"filter":"status=review"}'
|
|
21
|
+
|
|
22
|
+
ARGS=$(jq -cn --arg f "$TMP/board.json" '{file:$f}')
|
|
23
|
+
check "no filter counts all" "$(run "$ARGS")" '{"count":4,"total":4,"filter":""}'
|
|
24
|
+
|
|
25
|
+
ARGS=$(jq -cn --arg c "cat $TMP/nested.txt" '{command:$c, field:"s", value:"b"}')
|
|
26
|
+
check "command with preamble and nested items" "$(run "$ARGS")" '{"count":1,"total":2,"filter":"s=b"}'
|
|
27
|
+
|
|
28
|
+
ARGS=$(jq -cn --arg f "$TMP/board.json" '{file:$f, arrayPath:".", field:"status", value:"open"}')
|
|
29
|
+
check "explicit arrayPath" "$(run "$ARGS")" '{"count":1,"total":4,"filter":"status=open"}'
|
|
30
|
+
|
|
31
|
+
check "non-JSON errors" "$(run_err '{"command":"echo not json"}')" "no JSON found in output"
|
|
32
|
+
check "missing input errors" "$(run_err '{}')" "command or file is required"
|
|
33
|
+
|
|
34
|
+
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
35
|
+
[ "$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)}'
|