@shepai/cli 1.103.0 → 1.103.1-pr308.436876d
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/use-cases/upgrade/upgrade-cli.use-case.d.ts +27 -0
- package/dist/packages/core/src/application/use-cases/upgrade/upgrade-cli.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/upgrade/upgrade-cli.use-case.js +128 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +5 -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 +1 -3
- package/dist/src/presentation/cli/ui/symbols.d.ts +1 -1
- package/dist/src/presentation/web/app/api/cli-upgrade/route.d.ts +3 -0
- package/dist/src/presentation/web/app/api/cli-upgrade/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/cli-upgrade/route.js +31 -0
- package/dist/src/presentation/web/components/common/version-badge/version-badge.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/version-badge/version-badge.js +6 -2
- package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts +2 -2
- package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.js +20 -3
- package/dist/src/presentation/web/hooks/use-cli-upgrade.d.ts +11 -0
- package/dist/src/presentation/web/hooks/use-cli-upgrade.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/use-cli-upgrade.js +73 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +1 -0
- 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/routes-manifest.json +6 -0
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +20 -20
- 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 +25 -25
- 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 +25 -25
- 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 +18 -18
- 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 +20 -20
- 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 +25 -25
- 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 +25 -25
- 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 +18 -18
- 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 +18 -18
- 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/api/cli-upgrade/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/cli-upgrade/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/cli-upgrade/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/cli-upgrade/route.js +6 -0
- package/web/.next/server/app/api/cli-upgrade/route.js.map +5 -0
- package/web/.next/server/app/api/cli-upgrade/route.js.nft.json +1 -0
- package/web/.next/server/app/api/cli-upgrade/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/evidence/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/app-paths-manifest.json +1 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_cli-upgrade_route_actions_dc509b52.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_cli-upgrade_route_actions_dc509b52.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__d2c18946._.js +11 -0
- package/web/.next/server/chunks/[root-of-the-server]__d2c18946._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__f47bb8a5._.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/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_0a7546ed.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_0a7546ed.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_978cbb4c.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_978cbb4c.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]__24dd0927._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__51fc98b0._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__51fc98b0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__57f37786._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__57f37786._.js.map +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]__708dcad1._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__708dcad1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e002910._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e002910._.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]__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/_8dacd1e7._.js +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_43bc1b22._.js → _a09fb04a._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_43bc1b22._.js.map → _a09fb04a._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_6225647a._.js → _afa40e06._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_6225647a._.js.map → _afa40e06._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_798dcca3._.js → _baab52a9._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_798dcca3._.js.map → _baab52a9._.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_7275ce5d._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_7275ce5d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_758dfa10._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_758dfa10._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_84803221.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_84803221.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_components_bf50c527._.js +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_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 +30 -30
- package/web/.next/static/chunks/{790f576eb41aedc6.js → 2549eb5f74129ce6.js} +1 -1
- package/web/.next/static/chunks/{87ce4933c46c0c18.js → 2f3dedf11842dbb9.js} +1 -1
- package/web/.next/static/chunks/{f37993a7b6f87fcb.js → 3b5a1f399be3c204.js} +1 -1
- package/web/.next/static/chunks/3bb35e0689e8b6b7.js +1 -0
- package/web/.next/static/chunks/5a850475e2b3e8d7.js +2 -0
- package/web/.next/static/chunks/{28aa6c032562c065.js → 5b52afbeb6af43f8.js} +1 -1
- package/web/.next/static/chunks/{a39402a05bf12912.js → 6f16220ca6a15488.js} +1 -1
- package/web/.next/static/chunks/{3ff4c5790bf84403.js → c72a9bffb0609ccb.js} +1 -1
- package/web/.next/static/chunks/{12f2e950ef2c1a25.js → d7acdf8831c942f1.js} +1 -1
- package/web/.next/static/chunks/{27b176706ec35488.js → f164721e9111efd2.js} +2 -2
- package/web/.next/static/chunks/{5981cd90d8cbdad7.js → f8a27920b2acfead.js} +1 -1
- package/web/.next/static/chunks/2a6f05312c4f37ce.js +0 -1
- package/web/.next/static/chunks/8f9956f5871a8cdb.js +0 -2
- /package/web/.next/static/{YTwpzFRHYkkE5cDxaRlDQ → Bn9oiHUSrxNyoG9stevwc}/_buildManifest.js +0 -0
- /package/web/.next/static/{YTwpzFRHYkkE5cDxaRlDQ → Bn9oiHUSrxNyoG9stevwc}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{YTwpzFRHYkkE5cDxaRlDQ → Bn9oiHUSrxNyoG9stevwc}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UpgradeCliUseCase
|
|
3
|
+
*
|
|
4
|
+
* Executes a self-upgrade of @shepai/cli to the latest published version.
|
|
5
|
+
* Mirrors the CLI upgrade command logic but designed for use from the web layer.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Check latest version from npm registry (fail-open)
|
|
9
|
+
* 2. Compare with current version — return early if up to date
|
|
10
|
+
* 3. Run `npm i -g @shepai/cli@latest` with streamed output
|
|
11
|
+
* 4. Return result with old/new version info
|
|
12
|
+
*/
|
|
13
|
+
import type { IVersionService } from '../../ports/output/services/version-service.interface.js';
|
|
14
|
+
export interface UpgradeResult {
|
|
15
|
+
status: 'up-to-date' | 'upgraded' | 'error';
|
|
16
|
+
currentVersion: string;
|
|
17
|
+
latestVersion: string | null;
|
|
18
|
+
errorMessage?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare class UpgradeCliUseCase {
|
|
21
|
+
private readonly versionService;
|
|
22
|
+
constructor(versionService: IVersionService);
|
|
23
|
+
execute(onOutput?: (data: string) => void): Promise<UpgradeResult>;
|
|
24
|
+
private getLatestVersion;
|
|
25
|
+
private runNpmInstall;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=upgrade-cli.use-case.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade-cli.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/upgrade/upgrade-cli.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0DAA0D,CAAC;AAEhG,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,GAAG,UAAU,GAAG,OAAO,CAAC;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,qBACa,iBAAiB;IAG1B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,eAAe;IAG5C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IAkCxE,OAAO,CAAC,gBAAgB;IA6CxB,OAAO,CAAC,aAAa;CAuBtB"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UpgradeCliUseCase
|
|
3
|
+
*
|
|
4
|
+
* Executes a self-upgrade of @shepai/cli to the latest published version.
|
|
5
|
+
* Mirrors the CLI upgrade command logic but designed for use from the web layer.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Check latest version from npm registry (fail-open)
|
|
9
|
+
* 2. Compare with current version — return early if up to date
|
|
10
|
+
* 3. Run `npm i -g @shepai/cli@latest` with streamed output
|
|
11
|
+
* 4. Return result with old/new version info
|
|
12
|
+
*/
|
|
13
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
14
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
16
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
17
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
18
|
+
};
|
|
19
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
21
|
+
};
|
|
22
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
23
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
24
|
+
};
|
|
25
|
+
import { injectable, inject } from 'tsyringe';
|
|
26
|
+
import { spawn } from 'node:child_process';
|
|
27
|
+
const VERSION_CHECK_TIMEOUT_MS = 10_000;
|
|
28
|
+
let UpgradeCliUseCase = class UpgradeCliUseCase {
|
|
29
|
+
versionService;
|
|
30
|
+
constructor(versionService) {
|
|
31
|
+
this.versionService = versionService;
|
|
32
|
+
}
|
|
33
|
+
async execute(onOutput) {
|
|
34
|
+
const { version: currentVersion } = this.versionService.getVersion();
|
|
35
|
+
// 1. Check latest version (fail-open)
|
|
36
|
+
const latestVersion = await this.getLatestVersion(onOutput);
|
|
37
|
+
// 2. Already up to date
|
|
38
|
+
if (latestVersion && latestVersion === currentVersion) {
|
|
39
|
+
onOutput?.(`Already up to date (v${currentVersion})\n`);
|
|
40
|
+
return { status: 'up-to-date', currentVersion, latestVersion };
|
|
41
|
+
}
|
|
42
|
+
// 3. Run upgrade
|
|
43
|
+
const target = latestVersion ? `v${latestVersion}` : 'latest';
|
|
44
|
+
onOutput?.(`Upgrading from v${currentVersion} to ${target}...\n`);
|
|
45
|
+
try {
|
|
46
|
+
const exitCode = await this.runNpmInstall(onOutput);
|
|
47
|
+
if (exitCode === 0) {
|
|
48
|
+
onOutput?.(`Successfully upgraded to ${target}\n`);
|
|
49
|
+
return { status: 'upgraded', currentVersion, latestVersion };
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const msg = `npm install exited with code ${exitCode}`;
|
|
53
|
+
onOutput?.(`Error: ${msg}\n`);
|
|
54
|
+
return { status: 'error', currentVersion, latestVersion, errorMessage: msg };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
const msg = error instanceof Error ? error.message : 'Installation failed';
|
|
59
|
+
onOutput?.(`Error: ${msg}\n`);
|
|
60
|
+
return { status: 'error', currentVersion, latestVersion, errorMessage: msg };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
getLatestVersion(onOutput) {
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
let output = '';
|
|
66
|
+
let settled = false;
|
|
67
|
+
const child = spawn('npm', ['view', '@shepai/cli', 'version'], {
|
|
68
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
69
|
+
});
|
|
70
|
+
const timeout = setTimeout(() => {
|
|
71
|
+
if (!settled) {
|
|
72
|
+
settled = true;
|
|
73
|
+
child.kill();
|
|
74
|
+
onOutput?.('Version check timed out, proceeding with upgrade...\n');
|
|
75
|
+
resolve(null);
|
|
76
|
+
}
|
|
77
|
+
}, VERSION_CHECK_TIMEOUT_MS);
|
|
78
|
+
child.stdout?.on('data', (data) => {
|
|
79
|
+
output += data.toString();
|
|
80
|
+
});
|
|
81
|
+
child.on('close', (code) => {
|
|
82
|
+
if (!settled) {
|
|
83
|
+
settled = true;
|
|
84
|
+
clearTimeout(timeout);
|
|
85
|
+
if (code === 0 && output.trim()) {
|
|
86
|
+
resolve(output.trim());
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
resolve(null);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
child.on('error', () => {
|
|
94
|
+
if (!settled) {
|
|
95
|
+
settled = true;
|
|
96
|
+
clearTimeout(timeout);
|
|
97
|
+
onOutput?.('Could not check latest version\n');
|
|
98
|
+
resolve(null);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
runNpmInstall(onOutput) {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
const child = spawn('npm', ['i', '-g', '@shepai/cli@latest'], {
|
|
106
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
107
|
+
});
|
|
108
|
+
child.stdout?.on('data', (data) => {
|
|
109
|
+
onOutput?.(data.toString());
|
|
110
|
+
});
|
|
111
|
+
child.stderr?.on('data', (data) => {
|
|
112
|
+
onOutput?.(data.toString());
|
|
113
|
+
});
|
|
114
|
+
child.on('close', (code) => {
|
|
115
|
+
resolve(code ?? 1);
|
|
116
|
+
});
|
|
117
|
+
child.on('error', (err) => {
|
|
118
|
+
reject(err);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
UpgradeCliUseCase = __decorate([
|
|
124
|
+
injectable(),
|
|
125
|
+
__param(0, inject('IVersionService')),
|
|
126
|
+
__metadata("design:paramtypes", [Object])
|
|
127
|
+
], UpgradeCliUseCase);
|
|
128
|
+
export { UpgradeCliUseCase };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAkHrC;;;;;;GAMG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,SAAS,CAAC,CA8SrE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -77,6 +77,7 @@ import { DeleteRepositoryUseCase } from '../../application/use-cases/repositorie
|
|
|
77
77
|
import { CheckAndUnblockFeaturesUseCase } from '../../application/use-cases/features/check-and-unblock-features.use-case.js';
|
|
78
78
|
import { UpdateFeatureLifecycleUseCase } from '../../application/use-cases/features/update/update-feature-lifecycle.use-case.js';
|
|
79
79
|
import { CleanupFeatureWorktreeUseCase } from '../../application/use-cases/features/cleanup-feature-worktree.use-case.js';
|
|
80
|
+
import { UpgradeCliUseCase } from '../../application/use-cases/upgrade/upgrade-cli.use-case.js';
|
|
80
81
|
// Session listing
|
|
81
82
|
import { ClaudeCodeSessionRepository } from '../services/agents/sessions/claude-code-session.repository.js';
|
|
82
83
|
import { StubSessionRepository } from '../services/agents/sessions/stub-session.repository.js';
|
|
@@ -279,6 +280,7 @@ export async function initializeContainer() {
|
|
|
279
280
|
container.registerSingleton(CheckAndUnblockFeaturesUseCase);
|
|
280
281
|
container.registerSingleton(UpdateFeatureLifecycleUseCase);
|
|
281
282
|
container.registerSingleton(CleanupFeatureWorktreeUseCase);
|
|
283
|
+
container.registerSingleton(UpgradeCliUseCase);
|
|
282
284
|
// Session repositories (per-AgentType string tokens)
|
|
283
285
|
container.register(`IAgentSessionRepository:${AgentType.ClaudeCode}`, {
|
|
284
286
|
useFactory: () => new ClaudeCodeSessionRepository(),
|
|
@@ -360,6 +362,9 @@ export async function initializeContainer() {
|
|
|
360
362
|
container.register('CleanupFeatureWorktreeUseCase', {
|
|
361
363
|
useFactory: (c) => c.resolve(CleanupFeatureWorktreeUseCase),
|
|
362
364
|
});
|
|
365
|
+
container.register('UpgradeCliUseCase', {
|
|
366
|
+
useFactory: (c) => c.resolve(UpgradeCliUseCase),
|
|
367
|
+
});
|
|
363
368
|
_initialized = true;
|
|
364
369
|
return container;
|
|
365
370
|
}
|
|
@@ -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,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;
|
|
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;IAqC1D,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"}
|
|
@@ -127,9 +127,7 @@ let WorktreeService = class WorktreeService {
|
|
|
127
127
|
}
|
|
128
128
|
await this.execFile('git', ['config', 'user.name', GIT_AUTO_INIT_USER], { cwd: repoPath });
|
|
129
129
|
await this.execFile('git', ['config', 'user.email', GIT_AUTO_INIT_EMAIL], { cwd: repoPath });
|
|
130
|
-
await this.execFile('git', ['commit', '--allow-empty', '-m', 'Initial commit'], {
|
|
131
|
-
cwd: repoPath,
|
|
132
|
-
});
|
|
130
|
+
await this.execFile('git', ['commit', '--allow-empty', '--no-gpg-sign', '-m', 'Initial commit'], { cwd: repoPath });
|
|
133
131
|
}
|
|
134
132
|
catch (error) {
|
|
135
133
|
throw this.parseGitError(error);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/cli-upgrade/route.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,wBAAsB,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,CA+B9C"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { resolve } from '../../../lib/server-container.js';
|
|
2
|
+
// Force dynamic — SSE streams must never be statically optimized or cached
|
|
3
|
+
export const dynamic = 'force-dynamic';
|
|
4
|
+
export async function POST() {
|
|
5
|
+
const useCase = resolve('UpgradeCliUseCase');
|
|
6
|
+
const encoder = new TextEncoder();
|
|
7
|
+
const stream = new ReadableStream({
|
|
8
|
+
async start(controller) {
|
|
9
|
+
try {
|
|
10
|
+
const result = await useCase.execute((chunk) => {
|
|
11
|
+
controller.enqueue(encoder.encode(`data: ${chunk.replace(/\n/g, '\ndata: ')}\n\n`));
|
|
12
|
+
});
|
|
13
|
+
controller.enqueue(encoder.encode(`event: done\ndata: ${JSON.stringify(result)}\n\n`));
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
const message = error instanceof Error ? error.message : 'Upgrade failed';
|
|
17
|
+
controller.enqueue(encoder.encode(`event: done\ndata: ${JSON.stringify({ status: 'error', currentVersion: '', latestVersion: null, errorMessage: message })}\n\n`));
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
controller.close();
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
return new Response(stream, {
|
|
25
|
+
headers: {
|
|
26
|
+
'Content-Type': 'text/event-stream',
|
|
27
|
+
'Cache-Control': 'no-cache',
|
|
28
|
+
Connection: 'keep-alive',
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-badge.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/version-badge/version-badge.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"version-badge.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/version-badge/version-badge.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,MAAM,EACN,UAAU,EACV,KAAa,EACb,WAA2B,EAC3B,WAAW,EACX,YAAY,GACb,EAAE,iBAAiB,2CA2EnB"}
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
|
|
4
4
|
import { useNpmVersionCheck } from '../../../hooks/use-npm-version-check.js';
|
|
5
|
+
import { useCliUpgrade } from '../../../hooks/use-cli-upgrade.js';
|
|
5
6
|
export function VersionBadge({ version, branch, commitHash, isDev = false, packageName = '@shepai/cli', description, instancePath, }) {
|
|
6
7
|
const shortHash = commitHash?.slice(0, 7);
|
|
7
8
|
const { latest, updateAvailable } = useNpmVersionCheck(version);
|
|
9
|
+
const { status: upgradeStatus, startUpgrade } = useCliUpgrade();
|
|
8
10
|
// In dev mode show "1.92.2-dev", in production show "v1.92.2"
|
|
9
11
|
const displayVersion = isDev ? `${version}-dev` : `v${version}`;
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
+
const isUpgrading = upgradeStatus === 'upgrading';
|
|
13
|
+
const didUpgrade = upgradeStatus === 'upgraded';
|
|
14
|
+
const upgradeError = upgradeStatus === 'error';
|
|
15
|
+
return (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { className: "text-muted-foreground/80 hover:text-muted-foreground relative cursor-default text-[11px] leading-tight transition-colors", "data-testid": "version-label", children: [displayVersion, updateAvailable && !didUpgrade ? (_jsx("span", { className: "absolute -top-0.5 -right-1.5 size-1.5 rounded-full bg-emerald-400", "data-testid": "update-dot" })) : null] }) }), _jsxs(TooltipContent, { side: "right", className: "max-w-[280px] space-y-1 p-3 text-left", children: [_jsx("div", { className: "mb-1.5 text-xs font-semibold", children: packageName }), description ? (_jsx("div", { className: "text-[10px] leading-snug opacity-70", children: description })) : null, _jsxs("div", { className: "border-t border-white/10 pt-1.5", children: [_jsx(Row, { label: "Version", value: displayVersion }), isDev && branch ? _jsx(Row, { label: "Branch", value: branch }) : null, isDev && shortHash ? _jsx(Row, { label: "Commit", value: shortHash, mono: true }) : null, isDev && instancePath ? _jsx(Row, { label: "Path", value: instancePath, mono: true }) : null, latest ? (_jsx(Row, { label: "Latest", value: `v${latest}`, highlight: updateAvailable })) : null] }), didUpgrade ? (_jsx("div", { className: "border-t border-white/10 pt-1.5", children: _jsx("span", { className: "text-[10px] font-medium text-emerald-400", "data-testid": "upgrade-success", children: "Upgraded successfully \u2014 restart to apply" }) })) : upgradeError ? (_jsx("div", { className: "border-t border-white/10 pt-1.5", children: _jsx("span", { className: "text-[10px] font-medium text-red-400", "data-testid": "upgrade-error", children: "Upgrade failed" }) })) : updateAvailable ? (_jsx("div", { className: "border-t border-white/10 pt-1.5", children: _jsx("button", { type: "button", onClick: startUpgrade, disabled: isUpgrading, className: "inline-flex items-center gap-1 text-[10px] font-medium text-emerald-400 transition-colors hover:text-emerald-300 disabled:opacity-50", "data-testid": "upgrade-button", children: isUpgrading ? 'Upgrading...' : `Upgrade to v${latest}` }) })) : null] })] }) }));
|
|
12
16
|
}
|
|
13
17
|
function Row({ label, value, highlight, mono, }) {
|
|
14
18
|
return (_jsxs("div", { className: "flex items-center justify-between gap-4 text-[10px]", children: [_jsx("span", { className: "opacity-60", children: label }), _jsx("span", { className: [
|
package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts
CHANGED
|
@@ -11,9 +11,9 @@ export declare const Development: Story;
|
|
|
11
11
|
export declare const LongBranch: Story;
|
|
12
12
|
/** Minimal info — no optional fields. */
|
|
13
13
|
export declare const Minimal: Story;
|
|
14
|
-
/** Update available — green dot appears, tooltip shows "Upgrade to v2.0.0"
|
|
14
|
+
/** Update available — green dot appears, tooltip shows "Upgrade to v2.0.0" button. */
|
|
15
15
|
export declare const UpdateAvailable: Story;
|
|
16
|
-
/** Update available in dev mode — green dot + upgrade
|
|
16
|
+
/** Update available in dev mode — green dot + upgrade button alongside dev info. */
|
|
17
17
|
export declare const UpdateAvailableDev: Story;
|
|
18
18
|
/** Fetch error — no update info shown, badge behaves normally. */
|
|
19
19
|
export declare const FetchError: Story;
|
package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-badge.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/version-badge/version-badge.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAa,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"version-badge.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/version-badge/version-badge.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAa,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAwD/C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,YAAY,CAOnC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,YAAY,CAAC,CAAC;AAE3C,mFAAmF;AACnF,eAAO,MAAM,UAAU,EAAE,KAOxB,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,WAAW,EAAE,KAWzB,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,UAAU,EAAE,KAWxB,CAAC;AAEF,yCAAyC;AACzC,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,KAO7B,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,EAAE,KAWhC,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,UAAU,EAAE,KAOxB,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { VersionBadge } from './version-badge.js';
|
|
3
3
|
/**
|
|
4
|
-
* Decorator that mocks the /api/npm-version endpoint to return a specific latest version
|
|
4
|
+
* Decorator that mocks the /api/npm-version endpoint to return a specific latest version
|
|
5
|
+
* and the /api/cli-upgrade endpoint to simulate an upgrade.
|
|
5
6
|
*/
|
|
6
7
|
function withNpmVersion(latest) {
|
|
7
8
|
return (Story) => {
|
|
@@ -14,6 +15,22 @@ function withNpmVersion(latest) {
|
|
|
14
15
|
headers: { 'Content-Type': 'application/json' },
|
|
15
16
|
});
|
|
16
17
|
}
|
|
18
|
+
if (url.includes('/api/cli-upgrade')) {
|
|
19
|
+
const encoder = new TextEncoder();
|
|
20
|
+
const stream = new ReadableStream({
|
|
21
|
+
start(controller) {
|
|
22
|
+
controller.enqueue(encoder.encode(`data: Upgrading to v${latest}...\n\n`));
|
|
23
|
+
setTimeout(() => {
|
|
24
|
+
controller.enqueue(encoder.encode(`event: done\ndata: ${JSON.stringify({ status: 'upgraded', currentVersion: '1.90.0', latestVersion: latest })}\n\n`));
|
|
25
|
+
controller.close();
|
|
26
|
+
}, 1000);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
return new Response(stream, {
|
|
30
|
+
status: 200,
|
|
31
|
+
headers: { 'Content-Type': 'text/event-stream' },
|
|
32
|
+
});
|
|
33
|
+
}
|
|
17
34
|
return originalFetch(input, init);
|
|
18
35
|
});
|
|
19
36
|
return _jsx(Story, {});
|
|
@@ -82,7 +99,7 @@ export const Minimal = {
|
|
|
82
99
|
version: '1.0.0',
|
|
83
100
|
},
|
|
84
101
|
};
|
|
85
|
-
/** Update available — green dot appears, tooltip shows "Upgrade to v2.0.0"
|
|
102
|
+
/** Update available — green dot appears, tooltip shows "Upgrade to v2.0.0" button. */
|
|
86
103
|
export const UpdateAvailable = {
|
|
87
104
|
decorators: [withNpmVersion('2.0.0')],
|
|
88
105
|
args: {
|
|
@@ -91,7 +108,7 @@ export const UpdateAvailable = {
|
|
|
91
108
|
description: 'Autonomous AI Native SDLC Platform',
|
|
92
109
|
},
|
|
93
110
|
};
|
|
94
|
-
/** Update available in dev mode — green dot + upgrade
|
|
111
|
+
/** Update available in dev mode — green dot + upgrade button alongside dev info. */
|
|
95
112
|
export const UpdateAvailableDev = {
|
|
96
113
|
decorators: [withNpmVersion('2.0.0')],
|
|
97
114
|
args: {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type UpgradeStatus = 'idle' | 'upgrading' | 'upgraded' | 'up-to-date' | 'error';
|
|
2
|
+
export interface CliUpgradeState {
|
|
3
|
+
status: UpgradeStatus;
|
|
4
|
+
output: string;
|
|
5
|
+
errorMessage?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CliUpgradeActions {
|
|
8
|
+
startUpgrade: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function useCliUpgrade(): CliUpgradeState & CliUpgradeActions;
|
|
11
|
+
//# sourceMappingURL=use-cli-upgrade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-cli-upgrade.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-cli-upgrade.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC;AAEvF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,wBAAgB,aAAa,IAAI,eAAe,GAAG,iBAAiB,CA6EnE"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useCallback, useRef, useState } from 'react';
|
|
3
|
+
export function useCliUpgrade() {
|
|
4
|
+
const [status, setStatus] = useState('idle');
|
|
5
|
+
const [output, setOutput] = useState('');
|
|
6
|
+
const [errorMessage, setErrorMessage] = useState();
|
|
7
|
+
const abortRef = useRef(null);
|
|
8
|
+
const startUpgrade = useCallback(() => {
|
|
9
|
+
if (status === 'upgrading')
|
|
10
|
+
return;
|
|
11
|
+
setStatus('upgrading');
|
|
12
|
+
setOutput('');
|
|
13
|
+
setErrorMessage(undefined);
|
|
14
|
+
const controller = new AbortController();
|
|
15
|
+
abortRef.current = controller;
|
|
16
|
+
fetch('/api/cli-upgrade', { method: 'POST', signal: controller.signal })
|
|
17
|
+
.then(async (response) => {
|
|
18
|
+
if (!response.ok || !response.body) {
|
|
19
|
+
setStatus('error');
|
|
20
|
+
setErrorMessage(`Server returned ${response.status}`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const reader = response.body.getReader();
|
|
24
|
+
const decoder = new TextDecoder();
|
|
25
|
+
let buffer = '';
|
|
26
|
+
while (true) {
|
|
27
|
+
const { done, value } = await reader.read();
|
|
28
|
+
if (done)
|
|
29
|
+
break;
|
|
30
|
+
buffer += decoder.decode(value, { stream: true });
|
|
31
|
+
const lines = buffer.split('\n');
|
|
32
|
+
buffer = lines.pop() ?? '';
|
|
33
|
+
for (const line of lines) {
|
|
34
|
+
if (line.startsWith('event: done')) {
|
|
35
|
+
// Next data line contains the final result
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (line.startsWith('data: ')) {
|
|
39
|
+
const payload = line.slice(6);
|
|
40
|
+
// Try to parse as final JSON result
|
|
41
|
+
try {
|
|
42
|
+
const result = JSON.parse(payload);
|
|
43
|
+
if (result.status === 'upgraded') {
|
|
44
|
+
setStatus('upgraded');
|
|
45
|
+
}
|
|
46
|
+
else if (result.status === 'up-to-date') {
|
|
47
|
+
setStatus('up-to-date');
|
|
48
|
+
}
|
|
49
|
+
else if (result.status === 'error') {
|
|
50
|
+
setStatus('error');
|
|
51
|
+
setErrorMessage(result.errorMessage);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Regular output line
|
|
56
|
+
setOutput((prev) => prev + payload);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
.catch((err) => {
|
|
63
|
+
if (err instanceof DOMException && err.name === 'AbortError')
|
|
64
|
+
return;
|
|
65
|
+
setStatus('error');
|
|
66
|
+
setErrorMessage(err instanceof Error ? err.message : 'Upgrade failed');
|
|
67
|
+
});
|
|
68
|
+
return () => {
|
|
69
|
+
controller.abort();
|
|
70
|
+
};
|
|
71
|
+
}, [status]);
|
|
72
|
+
return { status, output, errorMessage, startUpgrade };
|
|
73
|
+
}
|