@aigne/afs-gce 1.11.0-beta.6 → 1.11.0-beta.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/errors.ts","../src/path-resolver.ts","../src/operations/actions.ts","../src/platform-ref.ts","../src/types.ts","../src/operations/list.ts","../src/operations/read.ts","../src/operations/stat.ts","../src/index.ts"],"sourcesContent":["/**\n * GCE Provider Error Handling\n *\n * Maps GCE SDK errors to AFS error types.\n */\n\n/**\n * AFS error codes\n */\nexport const AFSErrorCode = {\n ENTRY_NOT_FOUND: \"ENTRY_NOT_FOUND\",\n MODULE_NOT_FOUND: \"MODULE_NOT_FOUND\",\n PERMISSION_DENIED: \"PERMISSION_DENIED\",\n AUTH_ERROR: \"AUTH_ERROR\",\n RATE_LIMIT_EXCEEDED: \"RATE_LIMIT_EXCEEDED\",\n INVALID_OPERATION: \"INVALID_OPERATION\",\n ALREADY_EXISTS: \"ALREADY_EXISTS\",\n SERVICE_UNAVAILABLE: \"SERVICE_UNAVAILABLE\",\n UNKNOWN: \"UNKNOWN\",\n} as const;\n\nexport type AFSErrorCode = (typeof AFSErrorCode)[keyof typeof AFSErrorCode];\n\n/**\n * AFS Error class\n */\nexport class AFSError extends Error {\n readonly code: AFSErrorCode;\n readonly retryAfter?: number;\n\n constructor(code: AFSErrorCode, message: string, options?: { retryAfter?: number }) {\n super(message);\n this.name = \"AFSError\";\n this.code = code;\n this.retryAfter = options?.retryAfter;\n }\n}\n\n/**\n * Map GCE HTTP status codes to AFS error codes\n */\nconst STATUS_TO_AFS_ERROR: Record<number, AFSErrorCode> = {\n 400: AFSErrorCode.INVALID_OPERATION,\n 401: AFSErrorCode.AUTH_ERROR,\n 403: AFSErrorCode.PERMISSION_DENIED,\n 404: AFSErrorCode.ENTRY_NOT_FOUND,\n 409: AFSErrorCode.ALREADY_EXISTS,\n 429: AFSErrorCode.RATE_LIMIT_EXCEEDED,\n 503: AFSErrorCode.SERVICE_UNAVAILABLE,\n};\n\n/**\n * Map GCE error to AFS error\n *\n * @param error - GCE SDK error or generic error\n * @returns AFSError with appropriate error code\n */\nexport function mapGCEError(error: unknown): AFSError {\n // Handle GCE SDK errors (they have code property)\n if (typeof error === \"object\" && error !== null && \"code\" in error) {\n const err = error as { code: number; message?: string };\n const statusCode = typeof err.code === \"number\" ? err.code : 500;\n const message = err.message ?? \"Unknown GCE error\";\n const afsCode = STATUS_TO_AFS_ERROR[statusCode] ?? AFSErrorCode.UNKNOWN;\n return new AFSError(afsCode, message);\n }\n\n // Handle generic Error\n if (error instanceof Error) {\n return new AFSError(AFSErrorCode.UNKNOWN, error.message);\n }\n\n // Unknown error type\n return new AFSError(AFSErrorCode.UNKNOWN, String(error));\n}\n","/**\n * GCE Path Resolver\n *\n * Parses AFS paths into GCE resource identifiers.\n */\n\nimport type { ParsedPath } from \"./types.js\";\n\n/**\n * Parse an AFS path into GCE resource identifiers\n *\n * Path structure:\n * / - root\n * /instances - list all instances\n * /instances/{name} - specific instance\n * /instances/{name}/metadata.json - instance metadata\n * /instances/{name}/actions - list available actions\n * /instances/{name}/actions/{action} - specific action\n * /actions - global actions list\n * /actions/{action} - global action\n *\n * @param path - AFS path\n * @returns Parsed path with type and identifiers\n */\nexport function parsePath(path: string): ParsedPath {\n const normalizedPath = path.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n const segments = normalizedPath.split(\"/\").filter(Boolean);\n\n if (segments.length === 0) {\n return { type: \"root\", raw: path };\n }\n\n const [first, second, third, fourth] = segments;\n\n // /instances\n if (first === \"instances\") {\n if (!second) {\n return { type: \"instances\", raw: path };\n }\n\n // /instances/{name}\n if (!third) {\n return { type: \"instance\", instanceName: second, raw: path };\n }\n\n // /instances/{name}/metadata.json\n if (third === \"metadata.json\") {\n return { type: \"instance-metadata\", instanceName: second, fileName: third, raw: path };\n }\n\n // /instances/{name}/actions\n if (third === \"actions\") {\n if (!fourth) {\n return { type: \"instance-actions\", instanceName: second, raw: path };\n }\n // /instances/{name}/actions/{action}\n return { type: \"instance-action\", instanceName: second, action: fourth, raw: path };\n }\n\n return { type: \"unknown\", raw: path };\n }\n\n // /actions\n if (first === \"actions\") {\n if (!second) {\n return { type: \"actions\", raw: path };\n }\n // /actions/{action}\n return { type: \"global-action\", action: second, raw: path };\n }\n\n return { type: \"unknown\", raw: path };\n}\n\n/**\n * Build an AFS path from components\n */\nexport function buildPath(...segments: (string | undefined)[]): string {\n return `/${segments.filter(Boolean).join(\"/\")}`;\n}\n","/**\n * GCE Actions\n *\n * Executes actions on GCE resources (start, stop, reset, etc.)\n */\n\nimport type { InstancesClient } from \"@google-cloud/compute\";\nimport { mapGCEError } from \"../errors.js\";\nimport { parsePath } from \"../path-resolver.js\";\nimport type { GCEInstanceState } from \"../types.js\";\n\n/**\n * Action result\n */\nexport interface ActionResult {\n success: boolean;\n action: string;\n operationName?: string;\n error?: string;\n}\n\n/**\n * Execute an action on a GCE resource\n *\n * @param client - GCE InstancesClient\n * @param projectId - GCP project ID\n * @param zone - GCE zone\n * @param path - AFS path to the action\n * @returns Action result\n */\nexport async function executeAction(\n client: InstancesClient,\n projectId: string,\n zone: string,\n path: string,\n): Promise<ActionResult> {\n try {\n const parsed = parsePath(path);\n\n switch (parsed.type) {\n case \"instance-action\":\n return executeInstanceAction(client, projectId, zone, parsed.instanceName!, parsed.action!);\n\n case \"global-action\":\n return executeGlobalAction(parsed.action!);\n\n default:\n throw new Error(`Cannot execute action on path: ${path}`);\n }\n } catch (error) {\n throw mapGCEError(error);\n }\n}\n\n/**\n * Execute an action on a specific instance\n */\nasync function executeInstanceAction(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n action: string,\n): Promise<ActionResult> {\n // Get current instance state\n const [instance] = await client.get({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n const status = instance.status as GCEInstanceState;\n\n switch (action) {\n case \"start\":\n return startInstance(client, projectId, zone, instanceName, status);\n\n case \"stop\":\n return stopInstance(client, projectId, zone, instanceName, status);\n\n case \"reset\":\n return resetInstance(client, projectId, zone, instanceName, status);\n\n default:\n return {\n success: false,\n action,\n error: `Unknown action: ${action}`,\n };\n }\n}\n\n/**\n * Start an instance\n */\nasync function startInstance(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n currentStatus: GCEInstanceState,\n): Promise<ActionResult> {\n // Can only start stopped or terminated instances\n if (currentStatus !== \"STOPPED\" && currentStatus !== \"TERMINATED\") {\n return {\n success: false,\n action: \"start\",\n error: `Cannot start instance in ${currentStatus} state. Instance must be STOPPED or TERMINATED.`,\n };\n }\n\n const [operation] = await client.start({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n return {\n success: true,\n action: \"start\",\n operationName: (operation as any).latestResponse?.name || \"unknown\",\n };\n}\n\n/**\n * Stop an instance\n */\nasync function stopInstance(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n currentStatus: GCEInstanceState,\n): Promise<ActionResult> {\n // Can only stop running instances\n if (currentStatus !== \"RUNNING\") {\n return {\n success: false,\n action: \"stop\",\n error: `Cannot stop instance in ${currentStatus} state. Instance must be RUNNING.`,\n };\n }\n\n const [operation] = await client.stop({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n return {\n success: true,\n action: \"stop\",\n operationName: (operation as any).latestResponse?.name || \"unknown\",\n };\n}\n\n/**\n * Reset an instance\n */\nasync function resetInstance(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n currentStatus: GCEInstanceState,\n): Promise<ActionResult> {\n // Can only reset running instances\n if (currentStatus !== \"RUNNING\") {\n return {\n success: false,\n action: \"reset\",\n error: `Cannot reset instance in ${currentStatus} state. Instance must be RUNNING.`,\n };\n }\n\n const [operation] = await client.reset({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n return {\n success: true,\n action: \"reset\",\n operationName: (operation as any).latestResponse?.name || \"unknown\",\n };\n}\n\n/**\n * Execute a global action\n */\nfunction executeGlobalAction(action: string): ActionResult {\n switch (action) {\n case \"refresh\":\n // Refresh is a no-op for now - cache clearing would happen at provider level\n return {\n success: true,\n action: \"refresh\",\n };\n\n default:\n return {\n success: false,\n action,\n error: `Unknown global action: ${action}`,\n };\n }\n}\n","/**\n * GCE Platform Reference\n *\n * Generates Google Cloud Console URLs for GCE resources.\n */\n\n/**\n * Platform reference containing console URL\n */\nexport interface GCEPlatformRef {\n consoleUrl: string;\n}\n\n/**\n * Generate platform reference with GCP Console URL for an instance\n *\n * @param projectId - GCP project ID\n * @param zone - GCE zone\n * @param instanceName - Instance name\n * @returns Platform reference with console URL\n */\nexport function generateInstancePlatformRef(\n projectId: string,\n zone: string,\n instanceName: string,\n): GCEPlatformRef {\n return {\n consoleUrl: `https://console.cloud.google.com/compute/instancesDetail/zones/${zone}/instances/${instanceName}?project=${projectId}`,\n };\n}\n\n/**\n * Generate platform reference with GCP Console URL for instances list\n *\n * @param projectId - GCP project ID\n * @returns Platform reference with console URL\n */\nexport function generateInstancesListPlatformRef(projectId: string): GCEPlatformRef {\n return {\n consoleUrl: `https://console.cloud.google.com/compute/instances?project=${projectId}`,\n };\n}\n","/**\n * AFS GCE Provider Types\n */\n\nimport { camelize, optionalize } from \"@aigne/afs/utils/zod\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for AFSGCE\n */\nexport interface AFSGCEOptions {\n /** Module name (used as mount path segment) */\n name?: string;\n\n /** Module description */\n description?: string;\n\n /** GCP project ID */\n projectId: string;\n\n /** GCE zone (e.g., us-central1-a) */\n zone: string;\n\n /** Access mode */\n accessMode?: \"readonly\" | \"readwrite\";\n\n /** Path to service account key file */\n keyFilename?: string;\n\n /** Explicit credentials (for programmatic access) */\n credentials?: {\n clientEmail: string;\n privateKey: string;\n };\n\n /** Cache TTL in seconds (0 = no cache) */\n cacheTtl?: number;\n}\n\n/**\n * GCE zone validation regex\n * Format: region-zone (e.g., us-central1-a, europe-west1-b)\n */\nconst ZONE_REGEX = /^[a-z]+-[a-z]+\\d+-[a-z]$/;\n\n/**\n * Zod schema for options validation\n */\nexport const afsgceOptionsSchema = camelize(\n z\n .object({\n name: optionalize(z.string()),\n description: optionalize(z.string()),\n projectId: z.string().min(1),\n zone: z.string().regex(ZONE_REGEX, \"Invalid GCE zone format (e.g., us-central1-a)\"),\n accessMode: optionalize(z.enum([\"readonly\", \"readwrite\"])),\n keyFilename: optionalize(z.string()),\n credentials: optionalize(\n z.object({\n clientEmail: z.string(),\n privateKey: z.string(),\n }),\n ),\n cacheTtl: optionalize(z.number().int().min(0)),\n })\n .strict(),\n);\n\n/**\n * GCE instance states\n */\nexport const GCE_INSTANCE_STATES = [\n \"PROVISIONING\",\n \"STAGING\",\n \"RUNNING\",\n \"STOPPING\",\n \"STOPPED\",\n \"SUSPENDING\",\n \"SUSPENDED\",\n \"TERMINATED\",\n] as const;\n\nexport type GCEInstanceState = (typeof GCE_INSTANCE_STATES)[number];\n\n/**\n * Path types for GCE resources\n */\nexport type PathType =\n | \"root\"\n | \"instances\"\n | \"instance\"\n | \"instance-metadata\"\n | \"instance-actions\"\n | \"instance-action\"\n | \"actions\"\n | \"global-action\"\n | \"unknown\";\n\nexport interface ParsedPath {\n type: PathType;\n instanceName?: string;\n action?: string;\n fileName?: string;\n raw: string;\n}\n\n/**\n * Kind constants for GCE resources\n */\nexport const KINDS = {\n INSTANCE: \"gce:instance\",\n ACTION: \"gce:action\",\n EXECUTABLE: \"afs:executable\",\n NODE: \"afs:node\",\n GCP_RESOURCE: \"gcp:resource\",\n} as const;\n","/**\n * GCE List Operation\n *\n * Lists GCE resources.\n */\n\nimport type { AFSEntry, AFSListOptions, AFSListResult } from \"@aigne/afs\";\nimport type { InstancesClient } from \"@google-cloud/compute\";\nimport { mapGCEError } from \"../errors.js\";\nimport { buildPath, parsePath } from \"../path-resolver.js\";\nimport { generateInstancePlatformRef, generateInstancesListPlatformRef } from \"../platform-ref.js\";\nimport { type GCEInstanceState, KINDS } from \"../types.js\";\n\n/**\n * List GCE resources\n *\n * @param client - GCE InstancesClient\n * @param projectId - GCP project ID\n * @param zone - GCE zone\n * @param path - AFS path\n * @param options - List options\n * @returns List result with entries\n */\nexport async function list(\n client: InstancesClient,\n projectId: string,\n zone: string,\n path: string,\n options?: AFSListOptions,\n): Promise<AFSListResult> {\n try {\n const parsed = parsePath(path);\n\n switch (parsed.type) {\n case \"root\":\n return listRoot(projectId);\n\n case \"instances\":\n return listInstances(client, projectId, zone, options);\n\n case \"instance\":\n return listInstanceChildren(client, projectId, zone, parsed.instanceName!);\n\n case \"instance-actions\":\n return listInstanceActions(client, projectId, zone, parsed.instanceName!);\n\n case \"actions\":\n return listGlobalActions(projectId);\n\n default:\n return { data: [] };\n }\n } catch (error) {\n throw mapGCEError(error);\n }\n}\n\n/**\n * List root directory\n */\nfunction listRoot(projectId: string): AFSListResult {\n const entries: AFSEntry[] = [\n {\n id: `gce://${projectId}/instances`,\n path: \"/instances\",\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: 0,\n description: \"GCE Instances\",\n platformRef: generateInstancesListPlatformRef(projectId),\n },\n },\n {\n id: `gce://${projectId}/actions`,\n path: \"/actions\",\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: 0,\n description: \"Global Actions\",\n },\n },\n ];\n\n return { data: entries };\n}\n\n/**\n * List all instances\n */\nasync function listInstances(\n client: InstancesClient,\n projectId: string,\n zone: string,\n options?: AFSListOptions,\n): Promise<AFSListResult> {\n const maxChildren = options?.maxChildren ?? 1000;\n\n const [instances] = await client.list({\n project: projectId,\n zone,\n maxResults: maxChildren,\n });\n\n const entries: AFSEntry[] = (instances || []).map((instance) => {\n const name = instance.name!;\n const machineType = instance.machineType?.split(\"/\").pop() || \"unknown\";\n\n return {\n id: `gce://${projectId}/${zone}/${name}`,\n path: buildPath(\"instances\", name),\n metadata: {\n kind: KINDS.INSTANCE,\n kinds: [KINDS.INSTANCE, KINDS.GCP_RESOURCE, KINDS.NODE],\n childrenCount: 2, // metadata.json and actions\n status: instance.status as GCEInstanceState,\n machineType,\n privateIp: instance.networkInterfaces?.[0]?.networkIP,\n publicIp: instance.networkInterfaces?.[0]?.accessConfigs?.[0]?.natIP,\n createdAt: instance.creationTimestamp,\n labels: instance.labels,\n platformRef: generateInstancePlatformRef(projectId, zone, name),\n },\n };\n });\n\n return { data: entries };\n}\n\n/**\n * List instance children (metadata.json, actions)\n */\nasync function listInstanceChildren(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n): Promise<AFSListResult> {\n // Verify instance exists\n await client.get({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n const entries: AFSEntry[] = [\n {\n id: `gce://${projectId}/${zone}/${instanceName}/metadata.json`,\n path: buildPath(\"instances\", instanceName, \"metadata.json\"),\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n description: \"Instance metadata\",\n },\n },\n {\n id: `gce://${projectId}/${zone}/${instanceName}/actions`,\n path: buildPath(\"instances\", instanceName, \"actions\"),\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: 0,\n description: \"Instance actions\",\n },\n },\n ];\n\n return { data: entries };\n}\n\n/**\n * List available actions for an instance\n */\nasync function listInstanceActions(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n): Promise<AFSListResult> {\n const [instance] = await client.get({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n const status = instance.status as GCEInstanceState;\n const actions: string[] = [];\n\n // Available actions depend on instance state\n switch (status) {\n case \"RUNNING\":\n actions.push(\"stop\", \"reset\");\n break;\n case \"STOPPED\":\n case \"TERMINATED\":\n actions.push(\"start\");\n break;\n case \"SUSPENDED\":\n actions.push(\"resume\");\n break;\n default:\n // No actions available during transitional states\n break;\n }\n\n const entries: AFSEntry[] = actions.map((action) => ({\n id: `gce://${projectId}/${zone}/${instanceName}/actions/${action}`,\n path: buildPath(\"instances\", instanceName, \"actions\", action),\n metadata: {\n kind: KINDS.ACTION,\n kinds: [KINDS.ACTION, KINDS.EXECUTABLE, KINDS.NODE],\n description: `${action.charAt(0).toUpperCase() + action.slice(1)} the instance`,\n },\n }));\n\n return { data: entries };\n}\n\n/**\n * List global actions\n */\nfunction listGlobalActions(projectId: string): AFSListResult {\n const entries: AFSEntry[] = [\n {\n id: `gce://${projectId}/actions/refresh`,\n path: \"/actions/refresh\",\n metadata: {\n kind: KINDS.ACTION,\n kinds: [KINDS.ACTION, KINDS.EXECUTABLE, KINDS.NODE],\n description: \"Refresh instance cache\",\n },\n },\n ];\n\n return { data: entries };\n}\n","/**\n * GCE Read Operation\n *\n * Reads GCE resource data.\n */\n\nimport type { AFSReadOptions, AFSReadResult } from \"@aigne/afs\";\nimport type { InstancesClient } from \"@google-cloud/compute\";\nimport { mapGCEError } from \"../errors.js\";\nimport { buildPath, parsePath } from \"../path-resolver.js\";\nimport { KINDS } from \"../types.js\";\n\n/**\n * Read GCE resource data\n *\n * @param client - GCE InstancesClient\n * @param projectId - GCP project ID\n * @param zone - GCE zone\n * @param path - AFS path\n * @param options - Read options\n * @returns Read result with content\n */\nexport async function read(\n client: InstancesClient,\n projectId: string,\n zone: string,\n path: string,\n _options?: AFSReadOptions,\n): Promise<AFSReadResult> {\n try {\n const parsed = parsePath(path);\n\n switch (parsed.type) {\n case \"instance-metadata\":\n return readInstanceMetadata(client, projectId, zone, parsed.instanceName!);\n\n default:\n throw new Error(`Cannot read path: ${path}`);\n }\n } catch (error) {\n throw mapGCEError(error);\n }\n}\n\n/**\n * Read instance metadata as JSON\n */\nasync function readInstanceMetadata(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n): Promise<AFSReadResult> {\n const [instance] = await client.get({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n // Return full instance data as JSON content\n return {\n data: {\n id: `gce://${projectId}/${zone}/${instanceName}/metadata.json`,\n path: buildPath(\"instances\", instanceName, \"metadata.json\"),\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n description: \"Instance metadata\",\n },\n content: JSON.stringify(instance, null, 2),\n },\n };\n}\n","/**\n * GCE Stat Operation\n *\n * Returns metadata for GCE resources.\n */\n\nimport type { AFSEntry } from \"@aigne/afs\";\nimport type { InstancesClient } from \"@google-cloud/compute\";\nimport { mapGCEError } from \"../errors.js\";\nimport { buildPath, parsePath } from \"../path-resolver.js\";\nimport { generateInstancePlatformRef, generateInstancesListPlatformRef } from \"../platform-ref.js\";\nimport { type GCEInstanceState, KINDS } from \"../types.js\";\n\n/**\n * Get metadata for a GCE resource\n *\n * @param client - GCE InstancesClient\n * @param projectId - GCP project ID\n * @param zone - GCE zone\n * @param path - AFS path\n * @returns Entry with metadata\n */\nexport async function stat(\n client: InstancesClient,\n projectId: string,\n zone: string,\n path: string,\n): Promise<AFSEntry> {\n try {\n const parsed = parsePath(path);\n\n switch (parsed.type) {\n case \"root\":\n return statRoot(projectId);\n\n case \"instances\":\n return statInstances(projectId);\n\n case \"instance\":\n return statInstance(client, projectId, zone, parsed.instanceName!);\n\n case \"instance-metadata\":\n return statInstanceMetadata(client, projectId, zone, parsed.instanceName!);\n\n case \"instance-actions\":\n return statInstanceActions(client, projectId, zone, parsed.instanceName!);\n\n case \"instance-action\":\n return statInstanceAction(client, projectId, zone, parsed.instanceName!, parsed.action!);\n\n case \"actions\":\n return statGlobalActions(projectId);\n\n case \"global-action\":\n return statGlobalAction(projectId, parsed.action!);\n\n default:\n throw new Error(`Path not found: ${path}`);\n }\n } catch (error) {\n throw mapGCEError(error);\n }\n}\n\n/**\n * Stat root directory\n */\nfunction statRoot(projectId: string): AFSEntry {\n return {\n id: `gce://${projectId}/`,\n path: \"/\",\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: 2,\n description: \"GCE Root\",\n },\n };\n}\n\n/**\n * Stat instances directory\n */\nfunction statInstances(projectId: string): AFSEntry {\n return {\n id: `gce://${projectId}/instances`,\n path: \"/instances\",\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: 0, // Dynamic\n description: \"GCE Instances\",\n platformRef: generateInstancesListPlatformRef(projectId),\n },\n };\n}\n\n/**\n * Stat a specific instance\n */\nasync function statInstance(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n): Promise<AFSEntry> {\n const [instance] = await client.get({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n const machineType = instance.machineType?.split(\"/\").pop() || \"unknown\";\n\n return {\n id: `gce://${projectId}/${zone}/${instanceName}`,\n path: buildPath(\"instances\", instanceName),\n metadata: {\n kind: KINDS.INSTANCE,\n kinds: [KINDS.INSTANCE, KINDS.GCP_RESOURCE, KINDS.NODE],\n childrenCount: 2, // metadata.json and actions\n status: instance.status as GCEInstanceState,\n machineType,\n privateIp: instance.networkInterfaces?.[0]?.networkIP,\n publicIp: instance.networkInterfaces?.[0]?.accessConfigs?.[0]?.natIP,\n createdAt: instance.creationTimestamp,\n labels: instance.labels,\n platformRef: generateInstancePlatformRef(projectId, zone, instanceName),\n },\n };\n}\n\n/**\n * Stat instance metadata.json file\n */\nasync function statInstanceMetadata(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n): Promise<AFSEntry> {\n // Verify instance exists\n await client.get({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n return {\n id: `gce://${projectId}/${zone}/${instanceName}/metadata.json`,\n path: buildPath(\"instances\", instanceName, \"metadata.json\"),\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n description: \"Instance metadata\",\n },\n };\n}\n\n/**\n * Stat instance actions directory\n */\nasync function statInstanceActions(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n): Promise<AFSEntry> {\n // Verify instance exists\n await client.get({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n return {\n id: `gce://${projectId}/${zone}/${instanceName}/actions`,\n path: buildPath(\"instances\", instanceName, \"actions\"),\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: 0, // Dynamic based on state\n description: \"Instance actions\",\n },\n };\n}\n\n/**\n * Stat a specific instance action\n */\nasync function statInstanceAction(\n client: InstancesClient,\n projectId: string,\n zone: string,\n instanceName: string,\n action: string,\n): Promise<AFSEntry> {\n // Verify instance exists\n await client.get({\n project: projectId,\n zone,\n instance: instanceName,\n });\n\n return {\n id: `gce://${projectId}/${zone}/${instanceName}/actions/${action}`,\n path: buildPath(\"instances\", instanceName, \"actions\", action),\n metadata: {\n kind: KINDS.ACTION,\n kinds: [KINDS.ACTION, KINDS.EXECUTABLE, KINDS.NODE],\n description: `${action.charAt(0).toUpperCase() + action.slice(1)} the instance`,\n },\n };\n}\n\n/**\n * Stat global actions directory\n */\nfunction statGlobalActions(projectId: string): AFSEntry {\n return {\n id: `gce://${projectId}/actions`,\n path: \"/actions\",\n metadata: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: 1,\n description: \"Global Actions\",\n },\n };\n}\n\n/**\n * Stat a specific global action\n */\nfunction statGlobalAction(projectId: string, action: string): AFSEntry {\n return {\n id: `gce://${projectId}/actions/${action}`,\n path: buildPath(\"actions\", action),\n metadata: {\n kind: KINDS.ACTION,\n kinds: [KINDS.ACTION, KINDS.EXECUTABLE, KINDS.NODE],\n description: `${action.charAt(0).toUpperCase() + action.slice(1)} action`,\n },\n };\n}\n","/**\n * AFS GCE Provider\n *\n * Provides AFS access to Google Compute Engine instances.\n */\n\nimport type {\n AFSListOptions,\n AFSListResult,\n AFSModule,\n AFSReadOptions,\n AFSReadResult,\n AFSStatResult,\n AFSWriteEntryPayload,\n AFSWriteOptions,\n AFSWriteResult,\n} from \"@aigne/afs\";\nimport { InstancesClient } from \"@google-cloud/compute\";\nimport { mapGCEError } from \"./errors.js\";\nimport { executeAction } from \"./operations/actions.js\";\nimport { list } from \"./operations/list.js\";\nimport { read } from \"./operations/read.js\";\nimport { stat } from \"./operations/stat.js\";\nimport { parsePath } from \"./path-resolver.js\";\nimport { type AFSGCEOptions, afsgceOptionsSchema, KINDS } from \"./types.js\";\n\n/**\n * AFS GCE Provider\n *\n * Provides a file-system-like interface to GCE instances.\n *\n * @example\n * ```typescript\n * const provider = new AFSGCE({\n * projectId: 'my-project',\n * zone: 'us-central1-a',\n * });\n *\n * // List instances\n * const instances = await provider.list('/instances');\n *\n * // Get instance metadata\n * const metadata = await provider.read('/instances/my-vm/metadata.json');\n *\n * // Start an instance (requires readwrite mode)\n * await provider.write('/instances/my-vm/actions/start', {});\n * ```\n */\nexport class AFSGCE implements AFSModule {\n readonly name: string;\n readonly description?: string;\n readonly accessMode: \"readonly\" | \"readwrite\";\n\n private readonly client: InstancesClient;\n private readonly projectId: string;\n private readonly zone: string;\n\n constructor(options: AFSGCEOptions) {\n // Validate options\n const validated = afsgceOptionsSchema.parse(options);\n\n this.name = validated.name || \"gce\";\n this.description = validated.description;\n this.accessMode = validated.accessMode || \"readonly\";\n this.projectId = validated.projectId;\n this.zone = validated.zone;\n\n // Create compute client\n this.client = new InstancesClient({\n keyFilename: validated.keyFilename,\n credentials: validated.credentials\n ? {\n client_email: validated.credentials.clientEmail,\n private_key: validated.credentials.privateKey,\n }\n : undefined,\n });\n }\n\n /**\n * List GCE resources\n */\n async list(path: string, options?: AFSListOptions): Promise<AFSListResult> {\n return list(this.client, this.projectId, this.zone, path, options);\n }\n\n /**\n * Get metadata for a GCE resource\n */\n async stat(path: string): Promise<AFSStatResult> {\n const entry = await stat(this.client, this.projectId, this.zone, path);\n return {\n data: {\n path: entry.path,\n childrenCount: entry.metadata?.childrenCount as number | undefined,\n meta: entry.metadata as Record<string, unknown>,\n },\n };\n }\n\n /**\n * Read GCE resource data\n */\n async read(path: string, options?: AFSReadOptions): Promise<AFSReadResult> {\n return read(this.client, this.projectId, this.zone, path, options);\n }\n\n /**\n * Write/execute action on GCE resource\n *\n * In GCE, write is used to execute actions (start, stop, reset)\n */\n async write(\n path: string,\n _content: AFSWriteEntryPayload,\n _options?: AFSWriteOptions,\n ): Promise<AFSWriteResult> {\n if (this.accessMode !== \"readwrite\") {\n throw mapGCEError(new Error(\"Write operations require readwrite access mode\"));\n }\n\n const parsed = parsePath(path);\n\n if (parsed.type === \"instance-action\" || parsed.type === \"global-action\") {\n const result = await executeAction(this.client, this.projectId, this.zone, path);\n\n // Convert ActionResult to AFSWriteResult\n return {\n data: {\n id: `gce://${this.projectId}/${this.zone}/${path}`,\n path,\n metadata: {\n kind: KINDS.ACTION,\n kinds: [KINDS.ACTION, KINDS.EXECUTABLE, KINDS.NODE],\n success: result.success,\n operationName: result.operationName,\n error: result.error,\n },\n },\n message: result.success\n ? `Action ${result.action} executed successfully`\n : `Action ${result.action} failed: ${result.error}`,\n };\n }\n\n throw mapGCEError(new Error(`Cannot write to path: ${path}`));\n }\n}\n\n// Re-export types\nexport type { AFSGCEOptions } from \"./types.js\";\nexport { afsgceOptionsSchema } from \"./types.js\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/platform-ref.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["/**\n * GCE Platform Reference\n *\n * Generates Google Cloud Console URLs for GCE resources.\n */\n\n/**\n * Platform reference containing console URL\n */\nexport interface GCEPlatformRef {\n consoleUrl: string;\n}\n\n/**\n * Generate platform reference with GCP Console URL for an instance\n *\n * @param projectId - GCP project ID\n * @param zone - GCE zone\n * @param instanceName - Instance name\n * @returns Platform reference with console URL\n */\nexport function generateInstancePlatformRef(\n projectId: string,\n zone: string,\n instanceName: string,\n): GCEPlatformRef {\n return {\n consoleUrl: `https://console.cloud.google.com/compute/instancesDetail/zones/${zone}/instances/${instanceName}?project=${projectId}`,\n };\n}\n\n/**\n * Generate platform reference with GCP Console URL for instances list\n *\n * @param projectId - GCP project ID\n * @returns Platform reference with console URL\n */\nexport function generateInstancesListPlatformRef(projectId: string): GCEPlatformRef {\n return {\n consoleUrl: `https://console.cloud.google.com/compute/instances?project=${projectId}`,\n };\n}\n","/**\n * AFS GCE Provider Types\n */\n\nimport { camelize, optionalize } from \"@aigne/afs/utils/zod\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for AFSGCE\n */\nexport interface AFSGCEOptions {\n /** Module name (used as mount path segment) */\n name?: string;\n\n /** Module description */\n description?: string;\n\n /** GCP project ID */\n projectId: string;\n\n /** GCE zone (e.g., us-central1-a) */\n zone: string;\n\n /** Access mode */\n accessMode?: \"readonly\" | \"readwrite\";\n\n /** Path to service account key file */\n keyFilename?: string;\n\n /** Explicit credentials (for programmatic access) */\n credentials?: {\n clientEmail: string;\n privateKey: string;\n };\n\n /** Cache TTL in seconds (0 = no cache) */\n cacheTtl?: number;\n}\n\n/**\n * GCE zone validation regex\n * Format: region-zone (e.g., us-central1-a, europe-west1-b)\n */\nconst ZONE_REGEX = /^[a-z]+-[a-z]+\\d+-[a-z]$/;\n\n/**\n * Zod schema for options validation\n */\nexport const afsgceOptionsSchema = camelize(\n z\n .object({\n name: optionalize(z.string()),\n description: optionalize(z.string()),\n projectId: z.string().min(1),\n zone: z.string().regex(ZONE_REGEX, \"Invalid GCE zone format (e.g., us-central1-a)\"),\n accessMode: optionalize(z.enum([\"readonly\", \"readwrite\"])),\n keyFilename: optionalize(z.string()),\n credentials: optionalize(\n z.object({\n clientEmail: z.string(),\n privateKey: z.string(),\n }),\n ),\n cacheTtl: optionalize(z.number().int().min(0)),\n })\n .strict(),\n);\n\n/**\n * GCE instance states\n */\nexport const GCE_INSTANCE_STATES = [\n \"PROVISIONING\",\n \"STAGING\",\n \"RUNNING\",\n \"STOPPING\",\n \"STOPPED\",\n \"SUSPENDING\",\n \"SUSPENDED\",\n \"TERMINATED\",\n] as const;\n\nexport type GCEInstanceState = (typeof GCE_INSTANCE_STATES)[number];\n\n/**\n * Path types for GCE resources\n */\nexport type PathType =\n | \"root\"\n | \"instances\"\n | \"instance\"\n | \"instance-metadata\"\n | \"instance-actions\"\n | \"instance-action\"\n | \"actions\"\n | \"global-action\"\n | \"unknown\";\n\nexport interface ParsedPath {\n type: PathType;\n instanceName?: string;\n action?: string;\n fileName?: string;\n raw: string;\n}\n\n/**\n * Kind constants for GCE resources\n */\nexport const KINDS = {\n INSTANCE: \"gce:instance\",\n ACTION: \"gce:action\",\n EXECUTABLE: \"afs:executable\",\n NODE: \"afs:node\",\n GCP_RESOURCE: \"gcp:resource\",\n} as const;\n","/**\n * AFS GCE Provider\n *\n * GCE provider using AFSBaseProvider decorator routing pattern.\n * Provides file-system-like access to Google Compute Engine instances.\n */\n\nimport {\n type ActionCatalog,\n type ActionDefinition,\n Actions,\n type AFSAccessMode,\n AFSBaseProvider,\n type AFSDeleteResult,\n type AFSEntry,\n type AFSExecResult,\n type AFSExplainResult,\n type AFSListResult,\n type AFSModuleClass,\n type AFSModuleLoadParams,\n AFSNotFoundError,\n AFSReadonlyError,\n type AFSStatResult,\n type AFSWriteEntryPayload,\n type AFSWriteResult,\n type CapabilitiesManifest,\n Delete,\n Explain,\n List,\n Meta,\n Read,\n type RouteContext,\n Stat,\n Write,\n} from \"@aigne/afs\";\nimport { zodParse } from \"@aigne/afs/utils/zod\";\nimport { InstancesClient } from \"@google-cloud/compute\";\nimport { joinURL } from \"ufo\";\nimport { generateInstancePlatformRef, generateInstancesListPlatformRef } from \"./platform-ref.js\";\nimport {\n type AFSGCEOptions,\n afsgceOptionsSchema,\n GCE_INSTANCE_STATES,\n type GCEInstanceState,\n KINDS,\n} from \"./types.js\";\n\n/**\n * Map GCE SDK errors to appropriate AFS errors\n */\nfunction mapGCEError(error: unknown, path?: string): Error {\n if (error instanceof AFSNotFoundError || error instanceof AFSReadonlyError) {\n return error;\n }\n if (typeof error === \"object\" && error !== null && \"code\" in error) {\n const err = error as { code: number; message?: string };\n if (err.code === 404) {\n return new AFSNotFoundError(path ?? \"/\", err.message);\n }\n }\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n}\n\n/**\n * AFSGCE Provider using AFSBaseProvider pattern\n *\n * Provides file-system-like access to GCE instances.\n * Uses decorator routing (@List, @Read, @Write, @Delete, @Meta, @Actions, @Explain).\n *\n * @example\n * ```typescript\n * const gce = new AFSGCE({\n * projectId: \"my-project\",\n * zone: \"us-central1-a\",\n * });\n *\n * // Mount to AFS\n * afs.mount(gce);\n *\n * // List instances\n * const result = await afs.list(\"/modules/gce/instances\");\n *\n * // Read instance metadata\n * const meta = await afs.read(\"/modules/gce/instances/my-vm/metadata.json\");\n * ```\n */\nexport class AFSGCE extends AFSBaseProvider {\n override readonly name: string;\n override readonly description?: string;\n override readonly accessMode: AFSAccessMode;\n\n private readonly client: InstancesClient;\n private readonly projectId: string;\n private readonly zone: string;\n\n constructor(options: AFSGCEOptions) {\n super();\n\n const validated = afsgceOptionsSchema.parse(options);\n\n this.name = validated.name || \"gce\";\n this.description = validated.description;\n this.accessMode = validated.accessMode || \"readonly\";\n this.projectId = validated.projectId;\n this.zone = validated.zone;\n\n this.client = new InstancesClient({\n keyFilename: validated.keyFilename,\n credentials: validated.credentials\n ? {\n client_email: validated.credentials.clientEmail,\n private_key: validated.credentials.privateKey,\n }\n : undefined,\n });\n }\n\n static schema() {\n return afsgceOptionsSchema;\n }\n\n static async load({ basePath, config }: AFSModuleLoadParams = {}): Promise<AFSGCE> {\n const options = zodParse(afsgceOptionsSchema, config, { prefix: basePath });\n return new AFSGCE(options);\n }\n\n // ========== Helper Methods ==========\n\n private async getInstance(instanceName: string) {\n try {\n const [instance] = await this.client.get({\n project: this.projectId,\n zone: this.zone,\n instance: instanceName,\n });\n return instance;\n } catch (error) {\n throw mapGCEError(error, joinURL(\"/instances\", instanceName));\n }\n }\n\n private async listAllInstances(maxResults?: number) {\n const [instances] = await this.client.list({\n project: this.projectId,\n zone: this.zone,\n maxResults: maxResults ?? 1000,\n });\n return instances || [];\n }\n\n private buildInstanceEntry(instance: any, basePath: string): AFSEntry {\n const name = instance.name!;\n const machineType = instance.machineType?.split(\"/\").pop() || \"unknown\";\n\n return {\n id: `gce://${this.projectId}/${this.zone}/${name}`,\n path: joinURL(basePath, name),\n meta: {\n kind: KINDS.INSTANCE,\n kinds: [KINDS.INSTANCE, KINDS.GCP_RESOURCE, KINDS.NODE],\n childrenCount: -1,\n status: instance.status as GCEInstanceState,\n machineType,\n privateIp: instance.networkInterfaces?.[0]?.networkIP,\n publicIp: instance.networkInterfaces?.[0]?.accessConfigs?.[0]?.natIP,\n createdAt: instance.creationTimestamp,\n labels: instance.labels,\n platformRef: generateInstancePlatformRef(this.projectId, this.zone, name),\n },\n };\n }\n\n // ========== List Operations ==========\n\n @List(\"/\")\n async listRoot(_ctx: RouteContext): Promise<AFSListResult> {\n return {\n data: [\n {\n id: `gce://${this.projectId}/instances`,\n path: \"/instances\",\n meta: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: -1,\n description: \"GCE Instances\",\n platformRef: generateInstancesListPlatformRef(this.projectId),\n },\n },\n {\n id: `gce://${this.projectId}/by-status`,\n path: \"/by-status\",\n meta: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: GCE_INSTANCE_STATES.length,\n description: \"Instances grouped by status\",\n },\n },\n ],\n };\n }\n\n @List(\"/instances\")\n async listInstances(_ctx: RouteContext): Promise<AFSListResult> {\n try {\n const instances = await this.listAllInstances();\n const entries = instances.map((instance: any) =>\n this.buildInstanceEntry(instance, \"/instances\"),\n );\n return { data: entries };\n } catch (error) {\n throw mapGCEError(error, \"/instances\");\n }\n }\n\n @List(\"/instances/:instanceId\")\n @List(\"/by-status/:status/:instanceId\")\n async listInstanceChildren(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n ): Promise<AFSListResult> {\n await this.getInstance(ctx.params.instanceId);\n\n return {\n data: [\n {\n id: `gce://${this.projectId}/${this.zone}/${ctx.params.instanceId}/metadata.json`,\n path: joinURL(ctx.path, \"metadata.json\"),\n meta: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n description: \"Instance metadata\",\n },\n },\n {\n id: `gce://${this.projectId}/${this.zone}/${ctx.params.instanceId}/labels`,\n path: joinURL(ctx.path, \"labels\"),\n meta: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: -1,\n description: \"Instance labels\",\n },\n },\n ],\n };\n }\n\n @List(\"/instances/:instanceId/labels\")\n @List(\"/by-status/:status/:instanceId/labels\")\n async listInstanceLabels(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n ): Promise<AFSListResult> {\n const instance = await this.getInstance(ctx.params.instanceId);\n const labels = instance.labels || {};\n\n const entries: AFSEntry[] = Object.entries(labels).map(([key, value]) => ({\n id: `gce://${this.projectId}/${this.zone}/${ctx.params.instanceId}/labels/${key}`,\n path: joinURL(ctx.path, encodeURIComponent(key)),\n content: value,\n meta: {\n kind: \"gce:label\",\n },\n }));\n\n return { data: entries };\n }\n\n @List(\"/by-status\")\n async listByStatus(_ctx: RouteContext): Promise<AFSListResult> {\n const entries: AFSEntry[] = GCE_INSTANCE_STATES.map((status) => ({\n id: `gce://${this.projectId}/by-status/${status.toLowerCase()}`,\n path: joinURL(\"/by-status\", status.toLowerCase()),\n meta: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: -1,\n description: `Instances in ${status} state`,\n },\n }));\n\n return { data: entries };\n }\n\n @List(\"/by-status/:status\")\n async listByStatusFilter(ctx: RouteContext<{ status: string }>): Promise<AFSListResult> {\n try {\n const statusUpper = ctx.params.status.toUpperCase();\n const instances = await this.listAllInstances();\n const filtered = instances.filter(\n (inst: any) => (inst.status as string)?.toUpperCase() === statusUpper,\n );\n\n const entries = filtered.map((instance: any) => this.buildInstanceEntry(instance, ctx.path));\n\n return { data: entries };\n } catch (error) {\n throw mapGCEError(error, ctx.path);\n }\n }\n\n // ========== Read Operations ==========\n\n @Read(\"/.meta/.capabilities\")\n async readCapabilities(_ctx: RouteContext): Promise<AFSEntry> {\n const actionCatalogs: ActionCatalog[] = [];\n\n const instanceActions: ActionDefinition[] = [\n {\n name: \"start\",\n description: \"Start a stopped or terminated instance\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"stop\",\n description: \"Stop a running instance\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"reset\",\n description: \"Reset (hard reboot) a running instance\",\n inputSchema: { type: \"object\", properties: {} },\n },\n ];\n\n actionCatalogs.push({\n kind: \"gce:instance\",\n description: \"Instance lifecycle operations\",\n catalog: instanceActions,\n discovery: {\n pathTemplate: \"/instances/:instanceName/.actions\",\n note: \"Replace :instanceName with actual instance name\",\n },\n });\n\n if (this.accessMode === \"readwrite\") {\n actionCatalogs.push({\n kind: \"gce:global\",\n description: \"Global GCE operations\",\n catalog: [\n {\n name: \"refresh\",\n description: \"Refresh cached instance data\",\n inputSchema: { type: \"object\", properties: {} },\n },\n ],\n discovery: {\n pathTemplate: \"/.actions\",\n note: \"Available at provider root\",\n },\n });\n }\n\n const manifest: CapabilitiesManifest = {\n schemaVersion: 1,\n provider: this.name,\n version: \"1.0.0\",\n description: this.description,\n tools: [],\n actions: actionCatalogs,\n operations: this.getOperationsDeclaration(),\n };\n\n return {\n id: \"/.meta/.capabilities\",\n path: \"/.meta/.capabilities\",\n content: manifest,\n meta: { kind: \"afs:capabilities\" },\n };\n }\n\n @Read(\"/instances/:instanceId/metadata.json\")\n @Read(\"/by-status/:status/:instanceId/metadata.json\")\n async readInstanceMetadata(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n ): Promise<AFSEntry> {\n try {\n const instance = await this.getInstance(ctx.params.instanceId);\n\n return {\n id: `gce://${this.projectId}/${this.zone}/${ctx.params.instanceId}/metadata.json`,\n path: ctx.path,\n meta: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n description: \"Instance metadata\",\n },\n content: JSON.stringify(instance, null, 2),\n };\n } catch (error) {\n throw mapGCEError(error, ctx.path);\n }\n }\n\n @Read(\"/instances/:instanceId/labels/:labelKey\")\n @Read(\"/by-status/:status/:instanceId/labels/:labelKey\")\n async readInstanceLabel(\n ctx: RouteContext<{ instanceId: string; labelKey: string; status?: string }>,\n ): Promise<AFSEntry> {\n const instance = await this.getInstance(ctx.params.instanceId);\n const labels = instance.labels || {};\n const value = labels[ctx.params.labelKey];\n\n if (value === undefined) {\n throw new AFSNotFoundError(ctx.path);\n }\n\n return {\n id: `gce://${this.projectId}/${this.zone}/${ctx.params.instanceId}/labels/${ctx.params.labelKey}`,\n path: ctx.path,\n content: value,\n meta: { kind: \"gce:label\" },\n };\n }\n\n // ========== Meta Operations ==========\n\n @Meta(\"/\")\n async metaRoot(ctx: RouteContext): Promise<AFSEntry> {\n return {\n id: `gce://${this.projectId}/`,\n path: ctx.path,\n meta: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: 2,\n description: \"GCE Root\",\n },\n };\n }\n\n @Meta(\"/instances\")\n async metaInstances(ctx: RouteContext): Promise<AFSEntry> {\n return {\n id: `gce://${this.projectId}/instances`,\n path: ctx.path,\n meta: {\n kind: KINDS.NODE,\n kinds: [KINDS.NODE],\n childrenCount: -1,\n description: \"GCE Instances\",\n platformRef: generateInstancesListPlatformRef(this.projectId),\n },\n };\n }\n\n @Meta(\"/instances/:instanceId\")\n @Meta(\"/by-status/:status/:instanceId\")\n async metaInstance(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n ): Promise<AFSEntry> {\n try {\n const instance = await this.getInstance(ctx.params.instanceId);\n const machineType = instance.machineType?.split(\"/\").pop() || \"unknown\";\n\n return {\n id: `gce://${this.projectId}/${this.zone}/${ctx.params.instanceId}`,\n path: ctx.path,\n meta: {\n kind: KINDS.INSTANCE,\n kinds: [KINDS.INSTANCE, KINDS.GCP_RESOURCE, KINDS.NODE],\n childrenCount: -1,\n status: instance.status as GCEInstanceState,\n machineType,\n privateIp: instance.networkInterfaces?.[0]?.networkIP,\n publicIp: instance.networkInterfaces?.[0]?.accessConfigs?.[0]?.natIP,\n createdAt: instance.creationTimestamp,\n labels: instance.labels,\n platformRef: generateInstancePlatformRef(\n this.projectId,\n this.zone,\n ctx.params.instanceId,\n ),\n },\n };\n } catch (error) {\n throw mapGCEError(error, ctx.path);\n }\n }\n\n // ========== Stat Operations ==========\n\n @Stat(\"/\")\n async statRoot(ctx: RouteContext): Promise<AFSStatResult> {\n const meta = await this.metaRoot(ctx);\n return { data: { id: meta.id, path: ctx.path, meta: meta.meta as Record<string, unknown> } };\n }\n\n @Stat(\"/instances\")\n async statInstances(ctx: RouteContext): Promise<AFSStatResult> {\n const meta = await this.metaInstances(ctx);\n return { data: { id: meta.id, path: ctx.path, meta: meta.meta as Record<string, unknown> } };\n }\n\n @Stat(\"/instances/:instanceId\")\n @Stat(\"/by-status/:status/:instanceId\")\n async statInstance(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n ): Promise<AFSStatResult> {\n const meta = await this.metaInstance(ctx);\n return { data: { id: meta.id, path: ctx.path, meta: meta.meta as Record<string, unknown> } };\n }\n\n // ========== Write Operations ==========\n\n @Write(\"/instances/:instanceId/labels/:labelKey\")\n @Write(\"/by-status/:status/:instanceId/labels/:labelKey\")\n async writeInstanceLabel(\n ctx: RouteContext<{ instanceId: string; labelKey: string; status?: string }>,\n payload: AFSWriteEntryPayload,\n ): Promise<AFSWriteResult> {\n if (this.accessMode !== \"readwrite\") {\n throw new AFSReadonlyError(\"Write operations require readwrite access mode\");\n }\n\n try {\n const instance = await this.getInstance(ctx.params.instanceId);\n const labels = { ...(instance.labels || {}) };\n labels[ctx.params.labelKey] = String(payload.content ?? \"\");\n\n await this.client.setLabels({\n project: this.projectId,\n zone: this.zone,\n instance: ctx.params.instanceId,\n instancesSetLabelsRequestResource: {\n labels,\n labelFingerprint: instance.labelFingerprint,\n },\n });\n\n return {\n data: {\n id: `gce://${this.projectId}/${this.zone}/${ctx.params.instanceId}/labels/${ctx.params.labelKey}`,\n path: ctx.path,\n content: payload.content,\n meta: { kind: \"gce:label\" },\n },\n message: `Label '${ctx.params.labelKey}' set on instance '${ctx.params.instanceId}'`,\n };\n } catch (error) {\n throw mapGCEError(error, ctx.path);\n }\n }\n\n // ========== Delete Operations ==========\n\n @Delete(\"/instances/:instanceId/labels/:labelKey\")\n @Delete(\"/by-status/:status/:instanceId/labels/:labelKey\")\n async deleteInstanceLabel(\n ctx: RouteContext<{ instanceId: string; labelKey: string; status?: string }>,\n ): Promise<AFSDeleteResult> {\n if (this.accessMode !== \"readwrite\") {\n throw new AFSReadonlyError(\"Delete operations require readwrite access mode\");\n }\n\n try {\n const instance = await this.getInstance(ctx.params.instanceId);\n const labels = { ...(instance.labels || {}) };\n\n if (!(ctx.params.labelKey in labels)) {\n throw new AFSNotFoundError(\n ctx.path,\n `Label '${ctx.params.labelKey}' not found on instance '${ctx.params.instanceId}'`,\n );\n }\n\n delete labels[ctx.params.labelKey];\n\n await this.client.setLabels({\n project: this.projectId,\n zone: this.zone,\n instance: ctx.params.instanceId,\n instancesSetLabelsRequestResource: {\n labels,\n labelFingerprint: instance.labelFingerprint,\n },\n });\n\n return {\n message: `Label '${ctx.params.labelKey}' removed from instance '${ctx.params.instanceId}'`,\n };\n } catch (error) {\n if (error instanceof AFSNotFoundError) throw error;\n throw mapGCEError(error, ctx.path);\n }\n }\n\n // ========== Actions ==========\n\n @Actions(\"/\")\n async listGlobalActions(ctx: RouteContext): Promise<AFSListResult> {\n return {\n data: [\n {\n id: \"refresh\",\n path: joinURL(ctx.path, \"refresh\"),\n summary: \"Refresh instance cache\",\n meta: {\n kind: \"afs:executable\",\n kinds: [\"afs:executable\", \"afs:node\"],\n inputSchema: { type: \"object\", properties: {} },\n },\n },\n ],\n };\n }\n\n @Actions.Exec(\"/\", \"refresh\")\n async refreshAction(_ctx: RouteContext, _args: Record<string, unknown>): Promise<AFSExecResult> {\n return { success: true, data: { message: \"Cache refreshed\" } };\n }\n\n @Actions(\"/instances/:instanceId\")\n @Actions(\"/by-status/:status/:instanceId\")\n async listInstanceActions(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n ): Promise<AFSListResult> {\n const instance = await this.getInstance(ctx.params.instanceId);\n const status = instance.status as GCEInstanceState;\n\n const actions: Array<{ name: string; summary: string }> = [];\n\n switch (status) {\n case \"RUNNING\":\n actions.push(\n { name: \"stop\", summary: \"Stop the instance\" },\n { name: \"reset\", summary: \"Reset (hard reboot) the instance\" },\n );\n break;\n case \"STOPPED\":\n case \"TERMINATED\":\n actions.push({ name: \"start\", summary: \"Start the instance\" });\n break;\n case \"SUSPENDED\":\n actions.push({ name: \"start\", summary: \"Resume the instance\" });\n break;\n }\n\n return {\n data: actions.map((action) => ({\n id: action.name,\n path: joinURL(ctx.path, action.name),\n summary: action.summary,\n meta: {\n kind: \"afs:executable\",\n kinds: [\"afs:executable\", \"afs:node\"],\n inputSchema: { type: \"object\", properties: {} },\n },\n })),\n };\n }\n\n @Actions.Exec(\"/instances/:instanceId\", \"start\")\n @Actions.Exec(\"/by-status/:status/:instanceId\", \"start\")\n async startInstanceAction(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n _args: Record<string, unknown>,\n ): Promise<AFSExecResult> {\n try {\n const instance = await this.getInstance(ctx.params.instanceId);\n const status = instance.status as GCEInstanceState;\n\n if (status !== \"STOPPED\" && status !== \"TERMINATED\") {\n return {\n success: false,\n error: {\n code: \"INVALID_STATE\",\n message: `Cannot start instance in ${status} state. Instance must be STOPPED or TERMINATED.`,\n },\n };\n }\n\n const [operation] = await this.client.start({\n project: this.projectId,\n zone: this.zone,\n instance: ctx.params.instanceId,\n });\n\n return {\n success: true,\n data: { operationName: (operation as any).latestResponse?.name || \"unknown\" },\n };\n } catch (error) {\n throw mapGCEError(error, ctx.path);\n }\n }\n\n @Actions.Exec(\"/instances/:instanceId\", \"stop\")\n @Actions.Exec(\"/by-status/:status/:instanceId\", \"stop\")\n async stopInstanceAction(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n _args: Record<string, unknown>,\n ): Promise<AFSExecResult> {\n try {\n const instance = await this.getInstance(ctx.params.instanceId);\n const status = instance.status as GCEInstanceState;\n\n if (status !== \"RUNNING\") {\n return {\n success: false,\n error: {\n code: \"INVALID_STATE\",\n message: `Cannot stop instance in ${status} state. Instance must be RUNNING.`,\n },\n };\n }\n\n const [operation] = await this.client.stop({\n project: this.projectId,\n zone: this.zone,\n instance: ctx.params.instanceId,\n });\n\n return {\n success: true,\n data: { operationName: (operation as any).latestResponse?.name || \"unknown\" },\n };\n } catch (error) {\n throw mapGCEError(error, ctx.path);\n }\n }\n\n @Actions.Exec(\"/instances/:instanceId\", \"reset\")\n @Actions.Exec(\"/by-status/:status/:instanceId\", \"reset\")\n async resetInstanceAction(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n _args: Record<string, unknown>,\n ): Promise<AFSExecResult> {\n try {\n const instance = await this.getInstance(ctx.params.instanceId);\n const status = instance.status as GCEInstanceState;\n\n if (status !== \"RUNNING\") {\n return {\n success: false,\n error: {\n code: \"INVALID_STATE\",\n message: `Cannot reset instance in ${status} state. Instance must be RUNNING.`,\n },\n };\n }\n\n const [operation] = await this.client.reset({\n project: this.projectId,\n zone: this.zone,\n instance: ctx.params.instanceId,\n });\n\n return {\n success: true,\n data: { operationName: (operation as any).latestResponse?.name || \"unknown\" },\n };\n } catch (error) {\n throw mapGCEError(error, ctx.path);\n }\n }\n\n // ========== Explain ==========\n\n @Explain(\"/\")\n async explainRoot(_ctx: RouteContext): Promise<AFSExplainResult> {\n try {\n const instances = await this.listAllInstances();\n const byStatus: Record<string, number> = {};\n\n for (const inst of instances) {\n const status = (inst.status as string) || \"UNKNOWN\";\n byStatus[status] = (byStatus[status] || 0) + 1;\n }\n\n const statusLines = Object.entries(byStatus)\n .map(([status, count]) => `- **${status}**: ${count}`)\n .join(\"\\n\");\n\n const content = `# GCE Provider\n\n- **Project**: ${this.projectId}\n- **Zone**: ${this.zone}\n- **Access Mode**: ${this.accessMode}\n- **Total Instances**: ${instances.length}\n\n## Instances by Status\n\n${statusLines || \"- No instances found\"}\n\n## Navigation\n\n- \\`/instances/\\` — list all instances\n- \\`/by-status/\\` — instances grouped by status\n- \\`/.actions/\\` — global actions\n`;\n\n return { format: \"markdown\", content };\n } catch (error) {\n throw mapGCEError(error);\n }\n }\n\n @Explain(\"/instances/:instanceId\")\n @Explain(\"/by-status/:status/:instanceId\")\n async explainInstance(\n ctx: RouteContext<{ instanceId: string; status?: string }>,\n ): Promise<AFSExplainResult> {\n try {\n const instance = await this.getInstance(ctx.params.instanceId);\n const machineType = instance.machineType?.split(\"/\").pop() || \"unknown\";\n const privateIp = instance.networkInterfaces?.[0]?.networkIP || \"none\";\n const publicIp = instance.networkInterfaces?.[0]?.accessConfigs?.[0]?.natIP || \"none\";\n const labels = instance.labels || {};\n const labelLines = Object.entries(labels)\n .map(([k, v]) => `- \\`${k}\\`: ${v}`)\n .join(\"\\n\");\n\n const content = `# Instance: ${ctx.params.instanceId}\n\n- **Status**: ${instance.status}\n- **Machine Type**: ${machineType}\n- **Zone**: ${this.zone}\n- **Created**: ${instance.creationTimestamp || \"unknown\"}\n\n## Network\n\n- **Private IP**: ${privateIp}\n- **Public IP**: ${publicIp}\n\n## Labels\n\n${labelLines || \"- No labels\"}\n`;\n\n return { format: \"markdown\", content };\n } catch (error) {\n throw mapGCEError(error, ctx.path);\n }\n }\n}\n\n// Type check: AFSGCE should implement AFSModuleClass\nconst _typeCheck: AFSModuleClass<AFSGCE, AFSGCEOptions> = AFSGCE;\n\n// Re-export types\nexport type { AFSGCEOptions } from \"./types.js\";\nexport { afsgceOptionsSchema } from \"./types.js\";\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/afs-gce",
3
- "version": "1.11.0-beta.6",
3
+ "version": "1.11.0-beta.7",
4
4
  "description": "AIGNE AFS module for Google Compute Engine resources",
5
5
  "license": "UNLICENSED",
6
6
  "publishConfig": {
@@ -34,8 +34,9 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@google-cloud/compute": "^4.10.0",
37
+ "ufo": "^1.6.3",
37
38
  "zod": "^3.25.67",
38
- "@aigne/afs": "^1.11.0-beta.6"
39
+ "@aigne/afs": "^1.11.0-beta.7"
39
40
  },
40
41
  "devDependencies": {
41
42
  "@types/bun": "^1.3.6",