@easonwumac/computer-linker 0.1.2
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/CHANGELOG.md +230 -0
- package/LICENSE +21 -0
- package/README.md +539 -0
- package/SECURITY.md +48 -0
- package/dist/api.d.ts +2 -0
- package/dist/api.js +360 -0
- package/dist/audit.d.ts +70 -0
- package/dist/audit.js +102 -0
- package/dist/capabilities.d.ts +98 -0
- package/dist/capabilities.js +718 -0
- package/dist/capability-policy.d.ts +22 -0
- package/dist/capability-policy.js +103 -0
- package/dist/chatgpt.d.ts +167 -0
- package/dist/chatgpt.js +561 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +4621 -0
- package/dist/client-smoke.d.ts +44 -0
- package/dist/client-smoke.js +639 -0
- package/dist/client.d.ts +217 -0
- package/dist/client.js +357 -0
- package/dist/codex-runs.d.ts +35 -0
- package/dist/codex-runs.js +66 -0
- package/dist/computer-contract.d.ts +33 -0
- package/dist/computer-contract.js +384 -0
- package/dist/computer-operation-registry.d.ts +45 -0
- package/dist/computer-operation-registry.js +179 -0
- package/dist/config-diagnostics.d.ts +11 -0
- package/dist/config-diagnostics.js +185 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +69 -0
- package/dist/history-insights.d.ts +132 -0
- package/dist/history-insights.js +457 -0
- package/dist/http-auth.d.ts +3 -0
- package/dist/http-auth.js +15 -0
- package/dist/mcp-surface.d.ts +5 -0
- package/dist/mcp-surface.js +25 -0
- package/dist/oauth-provider.d.ts +52 -0
- package/dist/oauth-provider.js +325 -0
- package/dist/package-metadata.d.ts +7 -0
- package/dist/package-metadata.js +24 -0
- package/dist/permissions.d.ts +43 -0
- package/dist/permissions.js +150 -0
- package/dist/platform-shell.d.ts +28 -0
- package/dist/platform-shell.js +124 -0
- package/dist/processes.d.ts +50 -0
- package/dist/processes.js +178 -0
- package/dist/profile.d.ts +159 -0
- package/dist/profile.js +416 -0
- package/dist/screenshot.d.ts +47 -0
- package/dist/screenshot.js +302 -0
- package/dist/search.d.ts +34 -0
- package/dist/search.js +340 -0
- package/dist/security.d.ts +10 -0
- package/dist/security.js +108 -0
- package/dist/sensitive-files.d.ts +4 -0
- package/dist/sensitive-files.js +96 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +713 -0
- package/dist/service.d.ts +125 -0
- package/dist/service.js +486 -0
- package/dist/sessions.d.ts +26 -0
- package/dist/sessions.js +34 -0
- package/dist/tunnels.d.ts +161 -0
- package/dist/tunnels.js +1243 -0
- package/dist/workspace-operations.d.ts +170 -0
- package/dist/workspace-operations.js +3219 -0
- package/dist/workspaces.d.ts +61 -0
- package/dist/workspaces.js +353 -0
- package/docs/agent-instructions.md +65 -0
- package/docs/alpha-evidence.example.json +54 -0
- package/docs/api-compatibility.md +56 -0
- package/docs/architecture.md +561 -0
- package/docs/chatgpt-setup.md +397 -0
- package/docs/client-recipes.md +98 -0
- package/docs/client-sdk.md +163 -0
- package/docs/computer-operation-v1.schema.json +143 -0
- package/docs/manual-test-plan.md +322 -0
- package/docs/product-spec.md +911 -0
- package/docs/release-checklist.md +285 -0
- package/docs/service-mode.md +99 -0
- package/examples/minimal-mcp-client.mjs +114 -0
- package/package.json +87 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PathPermissions } from "./permissions.js";
|
|
2
|
+
import type { WorkspaceOperationName } from "./workspace-operations.js";
|
|
3
|
+
export type CapabilityName = "fs:read" | "fs:write" | "search:read" | "history:read" | "git:read" | "git:write" | "package:run" | "process:manage" | "shell:run" | "codex:readOnly" | "codex:write" | "screen:capture" | "network:false";
|
|
4
|
+
export interface CapabilityPolicy {
|
|
5
|
+
version: 1;
|
|
6
|
+
source: "derived-from-workspace-permissions";
|
|
7
|
+
capabilities: CapabilityName[];
|
|
8
|
+
limits: {
|
|
9
|
+
maxRuntimeSeconds: number;
|
|
10
|
+
maxFileBytes: number;
|
|
11
|
+
maxSearchResults: number;
|
|
12
|
+
maxBatchOperations: number;
|
|
13
|
+
};
|
|
14
|
+
notes: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface OperationCapabilityPolicy {
|
|
17
|
+
operation: WorkspaceOperationName;
|
|
18
|
+
capabilities: CapabilityName[];
|
|
19
|
+
limits?: Partial<CapabilityPolicy["limits"]>;
|
|
20
|
+
}
|
|
21
|
+
export declare function workspaceCapabilityPolicy(permissions: PathPermissions): CapabilityPolicy;
|
|
22
|
+
export declare function operationCapabilityPolicy(operation: WorkspaceOperationName): OperationCapabilityPolicy;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const DEFAULT_LIMITS = {
|
|
2
|
+
maxRuntimeSeconds: 3600,
|
|
3
|
+
maxFileBytes: 256 * 1024,
|
|
4
|
+
maxSearchResults: 1000,
|
|
5
|
+
maxBatchOperations: 25,
|
|
6
|
+
};
|
|
7
|
+
export function workspaceCapabilityPolicy(permissions) {
|
|
8
|
+
const capabilities = new Set(["network:false"]);
|
|
9
|
+
if (permissions.read) {
|
|
10
|
+
capabilities.add("fs:read");
|
|
11
|
+
capabilities.add("search:read");
|
|
12
|
+
capabilities.add("history:read");
|
|
13
|
+
capabilities.add("git:read");
|
|
14
|
+
}
|
|
15
|
+
if (permissions.write) {
|
|
16
|
+
capabilities.add("fs:write");
|
|
17
|
+
capabilities.add("git:write");
|
|
18
|
+
}
|
|
19
|
+
if (permissions.shell) {
|
|
20
|
+
capabilities.add("package:run");
|
|
21
|
+
capabilities.add("process:manage");
|
|
22
|
+
capabilities.add("shell:run");
|
|
23
|
+
}
|
|
24
|
+
if (permissions.codex) {
|
|
25
|
+
capabilities.add("codex:readOnly");
|
|
26
|
+
capabilities.add("codex:write");
|
|
27
|
+
capabilities.add("process:manage");
|
|
28
|
+
}
|
|
29
|
+
if (permissions.screen) {
|
|
30
|
+
capabilities.add("screen:capture");
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
version: 1,
|
|
34
|
+
source: "derived-from-workspace-permissions",
|
|
35
|
+
capabilities: [...capabilities],
|
|
36
|
+
limits: DEFAULT_LIMITS,
|
|
37
|
+
notes: [
|
|
38
|
+
"This policy is derived from the current read/write/shell/codex workspace permissions.",
|
|
39
|
+
"network:false means Computer Linker does not grant network access as a first-class capability; shell, package, and Codex processes may still use the host network if the underlying tools do.",
|
|
40
|
+
"maxRuntimeSeconds is the upper bound accepted by Computer Linker for shell, process, package, and Codex timeouts.",
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function operationCapabilityPolicy(operation) {
|
|
45
|
+
const capabilities = operationCapabilities(operation);
|
|
46
|
+
const limits = operationLimits(operation);
|
|
47
|
+
return {
|
|
48
|
+
operation,
|
|
49
|
+
capabilities,
|
|
50
|
+
limits: Object.keys(limits).length > 0 ? limits : undefined,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function operationCapabilities(operation) {
|
|
54
|
+
if (operation === "batch")
|
|
55
|
+
return ["network:false"];
|
|
56
|
+
if (operation === "history" || operation === "history_insight")
|
|
57
|
+
return ["history:read", "network:false"];
|
|
58
|
+
if (operation === "find_files" || operation === "search_text" || operation === "search_symbols")
|
|
59
|
+
return ["search:read", "fs:read", "network:false"];
|
|
60
|
+
if (operation.startsWith("git_") || operation === "repo_status" || operation === "git_changes" || operation === "git_diff" || operation === "git_log" || operation === "git_show" || operation === "change_summary") {
|
|
61
|
+
return gitOperationCapabilities(operation);
|
|
62
|
+
}
|
|
63
|
+
if (operation === "package_run" || operation === "package_start")
|
|
64
|
+
return ["package:run", "process:manage", "network:false"];
|
|
65
|
+
if (operation === "command")
|
|
66
|
+
return ["shell:run", "network:false"];
|
|
67
|
+
if (operation === "process_start" || operation === "process_list" || operation === "process_read" || operation === "process_stop")
|
|
68
|
+
return ["process:manage", "network:false"];
|
|
69
|
+
if (operation === "codex" || operation === "codex_start" || operation === "codex_plan" || operation === "codex_review" || operation === "codex_fix" || operation === "codex_test" || operation === "codex_continue" || operation === "codex_runs") {
|
|
70
|
+
return codexOperationCapabilities(operation);
|
|
71
|
+
}
|
|
72
|
+
if (operation === "screen_list" || operation === "screen_capture" || operation === "screen_capture_window" || operation === "screen_capture_process") {
|
|
73
|
+
return ["screen:capture", "network:false"];
|
|
74
|
+
}
|
|
75
|
+
if (operation === "write" || operation === "create_file" || operation === "write_if_unchanged" || operation === "edit" || operation === "patch" || operation === "mkdir" || operation === "delete" || operation === "move") {
|
|
76
|
+
return ["fs:write", "network:false"];
|
|
77
|
+
}
|
|
78
|
+
return ["fs:read", "network:false"];
|
|
79
|
+
}
|
|
80
|
+
function gitOperationCapabilities(operation) {
|
|
81
|
+
if (operation === "git_stage" || operation === "git_unstage" || operation === "git_commit" || operation === "git_worktree_create") {
|
|
82
|
+
return ["git:write", "fs:write", "network:false"];
|
|
83
|
+
}
|
|
84
|
+
return ["git:read", "fs:read", "network:false"];
|
|
85
|
+
}
|
|
86
|
+
function codexOperationCapabilities(operation) {
|
|
87
|
+
if (operation === "codex_plan" || operation === "codex_review" || operation === "codex_test" || operation === "codex_runs") {
|
|
88
|
+
return ["codex:readOnly", "process:manage", "network:false"];
|
|
89
|
+
}
|
|
90
|
+
return ["codex:write", "process:manage", "network:false"];
|
|
91
|
+
}
|
|
92
|
+
function operationLimits(operation) {
|
|
93
|
+
if (operation === "batch")
|
|
94
|
+
return { maxBatchOperations: DEFAULT_LIMITS.maxBatchOperations };
|
|
95
|
+
if (operation === "find_files" || operation === "search_text" || operation === "search_symbols" || operation === "history" || operation === "history_insight")
|
|
96
|
+
return { maxSearchResults: DEFAULT_LIMITS.maxSearchResults };
|
|
97
|
+
if (operation === "read" || operation === "read_many" || operation === "git_diff" || operation === "git_show" || operation === "repo_status")
|
|
98
|
+
return { maxFileBytes: DEFAULT_LIMITS.maxFileBytes };
|
|
99
|
+
if (operation === "command" || operation === "process_start" || operation === "package_run" || operation === "package_start" || operation === "codex" || operation === "codex_start" || operation === "codex_plan" || operation === "codex_review" || operation === "codex_fix" || operation === "codex_test" || operation === "codex_continue") {
|
|
100
|
+
return { maxRuntimeSeconds: DEFAULT_LIMITS.maxRuntimeSeconds };
|
|
101
|
+
}
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { type TunnelProcessSnapshot } from "./tunnels.js";
|
|
2
|
+
import type { ChatGptProfileMode } from "./profile.js";
|
|
3
|
+
import type { LocalPortConfig } from "./permissions.js";
|
|
4
|
+
export type ChatGptVerifyMode = ChatGptProfileMode;
|
|
5
|
+
export type ChatGptVerifyStatus = "pass" | "warn" | "fail";
|
|
6
|
+
export type ChatGptSetupWizardStatus = "ready" | "needs_action" | "blocked";
|
|
7
|
+
export type ChatGptSetupWizardStepStatus = "complete" | "current" | "blocked" | "pending";
|
|
8
|
+
export interface ChatGptVerifyCheck {
|
|
9
|
+
id: string;
|
|
10
|
+
status: ChatGptVerifyStatus;
|
|
11
|
+
message: string;
|
|
12
|
+
detail?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ChatGptVerifyReport {
|
|
15
|
+
kind: "chatgpt-verify";
|
|
16
|
+
schemaVersion: 1;
|
|
17
|
+
mode: ChatGptVerifyMode;
|
|
18
|
+
ready: boolean;
|
|
19
|
+
mcpServerUrl: string;
|
|
20
|
+
publicBaseUrl: string | null;
|
|
21
|
+
authMode: "loopback-only" | "owner-token-or-oauth";
|
|
22
|
+
tools: string[];
|
|
23
|
+
checks: ChatGptVerifyCheck[];
|
|
24
|
+
blockingReasons: string[];
|
|
25
|
+
warnings: string[];
|
|
26
|
+
nextActions: string[];
|
|
27
|
+
recommendedProfileCommand: string;
|
|
28
|
+
recommendedSmokeTest: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface ChatGptUrlReport {
|
|
31
|
+
kind: "chatgpt-url";
|
|
32
|
+
schemaVersion: 1;
|
|
33
|
+
ready: boolean;
|
|
34
|
+
mcpServerUrl: string | null;
|
|
35
|
+
publicBaseUrl: string | null;
|
|
36
|
+
publicBaseUrlSource: "configured" | "running-tunnel" | null;
|
|
37
|
+
configuredPublicBaseUrl: string | null;
|
|
38
|
+
detectedPublicUrl: string | null;
|
|
39
|
+
authHeader: string;
|
|
40
|
+
warnings: string[];
|
|
41
|
+
nextActions: string[];
|
|
42
|
+
}
|
|
43
|
+
export interface ChatGptUrlOptions {
|
|
44
|
+
tunnels?: TunnelProcessSnapshot[];
|
|
45
|
+
}
|
|
46
|
+
export interface ChatGptSmokeCheck {
|
|
47
|
+
id: string;
|
|
48
|
+
status: ChatGptVerifyStatus;
|
|
49
|
+
message: string;
|
|
50
|
+
url?: string;
|
|
51
|
+
statusCode?: number;
|
|
52
|
+
detail?: string;
|
|
53
|
+
durationMs?: number;
|
|
54
|
+
}
|
|
55
|
+
export interface ChatGptSmokeReport {
|
|
56
|
+
kind: "chatgpt-smoke";
|
|
57
|
+
schemaVersion: 1;
|
|
58
|
+
ready: boolean;
|
|
59
|
+
baseUrl: string | null;
|
|
60
|
+
mcpServerUrl: string | null;
|
|
61
|
+
authHeader: string;
|
|
62
|
+
checks: ChatGptSmokeCheck[];
|
|
63
|
+
blockingReasons: string[];
|
|
64
|
+
warnings: string[];
|
|
65
|
+
nextActions: string[];
|
|
66
|
+
}
|
|
67
|
+
export interface ChatGptSetupWizardStep {
|
|
68
|
+
id: "owner_token" | "public_url" | "mcp_url" | "oauth" | "workspace" | "ready";
|
|
69
|
+
label: string;
|
|
70
|
+
status: ChatGptSetupWizardStepStatus;
|
|
71
|
+
detail: string;
|
|
72
|
+
action?: string;
|
|
73
|
+
}
|
|
74
|
+
export interface ChatGptSetupWizard {
|
|
75
|
+
overallStatus: ChatGptSetupWizardStatus;
|
|
76
|
+
currentStepId: ChatGptSetupWizardStep["id"] | null;
|
|
77
|
+
effectiveMcpServerUrl: string | null;
|
|
78
|
+
detectedPublicUrl: string | null;
|
|
79
|
+
steps: ChatGptSetupWizardStep[];
|
|
80
|
+
}
|
|
81
|
+
export interface ChatGptSetupConnectProfile {
|
|
82
|
+
appName: string;
|
|
83
|
+
mode: ChatGptVerifyMode;
|
|
84
|
+
connectionType: "Remote MCP";
|
|
85
|
+
serverUrl: string;
|
|
86
|
+
auth: {
|
|
87
|
+
type: "oauth-or-bearer";
|
|
88
|
+
bearerHeader: string | null;
|
|
89
|
+
bearerTokenValue: "<ownerToken>" | null;
|
|
90
|
+
bearerTokenSource: "owner-token-config" | null;
|
|
91
|
+
oauthEnabled: boolean;
|
|
92
|
+
oauthScopes: string[];
|
|
93
|
+
oauthAuthorizationServerMetadataUrl: string | null;
|
|
94
|
+
oauthProtectedResourceMetadataUrl: string | null;
|
|
95
|
+
};
|
|
96
|
+
ready: boolean;
|
|
97
|
+
blockingReasons: string[];
|
|
98
|
+
warnings: string[];
|
|
99
|
+
nextActions: string[];
|
|
100
|
+
firstPrompt: string;
|
|
101
|
+
cli: {
|
|
102
|
+
verify: string;
|
|
103
|
+
profile: string;
|
|
104
|
+
manifest: string;
|
|
105
|
+
connectorConfig: string;
|
|
106
|
+
files: string;
|
|
107
|
+
localSmoke: string;
|
|
108
|
+
publicSmoke: string | null;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export interface ChatGptSetupStatus {
|
|
112
|
+
kind: "chatgpt-setup-status";
|
|
113
|
+
schemaVersion: 1;
|
|
114
|
+
mode: ChatGptVerifyMode;
|
|
115
|
+
ready: boolean;
|
|
116
|
+
mcpServerUrl: string;
|
|
117
|
+
publicBaseUrl: string | null;
|
|
118
|
+
authMode: "loopback-only" | "owner-token-or-oauth";
|
|
119
|
+
setupFields: {
|
|
120
|
+
appName: string;
|
|
121
|
+
connectionType: "Remote MCP";
|
|
122
|
+
mcpServerUrl: string;
|
|
123
|
+
authType: "oauth-or-bearer";
|
|
124
|
+
bearerHeader: string | null;
|
|
125
|
+
alternateBearerHeader: string | null;
|
|
126
|
+
};
|
|
127
|
+
oauthDiscovery: {
|
|
128
|
+
enabled: boolean;
|
|
129
|
+
issuer: string | null;
|
|
130
|
+
authorizationServerMetadataUrl: string | null;
|
|
131
|
+
protectedResourceMetadataUrl: string | null;
|
|
132
|
+
resource: string | null;
|
|
133
|
+
scopes: string[];
|
|
134
|
+
};
|
|
135
|
+
smoke: {
|
|
136
|
+
localCli: string;
|
|
137
|
+
publicCli: string | null;
|
|
138
|
+
};
|
|
139
|
+
cli: ChatGptSetupConnectProfile["cli"];
|
|
140
|
+
connectProfile: ChatGptSetupConnectProfile;
|
|
141
|
+
checks: ChatGptVerifyCheck[];
|
|
142
|
+
blockingReasons: string[];
|
|
143
|
+
warnings: string[];
|
|
144
|
+
nextActions: string[];
|
|
145
|
+
wizard: ChatGptSetupWizard;
|
|
146
|
+
}
|
|
147
|
+
export interface ChatGptSetupStatusOptions {
|
|
148
|
+
tunnels?: TunnelProcessSnapshot[];
|
|
149
|
+
}
|
|
150
|
+
export interface ChatGptSmokeOptions {
|
|
151
|
+
url?: string;
|
|
152
|
+
token?: string;
|
|
153
|
+
includeSecret?: boolean;
|
|
154
|
+
allowHttp?: boolean;
|
|
155
|
+
timeoutMs?: number;
|
|
156
|
+
fetchImpl?: typeof fetch;
|
|
157
|
+
}
|
|
158
|
+
export declare function chatGptVerify(config: LocalPortConfig, mode?: ChatGptVerifyMode): ChatGptVerifyReport;
|
|
159
|
+
export declare function chatGptSetupStatus(config: LocalPortConfig, mode?: ChatGptVerifyMode, options?: ChatGptSetupStatusOptions): ChatGptSetupStatus;
|
|
160
|
+
export declare function parseChatGptVerifyMode(value: string | undefined): ChatGptVerifyMode;
|
|
161
|
+
export declare function chatGptPublicBaseUrl(config: Pick<LocalPortConfig, "publicBaseUrl">, tunnels?: TunnelProcessSnapshot[]): string | undefined;
|
|
162
|
+
export declare function chatGptMcpServerUrl(config: Pick<LocalPortConfig, "publicBaseUrl">, tunnels?: TunnelProcessSnapshot[]): string | undefined;
|
|
163
|
+
export declare function chatGptUrl(config: LocalPortConfig, includeSecret?: boolean, options?: ChatGptUrlOptions): ChatGptUrlReport;
|
|
164
|
+
export declare function formatChatGptUrl(report: ChatGptUrlReport): string;
|
|
165
|
+
export declare function chatGptSmoke(config: LocalPortConfig, options?: ChatGptSmokeOptions): Promise<ChatGptSmokeReport>;
|
|
166
|
+
export declare function formatChatGptSmoke(report: ChatGptSmokeReport): string;
|
|
167
|
+
export declare function formatChatGptVerify(report: ChatGptVerifyReport): string;
|