@shepai/cli 1.136.0-pr417.01aebe9 → 1.136.0-pr438.9e52ee5
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/apis/json-schema/DoctorDiagnosticReport.yaml +30 -0
- package/apis/json-schema/FailedRunSummary.yaml +22 -0
- package/apis/json-schema/SystemInfo.yaml +22 -0
- package/apis/json-schema/WorkflowConfig.yaml +5 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +28 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/github-issue-service.interface.d.ts +57 -0
- package/dist/packages/core/src/application/ports/output/services/github-issue-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/github-issue-service.interface.js +39 -0
- package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.d.ts +37 -0
- package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.js +12 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts +5 -3
- package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/index.js +2 -1
- package/dist/packages/core/src/application/use-cases/doctor/doctor-diagnose.use-case.d.ts +56 -0
- package/dist/packages/core/src/application/use-cases/doctor/doctor-diagnose.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/doctor/doctor-diagnose.use-case.js +294 -0
- package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts +3 -8
- package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.js +8 -66
- package/dist/packages/core/src/domain/generated/output.d.ts +75 -0
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +4 -0
- package/dist/packages/core/src/infrastructure/services/external/github-issue-creator.service.d.ts +17 -0
- package/dist/packages/core/src/infrastructure/services/external/github-issue-creator.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/external/github-issue-creator.service.js +69 -0
- package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts +3 -1
- package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/external/github-repository.service.js +37 -1
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +2 -1
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +21 -0
- package/dist/src/presentation/cli/commands/doctor.command.d.ts +20 -0
- package/dist/src/presentation/cli/commands/doctor.command.d.ts.map +1 -0
- package/dist/src/presentation/cli/commands/doctor.command.js +129 -0
- package/dist/src/presentation/cli/index.js +2 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +25 -25
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +25 -25
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +31 -31
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +31 -31
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +23 -23
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +25 -25
- package/web/.next/server/app/(dashboard)/create/page.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +31 -31
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +31 -31
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +23 -23
- package/web/.next/server/app/(dashboard)/page.js +1 -1
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +23 -23
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +3 -3
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__c6e32a23._.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_b49d9c97.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_b49d9c97.js.map +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_28632197.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_28632197.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_10695d37.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_10695d37.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__47ded061._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__47ded061._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__68ce373c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__68ce373c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6ec59045._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__718766da._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__718766da._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a5f9c6e5._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a5f9c6e5._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdd058b2._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdd058b2._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_02ec1aea._.js +1 -1
- package/web/.next/server/chunks/ssr/_02ec1aea._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_036a2f1a._.js → _4dfa8bc3._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_036a2f1a._.js.map → _4dfa8bc3._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_7216273e._.js → _501af15d._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_7216273e._.js.map → _501af15d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_75d1e2c9._.js +4 -0
- package/web/.next/server/chunks/ssr/_75d1e2c9._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
- package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_d4b20e29._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
- package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_53666118._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_53666118._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{src_presentation_web_cc376559._.js → src_presentation_web_5c40524e._.js} +2 -2
- package/web/.next/server/chunks/ssr/{src_presentation_web_cc376559._.js.map → src_presentation_web_5c40524e._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_d95e128d.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_d95e128d.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e4df6dd7._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_e4df6dd7._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +39 -39
- package/web/.next/static/chunks/{419a8d8457d5c8e8.js → 10d405c1707bb323.js} +1 -1
- package/web/.next/static/chunks/{54c901337941d745.js → 29cefe3a2fa5573c.js} +1 -1
- package/web/.next/static/chunks/{6cbecb92bd68e7c8.js → 3de3ea3b101bf406.js} +1 -1
- package/web/.next/static/chunks/499c19f1bac689cf.js +1 -0
- package/web/.next/static/chunks/{76ef5cf3b4f4ef6b.js → 5074c99e4cbb0b4c.js} +1 -1
- package/web/.next/static/chunks/{33119fe287968581.js → 546a7dc733f92913.js} +1 -1
- package/web/.next/static/chunks/{666dabc5a947187d.js → 5a7a5794e1ece049.js} +1 -1
- package/web/.next/static/chunks/{bdc2d28b3db1cadf.js → a18c3f33018082cb.js} +1 -1
- package/web/.next/static/chunks/{32674ed600fd2d02.js → bb15bf7fcedc3a8d.js} +1 -1
- package/web/.next/static/chunks/{5cf49c75127f5c06.js → d03d87ed71050c43.js} +1 -1
- package/web/.next/static/chunks/{01e0452d72421732.js → f86e433dbea0ca20.js} +1 -1
- package/web/.next/static/chunks/{8586bee9919f310e.js → fee7ef7b7b194025.js} +2 -2
- package/web/.next/server/chunks/ssr/_e69a26ba._.js +0 -4
- package/web/.next/server/chunks/ssr/_e69a26ba._.js.map +0 -1
- package/web/.next/static/chunks/da46061d83a9de54.js +0 -1
- /package/web/.next/static/{cTPv5o2etR55f5kz8U-6Q → u2GE3dKD5GVgXCtUA64to}/_buildManifest.js +0 -0
- /package/web/.next/static/{cTPv5o2etR55f5kz8U-6Q → u2GE3dKD5GVgXCtUA64to}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{cTPv5o2etR55f5kz8U-6Q → u2GE3dKD5GVgXCtUA64to}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doctor Diagnose Use Case
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the shep doctor workflow:
|
|
5
|
+
* 1. Collect diagnostic context (failed agent runs, version, system info)
|
|
6
|
+
* 2. Create a structured GitHub issue on shep-ai/cli
|
|
7
|
+
* 3. Optionally attempt a fix via AI agent
|
|
8
|
+
* 4. Open a PR with the fix (direct push for maintainers, fork for contributors)
|
|
9
|
+
*
|
|
10
|
+
* Following Clean Architecture: all external operations are injected via interfaces.
|
|
11
|
+
*/
|
|
12
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
13
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
14
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
15
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
16
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
17
|
+
};
|
|
18
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
19
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
20
|
+
};
|
|
21
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
22
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
23
|
+
};
|
|
24
|
+
import { injectable, inject } from 'tsyringe';
|
|
25
|
+
import { randomUUID } from 'node:crypto';
|
|
26
|
+
import { tmpdir } from 'node:os';
|
|
27
|
+
import { mkdir, rm } from 'node:fs/promises';
|
|
28
|
+
import path from 'node:path';
|
|
29
|
+
import { AgentRunStatus } from '../../../domain/generated/output.js';
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Constants
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
const SHEP_REPO = 'shep-ai/cli';
|
|
34
|
+
const MAX_FAILED_RUNS = 10;
|
|
35
|
+
const ISSUE_LABELS = ['bug', 'shep-doctor'];
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Use Case
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
let DoctorDiagnoseUseCase = class DoctorDiagnoseUseCase {
|
|
40
|
+
agentRunRepo;
|
|
41
|
+
versionService;
|
|
42
|
+
issueService;
|
|
43
|
+
repoService;
|
|
44
|
+
prService;
|
|
45
|
+
agentExecutorProvider;
|
|
46
|
+
execFile;
|
|
47
|
+
featureRepo;
|
|
48
|
+
constructor(agentRunRepo, versionService, issueService, repoService, prService, agentExecutorProvider, execFile, featureRepo) {
|
|
49
|
+
this.agentRunRepo = agentRunRepo;
|
|
50
|
+
this.versionService = versionService;
|
|
51
|
+
this.issueService = issueService;
|
|
52
|
+
this.repoService = repoService;
|
|
53
|
+
this.prService = prService;
|
|
54
|
+
this.agentExecutorProvider = agentExecutorProvider;
|
|
55
|
+
this.execFile = execFile;
|
|
56
|
+
this.featureRepo = featureRepo;
|
|
57
|
+
}
|
|
58
|
+
async execute(input) {
|
|
59
|
+
// Step 1: Collect diagnostics
|
|
60
|
+
const diagnosticReport = await this.collectDiagnostics(input.description, input.featureId);
|
|
61
|
+
// Step 2: Create GitHub issue
|
|
62
|
+
const issueTitle = this.formatIssueTitle(input.description);
|
|
63
|
+
const issueBody = this.formatIssueBody(diagnosticReport);
|
|
64
|
+
const { url: issueUrl, number: issueNumber } = await this.issueService.createIssue(SHEP_REPO, issueTitle, issueBody, ISSUE_LABELS);
|
|
65
|
+
// Step 3: If no fix requested, return early
|
|
66
|
+
if (!input.fix) {
|
|
67
|
+
return {
|
|
68
|
+
diagnosticReport,
|
|
69
|
+
issueUrl,
|
|
70
|
+
issueNumber,
|
|
71
|
+
cleanedUp: false,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// Step 4: Attempt fix
|
|
75
|
+
return this.attemptFix(input, diagnosticReport, issueUrl, issueNumber);
|
|
76
|
+
}
|
|
77
|
+
// -------------------------------------------------------------------------
|
|
78
|
+
// Diagnostic Collection (Task 10)
|
|
79
|
+
// -------------------------------------------------------------------------
|
|
80
|
+
async collectDiagnostics(userDescription, featureId) {
|
|
81
|
+
// Resolve feature context if featureId is provided
|
|
82
|
+
let resolvedFeatureId;
|
|
83
|
+
let featureName;
|
|
84
|
+
if (featureId) {
|
|
85
|
+
const feature = (await this.featureRepo.findById(featureId)) ??
|
|
86
|
+
(await this.featureRepo.findByIdPrefix(featureId));
|
|
87
|
+
if (feature) {
|
|
88
|
+
resolvedFeatureId = feature.id;
|
|
89
|
+
featureName = feature.name;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const [failedRunSummaries, systemInfo, cliVersion] = await Promise.all([
|
|
93
|
+
this.collectFailedRuns(resolvedFeatureId),
|
|
94
|
+
this.collectSystemInfo(),
|
|
95
|
+
Promise.resolve(this.versionService.getVersion().version),
|
|
96
|
+
]);
|
|
97
|
+
return {
|
|
98
|
+
userDescription,
|
|
99
|
+
failedRunSummaries,
|
|
100
|
+
systemInfo,
|
|
101
|
+
cliVersion,
|
|
102
|
+
featureId: resolvedFeatureId,
|
|
103
|
+
featureName,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async collectFailedRuns(featureId) {
|
|
107
|
+
const allRuns = await this.agentRunRepo.list();
|
|
108
|
+
let filtered = allRuns.filter((run) => run.status === AgentRunStatus.failed);
|
|
109
|
+
// When a feature ID is provided, scope to runs associated with that feature
|
|
110
|
+
if (featureId) {
|
|
111
|
+
filtered = filtered.filter((run) => run.featureId === featureId);
|
|
112
|
+
}
|
|
113
|
+
return filtered.slice(0, MAX_FAILED_RUNS).map((run) => this.sanitizeRunSummary(run));
|
|
114
|
+
}
|
|
115
|
+
sanitizeRunSummary(run) {
|
|
116
|
+
return {
|
|
117
|
+
agentType: run.agentType,
|
|
118
|
+
agentName: run.agentName,
|
|
119
|
+
error: run.error ?? 'Unknown error',
|
|
120
|
+
timestamp: run.createdAt instanceof Date ? run.createdAt.toISOString() : String(run.createdAt),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async collectSystemInfo() {
|
|
124
|
+
let ghVersion = 'unknown';
|
|
125
|
+
try {
|
|
126
|
+
const { stdout } = await this.execFile('gh', ['--version']);
|
|
127
|
+
ghVersion = stdout.trim();
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// gh not installed or not available — use fallback
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
nodeVersion: process.version,
|
|
134
|
+
platform: process.platform,
|
|
135
|
+
arch: process.arch,
|
|
136
|
+
ghVersion,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// -------------------------------------------------------------------------
|
|
140
|
+
// Issue Formatting (Task 11)
|
|
141
|
+
// -------------------------------------------------------------------------
|
|
142
|
+
formatIssueTitle(description) {
|
|
143
|
+
const firstLine = description.split('\n')[0].trim();
|
|
144
|
+
const truncated = firstLine.length > 60 ? `${firstLine.slice(0, 60)}...` : firstLine;
|
|
145
|
+
return `[shep doctor] ${truncated}`;
|
|
146
|
+
}
|
|
147
|
+
formatIssueBody(report) {
|
|
148
|
+
const sections = [];
|
|
149
|
+
sections.push('## Problem Description\n');
|
|
150
|
+
sections.push(report.userDescription);
|
|
151
|
+
if (report.featureId) {
|
|
152
|
+
sections.push('\n## Feature Context\n');
|
|
153
|
+
sections.push(`- **Feature ID:** ${report.featureId}`);
|
|
154
|
+
if (report.featureName) {
|
|
155
|
+
sections.push(`- **Feature Name:** ${report.featureName}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
sections.push('\n## Environment\n');
|
|
159
|
+
sections.push(`- **shep CLI version:** ${report.cliVersion}`);
|
|
160
|
+
sections.push(`- **Node.js:** ${report.systemInfo.nodeVersion}`);
|
|
161
|
+
sections.push(`- **Platform:** ${report.systemInfo.platform} (${report.systemInfo.arch})`);
|
|
162
|
+
sections.push(`- **gh CLI:** ${report.systemInfo.ghVersion}`);
|
|
163
|
+
if (report.failedRunSummaries.length > 0) {
|
|
164
|
+
const heading = report.featureId
|
|
165
|
+
? '\n## Failed Agent Runs (feature-scoped)\n'
|
|
166
|
+
: '\n## Recent Failed Agent Runs\n';
|
|
167
|
+
sections.push(heading);
|
|
168
|
+
for (const run of report.failedRunSummaries) {
|
|
169
|
+
sections.push(`### ${run.agentName} (${run.agentType})`);
|
|
170
|
+
sections.push(`- **Error:** ${run.error}`);
|
|
171
|
+
sections.push(`- **Timestamp:** ${run.timestamp}`);
|
|
172
|
+
sections.push('');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
sections.push('\n---\n');
|
|
176
|
+
sections.push('_Reported via `shep doctor`_');
|
|
177
|
+
return sections.join('\n');
|
|
178
|
+
}
|
|
179
|
+
// -------------------------------------------------------------------------
|
|
180
|
+
// Fix Workflow (Task 11)
|
|
181
|
+
// -------------------------------------------------------------------------
|
|
182
|
+
async attemptFix(input, diagnosticReport, issueUrl, issueNumber) {
|
|
183
|
+
const isUserWorkdir = !!input.workdir;
|
|
184
|
+
const workdir = input.workdir ?? path.join(tmpdir(), `shep-doctor-${randomUUID()}`);
|
|
185
|
+
// Use a mutable result object so finally block can update cleanedUp
|
|
186
|
+
const result = {
|
|
187
|
+
diagnosticReport,
|
|
188
|
+
issueUrl,
|
|
189
|
+
issueNumber,
|
|
190
|
+
cleanedUp: false,
|
|
191
|
+
};
|
|
192
|
+
try {
|
|
193
|
+
// Ensure working directory exists
|
|
194
|
+
await mkdir(workdir, { recursive: true });
|
|
195
|
+
// Check push access (fall back to contributor flow on error)
|
|
196
|
+
let hasPushAccess = false;
|
|
197
|
+
try {
|
|
198
|
+
hasPushAccess = await this.repoService.checkPushAccess(SHEP_REPO);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// NFR-9: fall back to fork path on any detection failure
|
|
202
|
+
}
|
|
203
|
+
const flowType = hasPushAccess ? 'maintainer' : 'contributor';
|
|
204
|
+
result.flowType = flowType;
|
|
205
|
+
// Clone repository (direct or via fork)
|
|
206
|
+
let repoToClone = SHEP_REPO;
|
|
207
|
+
if (flowType === 'contributor') {
|
|
208
|
+
const { nameWithOwner } = await this.repoService.forkRepository(SHEP_REPO);
|
|
209
|
+
repoToClone = nameWithOwner;
|
|
210
|
+
}
|
|
211
|
+
await this.repoService.cloneRepository(repoToClone, workdir, undefined);
|
|
212
|
+
// Create fix branch
|
|
213
|
+
const branchName = `doctor/fix-${issueNumber}`;
|
|
214
|
+
await this.execFile('git', ['checkout', '-b', branchName], {
|
|
215
|
+
cwd: workdir,
|
|
216
|
+
});
|
|
217
|
+
// Invoke AI agent
|
|
218
|
+
try {
|
|
219
|
+
const executor = await this.agentExecutorProvider.getExecutor();
|
|
220
|
+
const prompt = this.buildFixPrompt(diagnosticReport, issueNumber);
|
|
221
|
+
await executor.execute(prompt, { cwd: workdir });
|
|
222
|
+
}
|
|
223
|
+
catch (agentError) {
|
|
224
|
+
result.error = `Fix attempt failed: ${agentError.message}`;
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
// Check if agent produced changes
|
|
228
|
+
const hasChanges = await this.prService.hasUncommittedChanges(workdir);
|
|
229
|
+
if (!hasChanges) {
|
|
230
|
+
result.error = 'Fix attempt produced no changes';
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
// Commit, push, and create PR
|
|
234
|
+
await this.prService.commitAll(workdir, `fix: address issue #${issueNumber} reported via shep doctor`);
|
|
235
|
+
await this.prService.push(workdir, branchName, true);
|
|
236
|
+
const prResult = await this.prService.createPrFromArgs(workdir, {
|
|
237
|
+
title: `fix: address shep doctor issue #${issueNumber}`,
|
|
238
|
+
body: `## Summary\n\nAutomated fix attempt for #${issueNumber}.\n\nThis PR was created by \`shep doctor\` after diagnosing a reported issue.\n\nRelates to #${issueNumber}`,
|
|
239
|
+
labels: ['shep-doctor'],
|
|
240
|
+
base: 'main',
|
|
241
|
+
repo: flowType === 'contributor' ? SHEP_REPO : undefined,
|
|
242
|
+
});
|
|
243
|
+
result.prUrl = prResult.url;
|
|
244
|
+
return result;
|
|
245
|
+
}
|
|
246
|
+
finally {
|
|
247
|
+
// Cleanup temp directory (unless user specified --workdir)
|
|
248
|
+
if (!isUserWorkdir) {
|
|
249
|
+
try {
|
|
250
|
+
await rm(workdir, { recursive: true, force: true });
|
|
251
|
+
result.cleanedUp = true;
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
// Best-effort cleanup
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
buildFixPrompt(report, issueNumber) {
|
|
260
|
+
const lines = [];
|
|
261
|
+
lines.push(`You are fixing issue #${issueNumber} in the shep-ai/cli codebase.`);
|
|
262
|
+
lines.push('');
|
|
263
|
+
lines.push('## Problem Description');
|
|
264
|
+
lines.push(report.userDescription);
|
|
265
|
+
lines.push('');
|
|
266
|
+
if (report.failedRunSummaries.length > 0) {
|
|
267
|
+
lines.push('## Error Context');
|
|
268
|
+
for (const run of report.failedRunSummaries) {
|
|
269
|
+
lines.push(`- Agent: ${run.agentName} (${run.agentType})`);
|
|
270
|
+
lines.push(` Error: ${run.error}`);
|
|
271
|
+
}
|
|
272
|
+
lines.push('');
|
|
273
|
+
}
|
|
274
|
+
lines.push('## Instructions');
|
|
275
|
+
lines.push('1. Analyze the codebase to identify the root cause');
|
|
276
|
+
lines.push('2. Implement a fix for the identified issue');
|
|
277
|
+
lines.push('3. Run tests to verify the fix works');
|
|
278
|
+
lines.push('4. Keep changes minimal and focused');
|
|
279
|
+
return lines.join('\n');
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
DoctorDiagnoseUseCase = __decorate([
|
|
283
|
+
injectable(),
|
|
284
|
+
__param(0, inject('IAgentRunRepository')),
|
|
285
|
+
__param(1, inject('IVersionService')),
|
|
286
|
+
__param(2, inject('IGitHubIssueService')),
|
|
287
|
+
__param(3, inject('IGitHubRepositoryService')),
|
|
288
|
+
__param(4, inject('IGitPrService')),
|
|
289
|
+
__param(5, inject('IAgentExecutorProvider')),
|
|
290
|
+
__param(6, inject('ExecFunction')),
|
|
291
|
+
__param(7, inject('IFeatureRepository')),
|
|
292
|
+
__metadata("design:paramtypes", [Object, Object, Object, Object, Object, Object, Function, Object])
|
|
293
|
+
], DoctorDiagnoseUseCase);
|
|
294
|
+
export { DoctorDiagnoseUseCase };
|
|
@@ -6,17 +6,14 @@
|
|
|
6
6
|
* and persists a Feature entity. Branches with an open PR get lifecycle=Review
|
|
7
7
|
* (shown as "REVIEW" in the UI); all others get lifecycle=Maintain (completed).
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* support agent execution (start, resume, reject) just like created features.
|
|
9
|
+
* This is a standalone use case — it does NOT extend or modify CreateFeatureUseCase.
|
|
10
|
+
* It needs only three dependencies: IFeatureRepository, IRepositoryRepository, and IWorktreeService.
|
|
12
11
|
*/
|
|
13
12
|
import type { Feature } from '../../../domain/generated/output.js';
|
|
14
13
|
import type { IFeatureRepository } from '../../ports/output/repositories/feature-repository.interface.js';
|
|
15
14
|
import type { IRepositoryRepository } from '../../ports/output/repositories/repository-repository.interface.js';
|
|
16
15
|
import type { IWorktreeService } from '../../ports/output/services/worktree-service.interface.js';
|
|
17
16
|
import type { IGitPrService } from '../../ports/output/services/git-pr-service.interface.js';
|
|
18
|
-
import type { IAgentRunRepository } from '../../ports/output/agents/agent-run-repository.interface.js';
|
|
19
|
-
import type { ISpecInitializerService } from '../../ports/output/services/spec-initializer.interface.js';
|
|
20
17
|
export interface AdoptBranchInput {
|
|
21
18
|
branchName: string;
|
|
22
19
|
repositoryPath: string;
|
|
@@ -29,9 +26,7 @@ export declare class AdoptBranchUseCase {
|
|
|
29
26
|
private readonly repositoryRepo;
|
|
30
27
|
private readonly worktreeService;
|
|
31
28
|
private readonly gitPrService;
|
|
32
|
-
|
|
33
|
-
private readonly specInitializer;
|
|
34
|
-
constructor(featureRepo: IFeatureRepository, repositoryRepo: IRepositoryRepository, worktreeService: IWorktreeService, gitPrService: IGitPrService, agentRunRepo: IAgentRunRepository, specInitializer: ISpecInitializerService);
|
|
29
|
+
constructor(featureRepo: IFeatureRepository, repositoryRepo: IRepositoryRepository, worktreeService: IWorktreeService, gitPrService: IGitPrService);
|
|
35
30
|
execute(input: AdoptBranchInput): Promise<AdoptBranchResult>;
|
|
36
31
|
/**
|
|
37
32
|
* Resolve the git ref to use for worktree creation.
|
package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adopt-branch.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/adopt-branch.use-case.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"adopt-branch.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/adopt-branch.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,qCAAqC,CAAC;AAEhF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oEAAoE,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAG7F,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;CAClB;AAKD,qBACa,kBAAkB;IAG3B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAEhC,OAAO,CAAC,QAAQ,CAAC,YAAY;gBANZ,WAAW,EAAE,kBAAkB,EAE/B,cAAc,EAAE,qBAAqB,EAErC,eAAe,EAAE,gBAAgB,EAEjC,YAAY,EAAE,aAAa;IAGxC,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAyFlE;;;;OAIG;YACW,gBAAgB;IAiB9B;;;;OAIG;YACW,iBAAiB;IA4B/B;;;OAGG;YACW,iBAAiB;CAuBhC"}
|
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
* and persists a Feature entity. Branches with an open PR get lifecycle=Review
|
|
7
7
|
* (shown as "REVIEW" in the UI); all others get lifecycle=Maintain (completed).
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* support agent execution (start, resume, reject) just like created features.
|
|
9
|
+
* This is a standalone use case — it does NOT extend or modify CreateFeatureUseCase.
|
|
10
|
+
* It needs only three dependencies: IFeatureRepository, IRepositoryRepository, and IWorktreeService.
|
|
12
11
|
*/
|
|
13
12
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
14
13
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -24,11 +23,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
24
23
|
};
|
|
25
24
|
import { injectable, inject } from 'tsyringe';
|
|
26
25
|
import { randomUUID } from 'node:crypto';
|
|
27
|
-
|
|
28
|
-
import { existsSync } from 'node:fs';
|
|
29
|
-
import { join } from 'node:path';
|
|
30
|
-
import { SdlcLifecycle, PrStatus, AgentRunStatus } from '../../../domain/generated/output.js';
|
|
31
|
-
import { getSettings } from '../../../infrastructure/services/settings.service.js';
|
|
26
|
+
import { SdlcLifecycle, PrStatus } from '../../../domain/generated/output.js';
|
|
32
27
|
import { deriveName, deriveSlug } from './branch-name-utils.js';
|
|
33
28
|
/** Branches that must not be adopted as features. */
|
|
34
29
|
const PROTECTED_BRANCHES = new Set(['main', 'master']);
|
|
@@ -37,15 +32,11 @@ let AdoptBranchUseCase = class AdoptBranchUseCase {
|
|
|
37
32
|
repositoryRepo;
|
|
38
33
|
worktreeService;
|
|
39
34
|
gitPrService;
|
|
40
|
-
|
|
41
|
-
specInitializer;
|
|
42
|
-
constructor(featureRepo, repositoryRepo, worktreeService, gitPrService, agentRunRepo, specInitializer) {
|
|
35
|
+
constructor(featureRepo, repositoryRepo, worktreeService, gitPrService) {
|
|
43
36
|
this.featureRepo = featureRepo;
|
|
44
37
|
this.repositoryRepo = repositoryRepo;
|
|
45
38
|
this.worktreeService = worktreeService;
|
|
46
39
|
this.gitPrService = gitPrService;
|
|
47
|
-
this.agentRunRepo = agentRunRepo;
|
|
48
|
-
this.specInitializer = specInitializer;
|
|
49
40
|
}
|
|
50
41
|
async execute(input) {
|
|
51
42
|
const { branchName, repositoryPath } = input;
|
|
@@ -70,65 +61,25 @@ let AdoptBranchUseCase = class AdoptBranchUseCase {
|
|
|
70
61
|
const branchRef = await this.resolveBranchRef(branchName, repositoryPath);
|
|
71
62
|
// --- Resolve or create repository entity ---
|
|
72
63
|
const repository = await this.resolveRepository(repositoryPath);
|
|
73
|
-
// --- Calculate feature number for spec directory ---
|
|
74
|
-
// Use existing feature count as hint; SpecInitializerService.resolveNextNumber()
|
|
75
|
-
// will scan filesystem to determine actual next available number
|
|
76
|
-
const effectiveRepoPath = repository.path;
|
|
77
|
-
const existingFeatures = await this.featureRepo.list({
|
|
78
|
-
repositoryPath: effectiveRepoPath,
|
|
79
|
-
});
|
|
80
|
-
const featureNumber = existingFeatures.length;
|
|
81
64
|
// --- Create or reuse worktree ---
|
|
82
65
|
const worktreePath = this.worktreeService.getWorktreePath(repositoryPath, slug);
|
|
83
66
|
const worktreeExists = await this.worktreeService.exists(repositoryPath, branchName);
|
|
84
67
|
if (!worktreeExists) {
|
|
85
68
|
await this.worktreeService.addExisting(repositoryPath, branchRef, worktreePath);
|
|
86
69
|
}
|
|
87
|
-
// --- Initialize or detect spec directory ---
|
|
88
|
-
// Check if spec directory already exists (e.g., from previous /shep-kit:new-feature work)
|
|
89
|
-
// If exists, preserve it. If not, initialize with empty YAMLs.
|
|
90
|
-
const nnn = String(featureNumber).padStart(3, '0');
|
|
91
|
-
const expectedSpecDir = join(worktreePath, 'specs', `${nnn}-${slug}`);
|
|
92
|
-
let specDir;
|
|
93
|
-
if (existsSync(expectedSpecDir)) {
|
|
94
|
-
// Spec directory already exists — use it without modification
|
|
95
|
-
specDir = expectedSpecDir;
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
// No spec directory — initialize with empty YAMLs
|
|
99
|
-
const result = await this.specInitializer.initialize(worktreePath, slug, featureNumber, '(adopted from existing branch)');
|
|
100
|
-
specDir = result.specDir;
|
|
101
|
-
}
|
|
102
|
-
// --- Create AgentRun record (following CreateFeatureUseCase pattern lines 156-210) ---
|
|
103
|
-
const runId = randomUUID();
|
|
104
|
-
const settings = getSettings();
|
|
105
|
-
const now = new Date();
|
|
106
|
-
const agentRun = {
|
|
107
|
-
id: runId,
|
|
108
|
-
agentType: settings.agent.type,
|
|
109
|
-
agentName: 'feature-agent',
|
|
110
|
-
status: AgentRunStatus.pending,
|
|
111
|
-
prompt: '(adopted from existing branch)',
|
|
112
|
-
threadId: randomUUID(), // New UUID for LangGraph checkpoint isolation
|
|
113
|
-
featureId: '', // Will be set after Feature creation, but we need runId first
|
|
114
|
-
repositoryPath: effectiveRepoPath,
|
|
115
|
-
...(settings.models?.default ? { modelId: settings.models.default } : {}),
|
|
116
|
-
createdAt: now.toISOString(),
|
|
117
|
-
updatedAt: now.toISOString(),
|
|
118
|
-
};
|
|
119
70
|
// --- Detect open PR for this branch ---
|
|
120
71
|
const prData = await this.detectPrForBranch(branchName, repositoryPath);
|
|
121
72
|
// --- Derive feature metadata ---
|
|
122
73
|
const name = deriveName(branchName);
|
|
74
|
+
const now = new Date();
|
|
123
75
|
const hasOpenPr = prData !== undefined;
|
|
124
76
|
// If the branch has an open (not yet merged) PR, place the feature in
|
|
125
77
|
// Review so the node shows "REVIEW" instead of "COMPLETED". Only truly
|
|
126
78
|
// finished branches (no PR, merged PR, or closed PR) get Maintain.
|
|
127
79
|
const lifecycle = prData?.status === PrStatus.Open ? SdlcLifecycle.Review : SdlcLifecycle.Maintain;
|
|
128
|
-
// ---
|
|
129
|
-
const featureId = randomUUID();
|
|
80
|
+
// --- Persist feature ---
|
|
130
81
|
const feature = {
|
|
131
|
-
id:
|
|
82
|
+
id: randomUUID(),
|
|
132
83
|
name,
|
|
133
84
|
slug,
|
|
134
85
|
description: '',
|
|
@@ -147,18 +98,11 @@ let AdoptBranchUseCase = class AdoptBranchUseCase {
|
|
|
147
98
|
allowMerge: false,
|
|
148
99
|
},
|
|
149
100
|
worktreePath,
|
|
150
|
-
specPath: specDir,
|
|
151
|
-
agentRunId: runId,
|
|
152
101
|
repositoryId: repository.id,
|
|
153
102
|
pr: prData,
|
|
154
103
|
createdAt: now,
|
|
155
104
|
updatedAt: now,
|
|
156
105
|
};
|
|
157
|
-
// --- Persist AgentRun before Feature (respects referential integrity) ---
|
|
158
|
-
// Set featureId now that we have it
|
|
159
|
-
agentRun.featureId = featureId;
|
|
160
|
-
await this.agentRunRepo.create(agentRun);
|
|
161
|
-
// --- Persist Feature (after AgentRun exists) ---
|
|
162
106
|
await this.featureRepo.create(feature);
|
|
163
107
|
return { feature };
|
|
164
108
|
}
|
|
@@ -239,8 +183,6 @@ AdoptBranchUseCase = __decorate([
|
|
|
239
183
|
__param(1, inject('IRepositoryRepository')),
|
|
240
184
|
__param(2, inject('IWorktreeService')),
|
|
241
185
|
__param(3, inject('IGitPrService')),
|
|
242
|
-
|
|
243
|
-
__param(5, inject('ISpecInitializerService')),
|
|
244
|
-
__metadata("design:paramtypes", [Object, Object, Object, Object, Object, Object])
|
|
186
|
+
__metadata("design:paramtypes", [Object, Object, Object, Object])
|
|
245
187
|
], AdoptBranchUseCase);
|
|
246
188
|
export { AdoptBranchUseCase };
|
|
@@ -417,6 +417,10 @@ export type WorkflowConfig = {
|
|
|
417
417
|
* Hide CI status badges from UI (default: true)
|
|
418
418
|
*/
|
|
419
419
|
hideCiStatus?: boolean;
|
|
420
|
+
/**
|
|
421
|
+
* Maximum number of doctor fix attempts before giving up (default: 1)
|
|
422
|
+
*/
|
|
423
|
+
doctorMaxFixAttempts?: number;
|
|
420
424
|
};
|
|
421
425
|
export declare enum AgentType {
|
|
422
426
|
ClaudeCode = "claude-code",
|
|
@@ -1606,6 +1610,77 @@ export type Evidence = {
|
|
|
1606
1610
|
*/
|
|
1607
1611
|
taskRef?: string;
|
|
1608
1612
|
};
|
|
1613
|
+
/**
|
|
1614
|
+
* Summary of a failed agent run for diagnostic reporting
|
|
1615
|
+
*/
|
|
1616
|
+
export type FailedRunSummary = {
|
|
1617
|
+
/**
|
|
1618
|
+
* Type of agent that failed (e.g. claude-code, gemini-cli)
|
|
1619
|
+
*/
|
|
1620
|
+
agentType: string;
|
|
1621
|
+
/**
|
|
1622
|
+
* Name/identifier of the agent run
|
|
1623
|
+
*/
|
|
1624
|
+
agentName: string;
|
|
1625
|
+
/**
|
|
1626
|
+
* Error message from the failed run
|
|
1627
|
+
*/
|
|
1628
|
+
error: string;
|
|
1629
|
+
/**
|
|
1630
|
+
* ISO 8601 timestamp when the failure occurred
|
|
1631
|
+
*/
|
|
1632
|
+
timestamp: string;
|
|
1633
|
+
};
|
|
1634
|
+
/**
|
|
1635
|
+
* System environment information for diagnostic reporting
|
|
1636
|
+
*/
|
|
1637
|
+
export type SystemInfo = {
|
|
1638
|
+
/**
|
|
1639
|
+
* Node.js version (e.g. v20.11.0)
|
|
1640
|
+
*/
|
|
1641
|
+
nodeVersion: string;
|
|
1642
|
+
/**
|
|
1643
|
+
* Operating system platform (e.g. darwin, linux, win32)
|
|
1644
|
+
*/
|
|
1645
|
+
platform: string;
|
|
1646
|
+
/**
|
|
1647
|
+
* CPU architecture (e.g. x64, arm64)
|
|
1648
|
+
*/
|
|
1649
|
+
arch: string;
|
|
1650
|
+
/**
|
|
1651
|
+
* gh CLI version string
|
|
1652
|
+
*/
|
|
1653
|
+
ghVersion: string;
|
|
1654
|
+
};
|
|
1655
|
+
/**
|
|
1656
|
+
* Structured diagnostic report collected by shep doctor for issue creation
|
|
1657
|
+
*/
|
|
1658
|
+
export type DoctorDiagnosticReport = {
|
|
1659
|
+
/**
|
|
1660
|
+
* User-provided description of the problem
|
|
1661
|
+
*/
|
|
1662
|
+
userDescription: string;
|
|
1663
|
+
/**
|
|
1664
|
+
* Summaries of recent failed agent runs
|
|
1665
|
+
*/
|
|
1666
|
+
failedRunSummaries: FailedRunSummary[];
|
|
1667
|
+
/**
|
|
1668
|
+
* System environment information
|
|
1669
|
+
*/
|
|
1670
|
+
systemInfo: SystemInfo;
|
|
1671
|
+
/**
|
|
1672
|
+
* Current shep CLI version
|
|
1673
|
+
*/
|
|
1674
|
+
cliVersion: string;
|
|
1675
|
+
/**
|
|
1676
|
+
* Feature ID when diagnosing a specific feature (optional)
|
|
1677
|
+
*/
|
|
1678
|
+
featureId?: string;
|
|
1679
|
+
/**
|
|
1680
|
+
* Feature name when diagnosing a specific feature (optional)
|
|
1681
|
+
*/
|
|
1682
|
+
featureName?: string;
|
|
1683
|
+
};
|
|
1609
1684
|
export declare enum AgentStatus {
|
|
1610
1685
|
Idle = "Idle",
|
|
1611
1686
|
Running = "Running",
|