@shepai/cli 1.90.1 → 1.91.0-pr271.bc71731
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/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts +6 -0
- package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.js +8 -0
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +8 -0
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts +2 -0
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +4 -0
- package/dist/src/presentation/web/app/api/attachments/preview/route.d.ts.map +1 -1
- package/dist/src/presentation/web/app/api/attachments/preview/route.js +47 -11
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts +29 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +83 -38
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts +13 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.js +213 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +2 -1
- package/dist/src/presentation/web/components/common/inline-attachments/index.d.ts +3 -0
- package/dist/src/presentation/web/components/common/inline-attachments/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/inline-attachments/index.js +1 -0
- package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.d.ts +20 -0
- package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.js +72 -0
- package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.stories.d.ts +16 -0
- package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.stories.js +46 -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/create/page/server-reference-manifest.json +18 -18
- 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]/page/server-reference-manifest.json +21 -21
- 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 +14 -14
- 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 +18 -18
- 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]/page/server-reference-manifest.json +21 -21
- 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 +14 -14
- 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 +14 -14
- 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 +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
- 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 +6 -6
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__0b10355c._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__0b10355c._.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/7f428_lucide-react_dist_esm_icons_9027d30a._.js +1 -1
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_9027d30a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__17143953._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__17143953._.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]__4be9a9bb._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9de266fa._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9de266fa._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
- 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]__b3a4cef4._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b3a4cef4._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c2173b6d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c2173b6d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f0d8d054._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_752e01fd._.js +1 -1
- package/web/.next/server/chunks/ssr/_752e01fd._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_2fa756cd._.js → _c029c9a4._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_2fa756cd._.js.map → _c029c9a4._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.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__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.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_e4510d10._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.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 +28 -28
- package/web/.next/static/chunks/{54de5c2f98832b92.js → 14559ed26d88e209.js} +1 -1
- package/web/.next/static/chunks/2a09571d38368a18.css +2 -0
- package/web/.next/static/chunks/{4354b4b30513e7f0.js → 3093f97266ae10d2.js} +1 -1
- package/web/.next/static/chunks/3a43fa3b19c0e203.js +1 -0
- package/web/.next/static/chunks/{38bb02c07a427f1e.js → 3f93c36c5ff5804f.js} +1 -1
- package/web/.next/static/chunks/55e7ff9b53257d70.js +1 -0
- package/web/.next/static/chunks/{bb3e32c60cb2e794.js → 7571697c821fb8ab.js} +1 -1
- package/web/.next/static/chunks/{132ff681f7e12121.js → 92a959d71ebef998.js} +1 -1
- package/web/.next/static/chunks/{0cbb35f940c9feef.js → 93571cb544c4314b.js} +1 -1
- package/web/.next/static/chunks/{4906aba274bc6920.js → b0970305659496af.js} +1 -1
- package/web/.next/static/chunks/{7c7da9e978216d2b.js → cf9b9742eaa0597b.js} +1 -1
- package/web/.next/static/chunks/{c0f23bc23fd8b8ad.js → fc0e743fdc0af440.js} +1 -1
- package/web/.next/static/chunks/5c55da0e28e6cdc8.js +0 -1
- package/web/.next/static/chunks/cb5c85c5e16e82d3.js +0 -1
- package/web/.next/static/chunks/f98eb6cb17b61cb2.css +0 -2
- /package/web/.next/static/{o8F4OKh6WJmRpbTqaCZ67 → qb5URkkFh30LDQB9hFt8M}/_buildManifest.js +0 -0
- /package/web/.next/static/{o8F4OKh6WJmRpbTqaCZ67 → qb5URkkFh30LDQB9hFt8M}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{o8F4OKh6WJmRpbTqaCZ67 → qb5URkkFh30LDQB9hFt8M}/_ssgManifest.js +0 -0
package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts
CHANGED
|
@@ -97,6 +97,12 @@ export interface IWorktreeService {
|
|
|
97
97
|
* @returns Computed worktree path (e.g., /repo/.worktrees/branch-name)
|
|
98
98
|
*/
|
|
99
99
|
getWorktreePath(repoPath: string, branch: string): string;
|
|
100
|
+
/**
|
|
101
|
+
* Prune stale worktree entries whose directories no longer exist.
|
|
102
|
+
*
|
|
103
|
+
* @param repoPath - Path to the git repository
|
|
104
|
+
*/
|
|
105
|
+
prune(repoPath: string): Promise<void>;
|
|
100
106
|
/**
|
|
101
107
|
* Ensure a directory is a valid git repository with at least one commit.
|
|
102
108
|
* If the directory is not a git repo, initializes it with `git init`
|
package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/worktree-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,oBAAY,iBAAiB;IAC3B,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,SAAS,cAAc;IACvB,cAAc,mBAAmB;IACjC,SAAS,cAAc;CACxB;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,EAAE,iBAAiB;aACvB,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,iBAAiB,EACvB,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;OASG;IACH,MAAM,CACJ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzB;;;;;;OAMG;IACH,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7D;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAEhD;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D;;;;;;OAMG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjE;;;;;;OAMG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvE;;;;;;OAMG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1D;;;;;;;OAOG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD"}
|
|
1
|
+
{"version":3,"file":"worktree-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/worktree-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,oBAAY,iBAAiB;IAC3B,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,SAAS,cAAc;IACvB,cAAc,mBAAmB;IACjC,SAAS,cAAc;CACxB;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,EAAE,iBAAiB;aACvB,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,iBAAiB,EACvB,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;OASG;IACH,MAAM,CACJ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzB;;;;;;OAMG;IACH,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7D;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAEhD;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D;;;;;;OAMG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjE;;;;;;OAMG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvE;;;;;;OAMG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1D;;;;OAIG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC;;;;;;;OAOG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleanup-feature-worktree.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAE7F,qBACa,6BAA6B;IAER,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAFP,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EACpC,YAAY,EAAE,aAAa;IAGjE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"cleanup-feature-worktree.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAE7F,qBACa,6BAA6B;IAER,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAFP,WAAW,EAAE,kBAAkB,EACjC,eAAe,EAAE,gBAAgB,EACpC,YAAY,EAAE,aAAa;IAGjE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4ChD"}
|
package/dist/packages/core/src/application/use-cases/features/cleanup-feature-worktree.use-case.js
CHANGED
|
@@ -44,6 +44,14 @@ let CleanupFeatureWorktreeUseCase = class CleanupFeatureWorktreeUseCase {
|
|
|
44
44
|
catch (err) {
|
|
45
45
|
// eslint-disable-next-line no-console
|
|
46
46
|
console.warn('[CleanupFeatureWorktreeUseCase] worktree remove failed:', err);
|
|
47
|
+
// Prune stale worktree entries so the branch is no longer considered "in use"
|
|
48
|
+
try {
|
|
49
|
+
await this.worktreeService.prune(feature.repositoryPath);
|
|
50
|
+
}
|
|
51
|
+
catch (pruneErr) {
|
|
52
|
+
// eslint-disable-next-line no-console
|
|
53
|
+
console.warn('[CleanupFeatureWorktreeUseCase] worktree prune failed:', pruneErr);
|
|
54
|
+
}
|
|
47
55
|
}
|
|
48
56
|
// Step 2: Delete the local feature branch
|
|
49
57
|
try {
|
|
@@ -19,6 +19,7 @@ export declare class WorktreeService implements IWorktreeService {
|
|
|
19
19
|
constructor(execFile: ExecFunction);
|
|
20
20
|
create(repoPath: string, branch: string, worktreePath: string, startPoint?: string): Promise<WorktreeInfo>;
|
|
21
21
|
remove(worktreePath: string, force?: boolean): Promise<void>;
|
|
22
|
+
prune(repoPath: string): Promise<void>;
|
|
22
23
|
list(repoPath: string): Promise<WorktreeInfo[]>;
|
|
23
24
|
exists(repoPath: string, branch: string): Promise<boolean>;
|
|
24
25
|
branchExists(repoPath: string, branch: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/worktree.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,0EAA0E,CAAC;AAOlF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjD,qBACa,eAAgB,YAAW,gBAAgB;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC;IAqBlB,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5D,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAO/C,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWhE,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWtE,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC1D,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAMzD,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;CAU9B"}
|
|
1
|
+
{"version":3,"file":"worktree.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/worktree.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,0EAA0E,CAAC;AAOlF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjD,qBACa,eAAgB,YAAW,gBAAgB;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC;IAqBlB,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5D,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAO/C,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWhE,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWtE,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC1D,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAMzD,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;CAU9B"}
|
|
@@ -60,6 +60,14 @@ let WorktreeService = class WorktreeService {
|
|
|
60
60
|
throw this.parseGitError(error);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
async prune(repoPath) {
|
|
64
|
+
try {
|
|
65
|
+
await this.execFile('git', ['worktree', 'prune'], { cwd: repoPath });
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
throw this.parseGitError(error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
63
71
|
async list(repoPath) {
|
|
64
72
|
const { stdout } = await this.execFile('git', ['worktree', 'list', '--porcelain'], {
|
|
65
73
|
cwd: repoPath,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-feature-phase-timings.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-feature-phase-timings.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"get-feature-phase-timings.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-feature-phase-timings.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,KAAK,qBAAqB,GACtB;IAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IAAC,iBAAiB,EAAE,qBAAqB,EAAE,CAAA;CAAE,GAC1E;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtB,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA2B9F"}
|
|
@@ -42,6 +42,10 @@ async function readRejectionFeedback(featureId) {
|
|
|
42
42
|
iteration: Number(entry.iteration ?? 1),
|
|
43
43
|
message: String(entry.message ?? ''),
|
|
44
44
|
phase: entry.phase ? String(entry.phase) : undefined,
|
|
45
|
+
timestamp: entry.timestamp ? String(entry.timestamp) : undefined,
|
|
46
|
+
attachments: Array.isArray(entry.attachments)
|
|
47
|
+
? entry.attachments.map(String)
|
|
48
|
+
: undefined,
|
|
45
49
|
}));
|
|
46
50
|
}
|
|
47
51
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/api/attachments/preview/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/api/attachments/preview/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA8D3C,wBAAsB,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA0BrE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server';
|
|
2
|
-
import { readFile, stat } from 'fs/promises';
|
|
3
|
-
import { extname, resolve } from 'path';
|
|
2
|
+
import { readFile, stat, readdir } from 'fs/promises';
|
|
3
|
+
import { basename, extname, join, resolve } from 'path';
|
|
4
4
|
import { getShepHomeDir } from '../../../../../../../packages/core/src/infrastructure/services/filesystem/shep-directory.service.js';
|
|
5
5
|
const MIME_MAP = {
|
|
6
6
|
'.png': 'image/png',
|
|
@@ -18,6 +18,44 @@ const MIME_MAP = {
|
|
|
18
18
|
'.yaml': 'text/yaml',
|
|
19
19
|
'.yml': 'text/yaml',
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* When the exact path doesn't exist (e.g. pending-<id> was renamed to <slug>),
|
|
23
|
+
* search all sibling attachment directories for the same filename.
|
|
24
|
+
*/
|
|
25
|
+
async function findAttachmentFallback(requestedPath, attachmentsRoot) {
|
|
26
|
+
const filename = basename(requestedPath);
|
|
27
|
+
try {
|
|
28
|
+
const dirs = await readdir(attachmentsRoot, { withFileTypes: true });
|
|
29
|
+
for (const entry of dirs) {
|
|
30
|
+
if (!entry.isDirectory())
|
|
31
|
+
continue;
|
|
32
|
+
const candidate = join(attachmentsRoot, entry.name, filename);
|
|
33
|
+
try {
|
|
34
|
+
await stat(candidate);
|
|
35
|
+
return candidate;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// not in this directory
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// attachments root doesn't exist
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
function serveFile(filePath, mimeTypeHint) {
|
|
48
|
+
return readFile(filePath).then((buffer) => {
|
|
49
|
+
const ext = extname(filePath).toLowerCase();
|
|
50
|
+
const contentType = MIME_MAP[ext] ?? mimeTypeHint ?? 'application/octet-stream';
|
|
51
|
+
return new NextResponse(buffer, {
|
|
52
|
+
headers: {
|
|
53
|
+
'Content-Type': contentType,
|
|
54
|
+
'Cache-Control': 'private, max-age=3600',
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
21
59
|
export async function GET(request) {
|
|
22
60
|
const path = request.nextUrl.searchParams.get('path');
|
|
23
61
|
const mimeTypeHint = request.nextUrl.searchParams.get('mimeType');
|
|
@@ -31,17 +69,15 @@ export async function GET(request) {
|
|
|
31
69
|
}
|
|
32
70
|
try {
|
|
33
71
|
await stat(path);
|
|
34
|
-
|
|
35
|
-
const ext = extname(path).toLowerCase();
|
|
36
|
-
const contentType = MIME_MAP[ext] ?? mimeTypeHint ?? 'application/octet-stream';
|
|
37
|
-
return new NextResponse(buffer, {
|
|
38
|
-
headers: {
|
|
39
|
-
'Content-Type': contentType,
|
|
40
|
-
'Cache-Control': 'private, max-age=3600',
|
|
41
|
-
},
|
|
42
|
-
});
|
|
72
|
+
return await serveFile(path, mimeTypeHint);
|
|
43
73
|
}
|
|
44
74
|
catch {
|
|
75
|
+
// File not found at exact path — try fallback search
|
|
76
|
+
// This handles the case where pending-<sessionId>/ was renamed to <featureSlug>/
|
|
77
|
+
const fallbackPath = await findAttachmentFallback(path, attachmentsRoot);
|
|
78
|
+
if (fallbackPath) {
|
|
79
|
+
return await serveFile(fallbackPath, mimeTypeHint);
|
|
80
|
+
}
|
|
45
81
|
return NextResponse.json({ error: 'File not found' }, { status: 404 });
|
|
46
82
|
}
|
|
47
83
|
}
|
|
@@ -5,5 +5,34 @@ export interface ActivityTabProps {
|
|
|
5
5
|
error: string | null;
|
|
6
6
|
rejectionFeedback?: RejectionFeedbackData[];
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* A single iteration in the lifecycle timeline.
|
|
10
|
+
*
|
|
11
|
+
* An iteration represents one cycle of work:
|
|
12
|
+
* started/resumed → phase work → rejected/completed/failed
|
|
13
|
+
*
|
|
14
|
+
* Each rejected iteration has associated rejection feedback.
|
|
15
|
+
*/
|
|
16
|
+
export interface TimelineIteration {
|
|
17
|
+
/** 1-based iteration number */
|
|
18
|
+
number: number;
|
|
19
|
+
/** The timing events in this iteration */
|
|
20
|
+
timings: PhaseTimingData[];
|
|
21
|
+
/** If this iteration ended with rejection, the feedback message */
|
|
22
|
+
rejectionMessage?: string;
|
|
23
|
+
/** If this iteration ended with rejection, any attachments */
|
|
24
|
+
rejectionAttachments?: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build a lifecycle-aware timeline from flat timing events and rejection feedback.
|
|
28
|
+
*
|
|
29
|
+
* Splits the timing stream at run:rejected boundaries to produce iterations.
|
|
30
|
+
* Each rejection feedback entry is matched to its iteration by index.
|
|
31
|
+
*
|
|
32
|
+
* When there are more feedback entries than run:rejected events in the timings,
|
|
33
|
+
* synthetic run:rejected + run:resumed events are appended to ensure every
|
|
34
|
+
* feedback entry is represented.
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildLifecycleTimeline(timings: PhaseTimingData[], feedback?: RejectionFeedbackData[]): TimelineIteration[];
|
|
8
37
|
export declare function ActivityTab({ timings, loading, error, rejectionFeedback }: ActivityTabProps): import("react/jsx-runtime").JSX.Element;
|
|
9
38
|
//# sourceMappingURL=activity-tab.d.ts.map
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"activity-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,MAAM,yCAAyC,CAAC;AAGjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC7C;AAiCD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EAAE,EAC1B,QAAQ,CAAC,EAAE,qBAAqB,EAAE,GACjC,iBAAiB,EAAE,CAgErB;AAMD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,2CAyD3F"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { Loader2, AlertCircle, Clock } from 'lucide-react';
|
|
4
|
+
import { InlineAttachments } from '../../common/inline-attachments/index.js';
|
|
4
5
|
const NODE_TO_PHASE = {
|
|
5
6
|
analyze: 'Analyzing',
|
|
6
7
|
requirements: 'Requirements',
|
|
@@ -24,37 +25,76 @@ function isLifecycleEvent(phase) {
|
|
|
24
25
|
function formatDuration(ms) {
|
|
25
26
|
return `${(ms / 1000).toFixed(1)}s`;
|
|
26
27
|
}
|
|
27
|
-
function groupTimingsByRun(timings) {
|
|
28
|
-
const groups = [];
|
|
29
|
-
for (const t of timings) {
|
|
30
|
-
const last = groups[groups.length - 1];
|
|
31
|
-
if (last?.runId === t.agentRunId) {
|
|
32
|
-
last.timings.push(t);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
groups.push({ runId: t.agentRunId, timings: [t] });
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return groups;
|
|
39
|
-
}
|
|
40
28
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
29
|
+
* Build a lifecycle-aware timeline from flat timing events and rejection feedback.
|
|
30
|
+
*
|
|
31
|
+
* Splits the timing stream at run:rejected boundaries to produce iterations.
|
|
32
|
+
* Each rejection feedback entry is matched to its iteration by index.
|
|
33
|
+
*
|
|
34
|
+
* When there are more feedback entries than run:rejected events in the timings,
|
|
35
|
+
* synthetic run:rejected + run:resumed events are appended to ensure every
|
|
36
|
+
* feedback entry is represented.
|
|
43
37
|
*/
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
38
|
+
export function buildLifecycleTimeline(timings, feedback) {
|
|
39
|
+
if (!timings.length)
|
|
40
|
+
return [];
|
|
41
|
+
// Count existing run:rejected events
|
|
42
|
+
const existingRejectionCount = timings.filter((t) => t.phase === 'run:rejected').length;
|
|
43
|
+
const feedbackCount = feedback?.length ?? 0;
|
|
44
|
+
// Augment timings with synthetic rejection/resumed cycles for unmatched feedback
|
|
45
|
+
let augmented = timings;
|
|
46
|
+
if (feedbackCount > existingRejectionCount) {
|
|
47
|
+
augmented = [...timings];
|
|
48
|
+
// Use last timing's agentRunId as template
|
|
49
|
+
const templateRunId = timings[timings.length - 1].agentRunId;
|
|
50
|
+
for (let i = existingRejectionCount; i < feedbackCount; i++) {
|
|
51
|
+
const fb = feedback[i];
|
|
52
|
+
// Add run:resumed before work (except for the first synthetic, which continues from existing)
|
|
53
|
+
if (i > existingRejectionCount) {
|
|
54
|
+
augmented.push({
|
|
55
|
+
agentRunId: templateRunId,
|
|
56
|
+
phase: 'run:resumed',
|
|
57
|
+
startedAt: fb.timestamp ?? `synthetic-resumed-${i}`,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// Add run:rejected
|
|
61
|
+
augmented.push({
|
|
62
|
+
agentRunId: templateRunId,
|
|
63
|
+
phase: 'run:rejected',
|
|
64
|
+
startedAt: fb.timestamp ?? `synthetic-${i}`,
|
|
65
|
+
});
|
|
54
66
|
}
|
|
55
67
|
}
|
|
56
|
-
|
|
68
|
+
// Split into iterations at run:rejected boundaries
|
|
69
|
+
const iterations = [];
|
|
70
|
+
let currentEvents = [];
|
|
71
|
+
let rejectionIndex = 0;
|
|
72
|
+
for (const t of augmented) {
|
|
73
|
+
currentEvents.push(t);
|
|
74
|
+
if (t.phase === 'run:rejected') {
|
|
75
|
+
const fb = feedback?.[rejectionIndex];
|
|
76
|
+
iterations.push({
|
|
77
|
+
number: iterations.length + 1,
|
|
78
|
+
timings: currentEvents,
|
|
79
|
+
rejectionMessage: fb?.message,
|
|
80
|
+
rejectionAttachments: fb?.attachments,
|
|
81
|
+
});
|
|
82
|
+
currentEvents = [];
|
|
83
|
+
rejectionIndex++;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Remaining events after last rejection (or all events if no rejections)
|
|
87
|
+
if (currentEvents.length > 0) {
|
|
88
|
+
iterations.push({
|
|
89
|
+
number: iterations.length + 1,
|
|
90
|
+
timings: currentEvents,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return iterations;
|
|
57
94
|
}
|
|
95
|
+
/* ---------------------------------------------------------------------------
|
|
96
|
+
* Component
|
|
97
|
+
* ------------------------------------------------------------------------- */
|
|
58
98
|
export function ActivityTab({ timings, loading, error, rejectionFeedback }) {
|
|
59
99
|
if (loading) {
|
|
60
100
|
return (_jsx("div", { "data-testid": "activity-tab-loading", className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
|
|
@@ -67,29 +107,34 @@ export function ActivityTab({ timings, loading, error, rejectionFeedback }) {
|
|
|
67
107
|
}
|
|
68
108
|
const nodeTimings = timings.filter((t) => !isLifecycleEvent(t.phase));
|
|
69
109
|
const maxDurationMs = Math.max(...nodeTimings.map((t) => t.durationMs ?? 0), ...nodeTimings.map((t) => t.approvalWaitMs ?? 0), 0);
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
const groups = groupTimingsByRun(timings);
|
|
73
|
-
const multiRun = groups.length > 1;
|
|
110
|
+
const iterations = buildLifecycleTimeline(timings, rejectionFeedback);
|
|
111
|
+
const hasMultipleIterations = iterations.length > 1;
|
|
74
112
|
const totalExecMs = nodeTimings.reduce((sum, t) => sum + (t.durationMs ?? 0), 0);
|
|
75
113
|
const totalWaitMs = nodeTimings.reduce((sum, t) => sum + (t.approvalWaitMs ?? 0), 0);
|
|
76
|
-
return (_jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsx("div", { "data-testid": "activity-timings", className: "flex flex-col gap-3", children:
|
|
114
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsx("div", { "data-testid": "activity-timings", className: "flex flex-col gap-3", children: iterations.map((iteration) => (_jsx(IterationGroup, { iteration: iteration, showHeader: hasMultipleIterations, maxDurationMs: maxDurationMs }, iteration.number))) }), totalExecMs > 0 ? (_jsx(SummaryTotals, { totalExecMs: totalExecMs, totalWaitMs: totalWaitMs })) : null] }));
|
|
77
115
|
}
|
|
78
|
-
|
|
79
|
-
|
|
116
|
+
/* ---------------------------------------------------------------------------
|
|
117
|
+
* Iteration group — one cycle of work
|
|
118
|
+
* ------------------------------------------------------------------------- */
|
|
119
|
+
function IterationGroup({ iteration, showHeader, maxDurationMs, }) {
|
|
120
|
+
return (_jsxs("div", { "data-testid": `iteration-${iteration.number}`, className: "flex flex-col gap-1.5", children: [showHeader ? (_jsxs("div", { className: "text-muted-foreground text-xs font-medium", children: ["Iteration ", iteration.number] })) : null, iteration.timings.map((t) => {
|
|
80
121
|
if (isLifecycleEvent(t.phase)) {
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
return _jsx(LifecycleEventRow, { timing: t, message:
|
|
122
|
+
// For run:rejected, the message comes from the iteration, not a separate map
|
|
123
|
+
const isRejection = t.phase === 'run:rejected';
|
|
124
|
+
return (_jsx(LifecycleEventRow, { timing: t, message: isRejection ? iteration.rejectionMessage : undefined, attachments: isRejection ? iteration.rejectionAttachments : undefined }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
|
|
84
125
|
}
|
|
85
126
|
return (_jsx(NodeTimingRow, { timing: t, maxDurationMs: maxDurationMs }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
|
|
86
127
|
})] }));
|
|
87
128
|
}
|
|
88
|
-
|
|
129
|
+
/* ---------------------------------------------------------------------------
|
|
130
|
+
* Row components
|
|
131
|
+
* ------------------------------------------------------------------------- */
|
|
132
|
+
function LifecycleEventRow({ timing, message, attachments, }) {
|
|
89
133
|
const event = LIFECYCLE_EVENTS[timing.phase];
|
|
90
134
|
if (!event)
|
|
91
135
|
return null;
|
|
92
|
-
|
|
136
|
+
const hasAttachments = attachments && attachments.length > 0;
|
|
137
|
+
return (_jsxs("div", { className: `text-xs ${event.colorClass}`, children: [_jsx("span", { children: event.label }), message ? (_jsxs("span", { "data-testid": "rejection-feedback-text", className: "text-muted-foreground ml-2 font-normal italic", children: ["\u2014 ", message] })) : null, hasAttachments ? (_jsx("div", { "data-testid": "rejection-feedback-attachments", className: "mt-1.5 ml-2", children: _jsx(InlineAttachments, { text: "", attachmentPaths: attachments }) })) : null] }));
|
|
93
138
|
}
|
|
94
139
|
function NodeTimingRow({ timing, maxDurationMs, }) {
|
|
95
140
|
const label = timing.phase.includes(':')
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts
CHANGED
|
@@ -17,6 +17,19 @@ export declare const Empty: Story;
|
|
|
17
17
|
export declare const Error: Story;
|
|
18
18
|
/** Rejection — shows rejected lifecycle event with user feedback text. */
|
|
19
19
|
export declare const WithRejection: Story;
|
|
20
|
+
/**
|
|
21
|
+
* Multiple rejection/resume cycles — realistic lifecycle showing:
|
|
22
|
+
* Iteration 1: work → rejected("rebase on main")
|
|
23
|
+
* Iteration 2: resumed → work → rejected("rebase on main")
|
|
24
|
+
* Iteration 3: rejected("add support for evidence agent...") — synthetic
|
|
25
|
+
* Iteration 4: rejected("screenshots broken...") — synthetic
|
|
26
|
+
*/
|
|
27
|
+
export declare const MultipleRejections: Story;
|
|
20
28
|
/** Approval wait indicators — phases with approval wait sub-rows. */
|
|
21
29
|
export declare const WithApprovalWaits: Story;
|
|
30
|
+
/**
|
|
31
|
+
* Full lifecycle — realistic multi-iteration rejection/resume cycle.
|
|
32
|
+
* Shows the full pattern: start → work → rejected → resumed → work → rejected → resumed → completed
|
|
33
|
+
*/
|
|
34
|
+
export declare const FullLifecycle: Story;
|
|
22
35
|
//# sourceMappingURL=activity-tab.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAclC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AAmK1C,2EAA2E;AAC3E,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,KAsE3B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,EAAE,KAgC/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"activity-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAclC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AAmK1C,2EAA2E;AAC3E,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,KAsE3B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAwEhC,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,EAAE,KAgC/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,KAiI3B,CAAC"}
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.js
CHANGED
|
@@ -288,6 +288,85 @@ export const WithRejection = {
|
|
|
288
288
|
error: null,
|
|
289
289
|
},
|
|
290
290
|
};
|
|
291
|
+
/**
|
|
292
|
+
* Multiple rejection/resume cycles — realistic lifecycle showing:
|
|
293
|
+
* Iteration 1: work → rejected("rebase on main")
|
|
294
|
+
* Iteration 2: resumed → work → rejected("rebase on main")
|
|
295
|
+
* Iteration 3: rejected("add support for evidence agent...") — synthetic
|
|
296
|
+
* Iteration 4: rejected("screenshots broken...") — synthetic
|
|
297
|
+
*/
|
|
298
|
+
export const MultipleRejections = {
|
|
299
|
+
args: {
|
|
300
|
+
timings: [
|
|
301
|
+
{
|
|
302
|
+
agentRunId: 'run-1',
|
|
303
|
+
phase: 'run:started',
|
|
304
|
+
startedAt: '2025-01-15T10:00:00Z',
|
|
305
|
+
durationMs: 0,
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
agentRunId: 'run-1',
|
|
309
|
+
phase: 'plan',
|
|
310
|
+
startedAt: '2025-01-15T10:00:01Z',
|
|
311
|
+
completedAt: '2025-01-15T10:05:00Z',
|
|
312
|
+
durationMs: 300000,
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
agentRunId: 'run-1',
|
|
316
|
+
phase: 'run:rejected',
|
|
317
|
+
startedAt: '2025-01-15T10:05:00Z',
|
|
318
|
+
durationMs: 0,
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
agentRunId: 'run-1',
|
|
322
|
+
phase: 'run:resumed',
|
|
323
|
+
startedAt: '2025-01-15T10:10:00Z',
|
|
324
|
+
durationMs: 0,
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
agentRunId: 'run-1',
|
|
328
|
+
phase: 'merge',
|
|
329
|
+
startedAt: '2025-01-15T10:10:01Z',
|
|
330
|
+
completedAt: '2025-01-15T10:15:00Z',
|
|
331
|
+
durationMs: 299000,
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
agentRunId: 'run-1',
|
|
335
|
+
phase: 'run:rejected',
|
|
336
|
+
startedAt: '2025-01-15T10:15:00Z',
|
|
337
|
+
durationMs: 0,
|
|
338
|
+
},
|
|
339
|
+
],
|
|
340
|
+
rejectionFeedback: [
|
|
341
|
+
{
|
|
342
|
+
iteration: 1,
|
|
343
|
+
message: 'rebase on main',
|
|
344
|
+
phase: 'plan',
|
|
345
|
+
timestamp: '2025-01-15T10:05:00Z',
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
iteration: 2,
|
|
349
|
+
message: 'rebase on main',
|
|
350
|
+
phase: 'merge',
|
|
351
|
+
timestamp: '2025-01-15T10:15:00Z',
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
iteration: 3,
|
|
355
|
+
message: 'add support for evidence agent into fast mode as well',
|
|
356
|
+
phase: 'merge',
|
|
357
|
+
timestamp: '2025-01-15T10:20:00Z',
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
iteration: 4,
|
|
361
|
+
message: "I've test and created a feature but the screenshots seems to be broken https://github.com/shep-ai/cli/pull/258 fix",
|
|
362
|
+
phase: 'merge',
|
|
363
|
+
timestamp: '2025-01-15T10:25:00Z',
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
loading: false,
|
|
367
|
+
error: null,
|
|
368
|
+
},
|
|
369
|
+
};
|
|
291
370
|
/** Approval wait indicators — phases with approval wait sub-rows. */
|
|
292
371
|
export const WithApprovalWaits = {
|
|
293
372
|
args: {
|
|
@@ -322,3 +401,137 @@ export const WithApprovalWaits = {
|
|
|
322
401
|
error: null,
|
|
323
402
|
},
|
|
324
403
|
};
|
|
404
|
+
/**
|
|
405
|
+
* Full lifecycle — realistic multi-iteration rejection/resume cycle.
|
|
406
|
+
* Shows the full pattern: start → work → rejected → resumed → work → rejected → resumed → completed
|
|
407
|
+
*/
|
|
408
|
+
export const FullLifecycle = {
|
|
409
|
+
args: {
|
|
410
|
+
timings: [
|
|
411
|
+
// Iteration 1
|
|
412
|
+
{
|
|
413
|
+
agentRunId: 'run-1',
|
|
414
|
+
phase: 'run:started',
|
|
415
|
+
startedAt: '2025-01-15T10:00:00Z',
|
|
416
|
+
durationMs: 0,
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
agentRunId: 'run-1',
|
|
420
|
+
phase: 'analyze',
|
|
421
|
+
startedAt: '2025-01-15T10:00:01Z',
|
|
422
|
+
completedAt: '2025-01-15T10:00:15Z',
|
|
423
|
+
durationMs: 14000,
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
agentRunId: 'run-1',
|
|
427
|
+
phase: 'requirements',
|
|
428
|
+
startedAt: '2025-01-15T10:00:15Z',
|
|
429
|
+
completedAt: '2025-01-15T10:02:00Z',
|
|
430
|
+
durationMs: 105000,
|
|
431
|
+
waitingApprovalAt: '2025-01-15T10:01:30Z',
|
|
432
|
+
approvalWaitMs: 20000,
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
agentRunId: 'run-1',
|
|
436
|
+
phase: 'plan',
|
|
437
|
+
startedAt: '2025-01-15T10:02:00Z',
|
|
438
|
+
completedAt: '2025-01-15T10:04:00Z',
|
|
439
|
+
durationMs: 120000,
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
agentRunId: 'run-1',
|
|
443
|
+
phase: 'implement',
|
|
444
|
+
startedAt: '2025-01-15T10:04:00Z',
|
|
445
|
+
completedAt: '2025-01-15T10:14:00Z',
|
|
446
|
+
durationMs: 600000,
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
agentRunId: 'run-1',
|
|
450
|
+
phase: 'merge',
|
|
451
|
+
startedAt: '2025-01-15T10:14:00Z',
|
|
452
|
+
completedAt: '2025-01-15T10:15:00Z',
|
|
453
|
+
durationMs: 60000,
|
|
454
|
+
waitingApprovalAt: '2025-01-15T10:14:30Z',
|
|
455
|
+
approvalWaitMs: 25000,
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
agentRunId: 'run-1',
|
|
459
|
+
phase: 'run:rejected',
|
|
460
|
+
startedAt: '2025-01-15T10:15:00Z',
|
|
461
|
+
durationMs: 0,
|
|
462
|
+
},
|
|
463
|
+
// Iteration 2
|
|
464
|
+
{
|
|
465
|
+
agentRunId: 'run-1',
|
|
466
|
+
phase: 'run:resumed',
|
|
467
|
+
startedAt: '2025-01-15T10:20:00Z',
|
|
468
|
+
durationMs: 0,
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
agentRunId: 'run-1',
|
|
472
|
+
phase: 'implement',
|
|
473
|
+
startedAt: '2025-01-15T10:20:01Z',
|
|
474
|
+
completedAt: '2025-01-15T10:28:00Z',
|
|
475
|
+
durationMs: 479000,
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
agentRunId: 'run-1',
|
|
479
|
+
phase: 'merge',
|
|
480
|
+
startedAt: '2025-01-15T10:28:00Z',
|
|
481
|
+
completedAt: '2025-01-15T10:29:00Z',
|
|
482
|
+
durationMs: 60000,
|
|
483
|
+
waitingApprovalAt: '2025-01-15T10:28:30Z',
|
|
484
|
+
approvalWaitMs: 20000,
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
agentRunId: 'run-1',
|
|
488
|
+
phase: 'run:rejected',
|
|
489
|
+
startedAt: '2025-01-15T10:29:00Z',
|
|
490
|
+
durationMs: 0,
|
|
491
|
+
},
|
|
492
|
+
// Iteration 3
|
|
493
|
+
{
|
|
494
|
+
agentRunId: 'run-1',
|
|
495
|
+
phase: 'run:resumed',
|
|
496
|
+
startedAt: '2025-01-15T10:35:00Z',
|
|
497
|
+
durationMs: 0,
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
agentRunId: 'run-1',
|
|
501
|
+
phase: 'implement',
|
|
502
|
+
startedAt: '2025-01-15T10:35:01Z',
|
|
503
|
+
completedAt: '2025-01-15T10:40:00Z',
|
|
504
|
+
durationMs: 299000,
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
agentRunId: 'run-1',
|
|
508
|
+
phase: 'merge',
|
|
509
|
+
startedAt: '2025-01-15T10:40:00Z',
|
|
510
|
+
completedAt: '2025-01-15T10:41:00Z',
|
|
511
|
+
durationMs: 60000,
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
agentRunId: 'run-1',
|
|
515
|
+
phase: 'run:completed',
|
|
516
|
+
startedAt: '2025-01-15T10:41:00Z',
|
|
517
|
+
durationMs: 0,
|
|
518
|
+
},
|
|
519
|
+
],
|
|
520
|
+
rejectionFeedback: [
|
|
521
|
+
{
|
|
522
|
+
iteration: 1,
|
|
523
|
+
message: 'The PR has merge conflicts — rebase on main first',
|
|
524
|
+
phase: 'merge',
|
|
525
|
+
timestamp: '2025-01-15T10:15:00Z',
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
iteration: 2,
|
|
529
|
+
message: 'Tests are failing in the CI pipeline — fix the snapshot tests',
|
|
530
|
+
phase: 'merge',
|
|
531
|
+
timestamp: '2025-01-15T10:29:00Z',
|
|
532
|
+
},
|
|
533
|
+
],
|
|
534
|
+
loading: false,
|
|
535
|
+
error: null,
|
|
536
|
+
},
|
|
537
|
+
};
|