Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/design/extension-management-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ type InitialActivation =
| { scope: 'workspace'; workspaceId: string };
```

The daemon install endpoint accepts HTTPS Git, GitHub Release, and npm sources
under the public network policy. SSH and local/link sources remain local CLI
features. Update preserves the extension id,
The daemon install endpoint accepts HTTPS Git, GitHub Release, npm, and
absolute-path local sources. SSH and link sources remain local CLI features.
Update preserves the extension id,
manifest name, settings, and activation policy. “Already current” is a
successful `updated: false` result. Uninstall is idempotent and removes both the
artifact and policy.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ describe('createExtensionsController', () => {
vi.restoreAllMocks();
});

it('does not impose a public-only extension network policy', () => {
const controller = createExtensionsController({
boundWorkspace: '/work/bound',
bridge: {} as AcpSessionBridge,
workspace: {} as DaemonWorkspaceService,
isWorkspaceTrusted: () => true,
});

const manager = controller.createExtensionManager() as unknown as {
networkPolicy?: string;
};

expect(manager.networkPolicy).toBeUndefined();
});

it('releases the commit lane when a manual refresh times out', async () => {
vi.useFakeTimers();
let refreshCalls = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,6 @@ export function createExtensionsController(
getWorkspaceTrustStatus(loadSettings(workspaceDir).merged, workspaceDir)
.effective.state === 'trusted',
requestConsent: () => Promise.resolve(),
networkPolicy: 'public',
requestSetting:
Comment thread
callmeYe marked this conversation as resolved.
interactions?.requestSetting ??
(async (setting: ExtensionSetting) => {
Expand Down
16 changes: 4 additions & 12 deletions packages/cli/src/serve/routes/workspace-extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,7 @@ const validateExtensionSourceMetadata = (
const parsed = parsePotentialSourceUrl(installMetadata.source);
return (
!!parsed &&
(installMetadata.networkPolicy === 'public'
? parsed.protocol === 'https:'
: parsed.protocol === 'https:' || parsed.protocol === 'ssh:') &&
parsed.protocol === 'https:' &&
!isBlockedAuthProviderHost(parsed.hostname)
);
};
Expand Down Expand Up @@ -1108,9 +1106,7 @@ export function registerWorkspaceExtensionRoutes(
isPortableAbsolutePath(sourceValue) || sourceValue.startsWith('.');
if (localSource) {
try {
const metadata = await parseInstallSource(sourceValue, {
networkPolicy: 'public',
});
const metadata = await parseInstallSource(sourceValue);
assertDaemonExtensionInstallSource(
metadata,
sourceValue,
Expand Down Expand Up @@ -1165,9 +1161,7 @@ export function registerWorkspaceExtensionRoutes(
res,
async (extensionManager, _signal, context, operationId) => {
const prepared = await context!.prepare(async (signal) => {
const installMetadata = await parseInstallSource(sourceValue, {
networkPolicy: 'public',
});
const installMetadata = await parseInstallSource(sourceValue);
Comment thread
callmeYe marked this conversation as resolved.
Comment thread
callmeYe marked this conversation as resolved.
Comment thread
callmeYe marked this conversation as resolved.

assertDaemonExtensionInstallSource(
installMetadata,
Expand Down Expand Up @@ -1970,9 +1964,7 @@ export function registerWorkspaceExtensionRoutes(
gitCredential?.persistence === 'one_time' ? {} : { source: sourceValue },
async (extensionManager, _signal, context) => {
const prepared = await context!.prepare(async (signal) => {
const metadata = await parseInstallSource(sourceValue, {
networkPolicy: 'public',
});
const metadata = await parseInstallSource(sourceValue);
Comment thread
callmeYe marked this conversation as resolved.
assertDaemonExtensionInstallSource(
metadata,
sourceValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1890,6 +1890,9 @@ describe('extension management v2 REST', () => {
},
}),
);
expect(
prepareInstall.mock.calls.at(-1)?.[0].installMetadata,
).not.toHaveProperty('networkPolicy');
expect(JSON.stringify(operation)).not.toContain('fine-grained-token');
expect(JSON.stringify(h.primary.bridge)).not.toContain(
'fine-grained-token',
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/serve/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8056,6 +8056,7 @@ describe('createServeApp', () => {
persistence: expected,
},
});
expect(captured?.installMetadata).not.toHaveProperty('networkPolicy');
await vi.waitFor(() =>
expect(bridge.extensionEvents.at(-1)).toMatchObject({
status: 'installed',
Expand Down
Loading