@shepai/cli 1.142.1 → 1.144.0-pr458.cd35c8d
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/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.d.ts +6 -3
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.js +104 -66
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.d.ts +12 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.js +33 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts +10 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +63 -0
- package/dist/src/presentation/cli/commands/feat/ls.command.d.ts +44 -2
- package/dist/src/presentation/cli/commands/feat/ls.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/ls.command.js +182 -82
- 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 +3 -3
- package/web/.next/required-server-files.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
- 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 +28 -28
- 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 +36 -36
- 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 +36 -36
- 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 +26 -26
- 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 +28 -28
- 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 +36 -36
- 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 +36 -36
- 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 +26 -26
- 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 +26 -26
- 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/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/[root-of-the-server]__2138fa7e._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.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]__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]__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]__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]__c094882b._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.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]__dac5dbf1._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_01046927._.js +1 -1
- package/web/.next/server/chunks/ssr/_0c5f56e3._.js +2 -2
- package/web/.next/server/chunks/ssr/_0c5f56e3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_1b719e7f._.js +1 -1
- package/web/.next/server/chunks/ssr/_1b719e7f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_3223b0bb._.js +3 -0
- package/web/.next/server/chunks/ssr/{_05b4c375._.js.map → _3223b0bb._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_37e8548b._.js +1 -1
- package/web/.next/server/chunks/ssr/_37e8548b._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_55d763e2._.js +1 -1
- package/web/.next/server/chunks/ssr/_55d763e2._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_6256a985._.js +1 -1
- package/web/.next/server/chunks/ssr/_6256a985._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_64bdfc6f._.js +2 -2
- package/web/.next/server/chunks/ssr/_64bdfc6f._.js.map +1 -1
- 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/{_be90dd43._.js → _a1b34bf7._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_be90dd43._.js.map → _a1b34bf7._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
- package/web/.next/server/chunks/ssr/_b71645b4._.js +1 -1
- package/web/.next/server/chunks/ssr/_b71645b4._.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_93e5fd0d._.js → src_presentation_web_31c9d413._.js} +2 -2
- package/web/.next/server/chunks/ssr/{src_presentation_web_93e5fd0d._.js.map → src_presentation_web_31c9d413._.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_app_actions_open-ide_ts_baaca5d5._.js +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/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +44 -44
- package/web/.next/static/chunks/{09084b604a4022a2.js → 010d105c609e1bd6.js} +1 -1
- package/web/.next/static/chunks/{7fe2bb39ee56a00a.js → 17c5af33f87628c6.js} +1 -1
- package/web/.next/static/chunks/{a05f5913e43443d6.js → 294094e93d072099.js} +1 -1
- package/web/.next/static/chunks/{6b099ae0735b3c21.js → 2b07e19607643fd1.js} +2 -2
- package/web/.next/static/chunks/{9f57fc63be1397a3.js → 2f446e4bf3ebac66.js} +1 -1
- package/web/.next/static/chunks/{8b7ba729b53257a1.js → 470c9f7c774540be.js} +1 -1
- package/web/.next/static/chunks/{3cd98a2f7a8a33a8.js → 4d877165e439230b.js} +1 -1
- package/web/.next/static/chunks/{d5475a9f1eed113d.js → 9a8245951ae65468.js} +1 -1
- package/web/.next/static/chunks/{41d77b193b5df1b7.js → a1df804f7ad7741d.js} +1 -1
- package/web/.next/static/chunks/{f7251d9aebce001c.js → e46684da592298f2.js} +1 -1
- package/web/.next/static/chunks/{d2eb3a9e6fa8cdad.js → e5e33ea2dd24ac54.js} +1 -1
- package/web/.next/static/chunks/{86afa5ddfcbbbf94.js → f65b1423092f2a4d.js} +1 -1
- package/web/.next/server/chunks/ssr/_05b4c375._.js +0 -3
- /package/web/.next/static/{Z9eZhnwItIVi_t0WGZSA4 → SkQlsizd7DM_CgdpQpBtr}/_buildManifest.js +0 -0
- /package/web/.next/static/{Z9eZhnwItIVi_t0WGZSA4 → SkQlsizd7DM_CgdpQpBtr}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{Z9eZhnwItIVi_t0WGZSA4 → SkQlsizd7DM_CgdpQpBtr}/_ssgManifest.js +0 -0
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CI Watch/Fix Loop
|
|
3
3
|
*
|
|
4
|
-
* After a push, watches CI status
|
|
4
|
+
* After a push, watches CI status using an agent-based approach and attempts
|
|
5
|
+
* automatic fixes when CI fails. The agent follows CI/CD best practices:
|
|
6
|
+
* checks ALL runs, waits for ALL to complete, and reports accurate status.
|
|
7
|
+
*
|
|
5
8
|
* Respects configurable max attempts, timeout, and log size from settings.
|
|
6
9
|
*/
|
|
7
10
|
import type { IAgentExecutor } from '../../../../../../application/ports/output/agents/agent-executor.interface.js';
|
|
@@ -34,8 +37,8 @@ export interface CiWatchFixResult {
|
|
|
34
37
|
ciFixStatus: CiFixStatusValue;
|
|
35
38
|
}
|
|
36
39
|
/**
|
|
37
|
-
* Run the CI watch/fix loop. Watches for the initial CI result
|
|
38
|
-
* iteratively attempts fixes up to the configured maximum.
|
|
40
|
+
* Run the CI watch/fix loop. Watches for the initial CI result using an
|
|
41
|
+
* agent-based approach, then iteratively attempts fixes up to the configured maximum.
|
|
39
42
|
*
|
|
40
43
|
* Throws on timeout or exhausted attempts (after updating feature state).
|
|
41
44
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci-watch-fix-loop.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ci-watch-fix-loop.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iEAAiE,CAAC;AACrG,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+DAA+D,CAAC;AAO3G,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,YAAY,EAAE,aAAa,CAAC;IAC5B,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC/E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAEpG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAyED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA4K3B"}
|
|
@@ -1,18 +1,70 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CI Watch/Fix Loop
|
|
3
3
|
*
|
|
4
|
-
* After a push, watches CI status
|
|
4
|
+
* After a push, watches CI status using an agent-based approach and attempts
|
|
5
|
+
* automatic fixes when CI fails. The agent follows CI/CD best practices:
|
|
6
|
+
* checks ALL runs, waits for ALL to complete, and reports accurate status.
|
|
7
|
+
*
|
|
5
8
|
* Respects configurable max attempts, timeout, and log size from settings.
|
|
6
9
|
*/
|
|
7
|
-
import { GitPrError, GitPrErrorCode, } from '../../../../../../application/ports/output/services/git-pr-service.interface.js';
|
|
8
10
|
import { CiStatus } from '../../../../../../domain/generated/output.js';
|
|
9
11
|
import { retryExecute } from '../node-helpers.js';
|
|
10
|
-
import { buildCiWatchFixPrompt } from '../prompts/merge-prompts.js';
|
|
12
|
+
import { buildCiWatchFixPrompt, buildCiWatchPrompt } from '../prompts/merge-prompts.js';
|
|
13
|
+
import { parseCiWatchResult } from './merge-output-parser.js';
|
|
11
14
|
import { extractRunId, handleCiTerminalFailure, buildCiExhaustedError } from './ci-helpers.js';
|
|
12
15
|
import { getSettings } from '../../../../../services/settings.service.js';
|
|
16
|
+
import { recordPhaseStart, recordPhaseEnd } from '../../phase-timing-context.js';
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
18
|
+
* Watch CI using an agent call. The agent checks ALL runs for the branch,
|
|
19
|
+
* waits for ALL to complete, and reports structured CI_STATUS.
|
|
20
|
+
*
|
|
21
|
+
* Records a phase timing entry for the activity timeline.
|
|
22
|
+
*
|
|
23
|
+
* @returns Parsed CI status result with usage metrics
|
|
24
|
+
*/
|
|
25
|
+
async function watchCiViaAgent(executor, branch, options, timeoutMs, log) {
|
|
26
|
+
const watchOptions = { ...options, timeout: timeoutMs };
|
|
27
|
+
const watchPrompt = buildCiWatchPrompt(branch);
|
|
28
|
+
const watchStart = Date.now();
|
|
29
|
+
const timingId = await recordPhaseStart('merge:ci-watch', {
|
|
30
|
+
agentType: executor.agentType,
|
|
31
|
+
prompt: watchPrompt,
|
|
32
|
+
});
|
|
33
|
+
try {
|
|
34
|
+
const result = await retryExecute(executor, watchPrompt, watchOptions, {
|
|
35
|
+
maxAttempts: 1,
|
|
36
|
+
logger: log,
|
|
37
|
+
});
|
|
38
|
+
const elapsed = Date.now() - watchStart;
|
|
39
|
+
await recordPhaseEnd(timingId, elapsed, {
|
|
40
|
+
inputTokens: result.usage?.inputTokens,
|
|
41
|
+
outputTokens: result.usage?.outputTokens,
|
|
42
|
+
costUsd: result.usage?.costUsd,
|
|
43
|
+
numTurns: result.usage?.numTurns,
|
|
44
|
+
durationApiMs: result.usage?.durationApiMs,
|
|
45
|
+
exitCode: 'success',
|
|
46
|
+
});
|
|
47
|
+
const parsed = parseCiWatchResult(result.result);
|
|
48
|
+
return { ...parsed, usage: result.usage };
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const elapsed = Date.now() - watchStart;
|
|
52
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
53
|
+
await recordPhaseEnd(timingId, elapsed, {
|
|
54
|
+
exitCode: 'error',
|
|
55
|
+
errorMessage: errMsg.slice(0, 500),
|
|
56
|
+
});
|
|
57
|
+
// Check if this is a timeout
|
|
58
|
+
if (errMsg.includes('timed out') || errMsg.includes('timeout')) {
|
|
59
|
+
return { status: 'failure', summary: 'CI watch timed out', timedOut: true };
|
|
60
|
+
}
|
|
61
|
+
// For other errors, treat as indeterminate (failure)
|
|
62
|
+
return { status: 'failure', summary: `CI watch agent error: ${errMsg.slice(0, 200)}` };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Run the CI watch/fix loop. Watches for the initial CI result using an
|
|
67
|
+
* agent-based approach, then iteratively attempts fixes up to the configured maximum.
|
|
16
68
|
*
|
|
17
69
|
* Throws on timeout or exhausted attempts (after updating feature state).
|
|
18
70
|
*/
|
|
@@ -23,12 +75,11 @@ export async function runCiWatchFixLoop(deps, params) {
|
|
|
23
75
|
const maxAttempts = settings.workflow?.ciMaxFixAttempts ?? 3;
|
|
24
76
|
const timeoutMs = settings.workflow?.ciWatchTimeoutMs ?? 600_000;
|
|
25
77
|
const logMaxChars = settings.workflow?.ciLogMaxChars ?? 50_000;
|
|
26
|
-
const pollInterval = settings.workflow?.ciWatchPollIntervalSeconds ?? 30;
|
|
27
78
|
let ciFixAttempts = params.existingAttempts;
|
|
28
79
|
const ciFixHistory = [];
|
|
29
80
|
let ciFixStatus;
|
|
30
81
|
log.info(`Starting CI watch (maxAttempts=${maxAttempts}, timeout=${timeoutMs}ms)`);
|
|
31
|
-
// Check if any CI run exists for this branch
|
|
82
|
+
// Check if any CI run exists for this branch (lightweight check before spawning agent)
|
|
32
83
|
let initialCiStatus;
|
|
33
84
|
try {
|
|
34
85
|
initialCiStatus = await gitPrService.getCiStatus(cwd, branch);
|
|
@@ -65,30 +116,22 @@ export async function runCiWatchFixLoop(deps, params) {
|
|
|
65
116
|
return { ciStatus: CiStatus.Success, ciFixAttempts, ciFixHistory, ciFixStatus: 'idle' };
|
|
66
117
|
}
|
|
67
118
|
let runUrl = initialCiStatus.runUrl;
|
|
68
|
-
// Initial CI watch
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
watchResult = await gitPrService.watchCi(cwd, branch, timeoutMs, pollInterval);
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
if (err instanceof GitPrError && err.code === GitPrErrorCode.CI_TIMEOUT) {
|
|
75
|
-
log.info('Initial CI watch timed out');
|
|
76
|
-
ciFixHistory.push({
|
|
77
|
-
attempt: ciFixAttempts + 1,
|
|
78
|
-
startedAt: new Date().toISOString(),
|
|
79
|
-
failureSummary: 'CI watch timed out',
|
|
80
|
-
outcome: 'timeout',
|
|
81
|
-
});
|
|
82
|
-
await handleCiTerminalFailure(feature, prUrl, prNumber, deps.featureRepository, messages);
|
|
83
|
-
throw buildCiExhaustedError(ciFixAttempts + 1, ciFixHistory, 'timeout');
|
|
84
|
-
}
|
|
85
|
-
throw err;
|
|
86
|
-
}
|
|
87
|
-
// Use the run URL from watchCi — it reflects the actual run watched,
|
|
88
|
-
// which may differ from the initial getCiStatus() result when multiple
|
|
89
|
-
// workflow runs exist for the same branch.
|
|
119
|
+
// Initial CI watch via agent
|
|
120
|
+
log.info('Watching CI via agent (checks ALL runs)');
|
|
121
|
+
const watchResult = await watchCiViaAgent(executor, branch, options, timeoutMs, log);
|
|
90
122
|
if (watchResult.runUrl)
|
|
91
123
|
runUrl = watchResult.runUrl;
|
|
124
|
+
if (watchResult.timedOut) {
|
|
125
|
+
log.info('Initial CI watch timed out');
|
|
126
|
+
ciFixHistory.push({
|
|
127
|
+
attempt: ciFixAttempts + 1,
|
|
128
|
+
startedAt: new Date().toISOString(),
|
|
129
|
+
failureSummary: 'CI watch timed out',
|
|
130
|
+
outcome: 'timeout',
|
|
131
|
+
});
|
|
132
|
+
await handleCiTerminalFailure(feature, prUrl, prNumber, deps.featureRepository, messages);
|
|
133
|
+
throw buildCiExhaustedError(ciFixAttempts + 1, ciFixHistory, 'timeout');
|
|
134
|
+
}
|
|
92
135
|
if (watchResult.status === 'success') {
|
|
93
136
|
log.info('CI passed on first watch');
|
|
94
137
|
return { ciStatus: CiStatus.Success, ciFixAttempts, ciFixHistory, ciFixStatus: 'success' };
|
|
@@ -101,23 +144,40 @@ export async function runCiWatchFixLoop(deps, params) {
|
|
|
101
144
|
ciFixStatus = 'exhausted';
|
|
102
145
|
break;
|
|
103
146
|
}
|
|
104
|
-
// Fetch failure logs
|
|
147
|
+
// Fetch failure logs for context
|
|
105
148
|
const runId = extractRunId(runUrl) ?? '';
|
|
106
149
|
const failureLogs = await gitPrService.getFailureLogs(cwd, runId, branch, logMaxChars);
|
|
107
150
|
const startedAt = new Date().toISOString();
|
|
108
151
|
log.info(`CI fix attempt ${ciFixAttempts + 1}/${maxAttempts} for run ${runId}`);
|
|
152
|
+
// Record fix phase timing
|
|
153
|
+
const fixStart = Date.now();
|
|
154
|
+
const fixTimingId = await recordPhaseStart('merge:ci-fix', {
|
|
155
|
+
agentType: executor.agentType,
|
|
156
|
+
});
|
|
109
157
|
// Invoke fix executor — maxAttempts:1 prevents retryExecute's internal
|
|
110
158
|
// retry logic from consuming CI fix attempts behind the outer loop's back.
|
|
111
|
-
// Each CI fix is a unique attempt with distinct failure logs and prompt;
|
|
112
|
-
// the outer loop already handles iteration.
|
|
113
159
|
const fixPrompt = buildCiWatchFixPrompt(failureLogs, ciFixAttempts + 1, maxAttempts, branch);
|
|
114
160
|
try {
|
|
115
|
-
await retryExecute(executor, fixPrompt, options, {
|
|
161
|
+
const fixResult = await retryExecute(executor, fixPrompt, options, {
|
|
162
|
+
maxAttempts: 1,
|
|
163
|
+
logger: log,
|
|
164
|
+
});
|
|
165
|
+
await recordPhaseEnd(fixTimingId, Date.now() - fixStart, {
|
|
166
|
+
inputTokens: fixResult.usage?.inputTokens,
|
|
167
|
+
outputTokens: fixResult.usage?.outputTokens,
|
|
168
|
+
costUsd: fixResult.usage?.costUsd,
|
|
169
|
+
numTurns: fixResult.usage?.numTurns,
|
|
170
|
+
durationApiMs: fixResult.usage?.durationApiMs,
|
|
171
|
+
exitCode: 'success',
|
|
172
|
+
});
|
|
116
173
|
}
|
|
117
174
|
catch (execErr) {
|
|
118
175
|
// If the fix executor fails, count it as a failed attempt and continue
|
|
119
|
-
// the loop rather than killing the entire CI fix process.
|
|
120
176
|
const execMsg = execErr instanceof Error ? execErr.message : String(execErr);
|
|
177
|
+
await recordPhaseEnd(fixTimingId, Date.now() - fixStart, {
|
|
178
|
+
exitCode: 'error',
|
|
179
|
+
errorMessage: execMsg.slice(0, 500),
|
|
180
|
+
});
|
|
121
181
|
log.info(`CI fix executor failed on attempt ${ciFixAttempts + 1}: ${execMsg}`);
|
|
122
182
|
ciFixAttempts++;
|
|
123
183
|
ciFixHistory.push({
|
|
@@ -130,44 +190,22 @@ export async function runCiWatchFixLoop(deps, params) {
|
|
|
130
190
|
continue;
|
|
131
191
|
}
|
|
132
192
|
ciFixAttempts++;
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
fixWatchResult = await gitPrService.watchCi(cwd, branch, timeoutMs, pollInterval);
|
|
141
|
-
}
|
|
142
|
-
catch (err) {
|
|
143
|
-
if (err instanceof GitPrError && err.code === GitPrErrorCode.CI_TIMEOUT) {
|
|
144
|
-
log.info(`CI watch timed out during fix attempt ${ciFixAttempts}`);
|
|
145
|
-
ciFixHistory.push({
|
|
146
|
-
attempt: ciFixAttempts,
|
|
147
|
-
startedAt,
|
|
148
|
-
failureSummary: failureLogs.slice(0, 500),
|
|
149
|
-
outcome: 'timeout',
|
|
150
|
-
});
|
|
151
|
-
ciFixStatus = 'timeout';
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
// For non-timeout watchCi errors (e.g. GIT_ERROR), treat as a failed
|
|
155
|
-
// attempt and continue the loop instead of killing it.
|
|
156
|
-
const watchMsg = err instanceof Error ? err.message : String(err);
|
|
157
|
-
log.info(`CI watch failed during fix attempt ${ciFixAttempts}: ${watchMsg}`);
|
|
193
|
+
// Watch CI after fix via agent (agent checks ALL runs for updated branch)
|
|
194
|
+
log.info('Watching CI after fix via agent');
|
|
195
|
+
const fixWatchResult = await watchCiViaAgent(executor, branch, options, timeoutMs, log);
|
|
196
|
+
if (fixWatchResult.runUrl)
|
|
197
|
+
runUrl = fixWatchResult.runUrl;
|
|
198
|
+
if (fixWatchResult.timedOut) {
|
|
199
|
+
log.info(`CI watch timed out during fix attempt ${ciFixAttempts}`);
|
|
158
200
|
ciFixHistory.push({
|
|
159
201
|
attempt: ciFixAttempts,
|
|
160
202
|
startedAt,
|
|
161
203
|
failureSummary: failureLogs.slice(0, 500),
|
|
162
|
-
outcome: '
|
|
204
|
+
outcome: 'timeout',
|
|
163
205
|
});
|
|
164
|
-
|
|
165
|
-
|
|
206
|
+
ciFixStatus = 'timeout';
|
|
207
|
+
break;
|
|
166
208
|
}
|
|
167
|
-
// Update runUrl to the run that was actually watched (avoids mismatch
|
|
168
|
-
// when multiple workflow runs exist for the same branch).
|
|
169
|
-
if (fixWatchResult.runUrl)
|
|
170
|
-
runUrl = fixWatchResult.runUrl;
|
|
171
209
|
const outcome = fixWatchResult.status === 'success' ? 'fixed' : 'failed';
|
|
172
210
|
ciFixHistory.push({
|
|
173
211
|
attempt: ciFixAttempts,
|
|
@@ -8,6 +8,11 @@ export interface PrParseResult {
|
|
|
8
8
|
url: string;
|
|
9
9
|
number: number;
|
|
10
10
|
}
|
|
11
|
+
export interface CiWatchParseResult {
|
|
12
|
+
status: 'success' | 'failure';
|
|
13
|
+
summary?: string;
|
|
14
|
+
runUrl?: string;
|
|
15
|
+
}
|
|
11
16
|
/**
|
|
12
17
|
* Extract the first commit SHA from agent output text.
|
|
13
18
|
* Looks for git commit output format `[branch SHA]` or `commit SHA`.
|
|
@@ -19,4 +24,11 @@ export declare function parseCommitHash(output: string): string | null;
|
|
|
19
24
|
* Returns null if no PR URL found.
|
|
20
25
|
*/
|
|
21
26
|
export declare function parsePrUrl(output: string): PrParseResult | null;
|
|
27
|
+
/**
|
|
28
|
+
* Extract CI watch result from agent output text.
|
|
29
|
+
* Looks for CI_STATUS: PASSED or CI_STATUS: FAILED markers.
|
|
30
|
+
* When multiple CI_STATUS markers appear, uses the last one.
|
|
31
|
+
* Returns failure with diagnostic summary if no marker found.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseCiWatchResult(output: string): CiWatchParseResult;
|
|
22
34
|
//# sourceMappingURL=merge-output-parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-output-parser.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAI/D"}
|
|
1
|
+
{"version":3,"file":"merge-output-parser.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge-output-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AASD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAI/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAuBrE"}
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
const COMMIT_SHA_RE = /\[[\w/.-]+\s+([0-9a-f]{7,40})\]|(?:commit\s+)([0-9a-f]{7,40})/i;
|
|
10
10
|
// Matches GitHub PR URL: https://github.com/owner/repo/pull/123
|
|
11
11
|
const PR_URL_RE = /(https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/pull\/(\d+))/;
|
|
12
|
+
// Matches CI_STATUS: PASSED or CI_STATUS: FAILED — <summary>
|
|
13
|
+
const CI_STATUS_PASSED_RE = /CI_STATUS:\s*PASSED/;
|
|
14
|
+
const CI_STATUS_FAILED_RE = /CI_STATUS:\s*FAILED(?:\s*—\s*(.+))?/;
|
|
15
|
+
// Matches GitHub Actions run URL
|
|
16
|
+
const RUN_URL_RE = /(https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/actions\/runs\/\d+)/;
|
|
12
17
|
/**
|
|
13
18
|
* Extract the first commit SHA from agent output text.
|
|
14
19
|
* Looks for git commit output format `[branch SHA]` or `commit SHA`.
|
|
@@ -30,3 +35,31 @@ export function parsePrUrl(output) {
|
|
|
30
35
|
return null;
|
|
31
36
|
return { url: match[1], number: parseInt(match[2], 10) };
|
|
32
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Extract CI watch result from agent output text.
|
|
40
|
+
* Looks for CI_STATUS: PASSED or CI_STATUS: FAILED markers.
|
|
41
|
+
* When multiple CI_STATUS markers appear, uses the last one.
|
|
42
|
+
* Returns failure with diagnostic summary if no marker found.
|
|
43
|
+
*/
|
|
44
|
+
export function parseCiWatchResult(output) {
|
|
45
|
+
const runUrlMatch = output.match(RUN_URL_RE);
|
|
46
|
+
const runUrl = runUrlMatch ? runUrlMatch[1] : undefined;
|
|
47
|
+
// Split into lines and check from bottom up (last status wins)
|
|
48
|
+
const lines = output.split('\n');
|
|
49
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
50
|
+
const line = lines[i];
|
|
51
|
+
if (CI_STATUS_PASSED_RE.test(line)) {
|
|
52
|
+
return { status: 'success', runUrl };
|
|
53
|
+
}
|
|
54
|
+
const failedMatch = line.match(CI_STATUS_FAILED_RE);
|
|
55
|
+
if (failedMatch) {
|
|
56
|
+
const summary = failedMatch[1]?.trim() || 'CI failed (no details provided)';
|
|
57
|
+
return { status: 'failure', summary, runUrl };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
status: 'failure',
|
|
62
|
+
summary: 'CI status could not be determined from agent output',
|
|
63
|
+
runUrl,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -44,4 +44,14 @@ export declare function buildCommitPushPrPrompt(state: FeatureAgentState, branch
|
|
|
44
44
|
* @param branch - Feature branch name to push to after fixing
|
|
45
45
|
*/
|
|
46
46
|
export declare function buildCiWatchFixPrompt(failureLogs: string, attemptNumber: number, maxAttempts: number, branch: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Build a prompt for the CI watch agent call.
|
|
49
|
+
*
|
|
50
|
+
* Instructs the agent to check ALL CI runs for a branch, wait for all
|
|
51
|
+
* to complete, verify every run passed, and report structured status.
|
|
52
|
+
* Generic — works with any git/gh repo, not tied to specific workflows.
|
|
53
|
+
*
|
|
54
|
+
* @param branch - Feature branch name to watch CI for
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildCiWatchPrompt(branch: string): string;
|
|
47
57
|
//# sourceMappingURL=merge-prompts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwCxD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU9F;AAuCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,EAAE,EACpB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAUR;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAqER;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CA0BR"}
|
|
1
|
+
{"version":3,"file":"merge-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwCxD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU9F;AAuCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,EAAE,EACpB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAUR;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAqER;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CA0BR;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqDzD"}
|
|
@@ -219,3 +219,66 @@ ${failureLogs}
|
|
|
219
219
|
- Do NOT create a new branch — push directly to \`${branch}\`
|
|
220
220
|
- If the failure is unclear, make your best diagnosis and explain your reasoning in the commit message`;
|
|
221
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Build a prompt for the CI watch agent call.
|
|
224
|
+
*
|
|
225
|
+
* Instructs the agent to check ALL CI runs for a branch, wait for all
|
|
226
|
+
* to complete, verify every run passed, and report structured status.
|
|
227
|
+
* Generic — works with any git/gh repo, not tied to specific workflows.
|
|
228
|
+
*
|
|
229
|
+
* @param branch - Feature branch name to watch CI for
|
|
230
|
+
*/
|
|
231
|
+
export function buildCiWatchPrompt(branch) {
|
|
232
|
+
return `You are checking CI status for branch \`${branch}\`.
|
|
233
|
+
|
|
234
|
+
## Instructions
|
|
235
|
+
|
|
236
|
+
Follow these steps EXACTLY:
|
|
237
|
+
|
|
238
|
+
### Step 1: List all CI runs for the branch
|
|
239
|
+
|
|
240
|
+
\`\`\`
|
|
241
|
+
gh run list --branch ${branch} --json databaseId,status,conclusion,name
|
|
242
|
+
\`\`\`
|
|
243
|
+
|
|
244
|
+
This shows ALL workflow runs. A single push can trigger MULTIPLE runs (e.g., CI/CD + PR validation).
|
|
245
|
+
You MUST check every run, not just one.
|
|
246
|
+
|
|
247
|
+
### Step 2: Watch all in-progress runs
|
|
248
|
+
|
|
249
|
+
For EACH run with \`status\` that is NOT \`completed\`, watch it:
|
|
250
|
+
|
|
251
|
+
\`\`\`
|
|
252
|
+
gh run watch <databaseId> --interval 20
|
|
253
|
+
\`\`\`
|
|
254
|
+
|
|
255
|
+
Wait for each in-progress run to finish before proceeding.
|
|
256
|
+
|
|
257
|
+
### Step 3: Verify all runs after watching
|
|
258
|
+
|
|
259
|
+
After all runs complete, run the list command again to confirm:
|
|
260
|
+
|
|
261
|
+
\`\`\`
|
|
262
|
+
gh run list --branch ${branch} --json databaseId,status,conclusion,name
|
|
263
|
+
\`\`\`
|
|
264
|
+
|
|
265
|
+
Check that EVERY run shows \`status: completed\`. Do NOT trust \`gh run watch\` exit status alone.
|
|
266
|
+
|
|
267
|
+
### Step 4: Report status
|
|
268
|
+
|
|
269
|
+
After verifying all runs are complete, report EXACTLY ONE of these lines:
|
|
270
|
+
|
|
271
|
+
- If every run has \`conclusion: success\`:
|
|
272
|
+
\`CI_STATUS: PASSED\`
|
|
273
|
+
|
|
274
|
+
- If any run has a non-success conclusion:
|
|
275
|
+
\`CI_STATUS: FAILED — <brief summary of which runs failed and why>\`
|
|
276
|
+
|
|
277
|
+
## Constraints
|
|
278
|
+
|
|
279
|
+
- NEVER claim CI passed until EVERY run shows \`completed\` + \`success\`
|
|
280
|
+
- NEVER watch a single run and assume it is the only one
|
|
281
|
+
- If \`gh run list\` returns no runs, wait 10 seconds and retry up to 3 times
|
|
282
|
+
- If rate-limited (403 error), report: \`CI_STATUS: PASSED\` (skip check gracefully)
|
|
283
|
+
- Print the URL of the failing run if CI fails`;
|
|
284
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Feature List Command
|
|
3
3
|
*
|
|
4
|
-
* Lists features in a
|
|
5
|
-
*
|
|
4
|
+
* Lists features in a hierarchical tree view: repo → feature → child → child…
|
|
5
|
+
* Repos and features are ordered by creation date descending.
|
|
6
6
|
*
|
|
7
7
|
* Usage: shep feat ls [options]
|
|
8
8
|
*
|
|
@@ -11,5 +11,47 @@
|
|
|
11
11
|
* $ shep feat ls --repo /path/to/project
|
|
12
12
|
*/
|
|
13
13
|
import { Command } from 'commander';
|
|
14
|
+
import type { Feature, AgentRun, PhaseTiming, Repository } from '../../../../../packages/core/src/domain/generated/output.js';
|
|
15
|
+
/** Convert a date value (any type from domain) to a timestamp for sorting. */
|
|
16
|
+
export declare function toTimestamp(val: unknown): number;
|
|
17
|
+
interface Entry {
|
|
18
|
+
feature: Feature;
|
|
19
|
+
run: AgentRun | null;
|
|
20
|
+
phases: PhaseTiming[];
|
|
21
|
+
}
|
|
22
|
+
interface TreeNode {
|
|
23
|
+
entry: Entry;
|
|
24
|
+
children: TreeNode[];
|
|
25
|
+
}
|
|
26
|
+
interface RepoGroup {
|
|
27
|
+
repoPath: string;
|
|
28
|
+
repoName: string;
|
|
29
|
+
repoCreatedAt: number;
|
|
30
|
+
roots: TreeNode[];
|
|
31
|
+
}
|
|
32
|
+
interface FlatRow {
|
|
33
|
+
entry: Entry;
|
|
34
|
+
parentIsLast: boolean[];
|
|
35
|
+
isLast: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build a recursive feature tree within a single repo group.
|
|
39
|
+
* Features with a parentId that matches another feature in the group become children.
|
|
40
|
+
* All levels are sorted by createdAt descending.
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildTree(entries: Entry[]): TreeNode[];
|
|
43
|
+
/**
|
|
44
|
+
* Group entries by repositoryPath and sort repos by createdAt desc.
|
|
45
|
+
* Uses the Repository entity's createdAt if available; falls back to the
|
|
46
|
+
* newest feature's createdAt in that repo group.
|
|
47
|
+
*/
|
|
48
|
+
export declare function groupByRepo(entries: Entry[], repos: Repository[]): RepoGroup[];
|
|
49
|
+
/** Flatten a tree into rows with prefix context for rendering. */
|
|
50
|
+
export declare function flattenTree(nodes: TreeNode[], parentIsLast: boolean[]): FlatRow[];
|
|
51
|
+
/** Build the tree-drawing prefix string for a given depth context. */
|
|
52
|
+
export declare function buildTreePrefix(parentIsLast: boolean[], isLast: boolean): string;
|
|
53
|
+
/** Render a single feature row as a formatted string. */
|
|
54
|
+
export declare function renderFeatureRow(entry: Entry, treePrefix: string): string;
|
|
14
55
|
export declare function createLsCommand(): Command;
|
|
56
|
+
export {};
|
|
15
57
|
//# sourceMappingURL=ls.command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ls.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/ls.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"ls.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/ls.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAyJ/F,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAOhD;AAiBD,UAAU,KAAK;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,UAAU,QAAQ;IAChB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB;AAED,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,UAAU,OAAO;IACf,KAAK,EAAE,KAAK,CAAC;IACb,YAAY,EAAE,OAAO,EAAE,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAgCtD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,SAAS,EAAE,CA8B9E;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAWjF;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAOhF;AAQD,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAazE;AAeD,wBAAgB,eAAe,IAAI,OAAO,CAiFzC"}
|