paseo-acp-agy 1.1.0

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.
@@ -0,0 +1,19 @@
1
+ export type LogLevel = "debug" | "info" | "warn" | "error";
2
+ export declare function sanitizeString(str: string): string;
3
+ export declare function sanitize(data: unknown): unknown;
4
+ export declare class Logger {
5
+ logFilePath: string;
6
+ private minLevel;
7
+ private writeStream;
8
+ constructor(options?: {
9
+ minLevel?: LogLevel;
10
+ logDir?: string;
11
+ });
12
+ private log;
13
+ debug(message: string, meta?: unknown): void;
14
+ info(message: string, meta?: unknown): void;
15
+ warn(message: string, meta?: unknown): void;
16
+ error(message: string, meta?: unknown): void;
17
+ close(): void;
18
+ }
19
+ export declare const logger: Logger;
package/dist/logger.js ADDED
@@ -0,0 +1,124 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ const LOG_LEVELS = {
5
+ debug: 10,
6
+ info: 20,
7
+ warn: 30,
8
+ error: 40,
9
+ };
10
+ function getLogDir() {
11
+ if (process.env.AGY_ACP_LOG_DIR) {
12
+ return process.env.AGY_ACP_LOG_DIR;
13
+ }
14
+ const stateHome = process.env.XDG_STATE_HOME || path.join(os.homedir(), ".local", "state");
15
+ return path.join(stateHome, "agy-acp");
16
+ }
17
+ function resolveLogLevel() {
18
+ const envLevel = process.env.AGY_ACP_LOG_LEVEL?.toLowerCase();
19
+ if (envLevel === "debug" || envLevel === "info" || envLevel === "warn" || envLevel === "error") {
20
+ return envLevel;
21
+ }
22
+ return "info";
23
+ }
24
+ export function sanitizeString(str) {
25
+ return str
26
+ .replace(/(Bearer\s+)[a-zA-Z0-9_\-\.]{8,}/gi, "$1[REDACTED]")
27
+ .replace(/(token|key|secret|password|auth|authorization|api[_-]?key)(\s*[:=]\s*['"]?)[a-zA-Z0-9_\-\.]{6,}(['"]?)/gi, "$1$2[REDACTED]$3")
28
+ .replace(/AIza[0-9A-Za-z-_]{35}/g, "[REDACTED_API_KEY]")
29
+ .replace(/ya29\.[0-9A-Za-z-_]+/g, "[REDACTED_OAUTH_TOKEN]");
30
+ }
31
+ export function sanitize(data) {
32
+ if (typeof data === "string") {
33
+ return sanitizeString(data);
34
+ }
35
+ if (data && typeof data === "object") {
36
+ if (Array.isArray(data)) {
37
+ return data.map(sanitize);
38
+ }
39
+ const clean = {};
40
+ for (const [k, v] of Object.entries(data)) {
41
+ if (/token|secret|password|auth|cookie|credential|authorization|api[_-]?key/i.test(k)) {
42
+ clean[k] = typeof v === "object" && v !== null ? sanitize(v) : "[REDACTED]";
43
+ }
44
+ else {
45
+ clean[k] = sanitize(v);
46
+ }
47
+ }
48
+ return clean;
49
+ }
50
+ return data;
51
+ }
52
+ export class Logger {
53
+ logFilePath;
54
+ minLevel;
55
+ writeStream = null;
56
+ constructor(options) {
57
+ this.minLevel = options?.minLevel || resolveLogLevel();
58
+ const dir = options?.logDir || getLogDir();
59
+ try {
60
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
61
+ try {
62
+ fs.chmodSync(dir, 0o700);
63
+ }
64
+ catch { }
65
+ }
66
+ catch { }
67
+ this.logFilePath = path.join(dir, "agy-acp.log");
68
+ try {
69
+ if (!fs.existsSync(this.logFilePath)) {
70
+ fs.writeFileSync(this.logFilePath, "", { mode: 0o600 });
71
+ }
72
+ else {
73
+ try {
74
+ fs.chmodSync(this.logFilePath, 0o600);
75
+ }
76
+ catch { }
77
+ }
78
+ this.writeStream = fs.createWriteStream(this.logFilePath, { flags: "a", mode: 0o600 });
79
+ this.writeStream.on("error", () => { });
80
+ }
81
+ catch {
82
+ this.writeStream = null;
83
+ }
84
+ }
85
+ log(level, message, meta) {
86
+ if (LOG_LEVELS[level] < LOG_LEVELS[this.minLevel]) {
87
+ return;
88
+ }
89
+ const timestamp = new Date().toISOString();
90
+ const sanitizedMeta = meta !== undefined ? sanitize(meta) : undefined;
91
+ const entry = {
92
+ timestamp,
93
+ level,
94
+ message: sanitizeString(message),
95
+ ...(sanitizedMeta !== undefined ? { data: sanitizedMeta } : {}),
96
+ };
97
+ const line = JSON.stringify(entry) + "\n";
98
+ if (this.writeStream) {
99
+ this.writeStream.write(line);
100
+ }
101
+ if (process.env.AGY_ACP_STDERR_LOG === "true" || process.env.AGY_ACP_STDERR_LOG === "1") {
102
+ process.stderr.write(`[agy-acp] ${timestamp} [${level.toUpperCase()}] ${entry.message} ${meta ? JSON.stringify(sanitizedMeta) : ""}\n`);
103
+ }
104
+ }
105
+ debug(message, meta) {
106
+ this.log("debug", message, meta);
107
+ }
108
+ info(message, meta) {
109
+ this.log("info", message, meta);
110
+ }
111
+ warn(message, meta) {
112
+ this.log("warn", message, meta);
113
+ }
114
+ error(message, meta) {
115
+ this.log("error", message, meta);
116
+ }
117
+ close() {
118
+ if (this.writeStream) {
119
+ this.writeStream.end();
120
+ this.writeStream = null;
121
+ }
122
+ }
123
+ }
124
+ export const logger = new Logger();
@@ -0,0 +1,11 @@
1
+ export interface PermissionSettings {
2
+ sandbox: boolean;
3
+ dangerouslySkipPermissions: boolean;
4
+ mode?: string;
5
+ }
6
+ export declare function resolvePermissionSettings(options?: {
7
+ sandbox?: boolean;
8
+ dangerouslySkipPermissions?: boolean;
9
+ mode?: string;
10
+ }): PermissionSettings;
11
+ export declare function buildAgyArgs(settings: PermissionSettings, extraArgs?: string[]): string[];
@@ -0,0 +1,29 @@
1
+ // Permission and security settings for Antigravity ACP adapter
2
+ export function resolvePermissionSettings(options) {
3
+ const envSandbox = process.env.AGY_ACP_SANDBOX;
4
+ const envSkipPerms = process.env.AGY_ACP_DANGEROUSLY_SKIP_PERMISSIONS;
5
+ const sandbox = options?.sandbox ?? (envSandbox === "true" || envSandbox === "1");
6
+ // Never default to skip permissions; must be explicit
7
+ const dangerouslySkipPermissions = options?.dangerouslySkipPermissions ?? (envSkipPerms === "true" || envSkipPerms === "1");
8
+ return {
9
+ sandbox,
10
+ dangerouslySkipPermissions,
11
+ mode: options?.mode,
12
+ };
13
+ }
14
+ export function buildAgyArgs(settings, extraArgs) {
15
+ const args = ["--input-format", "stream-json", "--output-format", "stream-json", "--print="];
16
+ if (settings.sandbox) {
17
+ args.push("--sandbox");
18
+ }
19
+ if (settings.dangerouslySkipPermissions) {
20
+ args.push("--dangerously-skip-permissions");
21
+ }
22
+ if (settings.mode && settings.mode !== "default") {
23
+ args.push("--mode", settings.mode);
24
+ }
25
+ if (extraArgs && extraArgs.length > 0) {
26
+ args.push(...extraArgs);
27
+ }
28
+ return args;
29
+ }
@@ -0,0 +1,201 @@
1
+ export interface AgyInitEvent {
2
+ event: "init";
3
+ conversation_id: string;
4
+ init: {
5
+ cwd?: string;
6
+ tools?: string[];
7
+ permission_mode?: string;
8
+ model?: string;
9
+ [key: string]: unknown;
10
+ };
11
+ }
12
+ export interface AgyStepUpdateEvent {
13
+ event: "step_update";
14
+ step_update: {
15
+ conversation_id: string;
16
+ step_index: number;
17
+ state: "ACTIVE" | "DONE" | "ERROR";
18
+ step_type: "user_input" | "agent_response" | "tool" | "thought" | string;
19
+ text_delta?: string;
20
+ duration_seconds?: number;
21
+ tool_name?: string;
22
+ tool_info?: {
23
+ name: string;
24
+ parameters?: Record<string, unknown>;
25
+ output?: string;
26
+ error?: {
27
+ type?: string;
28
+ message?: string;
29
+ [key: string]: unknown;
30
+ };
31
+ [key: string]: unknown;
32
+ };
33
+ usage?: {
34
+ input_tokens?: number;
35
+ output_tokens?: number;
36
+ thinking_tokens?: number;
37
+ cache_read_tokens?: number;
38
+ total_tokens?: number;
39
+ };
40
+ [key: string]: unknown;
41
+ };
42
+ }
43
+ export interface AgyResultEvent {
44
+ event: "result";
45
+ result: {
46
+ conversation_id: string;
47
+ status: "SUCCESS" | "ERROR";
48
+ response: string;
49
+ error?: string;
50
+ duration_seconds?: number;
51
+ num_turns?: number;
52
+ usage?: {
53
+ input_tokens?: number;
54
+ output_tokens?: number;
55
+ thinking_tokens?: number;
56
+ cache_read_tokens?: number;
57
+ total_tokens?: number;
58
+ };
59
+ [key: string]: unknown;
60
+ };
61
+ }
62
+ export type AgyIncomingEvent = AgyInitEvent | AgyStepUpdateEvent | AgyResultEvent;
63
+ export interface AgyStreamInputUserMessage {
64
+ event: "user";
65
+ message: {
66
+ content: string | Array<{
67
+ type: string;
68
+ text?: string;
69
+ [key: string]: unknown;
70
+ }>;
71
+ };
72
+ }
73
+ export type RequestId = string | number;
74
+ export interface JsonRpcRequest<T = unknown> {
75
+ jsonrpc: "2.0";
76
+ id: RequestId;
77
+ method: string;
78
+ params?: T;
79
+ }
80
+ export interface JsonRpcNotification<T = unknown> {
81
+ jsonrpc: "2.0";
82
+ method: string;
83
+ params?: T;
84
+ }
85
+ export interface JsonRpcSuccessResponse<T = unknown> {
86
+ jsonrpc: "2.0";
87
+ id: RequestId;
88
+ result: T;
89
+ }
90
+ export interface JsonRpcErrorObject {
91
+ code: number;
92
+ message: string;
93
+ data?: unknown;
94
+ }
95
+ export interface JsonRpcErrorResponse {
96
+ jsonrpc: "2.0";
97
+ id: RequestId | null;
98
+ error: JsonRpcErrorObject;
99
+ }
100
+ export type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcSuccessResponse | JsonRpcErrorResponse;
101
+ export declare const ACP_METHODS: {
102
+ readonly INITIALIZE: "initialize";
103
+ readonly SESSION_NEW: "session/new";
104
+ readonly SESSION_NEW_ALIAS: "newSession";
105
+ readonly SESSION_LOAD: "session/load";
106
+ readonly SESSION_LOAD_ALIAS: "loadSession";
107
+ readonly SESSION_RESUME: "session/resume";
108
+ readonly SESSION_RESUME_ALIAS: "unstable_resumeSession";
109
+ readonly SESSION_PROMPT: "session/prompt";
110
+ readonly SESSION_PROMPT_ALIAS: "prompt";
111
+ readonly SESSION_CANCEL: "session/cancel";
112
+ readonly SESSION_CANCEL_ALIAS: "cancel";
113
+ readonly SESSION_CLOSE: "session/close";
114
+ readonly SESSION_CLOSE_ALIAS: "unstable_closeSession";
115
+ readonly SESSION_SET_MODE: "session/set_mode";
116
+ readonly SESSION_SET_MODE_ALIAS: "setSessionMode";
117
+ readonly SESSION_SET_MODEL: "session/set_model";
118
+ readonly SESSION_SET_MODEL_ALIAS: "unstable_setSessionModel";
119
+ readonly SESSION_SET_CONFIG_OPTION: "session/set_config_option";
120
+ readonly SESSION_SET_CONFIG_OPTION_ALIAS: "setSessionConfigOption";
121
+ readonly SESSION_UPDATE: "session/update";
122
+ };
123
+ export type ToolKind = "read" | "edit" | "execute" | "fetch" | "other";
124
+ export declare function mapToolNameToKind(toolName: string): ToolKind;
125
+ export declare function extractPromptText(promptInput: unknown): string;
126
+ export interface ModelDefinition {
127
+ modelId: string;
128
+ name: string;
129
+ description?: string;
130
+ supportedEfforts: string[];
131
+ contextWindowMaxTokens?: number;
132
+ }
133
+ export interface ModelPricing {
134
+ inputCostPerM: number;
135
+ outputCostPerM: number;
136
+ cachedInputCostPerM: number;
137
+ }
138
+ export declare const MODEL_PRICING: Record<string, ModelPricing>;
139
+ export declare const MODEL_CONTEXT_WINDOWS: Record<string, number>;
140
+ export declare function getModelContextWindow(modelId?: string): number;
141
+ export declare function getModelPricing(modelId?: string): ModelPricing | null;
142
+ export declare function calculateUsageCostUsd(modelId?: string, inputTokens?: number, outputTokens?: number, cachedInputTokens?: number): number;
143
+ export declare function roundUsageCostUsd(costUsd: number, decimals?: number): number;
144
+ export interface QuotaWindow {
145
+ id: string;
146
+ label: string;
147
+ usedPct: number;
148
+ remainingPct: number;
149
+ resetsAt: string | null;
150
+ tone: "ok" | "warning" | "danger" | "default";
151
+ }
152
+ export declare function deriveUsageTone(usedPct: number): "ok" | "warning" | "danger" | "default";
153
+ export declare function parseAgyQuotaOutput(raw: string): QuotaWindow[];
154
+ export interface CreditsBalance {
155
+ id: string;
156
+ label: string;
157
+ remaining: number;
158
+ unit: "usd";
159
+ tone: "ok" | "warning" | "danger" | "default";
160
+ }
161
+ export declare function parseAgyCreditsOutput(raw: string): CreditsBalance;
162
+ export interface ProviderUsage {
163
+ providerId: string;
164
+ displayName: string;
165
+ status: "available" | "unavailable";
166
+ planLabel: string | null;
167
+ windows: QuotaWindow[];
168
+ balances: CreditsBalance[];
169
+ details: Array<{
170
+ id: string;
171
+ label: string;
172
+ value: string;
173
+ }>;
174
+ error: string | null;
175
+ }
176
+ export declare function fetchAntigravityUsage(binaryPath?: string, force?: boolean): Promise<ProviderUsage>;
177
+ export declare const ALL_THINKING_LEVELS: Record<string, {
178
+ name: string;
179
+ description: string;
180
+ }>;
181
+ export declare const FALLBACK_MODELS: ModelDefinition[];
182
+ export declare function parseAgyModelsOutput(rawOutput: string): ModelDefinition[];
183
+ export declare function fetchAvailableModels(binaryPath?: string, force?: boolean): Promise<ModelDefinition[]>;
184
+ export declare function getEffectiveEffortForModel(modelId?: string, requestedEffort?: string, models?: ModelDefinition[]): string | undefined;
185
+ export declare const AVAILABLE_MODES: {
186
+ id: string;
187
+ name: string;
188
+ description: string;
189
+ }[];
190
+ export declare function buildConfigOptionsForModel(modelId: string, currentEffort?: string, availableModels?: ModelDefinition[]): {
191
+ id: string;
192
+ name: string;
193
+ category: string;
194
+ type: "select";
195
+ currentValue: string;
196
+ options: {
197
+ value: string;
198
+ name: string;
199
+ description: string;
200
+ }[];
201
+ }[];