shipwright-cli 3.0.0 → 3.2.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 +21 -7
- package/completions/_shipwright +247 -93
- package/completions/shipwright.bash +69 -15
- package/completions/shipwright.fish +309 -41
- package/config/decision-tiers.json +55 -0
- package/config/defaults.json +25 -2
- package/config/event-schema.json +142 -5
- package/config/policy.json +8 -0
- package/dashboard/public/index.html +6 -0
- package/dashboard/public/styles.css +76 -0
- package/dashboard/server.ts +51 -0
- package/dashboard/src/core/api.ts +5 -0
- package/dashboard/src/types/api.ts +10 -0
- package/dashboard/src/views/metrics.ts +69 -1
- package/package.json +3 -3
- package/scripts/lib/architecture.sh +2 -1
- package/scripts/lib/bootstrap.sh +0 -0
- package/scripts/lib/config.sh +0 -0
- package/scripts/lib/daemon-adaptive.sh +4 -2
- package/scripts/lib/daemon-dispatch.sh +24 -1
- package/scripts/lib/daemon-failure.sh +0 -0
- package/scripts/lib/daemon-health.sh +0 -0
- package/scripts/lib/daemon-patrol.sh +42 -7
- package/scripts/lib/daemon-poll.sh +17 -0
- package/scripts/lib/daemon-state.sh +17 -0
- package/scripts/lib/daemon-triage.sh +1 -1
- package/scripts/lib/decide-autonomy.sh +295 -0
- package/scripts/lib/decide-scoring.sh +228 -0
- package/scripts/lib/decide-signals.sh +462 -0
- package/scripts/lib/fleet-failover.sh +0 -0
- package/scripts/lib/helpers.sh +19 -18
- package/scripts/lib/pipeline-detection.sh +1 -1
- package/scripts/lib/pipeline-github.sh +0 -0
- package/scripts/lib/pipeline-intelligence.sh +23 -4
- package/scripts/lib/pipeline-quality-checks.sh +11 -6
- package/scripts/lib/pipeline-quality.sh +0 -0
- package/scripts/lib/pipeline-stages.sh +330 -33
- package/scripts/lib/pipeline-state.sh +14 -0
- package/scripts/lib/policy.sh +0 -0
- package/scripts/lib/test-helpers.sh +0 -0
- package/scripts/postinstall.mjs +75 -1
- package/scripts/signals/example-collector.sh +36 -0
- package/scripts/sw +8 -4
- package/scripts/sw-activity.sh +1 -7
- package/scripts/sw-adaptive.sh +7 -7
- package/scripts/sw-adversarial.sh +1 -1
- package/scripts/sw-architecture-enforcer.sh +1 -1
- package/scripts/sw-auth.sh +1 -1
- package/scripts/sw-autonomous.sh +1 -1
- package/scripts/sw-changelog.sh +1 -1
- package/scripts/sw-checkpoint.sh +1 -1
- package/scripts/sw-ci.sh +11 -6
- package/scripts/sw-cleanup.sh +1 -1
- package/scripts/sw-code-review.sh +36 -17
- package/scripts/sw-connect.sh +1 -1
- package/scripts/sw-context.sh +1 -1
- package/scripts/sw-cost.sh +71 -5
- package/scripts/sw-daemon.sh +6 -3
- package/scripts/sw-dashboard.sh +1 -1
- package/scripts/sw-db.sh +53 -38
- package/scripts/sw-decide.sh +685 -0
- package/scripts/sw-decompose.sh +1 -1
- package/scripts/sw-deps.sh +1 -1
- package/scripts/sw-developer-simulation.sh +1 -1
- package/scripts/sw-discovery.sh +80 -4
- package/scripts/sw-doc-fleet.sh +1 -1
- package/scripts/sw-docs-agent.sh +1 -1
- package/scripts/sw-docs.sh +1 -1
- package/scripts/sw-doctor.sh +1 -1
- package/scripts/sw-dora.sh +1 -1
- package/scripts/sw-durable.sh +9 -5
- package/scripts/sw-e2e-orchestrator.sh +1 -1
- package/scripts/sw-eventbus.sh +7 -4
- package/scripts/sw-evidence.sh +1 -1
- package/scripts/sw-feedback.sh +1 -1
- package/scripts/sw-fix.sh +1 -1
- package/scripts/sw-fleet-discover.sh +1 -1
- package/scripts/sw-fleet-viz.sh +6 -4
- package/scripts/sw-fleet.sh +1 -1
- package/scripts/sw-github-app.sh +3 -2
- package/scripts/sw-github-checks.sh +1 -1
- package/scripts/sw-github-deploy.sh +1 -1
- package/scripts/sw-github-graphql.sh +1 -1
- package/scripts/sw-guild.sh +1 -1
- package/scripts/sw-heartbeat.sh +1 -1
- package/scripts/sw-hygiene.sh +5 -3
- package/scripts/sw-incident.sh +9 -5
- package/scripts/sw-init.sh +1 -1
- package/scripts/sw-instrument.sh +1 -1
- package/scripts/sw-intelligence.sh +11 -6
- package/scripts/sw-jira.sh +1 -1
- package/scripts/sw-launchd.sh +1 -1
- package/scripts/sw-linear.sh +1 -1
- package/scripts/sw-logs.sh +1 -1
- package/scripts/sw-loop.sh +338 -32
- package/scripts/sw-memory.sh +23 -6
- package/scripts/sw-mission-control.sh +1 -1
- package/scripts/sw-model-router.sh +3 -2
- package/scripts/sw-otel.sh +8 -4
- package/scripts/sw-oversight.sh +1 -1
- package/scripts/sw-pipeline-composer.sh +3 -1
- package/scripts/sw-pipeline-vitals.sh +11 -6
- package/scripts/sw-pipeline.sh +92 -8
- package/scripts/sw-pm.sh +5 -4
- package/scripts/sw-pr-lifecycle.sh +7 -4
- package/scripts/sw-predictive.sh +11 -5
- package/scripts/sw-prep.sh +1 -1
- package/scripts/sw-ps.sh +1 -1
- package/scripts/sw-public-dashboard.sh +3 -2
- package/scripts/sw-quality.sh +21 -10
- package/scripts/sw-reaper.sh +1 -1
- package/scripts/sw-recruit.sh +1 -1
- package/scripts/sw-regression.sh +1 -1
- package/scripts/sw-release-manager.sh +1 -1
- package/scripts/sw-release.sh +1 -1
- package/scripts/sw-remote.sh +1 -1
- package/scripts/sw-replay.sh +1 -1
- package/scripts/sw-retro.sh +1 -1
- package/scripts/sw-review-rerun.sh +1 -1
- package/scripts/sw-scale.sh +69 -11
- package/scripts/sw-security-audit.sh +1 -1
- package/scripts/sw-self-optimize.sh +168 -4
- package/scripts/sw-session.sh +3 -3
- package/scripts/sw-setup.sh +1 -1
- package/scripts/sw-standup.sh +1 -1
- package/scripts/sw-status.sh +1 -1
- package/scripts/sw-strategic.sh +11 -6
- package/scripts/sw-stream.sh +7 -4
- package/scripts/sw-swarm.sh +3 -2
- package/scripts/sw-team-stages.sh +1 -1
- package/scripts/sw-templates.sh +3 -3
- package/scripts/sw-testgen.sh +11 -6
- package/scripts/sw-tmux-pipeline.sh +1 -1
- package/scripts/sw-tmux.sh +35 -1
- package/scripts/sw-trace.sh +1 -1
- package/scripts/sw-tracker.sh +1 -1
- package/scripts/sw-triage.sh +7 -7
- package/scripts/sw-upgrade.sh +1 -1
- package/scripts/sw-ux.sh +1 -1
- package/scripts/sw-webhook.sh +3 -2
- package/scripts/sw-widgets.sh +7 -4
- package/scripts/sw-worktree.sh +1 -1
- package/scripts/update-homebrew-sha.sh +21 -15
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://shipwright.dev/schemas/decision-tiers-v1.json",
|
|
3
|
+
"description": "Autonomy tiers for Shipwright decision engine. Controls which actions the engine takes automatically vs proposing for human review.",
|
|
4
|
+
"version": "1",
|
|
5
|
+
"tiers": {
|
|
6
|
+
"auto": {
|
|
7
|
+
"description": "Create issue and auto-spawn pipeline — no human approval needed",
|
|
8
|
+
"labels": ["shipwright", "shipwright:auto", "ready-to-build"],
|
|
9
|
+
"pipeline_template": "fast"
|
|
10
|
+
},
|
|
11
|
+
"propose": {
|
|
12
|
+
"description": "Create issue with proposed label — human approves before build",
|
|
13
|
+
"labels": ["shipwright", "shipwright:proposed"],
|
|
14
|
+
"pipeline_template": "standard"
|
|
15
|
+
},
|
|
16
|
+
"draft": {
|
|
17
|
+
"description": "Write to decision-drafts directory only — human reviews offline",
|
|
18
|
+
"labels": [],
|
|
19
|
+
"pipeline_template": null
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"category_rules": {
|
|
23
|
+
"deps_patch": { "tier": "auto", "risk_ceiling": 30 },
|
|
24
|
+
"deps_minor": { "tier": "auto", "risk_ceiling": 40 },
|
|
25
|
+
"deps_major": { "tier": "propose", "risk_ceiling": 60 },
|
|
26
|
+
"security_patch": { "tier": "auto", "risk_ceiling": 50 },
|
|
27
|
+
"security_critical": { "tier": "propose", "risk_ceiling": 80 },
|
|
28
|
+
"test_coverage": { "tier": "auto", "risk_ceiling": 30 },
|
|
29
|
+
"doc_sync": { "tier": "auto", "risk_ceiling": 20 },
|
|
30
|
+
"dead_code": { "tier": "auto", "risk_ceiling": 35 },
|
|
31
|
+
"refactor_hotspot": { "tier": "propose", "risk_ceiling": 60 },
|
|
32
|
+
"architecture_drift": { "tier": "propose", "risk_ceiling": 70 },
|
|
33
|
+
"performance_regression": { "tier": "propose", "risk_ceiling": 60 },
|
|
34
|
+
"recurring_failure": { "tier": "propose", "risk_ceiling": 50 },
|
|
35
|
+
"dora_regression": { "tier": "propose", "risk_ceiling": 55 },
|
|
36
|
+
"new_feature": { "tier": "draft", "risk_ceiling": 90 },
|
|
37
|
+
"breaking_change": { "tier": "draft", "risk_ceiling": 95 },
|
|
38
|
+
"business_logic": { "tier": "draft", "risk_ceiling": 90 },
|
|
39
|
+
"api_change": { "tier": "draft", "risk_ceiling": 85 },
|
|
40
|
+
"data_model_change": { "tier": "draft", "risk_ceiling": 90 }
|
|
41
|
+
},
|
|
42
|
+
"limits": {
|
|
43
|
+
"max_issues_per_day": 15,
|
|
44
|
+
"max_cost_per_day_usd": 25,
|
|
45
|
+
"cooldown_seconds": 300,
|
|
46
|
+
"halt_after_consecutive_failures": 3
|
|
47
|
+
},
|
|
48
|
+
"scoring_weights": {
|
|
49
|
+
"impact": 0.3,
|
|
50
|
+
"urgency": 0.25,
|
|
51
|
+
"effort": 0.2,
|
|
52
|
+
"confidence": 0.15,
|
|
53
|
+
"risk": 0.1
|
|
54
|
+
}
|
|
55
|
+
}
|
package/config/defaults.json
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"build_test_retries": 3,
|
|
26
26
|
"claude_timeout": 1800,
|
|
27
27
|
"heartbeat_interval": 30,
|
|
28
|
+
"composed_cache_ttl": 3600,
|
|
28
29
|
"branch_pattern": "shipwright/issue-{issue}",
|
|
29
30
|
"stage_order": [
|
|
30
31
|
"intake",
|
|
@@ -47,7 +48,12 @@
|
|
|
47
48
|
"max_restarts": 0,
|
|
48
49
|
"fast_test_interval": 5,
|
|
49
50
|
"convergence_threshold": 3,
|
|
50
|
-
"multi_agent_sleep": 5
|
|
51
|
+
"multi_agent_sleep": 5,
|
|
52
|
+
"context_budget_chars": 180000,
|
|
53
|
+
"context_trim_memory_chars": 20000,
|
|
54
|
+
"context_trim_git_entries": 10,
|
|
55
|
+
"context_trim_hotspot_files": 5,
|
|
56
|
+
"context_trim_test_lines": 50
|
|
51
57
|
},
|
|
52
58
|
"dashboard": {
|
|
53
59
|
"port": 8767,
|
|
@@ -77,12 +83,29 @@
|
|
|
77
83
|
"ab_test_ratio": 0.2,
|
|
78
84
|
"claude_timeout": 60
|
|
79
85
|
},
|
|
86
|
+
"predictive": {
|
|
87
|
+
"default_risk_score": 50,
|
|
88
|
+
"keyword_risk_score": 70
|
|
89
|
+
},
|
|
90
|
+
"api_optimization": {
|
|
91
|
+
"programmatic_tool_calling": true,
|
|
92
|
+
"tool_search_enabled": true,
|
|
93
|
+
"tool_search_type": "bm25",
|
|
94
|
+
"defer_unused_tools": true,
|
|
95
|
+
"web_search_version": "web_search_20260209",
|
|
96
|
+
"web_fetch_version": "web_fetch_20260209",
|
|
97
|
+
"dynamic_filtering": true,
|
|
98
|
+
"code_execution_sandbox": true,
|
|
99
|
+
"beta_header": "code-execution-web-tools-2026-02-09"
|
|
100
|
+
},
|
|
80
101
|
"quality": {
|
|
81
102
|
"gate_score_threshold": 70,
|
|
82
103
|
"secret_threshold": 3,
|
|
83
104
|
"min_file_count": 10,
|
|
84
105
|
"score_weight_per_file": 25,
|
|
85
|
-
"pass_rate_threshold": 5.0
|
|
106
|
+
"pass_rate_threshold": 5.0,
|
|
107
|
+
"bundle_growth_legacy_pct": 20,
|
|
108
|
+
"perf_regression_legacy_pct": 30
|
|
86
109
|
},
|
|
87
110
|
"cleanup": {
|
|
88
111
|
"artifact_age_days": 7,
|
package/config/event-schema.json
CHANGED
|
@@ -15,12 +15,15 @@
|
|
|
15
15
|
"required": ["job_id"],
|
|
16
16
|
"optional": ["error", "stage"]
|
|
17
17
|
},
|
|
18
|
-
"stage.started": { "required": ["
|
|
18
|
+
"stage.started": { "required": ["stage"], "optional": ["issue", "job_id"] },
|
|
19
19
|
"stage.completed": {
|
|
20
|
-
"required": ["
|
|
21
|
-
"optional": ["duration_s"]
|
|
20
|
+
"required": ["stage"],
|
|
21
|
+
"optional": ["issue", "job_id", "duration_s", "result"]
|
|
22
|
+
},
|
|
23
|
+
"stage.failed": {
|
|
24
|
+
"required": ["stage"],
|
|
25
|
+
"optional": ["issue", "job_id", "error", "error_class", "duration_s"]
|
|
22
26
|
},
|
|
23
|
-
"stage.failed": { "required": ["job_id", "stage"], "optional": ["error"] },
|
|
24
27
|
"daemon.started": { "required": [], "optional": ["pid", "mode"] },
|
|
25
28
|
"daemon.stopped": { "required": [], "optional": ["reason"] },
|
|
26
29
|
"daemon.claimed": { "required": ["issue"], "optional": ["repo", "title"] },
|
|
@@ -76,6 +79,140 @@
|
|
|
76
79
|
"required": ["session_id"],
|
|
77
80
|
"optional": ["template", "agents"]
|
|
78
81
|
},
|
|
79
|
-
"session.ended": { "required": ["session_id"], "optional": ["duration_s"] }
|
|
82
|
+
"session.ended": { "required": ["session_id"], "optional": ["duration_s"] },
|
|
83
|
+
"memory.fix_outcome": {
|
|
84
|
+
"required": ["pattern"],
|
|
85
|
+
"optional": ["outcome", "repo"]
|
|
86
|
+
},
|
|
87
|
+
"memory.global_aggregated": {
|
|
88
|
+
"required": [],
|
|
89
|
+
"optional": ["repo", "patterns_promoted"]
|
|
90
|
+
},
|
|
91
|
+
"memory.not_available": {
|
|
92
|
+
"required": ["path"],
|
|
93
|
+
"optional": ["action"]
|
|
94
|
+
},
|
|
95
|
+
"memory.export": {
|
|
96
|
+
"required": [],
|
|
97
|
+
"optional": ["repo"]
|
|
98
|
+
},
|
|
99
|
+
"cost.budget_unconfigured": {
|
|
100
|
+
"required": ["status"],
|
|
101
|
+
"optional": []
|
|
102
|
+
},
|
|
103
|
+
"scale.recommendation": {
|
|
104
|
+
"required": [],
|
|
105
|
+
"optional": ["iterations", "coverage", "modules", "has_recommendations"]
|
|
106
|
+
},
|
|
107
|
+
"pr.skipped": {
|
|
108
|
+
"required": ["issue"],
|
|
109
|
+
"optional": ["reason"]
|
|
110
|
+
},
|
|
111
|
+
"pr.rejected": {
|
|
112
|
+
"required": ["issue"],
|
|
113
|
+
"optional": ["reason"]
|
|
114
|
+
},
|
|
115
|
+
"intelligence.compose": {
|
|
116
|
+
"required": [],
|
|
117
|
+
"optional": ["stage_count", "complexity"]
|
|
118
|
+
},
|
|
119
|
+
"intelligence.synthesize": {
|
|
120
|
+
"required": [],
|
|
121
|
+
"optional": ["fix_count", "cause_count"]
|
|
122
|
+
},
|
|
123
|
+
"simulation.complete": {
|
|
124
|
+
"required": [],
|
|
125
|
+
"optional": ["issue", "concerns"]
|
|
126
|
+
},
|
|
127
|
+
"daemon.hard_limit": {
|
|
128
|
+
"required": ["issue"],
|
|
129
|
+
"optional": ["elapsed_s", "limit_s", "pid"]
|
|
130
|
+
},
|
|
131
|
+
"daemon.stalled": {
|
|
132
|
+
"required": ["issue"],
|
|
133
|
+
"optional": ["no_progress", "elapsed_s", "pid"]
|
|
134
|
+
},
|
|
135
|
+
"daemon.nudge": {
|
|
136
|
+
"required": ["issue"],
|
|
137
|
+
"optional": ["no_progress", "stage", "elapsed_s"]
|
|
138
|
+
},
|
|
139
|
+
"daemon.stuck_kill": {
|
|
140
|
+
"required": ["issue"],
|
|
141
|
+
"optional": [
|
|
142
|
+
"no_progress",
|
|
143
|
+
"repeated_errors",
|
|
144
|
+
"stage",
|
|
145
|
+
"elapsed_s",
|
|
146
|
+
"pid",
|
|
147
|
+
"reason"
|
|
148
|
+
]
|
|
149
|
+
},
|
|
150
|
+
"convergence.tests_passed": {
|
|
151
|
+
"required": [],
|
|
152
|
+
"optional": ["issue", "cycle"]
|
|
153
|
+
},
|
|
154
|
+
"vitals.snapshot": {
|
|
155
|
+
"required": [],
|
|
156
|
+
"optional": [
|
|
157
|
+
"issue",
|
|
158
|
+
"stage",
|
|
159
|
+
"iteration",
|
|
160
|
+
"diff_count",
|
|
161
|
+
"files_changed",
|
|
162
|
+
"error"
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
"retry.classified": {
|
|
166
|
+
"required": ["stage"],
|
|
167
|
+
"optional": ["issue", "attempt", "error_class"]
|
|
168
|
+
},
|
|
169
|
+
"retry.escalated": {
|
|
170
|
+
"required": ["stage"],
|
|
171
|
+
"optional": ["issue", "reason"]
|
|
172
|
+
},
|
|
173
|
+
"retry.skipped": {
|
|
174
|
+
"required": ["stage"],
|
|
175
|
+
"optional": ["issue", "reason"]
|
|
176
|
+
},
|
|
177
|
+
"pipeline.anomaly": {
|
|
178
|
+
"required": ["stage"],
|
|
179
|
+
"optional": ["metric", "value", "severity"]
|
|
180
|
+
},
|
|
181
|
+
"pipeline.cost": {
|
|
182
|
+
"required": [],
|
|
183
|
+
"optional": ["issue", "stage", "cost_usd", "model"]
|
|
184
|
+
},
|
|
185
|
+
"pipeline.cleanup": {
|
|
186
|
+
"required": [],
|
|
187
|
+
"optional": ["issue", "reason"]
|
|
188
|
+
},
|
|
189
|
+
"pipeline.comment_failed": {
|
|
190
|
+
"required": [],
|
|
191
|
+
"optional": ["issue"]
|
|
192
|
+
},
|
|
193
|
+
"loop.iteration_start": {
|
|
194
|
+
"required": ["iteration"],
|
|
195
|
+
"optional": ["issue", "goal"]
|
|
196
|
+
},
|
|
197
|
+
"loop.iteration_complete": {
|
|
198
|
+
"required": ["iteration"],
|
|
199
|
+
"optional": ["issue", "test_result", "duration_s"]
|
|
200
|
+
},
|
|
201
|
+
"loop.restart": {
|
|
202
|
+
"required": [],
|
|
203
|
+
"optional": ["issue", "restart_count", "reason"]
|
|
204
|
+
},
|
|
205
|
+
"loop.stuckness_detected": {
|
|
206
|
+
"required": [],
|
|
207
|
+
"optional": ["issue", "iteration", "reason"]
|
|
208
|
+
},
|
|
209
|
+
"stage.skipped": {
|
|
210
|
+
"required": ["stage"],
|
|
211
|
+
"optional": ["issue", "reason"]
|
|
212
|
+
},
|
|
213
|
+
"stage.artifact_miss": {
|
|
214
|
+
"required": ["stage"],
|
|
215
|
+
"optional": ["issue"]
|
|
216
|
+
}
|
|
80
217
|
}
|
|
81
218
|
}
|
package/config/policy.json
CHANGED
|
@@ -222,5 +222,13 @@
|
|
|
222
222
|
"default_model": "sonnet",
|
|
223
223
|
"promote_threshold_tasks": 10,
|
|
224
224
|
"promote_threshold_success_rate": 85
|
|
225
|
+
},
|
|
226
|
+
"decision": {
|
|
227
|
+
"enabled": true,
|
|
228
|
+
"cycle_interval_seconds": 1800,
|
|
229
|
+
"tiers_file": "config/decision-tiers.json",
|
|
230
|
+
"outcome_learning_enabled": true,
|
|
231
|
+
"outcome_min_samples": 10,
|
|
232
|
+
"dedup_window_days": 7
|
|
225
233
|
}
|
|
226
234
|
}
|
|
@@ -516,6 +516,12 @@
|
|
|
516
516
|
id="cost-trend-container"
|
|
517
517
|
></div>
|
|
518
518
|
|
|
519
|
+
<!-- Context efficiency -->
|
|
520
|
+
<div
|
|
521
|
+
class="metric-card metric-card-wide"
|
|
522
|
+
id="context-efficiency-container"
|
|
523
|
+
></div>
|
|
524
|
+
|
|
519
525
|
<!-- DORA trend -->
|
|
520
526
|
<div
|
|
521
527
|
class="metric-card metric-card-wide"
|
|
@@ -3634,6 +3634,82 @@ body::-webkit-scrollbar-thumb {
|
|
|
3634
3634
|
text-align: center;
|
|
3635
3635
|
}
|
|
3636
3636
|
|
|
3637
|
+
/* Context efficiency widget */
|
|
3638
|
+
.ctx-eff-grid {
|
|
3639
|
+
display: grid;
|
|
3640
|
+
grid-template-columns: repeat(4, 1fr);
|
|
3641
|
+
gap: 16px;
|
|
3642
|
+
}
|
|
3643
|
+
|
|
3644
|
+
.ctx-eff-card {
|
|
3645
|
+
background: var(--glass-bg);
|
|
3646
|
+
border: 1px solid var(--glass-border);
|
|
3647
|
+
border-radius: 10px;
|
|
3648
|
+
padding: 12px;
|
|
3649
|
+
display: flex;
|
|
3650
|
+
flex-direction: column;
|
|
3651
|
+
gap: 6px;
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3654
|
+
.ctx-eff-card-label {
|
|
3655
|
+
font-family: var(--font-mono);
|
|
3656
|
+
font-size: 0.65rem;
|
|
3657
|
+
font-weight: 600;
|
|
3658
|
+
letter-spacing: 0.08em;
|
|
3659
|
+
color: var(--text-muted);
|
|
3660
|
+
text-transform: uppercase;
|
|
3661
|
+
}
|
|
3662
|
+
|
|
3663
|
+
.ctx-eff-gauge {
|
|
3664
|
+
height: 8px;
|
|
3665
|
+
border-radius: 4px;
|
|
3666
|
+
background: var(--glass-border);
|
|
3667
|
+
overflow: hidden;
|
|
3668
|
+
}
|
|
3669
|
+
|
|
3670
|
+
.ctx-eff-gauge-fill {
|
|
3671
|
+
height: 100%;
|
|
3672
|
+
border-radius: 4px;
|
|
3673
|
+
transition: width 0.5s ease;
|
|
3674
|
+
}
|
|
3675
|
+
|
|
3676
|
+
.ctx-eff-gauge-fill.ctx-eff-high {
|
|
3677
|
+
background: #4ade80;
|
|
3678
|
+
}
|
|
3679
|
+
|
|
3680
|
+
.ctx-eff-gauge-fill.ctx-eff-mid {
|
|
3681
|
+
background: #00d4ff;
|
|
3682
|
+
}
|
|
3683
|
+
|
|
3684
|
+
.ctx-eff-gauge-fill.ctx-eff-low {
|
|
3685
|
+
background: #f43f5e;
|
|
3686
|
+
}
|
|
3687
|
+
|
|
3688
|
+
.ctx-eff-gauge-fill.ctx-eff-trim {
|
|
3689
|
+
background: #7c3aed;
|
|
3690
|
+
}
|
|
3691
|
+
|
|
3692
|
+
.ctx-eff-value {
|
|
3693
|
+
font-family: var(--font-mono);
|
|
3694
|
+
font-size: 0.85rem;
|
|
3695
|
+
font-weight: 700;
|
|
3696
|
+
color: var(--text-primary);
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3699
|
+
.ctx-eff-big {
|
|
3700
|
+
font-family: var(--font-mono);
|
|
3701
|
+
font-size: 1.4rem;
|
|
3702
|
+
font-weight: 700;
|
|
3703
|
+
color: var(--text-primary);
|
|
3704
|
+
line-height: 1;
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3707
|
+
.ctx-eff-sub {
|
|
3708
|
+
font-family: var(--font-mono);
|
|
3709
|
+
font-size: 0.65rem;
|
|
3710
|
+
color: var(--text-muted);
|
|
3711
|
+
}
|
|
3712
|
+
|
|
3637
3713
|
.dora-trend-grid {
|
|
3638
3714
|
display: grid;
|
|
3639
3715
|
grid-template-columns: repeat(4, 1fr);
|
package/dashboard/server.ts
CHANGED
|
@@ -3690,6 +3690,57 @@ const server = Bun.serve({
|
|
|
3690
3690
|
});
|
|
3691
3691
|
}
|
|
3692
3692
|
|
|
3693
|
+
// REST: Context efficiency metrics (from loop.context_efficiency events)
|
|
3694
|
+
if (pathname === "/api/context-efficiency") {
|
|
3695
|
+
const period = parseInt(url.searchParams.get("period") || "7");
|
|
3696
|
+
const events = readEvents();
|
|
3697
|
+
const now = Math.floor(Date.now() / 1000);
|
|
3698
|
+
const cutoff = now - period * 86400;
|
|
3699
|
+
|
|
3700
|
+
let totalUtil = 0;
|
|
3701
|
+
let totalRatio = 0;
|
|
3702
|
+
let totalRaw = 0;
|
|
3703
|
+
let totalTrimmed = 0;
|
|
3704
|
+
let trimEvents = 0;
|
|
3705
|
+
let count = 0;
|
|
3706
|
+
|
|
3707
|
+
for (const e of events) {
|
|
3708
|
+
if ((e.ts_epoch || 0) < cutoff) continue;
|
|
3709
|
+
if (e.type !== "loop.context_efficiency") continue;
|
|
3710
|
+
|
|
3711
|
+
const util = parseFloat(String(e.budget_utilization || 0));
|
|
3712
|
+
const ratio = parseFloat(String(e.trim_ratio || 0));
|
|
3713
|
+
const raw = parseInt(String(e.raw_prompt_chars || 0), 10);
|
|
3714
|
+
const trimmed = parseInt(String(e.trimmed_prompt_chars || 0), 10);
|
|
3715
|
+
|
|
3716
|
+
totalUtil += util;
|
|
3717
|
+
totalRatio += ratio;
|
|
3718
|
+
totalRaw += raw;
|
|
3719
|
+
totalTrimmed += trimmed;
|
|
3720
|
+
if (ratio > 0) trimEvents++;
|
|
3721
|
+
count++;
|
|
3722
|
+
}
|
|
3723
|
+
|
|
3724
|
+
const avgUtilization =
|
|
3725
|
+
count > 0 ? Math.round((totalUtil / count) * 10) / 10 : 0;
|
|
3726
|
+
const avgTrimRatio =
|
|
3727
|
+
count > 0 ? Math.round((totalRatio / count) * 10) / 10 : 0;
|
|
3728
|
+
const totalDiscarded = totalRaw - totalTrimmed;
|
|
3729
|
+
|
|
3730
|
+
return new Response(
|
|
3731
|
+
JSON.stringify({
|
|
3732
|
+
avg_utilization: avgUtilization,
|
|
3733
|
+
avg_trim_ratio: avgTrimRatio,
|
|
3734
|
+
total_raw_chars: totalRaw,
|
|
3735
|
+
total_trimmed_chars: totalTrimmed,
|
|
3736
|
+
total_discarded_chars: totalDiscarded,
|
|
3737
|
+
trim_events: trimEvents,
|
|
3738
|
+
total_iterations: count,
|
|
3739
|
+
}),
|
|
3740
|
+
{ headers: { "Content-Type": "application/json", ...CORS_HEADERS } },
|
|
3741
|
+
);
|
|
3742
|
+
}
|
|
3743
|
+
|
|
3693
3744
|
// REST: DORA trend (weekly sliding windows)
|
|
3694
3745
|
if (pathname === "/api/metrics/dora-trend") {
|
|
3695
3746
|
const period = parseInt(url.searchParams.get("period") || "30");
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
MachineInfo,
|
|
8
8
|
JoinToken,
|
|
9
9
|
CostBreakdown,
|
|
10
|
+
ContextEfficiency,
|
|
10
11
|
DaemonConfig,
|
|
11
12
|
AlertInfo,
|
|
12
13
|
InsightsData,
|
|
@@ -113,6 +114,10 @@ export const fetchCostTrend = (period = 30) =>
|
|
|
113
114
|
`/api/costs/trend?period=${period}`,
|
|
114
115
|
);
|
|
115
116
|
|
|
117
|
+
// Context efficiency
|
|
118
|
+
export const fetchContextEfficiency = (period = 7) =>
|
|
119
|
+
request<ContextEfficiency>(`/api/context-efficiency?period=${period}`);
|
|
120
|
+
|
|
116
121
|
// Daemon
|
|
117
122
|
export const fetchDaemonConfig = () =>
|
|
118
123
|
request<DaemonConfig>("/api/daemon/config");
|
|
@@ -255,6 +255,16 @@ export interface HeatmapData {
|
|
|
255
255
|
heatmap: Record<string, Record<string, number>>;
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
+
export interface ContextEfficiency {
|
|
259
|
+
avg_utilization: number;
|
|
260
|
+
avg_trim_ratio: number;
|
|
261
|
+
total_raw_chars: number;
|
|
262
|
+
total_trimmed_chars: number;
|
|
263
|
+
total_discarded_chars: number;
|
|
264
|
+
trim_events: number;
|
|
265
|
+
total_iterations: number;
|
|
266
|
+
}
|
|
267
|
+
|
|
258
268
|
export interface DaemonConfig {
|
|
259
269
|
paused?: boolean;
|
|
260
270
|
config?: Record<string, unknown>;
|
|
@@ -82,10 +82,12 @@ function renderMetrics(data: MetricsData): void {
|
|
|
82
82
|
doraContainer.style.display = "none";
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
// Cost breakdown/trend
|
|
85
|
+
// Cost breakdown/trend/context efficiency
|
|
86
86
|
if (document.getElementById("cost-breakdown-container"))
|
|
87
87
|
renderCostBreakdown();
|
|
88
88
|
if (document.getElementById("cost-trend-container")) renderCostTrend();
|
|
89
|
+
if (document.getElementById("context-efficiency-container"))
|
|
90
|
+
renderContextEfficiency();
|
|
89
91
|
if (document.getElementById("dora-trend-container")) renderDoraTrend();
|
|
90
92
|
if (document.getElementById("stage-performance-container"))
|
|
91
93
|
renderStagePerformance();
|
|
@@ -256,6 +258,72 @@ function renderCostTrend(): void {
|
|
|
256
258
|
});
|
|
257
259
|
}
|
|
258
260
|
|
|
261
|
+
function renderContextEfficiency(): void {
|
|
262
|
+
const container = document.getElementById("context-efficiency-container");
|
|
263
|
+
if (!container) return;
|
|
264
|
+
api
|
|
265
|
+
.fetchContextEfficiency()
|
|
266
|
+
.then((data) => {
|
|
267
|
+
if (!data.total_iterations) {
|
|
268
|
+
container.innerHTML =
|
|
269
|
+
'<div class="empty-state"><p>No context efficiency data</p></div>';
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const utilPct = Math.min(data.avg_utilization, 100);
|
|
273
|
+
const utilClass =
|
|
274
|
+
utilPct >= 90
|
|
275
|
+
? "ctx-eff-high"
|
|
276
|
+
: utilPct >= 60
|
|
277
|
+
? "ctx-eff-mid"
|
|
278
|
+
: "ctx-eff-low";
|
|
279
|
+
const trimPct = Math.min(data.avg_trim_ratio, 100);
|
|
280
|
+
|
|
281
|
+
let html =
|
|
282
|
+
'<span class="metric-label">CONTEXT EFFICIENCY</span>' +
|
|
283
|
+
'<div class="ctx-eff-grid">';
|
|
284
|
+
|
|
285
|
+
// Budget utilization gauge
|
|
286
|
+
html +=
|
|
287
|
+
'<div class="ctx-eff-card">' +
|
|
288
|
+
'<span class="ctx-eff-card-label">Budget Utilization</span>' +
|
|
289
|
+
`<div class="ctx-eff-gauge"><div class="ctx-eff-gauge-fill ${utilClass}" style="width:${utilPct.toFixed(0)}%"></div></div>` +
|
|
290
|
+
`<span class="ctx-eff-value">${data.avg_utilization.toFixed(1)}%</span>` +
|
|
291
|
+
"</div>";
|
|
292
|
+
|
|
293
|
+
// Trim ratio
|
|
294
|
+
html +=
|
|
295
|
+
'<div class="ctx-eff-card">' +
|
|
296
|
+
'<span class="ctx-eff-card-label">Avg Trim Ratio</span>' +
|
|
297
|
+
`<div class="ctx-eff-gauge"><div class="ctx-eff-gauge-fill ctx-eff-trim" style="width:${trimPct.toFixed(0)}%"></div></div>` +
|
|
298
|
+
`<span class="ctx-eff-value">${data.avg_trim_ratio.toFixed(1)}%</span>` +
|
|
299
|
+
"</div>";
|
|
300
|
+
|
|
301
|
+
// Chars saved
|
|
302
|
+
const savedK = Math.round(data.total_discarded_chars / 1000);
|
|
303
|
+
const totalK = Math.round(data.total_raw_chars / 1000);
|
|
304
|
+
html +=
|
|
305
|
+
'<div class="ctx-eff-card">' +
|
|
306
|
+
'<span class="ctx-eff-card-label">Chars Discarded</span>' +
|
|
307
|
+
`<span class="ctx-eff-big">${fmtNum(savedK)}K</span>` +
|
|
308
|
+
`<span class="ctx-eff-sub">of ${fmtNum(totalK)}K generated</span>` +
|
|
309
|
+
"</div>";
|
|
310
|
+
|
|
311
|
+
// Trim events
|
|
312
|
+
html +=
|
|
313
|
+
'<div class="ctx-eff-card">' +
|
|
314
|
+
'<span class="ctx-eff-card-label">Trim Events</span>' +
|
|
315
|
+
`<span class="ctx-eff-big">${data.trim_events}</span>` +
|
|
316
|
+
`<span class="ctx-eff-sub">of ${data.total_iterations} iterations</span>` +
|
|
317
|
+
"</div>";
|
|
318
|
+
|
|
319
|
+
html += "</div>";
|
|
320
|
+
container.innerHTML = html;
|
|
321
|
+
})
|
|
322
|
+
.catch((err) => {
|
|
323
|
+
container.innerHTML = `<div class="empty-state"><p>Failed to load: ${escapeHtml(String(err))}</p></div>`;
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
259
327
|
function renderDoraTrend(): void {
|
|
260
328
|
const container = document.getElementById("dora-trend-container");
|
|
261
329
|
if (!container) return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shipwright-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Orchestrate autonomous Claude Code agent teams in tmux",
|
|
5
5
|
"bin": {
|
|
6
6
|
"shipwright": "scripts/sw",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"dashboard:test": "vitest run --config dashboard/vitest.config.ts",
|
|
37
37
|
"dashboard:test:watch": "vitest --config dashboard/vitest.config.ts",
|
|
38
38
|
"dashboard:test:coverage": "vitest run --config dashboard/vitest.config.ts --coverage",
|
|
39
|
-
"test": "bash scripts/sw-agi-roadmap-test.sh && bash scripts/sw-activity-test.sh && bash scripts/sw-adaptive-test.sh && bash scripts/sw-adversarial-test.sh && bash scripts/sw-architecture-enforcer-test.sh && bash scripts/sw-auth-test.sh && bash scripts/sw-autonomous-test.sh && bash scripts/sw-changelog-test.sh && bash scripts/sw-checkpoint-test.sh && bash scripts/sw-ci-test.sh && bash scripts/sw-cleanup-test.sh && bash scripts/sw-code-review-test.sh && bash scripts/sw-connect-test.sh && bash scripts/sw-context-test.sh && bash scripts/sw-cost-test.sh && bash scripts/sw-daemon-test.sh && bash scripts/sw-dashboard-test.sh && bash scripts/sw-db-test.sh && bash scripts/sw-decompose-test.sh && bash scripts/sw-deps-test.sh && bash scripts/sw-developer-simulation-test.sh && bash scripts/sw-discovery-test.sh && bash scripts/sw-doc-fleet-test.sh && bash scripts/sw-docs-agent-test.sh && bash scripts/sw-docs-test.sh && bash scripts/sw-doctor-test.sh && bash scripts/sw-dora-test.sh && bash scripts/sw-durable-test.sh && bash scripts/sw-e2e-orchestrator-test.sh && bash scripts/sw-eventbus-test.sh && bash scripts/sw-feedback-test.sh && bash scripts/sw-fix-test.sh && bash scripts/sw-fleet-discover-test.sh && bash scripts/sw-fleet-test.sh && bash scripts/sw-fleet-viz-test.sh && bash scripts/sw-frontier-test.sh && bash scripts/sw-github-app-test.sh && bash scripts/sw-github-checks-test.sh && bash scripts/sw-github-deploy-test.sh && bash scripts/sw-github-graphql-test.sh && bash scripts/sw-guild-test.sh && bash scripts/sw-heartbeat-test.sh && bash scripts/sw-hygiene-test.sh && bash scripts/sw-incident-test.sh && bash scripts/sw-init-test.sh && bash scripts/sw-instrument-test.sh && bash scripts/sw-intelligence-test.sh && bash scripts/sw-jira-test.sh && bash scripts/sw-launchd-test.sh && bash scripts/sw-linear-test.sh && bash scripts/sw-logs-test.sh && bash scripts/sw-loop-test.sh && bash scripts/sw-memory-test.sh && bash scripts/sw-mission-control-test.sh && bash scripts/sw-model-router-test.sh && bash scripts/sw-otel-test.sh && bash scripts/sw-oversight-test.sh && bash scripts/sw-patrol-meta-test.sh && bash scripts/sw-pipeline-composer-test.sh && bash scripts/sw-pipeline-test.sh && bash scripts/sw-pipeline-vitals-test.sh && bash scripts/sw-pm-test.sh && bash scripts/sw-pr-lifecycle-test.sh && bash scripts/sw-predictive-test.sh && bash scripts/sw-prep-test.sh && bash scripts/sw-ps-test.sh && bash scripts/sw-public-dashboard-test.sh && bash scripts/sw-quality-test.sh && bash scripts/sw-reaper-test.sh && bash scripts/sw-recruit-test.sh && bash scripts/sw-regression-test.sh && bash scripts/sw-release-manager-test.sh && bash scripts/sw-release-test.sh && bash scripts/sw-remote-test.sh && bash scripts/sw-replay-test.sh && bash scripts/sw-retro-test.sh && bash scripts/sw-scale-test.sh && bash scripts/sw-security-audit-test.sh && bash scripts/sw-self-optimize-test.sh && bash scripts/sw-session-test.sh && bash scripts/sw-setup-test.sh && bash scripts/sw-standup-test.sh && bash scripts/sw-status-test.sh && bash scripts/sw-strategic-test.sh && bash scripts/sw-stream-test.sh && bash scripts/sw-swarm-test.sh && bash scripts/sw-team-stages-test.sh && bash scripts/sw-templates-test.sh && bash scripts/sw-testgen-test.sh && bash scripts/sw-tmux-pipeline-test.sh && bash scripts/sw-tmux-test.sh && bash scripts/sw-trace-test.sh && bash scripts/sw-tracker-test.sh && bash scripts/sw-triage-test.sh && bash scripts/sw-upgrade-test.sh && bash scripts/sw-ux-test.sh && bash scripts/sw-webhook-test.sh && bash scripts/sw-widgets-test.sh && bash scripts/sw-worktree-test.sh && bash scripts/sw-policy-e2e-test.sh && bash scripts/sw-e2e-smoke-test.sh && bash scripts/sw-dashboard-e2e-test.sh",
|
|
39
|
+
"test": "bash scripts/sw-agi-roadmap-test.sh && bash scripts/sw-activity-test.sh && bash scripts/sw-adaptive-test.sh && bash scripts/sw-adversarial-test.sh && bash scripts/sw-architecture-enforcer-test.sh && bash scripts/sw-auth-test.sh && bash scripts/sw-autonomous-test.sh && bash scripts/sw-changelog-test.sh && bash scripts/sw-checkpoint-test.sh && bash scripts/sw-ci-test.sh && bash scripts/sw-cleanup-test.sh && bash scripts/sw-code-review-test.sh && bash scripts/sw-connect-test.sh && bash scripts/sw-context-test.sh && bash scripts/sw-cost-test.sh && bash scripts/sw-daemon-test.sh && bash scripts/sw-dashboard-test.sh && bash scripts/sw-db-test.sh && bash scripts/sw-decompose-test.sh && bash scripts/sw-decide-test.sh && bash scripts/sw-deps-test.sh && bash scripts/sw-developer-simulation-test.sh && bash scripts/sw-discovery-test.sh && bash scripts/sw-doc-fleet-test.sh && bash scripts/sw-docs-agent-test.sh && bash scripts/sw-docs-test.sh && bash scripts/sw-doctor-test.sh && bash scripts/sw-dora-test.sh && bash scripts/sw-durable-test.sh && bash scripts/sw-e2e-orchestrator-test.sh && bash scripts/sw-eventbus-test.sh && bash scripts/sw-feedback-test.sh && bash scripts/sw-fix-test.sh && bash scripts/sw-fleet-discover-test.sh && bash scripts/sw-fleet-test.sh && bash scripts/sw-fleet-viz-test.sh && bash scripts/sw-frontier-test.sh && bash scripts/sw-github-app-test.sh && bash scripts/sw-github-checks-test.sh && bash scripts/sw-github-deploy-test.sh && bash scripts/sw-github-graphql-test.sh && bash scripts/sw-guild-test.sh && bash scripts/sw-heartbeat-test.sh && bash scripts/sw-hygiene-test.sh && bash scripts/sw-incident-test.sh && bash scripts/sw-init-test.sh && bash scripts/sw-instrument-test.sh && bash scripts/sw-intelligence-test.sh && bash scripts/sw-jira-test.sh && bash scripts/sw-launchd-test.sh && bash scripts/sw-linear-test.sh && bash scripts/sw-logs-test.sh && bash scripts/sw-loop-test.sh && bash scripts/sw-memory-test.sh && bash scripts/sw-mission-control-test.sh && bash scripts/sw-model-router-test.sh && bash scripts/sw-otel-test.sh && bash scripts/sw-oversight-test.sh && bash scripts/sw-patrol-meta-test.sh && bash scripts/sw-pipeline-composer-test.sh && bash scripts/sw-pipeline-test.sh && bash scripts/sw-pipeline-vitals-test.sh && bash scripts/sw-pm-test.sh && bash scripts/sw-pr-lifecycle-test.sh && bash scripts/sw-predictive-test.sh && bash scripts/sw-prep-test.sh && bash scripts/sw-ps-test.sh && bash scripts/sw-public-dashboard-test.sh && bash scripts/sw-quality-test.sh && bash scripts/sw-reaper-test.sh && bash scripts/sw-recruit-test.sh && bash scripts/sw-regression-test.sh && bash scripts/sw-release-manager-test.sh && bash scripts/sw-release-test.sh && bash scripts/sw-remote-test.sh && bash scripts/sw-replay-test.sh && bash scripts/sw-retro-test.sh && bash scripts/sw-scale-test.sh && bash scripts/sw-security-audit-test.sh && bash scripts/sw-self-optimize-test.sh && bash scripts/sw-session-test.sh && bash scripts/sw-setup-test.sh && bash scripts/sw-standup-test.sh && bash scripts/sw-status-test.sh && bash scripts/sw-strategic-test.sh && bash scripts/sw-stream-test.sh && bash scripts/sw-swarm-test.sh && bash scripts/sw-team-stages-test.sh && bash scripts/sw-templates-test.sh && bash scripts/sw-testgen-test.sh && bash scripts/sw-tmux-pipeline-test.sh && bash scripts/sw-tmux-test.sh && bash scripts/sw-trace-test.sh && bash scripts/sw-tracker-test.sh && bash scripts/sw-triage-test.sh && bash scripts/sw-upgrade-test.sh && bash scripts/sw-ux-test.sh && bash scripts/sw-webhook-test.sh && bash scripts/sw-widgets-test.sh && bash scripts/sw-worktree-test.sh && bash scripts/sw-lib-compat-test.sh && bash scripts/sw-lib-helpers-test.sh && bash scripts/sw-lib-daemon-dispatch-test.sh && bash scripts/sw-lib-daemon-failure-test.sh && bash scripts/sw-lib-daemon-poll-test.sh && bash scripts/sw-lib-daemon-state-test.sh && bash scripts/sw-lib-daemon-triage-test.sh && bash scripts/sw-lib-pipeline-detection-test.sh && bash scripts/sw-lib-pipeline-intelligence-test.sh && bash scripts/sw-lib-pipeline-quality-checks-test.sh && bash scripts/sw-lib-pipeline-stages-test.sh && bash scripts/sw-lib-pipeline-state-test.sh && bash scripts/sw-adapters-test.sh && bash scripts/sw-evidence-test.sh && bash scripts/sw-review-rerun-test.sh && bash scripts/sw-tracker-providers-test.sh && bash scripts/sw-budget-chaos-test.sh && bash scripts/sw-autonomous-e2e-test.sh && bash scripts/sw-memory-discovery-e2e-test.sh && bash scripts/sw-policy-e2e-test.sh && bash scripts/sw-e2e-smoke-test.sh && bash scripts/sw-dashboard-e2e-test.sh",
|
|
40
40
|
"test:smoke": "bash scripts/sw-e2e-smoke-test.sh",
|
|
41
|
-
"test:integration": "bash scripts/sw-e2e-integration-test.sh",
|
|
41
|
+
"test:integration": "bash scripts/sw-e2e-integration-test.sh && bash scripts/sw-e2e-system-test.sh && bash scripts/sw-server-api-test.sh && bash scripts/sw-integration-claude-test.sh",
|
|
42
42
|
"harness:evidence:capture": "bash scripts/sw-evidence.sh capture",
|
|
43
43
|
"harness:evidence:verify": "bash scripts/sw-evidence.sh verify",
|
|
44
44
|
"harness:evidence:pre-pr": "bash scripts/sw-evidence.sh pre-pr",
|
|
@@ -45,7 +45,8 @@ $(find "$repo_root" -type f \( -name '*.ts' -o -name '*.js' -o -name '*.py' -o -
|
|
|
45
45
|
while IFS= read -r f; do
|
|
46
46
|
[[ -f "$f" ]] || continue
|
|
47
47
|
local exports=0
|
|
48
|
-
exports=$(grep -c "^export " "$f" 2>/dev/null ||
|
|
48
|
+
exports=$(grep -c "^export " "$f" 2>/dev/null || true)
|
|
49
|
+
exports="${exports:-0}"
|
|
49
50
|
[[ "$exports" -gt 2 ]] 2>/dev/null && context="${context} $(basename "$f"): $exports exports
|
|
50
51
|
"
|
|
51
52
|
done < <(find "$repo_root/src" "$repo_root/lib" -name "*.ts" -o -name "*.js" 2>/dev/null | head -30)
|
package/scripts/lib/bootstrap.sh
CHANGED
|
File without changes
|
package/scripts/lib/config.sh
CHANGED
|
File without changes
|
|
@@ -223,10 +223,12 @@ daemon_collect_snapshot() {
|
|
|
223
223
|
if [[ -d "$worktree/.git" ]] || [[ -f "$worktree/.git" ]]; then
|
|
224
224
|
diff_lines=$(cd "$worktree" && git diff --stat 2>/dev/null | tail -1 | grep -o '[0-9]* insertion' | grep -o '[0-9]*' || echo "0")
|
|
225
225
|
[[ -z "$diff_lines" ]] && diff_lines=0
|
|
226
|
-
files_changed=$(cd "$worktree" && git diff --name-only 2>/dev/null | wc -l | tr -d ' ' ||
|
|
226
|
+
files_changed=$(cd "$worktree" && git diff --name-only 2>/dev/null | wc -l | tr -d ' ' || true)
|
|
227
|
+
files_changed="${files_changed:-0}"
|
|
227
228
|
# Also count untracked files the agent has created
|
|
228
229
|
local untracked
|
|
229
|
-
untracked=$(cd "$worktree" && git ls-files --others --exclude-standard 2>/dev/null | wc -l | tr -d ' ' ||
|
|
230
|
+
untracked=$(cd "$worktree" && git ls-files --others --exclude-standard 2>/dev/null | wc -l | tr -d ' ' || true)
|
|
231
|
+
untracked="${untracked:-0}"
|
|
230
232
|
files_changed=$((files_changed + untracked))
|
|
231
233
|
fi
|
|
232
234
|
|