gitspace 0.2.0-rc.17 → 0.2.0-rc.19
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/.gitspace/{select → scripts/select}/01-status.sh +6 -6
- package/README.md +22 -7
- package/bun.lock +5 -5
- package/docs/SITE_DOCS_FIGMA_MAKE.md +7 -8
- package/landing-page/src/components/docs/DocsContent.tsx +2 -2
- package/package.json +5 -5
- package/src/app.web.tsx +85 -3
- package/src/commands/bundle.ts +10 -17
- package/src/commands/review.ts +787 -0
- package/src/components/DiffViewer.web.tsx +1192 -0
- package/src/components/SpacesBrowser.web.tsx +19 -2
- package/src/components/ThreadPanel.web.tsx +798 -0
- package/src/components/review-decision-colors.ts +11 -0
- package/src/core/__tests__/bundle.test.ts +209 -0
- package/src/core/__tests__/github-review.test.ts +781 -0
- package/src/core/bundle.ts +70 -0
- package/src/core/git.ts +430 -0
- package/src/core/github-review.ts +761 -0
- package/src/core/review-executor.ts +316 -0
- package/src/core/review.ts +407 -0
- package/src/core/shell.ts +11 -8
- package/src/hooks/__tests__/useLocalSession.tui.test.ts +4 -0
- package/src/hooks/useReview.web.ts +248 -0
- package/src/index.ts +204 -0
- package/src/lib/remote-session/protocol.ts +25 -2
- package/src/lib/remote-session/session-handler.ts +82 -10
- package/src/lib/tmux-lite/cli.ts +7 -2
- package/src/lib/tmux-lite/protocol.ts +17 -1
- package/src/lib/tmux-lite/server.ts +54 -6
- package/src/pages/ReviewPage.web.tsx +511 -0
- package/src/session/__tests__/backend-manager.test.ts +3 -0
- package/src/session/__tests__/useRemoteSessionClient.test.ts +4 -0
- package/src/session/__tests__/workspace-shell-hooks.integration.test.ts +268 -0
- package/src/session/__tests__/workspace-shell-hooks.test.ts +24 -0
- package/src/session/backend.ts +3 -0
- package/src/session/backends/local-session-backend.ts +19 -22
- package/src/session/backends/remote-session-backend.ts +106 -0
- package/src/session/events.ts +6 -1
- package/src/session/useRemoteSessionClient.ts +17 -0
- package/src/session/useSessionEngine.ts +20 -0
- package/src/session/workspace-shell-hooks.ts +35 -0
- package/src/types/errors.ts +39 -0
- package/src/types/review.ts +349 -0
- package/src/utils/__tests__/run-scripts.test.ts +106 -5
- package/src/utils/hunk-header.ts +17 -0
- package/src/utils/id.ts +9 -0
- package/src/utils/normalize-env-key.ts +13 -0
- package/src/utils/run-scripts.ts +109 -14
- package/src/utils/workspace-id.ts +55 -0
- package/web/bun.lock +97 -0
- package/web/package.json +1 -0
- package/web/tsconfig.app.json +3 -1
- package/web/vite.config.ts +3 -0
- /package/.gitspace/{setup → scripts/setup}/01-install-deps.sh +0 -0
- /package/.gitspace/{setup → scripts/setup}/02-typecheck.sh +0 -0
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
#
|
|
4
4
|
# This runs every time you switch to an existing workspace.
|
|
5
5
|
#
|
|
6
|
-
# Bundle values are available
|
|
7
|
-
# Example:
|
|
6
|
+
# Bundle values are available using exact keys and uppercase snake-case aliases.
|
|
7
|
+
# Example aliases: DEVELOPER_NAME, EXAMPLE_API_TOKEN
|
|
8
8
|
|
|
9
9
|
WORKSPACE_NAME=$1
|
|
10
10
|
REPOSITORY=$2
|
|
@@ -14,14 +14,14 @@ echo "=== Workspace: $WORKSPACE_NAME ==="
|
|
|
14
14
|
echo ""
|
|
15
15
|
|
|
16
16
|
# Show bundle values (proof of concept)
|
|
17
|
-
if [ -n "$
|
|
18
|
-
echo "Welcome back, $
|
|
17
|
+
if [ -n "$DEVELOPER_NAME" ]; then
|
|
18
|
+
echo "Welcome back, $DEVELOPER_NAME!"
|
|
19
19
|
fi
|
|
20
20
|
|
|
21
21
|
# Show that we have access to the secret (masked)
|
|
22
|
-
if [ -n "$
|
|
22
|
+
if [ -n "$EXAMPLE_API_TOKEN" ]; then
|
|
23
23
|
# Only show first 4 characters to prove we have access
|
|
24
|
-
TOKEN_PREVIEW="${
|
|
24
|
+
TOKEN_PREVIEW="${EXAMPLE_API_TOKEN:0:4}..."
|
|
25
25
|
echo "API Token available: $TOKEN_PREVIEW (stored in OS keychain)"
|
|
26
26
|
fi
|
|
27
27
|
|
package/README.md
CHANGED
|
@@ -106,6 +106,22 @@ gssh switch
|
|
|
106
106
|
gssh switch my-feature
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
### Workspace Session Mode (`space`)
|
|
110
|
+
|
|
111
|
+
When GitSpace opens a workspace-scoped terminal session, it injects a `space` shell function (bash/zsh).
|
|
112
|
+
|
|
113
|
+
- Use `space ...` for workspace operations without repeating `--project` and `--workspace`
|
|
114
|
+
- `gssh` commands are restricted in this mode to avoid cross-workspace mistakes
|
|
115
|
+
- `gssh tmux ...` is blocked inside workspace sessions
|
|
116
|
+
|
|
117
|
+
Examples:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
space context --json
|
|
121
|
+
space review hunks src/app.ts --format json
|
|
122
|
+
space review add-hunk src/app.ts --index 1 --approve --body "Looks good"
|
|
123
|
+
```
|
|
124
|
+
|
|
109
125
|
## Repo Config Bundles
|
|
110
126
|
|
|
111
127
|
Repo config bundles allow repository owners to share onboarding configurations with their team. When someone clones a project that contains a bundle, they'll be guided through setup steps and have scripts automatically installed.
|
|
@@ -183,7 +199,7 @@ A bundle is a directory (typically `.gitspace/`) containing:
|
|
|
183
199
|
Bundle values are passed to scripts as environment variables using the configured bundle keys:
|
|
184
200
|
|
|
185
201
|
- `<KEY>` - Regular or secret value using the exact `configKey` from `bundle.json`
|
|
186
|
-
-
|
|
202
|
+
- `<NORMALIZED_KEY>` - Uppercase snake-case alias (for example, `teamName` -> `TEAM_NAME`)
|
|
187
203
|
|
|
188
204
|
**Example script:**
|
|
189
205
|
|
|
@@ -195,12 +211,12 @@ WORKSPACE_NAME=$1
|
|
|
195
211
|
REPOSITORY=$2
|
|
196
212
|
|
|
197
213
|
# Access bundle values
|
|
198
|
-
if [ -n "$
|
|
199
|
-
echo "Welcome, $
|
|
214
|
+
if [ -n "$TEAM_NAME" ]; then
|
|
215
|
+
echo "Welcome, $TEAM_NAME team!"
|
|
200
216
|
fi
|
|
201
217
|
|
|
202
218
|
# Access secrets (stored securely in OS keychain)
|
|
203
|
-
if [ -n "$
|
|
219
|
+
if [ -n "$API_KEY" ]; then
|
|
204
220
|
echo "API Key configured"
|
|
205
221
|
fi
|
|
206
222
|
```
|
|
@@ -393,9 +409,8 @@ inside each workspace so they can vary by branch:
|
|
|
393
409
|
export SPACES_CURRENT_PROJECT="my-app"
|
|
394
410
|
|
|
395
411
|
# Available in scripts (from bundle onboarding):
|
|
396
|
-
# <KEY> - Value by bundle config key name
|
|
397
|
-
#
|
|
398
|
-
# SPACE_SECRET_<KEY> - Legacy alias for secret values
|
|
412
|
+
# <KEY> - Value by exact bundle config key name
|
|
413
|
+
# <NORMALIZED_KEY> - Uppercase snake-case alias (e.g. teamName -> TEAM_NAME)
|
|
399
414
|
```
|
|
400
415
|
|
|
401
416
|
## Directory Structure
|
package/bun.lock
CHANGED
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"typescript": "^5.9.3",
|
|
40
40
|
},
|
|
41
41
|
"optionalDependencies": {
|
|
42
|
-
"@gitspace/darwin-arm64": "0.2.0-rc.
|
|
43
|
-
"@gitspace/darwin-x64": "0.2.0-rc.
|
|
44
|
-
"@gitspace/linux-arm64": "0.2.0-rc.
|
|
45
|
-
"@gitspace/linux-x64": "0.2.0-rc.
|
|
42
|
+
"@gitspace/darwin-arm64": "0.2.0-rc.17",
|
|
43
|
+
"@gitspace/darwin-x64": "0.2.0-rc.17",
|
|
44
|
+
"@gitspace/linux-arm64": "0.2.0-rc.17",
|
|
45
|
+
"@gitspace/linux-x64": "0.2.0-rc.17",
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
48
|
},
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
|
|
64
64
|
"@eslint/js": ["@eslint/js@8.57.1", "", {}, "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q=="],
|
|
65
65
|
|
|
66
|
-
"@gitspace/darwin-arm64": ["@gitspace/darwin-arm64@0.2.0-rc.
|
|
66
|
+
"@gitspace/darwin-arm64": ["@gitspace/darwin-arm64@0.2.0-rc.17", "", { "os": "darwin", "cpu": "arm64", "bin": { "gssh-darwin-arm64": "bin/gssh" } }, "sha512-aPei17D31di296UBdqOt59HrdvcIRL2oVGVRWT4etCIESgjTyhZQcCLsIezsWI4E4/9DQAqaLAfTif7TsuCRHQ=="],
|
|
67
67
|
|
|
68
68
|
"@graphql-typed-document-node/core": ["@graphql-typed-document-node/core@3.2.0", "", { "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="],
|
|
69
69
|
|
|
@@ -377,15 +377,14 @@ Using bundle values in scripts:
|
|
|
377
377
|
```bash
|
|
378
378
|
#!/bin/bash
|
|
379
379
|
# Values available as environment variables:
|
|
380
|
-
# <KEY> - Value by bundle config key name
|
|
381
|
-
#
|
|
382
|
-
# SPACE_SECRET_<KEY> - Legacy alias for secret values
|
|
380
|
+
# <KEY> - Value by exact bundle config key name
|
|
381
|
+
# <NORMALIZED_KEY> - Uppercase snake-case alias (e.g. teamName -> TEAM_NAME)
|
|
383
382
|
|
|
384
|
-
if [ -n "$
|
|
385
|
-
echo "Welcome, $
|
|
383
|
+
if [ -n "$TEAM_NAME" ]; then
|
|
384
|
+
echo "Welcome, $TEAM_NAME team!"
|
|
386
385
|
fi
|
|
387
386
|
|
|
388
|
-
if [ -n "$
|
|
387
|
+
if [ -n "$API_KEY" ]; then
|
|
389
388
|
echo "API Key configured"
|
|
390
389
|
fi
|
|
391
390
|
```
|
|
@@ -960,8 +959,8 @@ Bundles allow teams to share onboarding configurations. Place in `.gitspace/`:
|
|
|
960
959
|
|
|
961
960
|
**Using values in scripts:**
|
|
962
961
|
```bash
|
|
963
|
-
echo "Team: $
|
|
964
|
-
echo "Has API key: $
|
|
962
|
+
echo "Team: $TEAM_NAME"
|
|
963
|
+
echo "Has API key: $API_KEY"
|
|
965
964
|
```
|
|
966
965
|
|
|
967
966
|
---
|
|
@@ -378,8 +378,8 @@ git status`} />
|
|
|
378
378
|
</div>
|
|
379
379
|
|
|
380
380
|
<h3 className="text-xl font-semibold text-white mb-4">Using Values in Scripts</h3>
|
|
381
|
-
<JsonBlock code={`echo "Team: $
|
|
382
|
-
echo "Has API key: $
|
|
381
|
+
<JsonBlock code={`echo "Team: $TEAM_NAME"
|
|
382
|
+
echo "Has API key: $API_KEY"`} />
|
|
383
383
|
</div>
|
|
384
384
|
);
|
|
385
385
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gitspace",
|
|
3
|
-
"version": "0.2.0-rc.
|
|
3
|
+
"version": "0.2.0-rc.19",
|
|
4
4
|
"description": "CLI for managing GitHub workspaces with git worktrees and secure remote terminal access",
|
|
5
5
|
"bin": {
|
|
6
6
|
"gssh": "./bin/gssh"
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"relay": "bun src/relay/index.ts"
|
|
18
18
|
},
|
|
19
19
|
"optionalDependencies": {
|
|
20
|
-
"@gitspace/darwin-arm64": "0.2.0-rc.
|
|
21
|
-
"@gitspace/darwin-x64": "0.2.0-rc.
|
|
22
|
-
"@gitspace/linux-x64": "0.2.0-rc.
|
|
23
|
-
"@gitspace/linux-arm64": "0.2.0-rc.
|
|
20
|
+
"@gitspace/darwin-arm64": "0.2.0-rc.19",
|
|
21
|
+
"@gitspace/darwin-x64": "0.2.0-rc.19",
|
|
22
|
+
"@gitspace/linux-x64": "0.2.0-rc.19",
|
|
23
|
+
"@gitspace/linux-arm64": "0.2.0-rc.19"
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
26
26
|
"cli",
|
package/src/app.web.tsx
CHANGED
|
@@ -19,6 +19,7 @@ import { useUserActivity } from "./hooks/index.js";
|
|
|
19
19
|
import { useBundleRefreshAttachFlow } from './session/useBundleRefreshAttachFlow.js';
|
|
20
20
|
import { useAttachController } from './app/session/useAttachController.js';
|
|
21
21
|
import { useWorkspaceDeleteFlow } from './app/session/useWorkspaceDeleteFlow.js';
|
|
22
|
+
import { ReviewPage } from './pages/ReviewPage.web.js';
|
|
22
23
|
|
|
23
24
|
// Import shared components and hooks
|
|
24
25
|
import {
|
|
@@ -27,6 +28,7 @@ import {
|
|
|
27
28
|
useFlow,
|
|
28
29
|
getDefaultShortcuts,
|
|
29
30
|
type MachineInfo,
|
|
31
|
+
type WorkspaceInfo,
|
|
30
32
|
} from "./components/index.js";
|
|
31
33
|
import { MachineListWeb } from "./components/MachineList.web.js";
|
|
32
34
|
import { SpacesBrowserWeb } from "./components/SpacesBrowser.web.js";
|
|
@@ -46,7 +48,7 @@ import {
|
|
|
46
48
|
resolveSessionBrowserCommand,
|
|
47
49
|
} from './app/input/sessionCommands.js';
|
|
48
50
|
|
|
49
|
-
type View = "machines" | "terminal";
|
|
51
|
+
type View = "machines" | "terminal" | "review";
|
|
50
52
|
|
|
51
53
|
const PAGE_UP = '\x1b[5~';
|
|
52
54
|
const PAGE_DOWN = '\x1b[6~';
|
|
@@ -88,6 +90,13 @@ export default function App() {
|
|
|
88
90
|
inviteToken?: string;
|
|
89
91
|
} | null>(null);
|
|
90
92
|
|
|
93
|
+
// Review workspace/project state
|
|
94
|
+
const [reviewWorkspace, setReviewWorkspace] = useState<{
|
|
95
|
+
projectName: string;
|
|
96
|
+
workspaceId: string;
|
|
97
|
+
workspaceLabel?: string;
|
|
98
|
+
} | null>(null);
|
|
99
|
+
|
|
91
100
|
// Relay connection (for machine list)
|
|
92
101
|
const relay = useRelayConnection();
|
|
93
102
|
|
|
@@ -234,7 +243,7 @@ export default function App() {
|
|
|
234
243
|
setLocalNotificationConfig(terminal.notificationConfig);
|
|
235
244
|
}, [terminal.notificationConfig]);
|
|
236
245
|
|
|
237
|
-
// Parse invite from URL hash on load
|
|
246
|
+
// Parse invite from URL hash on load, and review params from query string
|
|
238
247
|
useEffect(() => {
|
|
239
248
|
const hash = window.location.hash;
|
|
240
249
|
if (hash.startsWith("#invite=")) {
|
|
@@ -248,6 +257,16 @@ export default function App() {
|
|
|
248
257
|
}
|
|
249
258
|
});
|
|
250
259
|
}
|
|
260
|
+
|
|
261
|
+
const params = new URLSearchParams(window.location.search);
|
|
262
|
+
if (params.get('view') === 'review') {
|
|
263
|
+
const ws = params.get('workspace');
|
|
264
|
+
const proj = params.get('project');
|
|
265
|
+
if (ws && proj) {
|
|
266
|
+
setReviewWorkspace({ projectName: proj, workspaceId: ws, workspaceLabel: ws });
|
|
267
|
+
setView('review');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
251
270
|
}, []);
|
|
252
271
|
|
|
253
272
|
// Auto-connect on load (no token required for personal relays)
|
|
@@ -419,6 +438,16 @@ export default function App() {
|
|
|
419
438
|
await attachController.attachFromSelection(params);
|
|
420
439
|
}, [attachController]);
|
|
421
440
|
|
|
441
|
+
// Handle opening review for a workspace
|
|
442
|
+
const handleOpenReview = useCallback((workspace: WorkspaceInfo) => {
|
|
443
|
+
setReviewWorkspace({
|
|
444
|
+
projectName: workspace.projectName,
|
|
445
|
+
workspaceId: workspace.id,
|
|
446
|
+
workspaceLabel: workspace.name,
|
|
447
|
+
});
|
|
448
|
+
setView('review');
|
|
449
|
+
}, []);
|
|
450
|
+
|
|
422
451
|
// Spaces browser hook
|
|
423
452
|
const spacesBrowserProps = useSpacesBrowser({
|
|
424
453
|
workspaces: terminal.workspaces,
|
|
@@ -740,6 +769,59 @@ export default function App() {
|
|
|
740
769
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
741
770
|
}, [notifications.activeToast, notifications.attachToActiveToast, flow]);
|
|
742
771
|
|
|
772
|
+
// ========== Review View ==========
|
|
773
|
+
if (view === 'review' && reviewWorkspace) {
|
|
774
|
+
if (terminal.status === 'established') {
|
|
775
|
+
return (
|
|
776
|
+
<>
|
|
777
|
+
<ReviewPage
|
|
778
|
+
projectName={reviewWorkspace.projectName}
|
|
779
|
+
workspaceName={reviewWorkspace.workspaceId}
|
|
780
|
+
workspaceLabel={reviewWorkspace.workspaceLabel}
|
|
781
|
+
machineName={selectedMachine?.label || selectedMachine?.machineId}
|
|
782
|
+
sendReviewRequest={terminal.sendReviewRequest}
|
|
783
|
+
onBack={() => {
|
|
784
|
+
setView('terminal');
|
|
785
|
+
setReviewWorkspace(null);
|
|
786
|
+
}}
|
|
787
|
+
/>
|
|
788
|
+
<Toaster theme="dark" position="top-right" richColors />
|
|
789
|
+
</>
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// Connection not yet established — show a targeted connecting screen
|
|
794
|
+
// rather than falling through to the generic machine list.
|
|
795
|
+
const statusMessage = {
|
|
796
|
+
disconnected: "Disconnected",
|
|
797
|
+
connecting: "Connecting to relay...",
|
|
798
|
+
connected: "Connected, authenticating...",
|
|
799
|
+
handshaking: "Establishing secure connection...",
|
|
800
|
+
established: "Connected!",
|
|
801
|
+
error: "Connection failed",
|
|
802
|
+
}[terminal.status];
|
|
803
|
+
|
|
804
|
+
return (
|
|
805
|
+
<>
|
|
806
|
+
<div className="h-screen w-screen flex flex-col items-center justify-center bg-[#0d1117] px-4">
|
|
807
|
+
<div className="text-center">
|
|
808
|
+
<div className="text-lg text-[#e6edf3] mb-2">
|
|
809
|
+
Loading review for <span className="text-[#58a6ff]">{reviewWorkspace.workspaceLabel ?? reviewWorkspace.workspaceId}</span>
|
|
810
|
+
</div>
|
|
811
|
+
<div className="text-sm text-[#8b949e]">{statusMessage}</div>
|
|
812
|
+
<button
|
|
813
|
+
onClick={() => { setView('machines'); setReviewWorkspace(null); }}
|
|
814
|
+
className="mt-4 px-6 py-3 text-base bg-[#21262d] hover:bg-[#30363d] rounded-lg text-[#e6edf3] min-h-[48px] border border-[#30363d]"
|
|
815
|
+
>
|
|
816
|
+
Back to Machines
|
|
817
|
+
</button>
|
|
818
|
+
</div>
|
|
819
|
+
</div>
|
|
820
|
+
<Toaster theme="dark" position="top-right" richColors />
|
|
821
|
+
</>
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
|
|
743
825
|
// ========== Spaces Browser View (browsing mode) ==========
|
|
744
826
|
if (
|
|
745
827
|
view === 'terminal' &&
|
|
@@ -819,7 +901,7 @@ export default function App() {
|
|
|
819
901
|
</div>
|
|
820
902
|
</div>
|
|
821
903
|
<div className="flex-1 overflow-hidden">
|
|
822
|
-
<SpacesBrowserWeb {...spacesBrowserProps} />
|
|
904
|
+
<SpacesBrowserWeb {...spacesBrowserProps} onReview={handleOpenReview} />
|
|
823
905
|
</div>
|
|
824
906
|
</div>
|
|
825
907
|
<FlowWeb flow={flow} />
|
package/src/commands/bundle.ts
CHANGED
|
@@ -8,15 +8,16 @@ import { exec } from 'child_process';
|
|
|
8
8
|
import { promisify } from 'util';
|
|
9
9
|
import { logger } from '../utils/logger.js';
|
|
10
10
|
import { SpacesError } from '../types/errors.js';
|
|
11
|
-
import { getCurrentProject, getProjectBaseDir, getProjectWorkspacesDir } from '../core/config.js';
|
|
11
|
+
import { getCurrentProject, getGitspaceDir, getProjectBaseDir, getProjectWorkspacesDir } from '../core/config.js';
|
|
12
12
|
import {
|
|
13
13
|
detectBundleChanges,
|
|
14
14
|
formatBundleChangeDetails,
|
|
15
15
|
refreshBundle,
|
|
16
16
|
type BundleRefreshOptions,
|
|
17
17
|
} from '../core/bundle-refresh.js';
|
|
18
|
-
import { join
|
|
18
|
+
import { join } from 'path';
|
|
19
19
|
import { existsSync } from 'fs';
|
|
20
|
+
import { detectWorkspaceContextFromCwd } from '../utils/workspace-id.js';
|
|
20
21
|
|
|
21
22
|
const execAsync = promisify(exec);
|
|
22
23
|
|
|
@@ -43,24 +44,16 @@ export interface BundleStatusOptions {
|
|
|
43
44
|
* Returns the workspace path if found, undefined otherwise
|
|
44
45
|
*/
|
|
45
46
|
function detectWorkspaceFromCwd(projectName: string): string | undefined {
|
|
46
|
-
const cwd = process.cwd();
|
|
47
47
|
const workspacesDir = getProjectWorkspacesDir(projectName);
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (resolvedCwd.startsWith(resolvedWorkspacesDir + '/') || resolvedCwd === resolvedWorkspacesDir) {
|
|
54
|
-
// Extract the workspace name (first path segment after workspaces/)
|
|
55
|
-
const relativePath = resolvedCwd.slice(resolvedWorkspacesDir.length + 1);
|
|
56
|
-
const workspaceName = relativePath.split('/')[0];
|
|
49
|
+
const context = detectWorkspaceContextFromCwd(process.cwd(), getGitspaceDir());
|
|
50
|
+
if (!context || context.projectName !== projectName) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return workspacePath;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
54
|
+
const workspacePath = join(workspacesDir, context.workspaceName);
|
|
55
|
+
if (existsSync(workspacePath)) {
|
|
56
|
+
return workspacePath;
|
|
64
57
|
}
|
|
65
58
|
|
|
66
59
|
return undefined;
|