opensteer 0.6.3 → 0.6.5
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/bin/opensteer.mjs +94 -8
- package/dist/{browser-profile-client-DK9qa_Dj.d.cts → browser-profile-client-D6PuRefA.d.cts} +1 -1
- package/dist/{browser-profile-client-CaL-mwqs.d.ts → browser-profile-client-OUHaODro.d.ts} +1 -1
- package/dist/{chunk-SCNX4NN3.js → chunk-54KNQTOL.js} +141 -2
- package/dist/{chunk-FTKWQ6X3.js → chunk-6B6LOYU3.js} +1 -1
- package/dist/{chunk-3OMXCBPD.js → chunk-G6V2DJRN.js} +442 -591
- package/dist/chunk-K5CL76MG.js +81 -0
- package/dist/{chunk-KE35RQOJ.js → chunk-KPPOTU3D.js} +53 -144
- package/dist/cli/auth.cjs +53 -6
- package/dist/cli/auth.d.cts +1 -1
- package/dist/cli/auth.d.ts +1 -1
- package/dist/cli/auth.js +2 -2
- package/dist/cli/local-profile.cjs +197 -0
- package/dist/cli/local-profile.d.cts +18 -0
- package/dist/cli/local-profile.d.ts +18 -0
- package/dist/cli/local-profile.js +97 -0
- package/dist/cli/profile.cjs +2844 -2412
- package/dist/cli/profile.d.cts +2 -2
- package/dist/cli/profile.d.ts +2 -2
- package/dist/cli/profile.js +469 -7
- package/dist/cli/server.cjs +649 -204
- package/dist/cli/server.js +69 -16
- package/dist/index.cjs +578 -185
- package/dist/index.d.cts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +4 -3
- package/dist/{types-BxiRblC7.d.cts → types-BWItZPl_.d.cts} +31 -13
- package/dist/{types-BxiRblC7.d.ts → types-BWItZPl_.d.ts} +31 -13
- package/package.json +2 -2
- package/skills/opensteer/SKILL.md +34 -14
- package/skills/opensteer/references/cli-reference.md +1 -1
- package/skills/opensteer/references/examples.md +5 -3
- package/skills/opensteer/references/sdk-reference.md +16 -14
package/bin/opensteer.mjs
CHANGED
|
@@ -27,6 +27,13 @@ const SKILLS_INSTALLER_SCRIPT = join(
|
|
|
27
27
|
'skills-installer.js'
|
|
28
28
|
)
|
|
29
29
|
const PROFILE_CLI_SCRIPT = join(__dirname, '..', 'dist', 'cli', 'profile.js')
|
|
30
|
+
const LOCAL_PROFILE_CLI_SCRIPT = join(
|
|
31
|
+
__dirname,
|
|
32
|
+
'..',
|
|
33
|
+
'dist',
|
|
34
|
+
'cli',
|
|
35
|
+
'local-profile.js'
|
|
36
|
+
)
|
|
30
37
|
const AUTH_CLI_SCRIPT = join(__dirname, '..', 'dist', 'cli', 'auth.js')
|
|
31
38
|
const SKILLS_HELP_TEXT = `Usage: opensteer skills <install|add> [options]
|
|
32
39
|
|
|
@@ -60,6 +67,15 @@ Commands:
|
|
|
60
67
|
|
|
61
68
|
Run "opensteer profile --help" after building for full command details.
|
|
62
69
|
`
|
|
70
|
+
const LOCAL_PROFILE_HELP_TEXT = `Usage: opensteer local-profile <command> [options]
|
|
71
|
+
|
|
72
|
+
Inspect local Chrome profiles for real-browser mode.
|
|
73
|
+
|
|
74
|
+
Commands:
|
|
75
|
+
list
|
|
76
|
+
|
|
77
|
+
Run "opensteer local-profile --help" after building for full command details.
|
|
78
|
+
`
|
|
63
79
|
const AUTH_HELP_TEXT = `Usage: opensteer auth <command> [options]
|
|
64
80
|
|
|
65
81
|
Authenticate Opensteer CLI with Opensteer Cloud.
|
|
@@ -87,6 +103,7 @@ const CLOSE_ALL_REQUEST = { id: 1, command: 'close', args: {} }
|
|
|
87
103
|
const PING_REQUEST = { id: 1, command: 'ping', args: {} }
|
|
88
104
|
const SESSION_ID_PATTERN = /^[a-zA-Z0-9_-]+$/
|
|
89
105
|
const RUNTIME_SESSION_PREFIX = 'sc-'
|
|
106
|
+
const BOOLEAN_FLAGS = new Set(['all', 'headless', 'headed', 'json'])
|
|
90
107
|
|
|
91
108
|
function getVersion() {
|
|
92
109
|
try {
|
|
@@ -118,7 +135,14 @@ function parseArgs(argv) {
|
|
|
118
135
|
if (arg.startsWith('--')) {
|
|
119
136
|
const key = arg.slice(2)
|
|
120
137
|
const next = args[i + 1]
|
|
121
|
-
if (
|
|
138
|
+
if (
|
|
139
|
+
BOOLEAN_FLAGS.has(key) &&
|
|
140
|
+
next !== undefined &&
|
|
141
|
+
next !== 'true' &&
|
|
142
|
+
next !== 'false'
|
|
143
|
+
) {
|
|
144
|
+
flags[key] = true
|
|
145
|
+
} else if (next !== undefined && !next.startsWith('--')) {
|
|
122
146
|
flags[key] = parseValue(next)
|
|
123
147
|
i++
|
|
124
148
|
} else {
|
|
@@ -334,9 +358,11 @@ function buildRequest(command, flags, positional) {
|
|
|
334
358
|
for (const key of [
|
|
335
359
|
'headless',
|
|
336
360
|
'json',
|
|
337
|
-
'
|
|
338
|
-
'
|
|
339
|
-
'
|
|
361
|
+
'browser',
|
|
362
|
+
'profile',
|
|
363
|
+
'cdp-url',
|
|
364
|
+
'user-data-dir',
|
|
365
|
+
'browser-path',
|
|
340
366
|
'cloud-profile-id',
|
|
341
367
|
'cloud-profile-reuse-if-active',
|
|
342
368
|
'cursor',
|
|
@@ -348,6 +374,11 @@ function buildRequest(command, flags, positional) {
|
|
|
348
374
|
}
|
|
349
375
|
|
|
350
376
|
const args = { ...globalFlags, ...flags }
|
|
377
|
+
if ('headed' in flags) {
|
|
378
|
+
const headed = flags.headed === false ? false : Boolean(flags.headed)
|
|
379
|
+
args.headless = args.headless ?? !headed
|
|
380
|
+
delete args.headed
|
|
381
|
+
}
|
|
351
382
|
|
|
352
383
|
switch (command) {
|
|
353
384
|
case 'open':
|
|
@@ -975,6 +1006,30 @@ async function runProfileSubcommand(args) {
|
|
|
975
1006
|
}
|
|
976
1007
|
}
|
|
977
1008
|
|
|
1009
|
+
async function runLocalProfileSubcommand(args) {
|
|
1010
|
+
if (
|
|
1011
|
+
args.length === 0 ||
|
|
1012
|
+
args.includes('--help') ||
|
|
1013
|
+
args.includes('-h')
|
|
1014
|
+
) {
|
|
1015
|
+
process.stdout.write(LOCAL_PROFILE_HELP_TEXT)
|
|
1016
|
+
return
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
if (!existsSync(LOCAL_PROFILE_CLI_SCRIPT)) {
|
|
1020
|
+
throw new Error(
|
|
1021
|
+
`Local profile CLI module was not found at "${LOCAL_PROFILE_CLI_SCRIPT}". Run "npm run build" to generate dist artifacts.`
|
|
1022
|
+
)
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
const moduleUrl = pathToFileURL(LOCAL_PROFILE_CLI_SCRIPT).href
|
|
1026
|
+
const { runOpensteerLocalProfileCli } = await import(moduleUrl)
|
|
1027
|
+
const exitCode = await runOpensteerLocalProfileCli(args)
|
|
1028
|
+
if (exitCode !== 0) {
|
|
1029
|
+
process.exit(exitCode)
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
|
|
978
1033
|
async function runAuthSubcommand(args) {
|
|
979
1034
|
if (isAuthHelpRequest(args)) {
|
|
980
1035
|
process.stdout.write(AUTH_HELP_TEXT)
|
|
@@ -1119,6 +1174,7 @@ Skills:
|
|
|
1119
1174
|
skills add [options] Alias for "skills install"
|
|
1120
1175
|
skills --help Show skills installer help
|
|
1121
1176
|
profile <command> Manage cloud browser profiles and cookie sync
|
|
1177
|
+
local-profile <command> Inspect local Chrome profiles for real-browser mode
|
|
1122
1178
|
auth <command> Manage cloud login credentials (login/status/logout)
|
|
1123
1179
|
login Alias for "auth login"
|
|
1124
1180
|
logout Alias for "auth logout"
|
|
@@ -1126,10 +1182,13 @@ Skills:
|
|
|
1126
1182
|
Global Flags:
|
|
1127
1183
|
--session <id> Logical session id (scoped by canonical cwd)
|
|
1128
1184
|
--name <namespace> Selector namespace for cache storage on 'open'
|
|
1129
|
-
--headless Launch
|
|
1130
|
-
--
|
|
1131
|
-
--
|
|
1132
|
-
--
|
|
1185
|
+
--headless Launch chromium mode in headless mode
|
|
1186
|
+
--browser <mode> Browser mode: chromium or real
|
|
1187
|
+
--profile <name> Browser profile directory name for real-browser mode
|
|
1188
|
+
--headed Launch real-browser mode with a visible window
|
|
1189
|
+
--cdp-url <url> Connect to a running browser (e.g. http://localhost:9222)
|
|
1190
|
+
--user-data-dir <path> Browser user-data root for real-browser mode
|
|
1191
|
+
--browser-path <path> Override Chrome executable path for real-browser mode
|
|
1133
1192
|
--cloud-profile-id <id> Launch cloud session with a specific browser profile
|
|
1134
1193
|
--cloud-profile-reuse-if-active <true|false>
|
|
1135
1194
|
Reuse active cloud session for that browser profile
|
|
@@ -1151,6 +1210,10 @@ Environment:
|
|
|
1151
1210
|
OPENSTEER_BASE_URL Override cloud control-plane base URL
|
|
1152
1211
|
OPENSTEER_AUTH_SCHEME Cloud auth scheme: api-key (default) or bearer
|
|
1153
1212
|
OPENSTEER_REMOTE_ANNOUNCE Cloud session announcement policy: always (default), off, tty
|
|
1213
|
+
OPENSTEER_BROWSER Local browser mode: chromium or real
|
|
1214
|
+
OPENSTEER_CDP_URL Connect to a running browser (e.g. http://localhost:9222)
|
|
1215
|
+
OPENSTEER_USER_DATA_DIR Browser user-data root for real-browser mode
|
|
1216
|
+
OPENSTEER_PROFILE_DIRECTORY Browser profile directory for real-browser mode
|
|
1154
1217
|
`)
|
|
1155
1218
|
}
|
|
1156
1219
|
|
|
@@ -1211,11 +1274,34 @@ async function main() {
|
|
|
1211
1274
|
}
|
|
1212
1275
|
return
|
|
1213
1276
|
}
|
|
1277
|
+
if (rawArgs[0] === 'local-profile') {
|
|
1278
|
+
try {
|
|
1279
|
+
await runLocalProfileSubcommand(rawArgs.slice(1))
|
|
1280
|
+
} catch (err) {
|
|
1281
|
+
const message =
|
|
1282
|
+
err instanceof Error
|
|
1283
|
+
? err.message
|
|
1284
|
+
: 'Failed to run local-profile command'
|
|
1285
|
+
process.stderr.write(`${message}\n`)
|
|
1286
|
+
process.exit(1)
|
|
1287
|
+
}
|
|
1288
|
+
return
|
|
1289
|
+
}
|
|
1214
1290
|
|
|
1215
1291
|
const scopeDir = resolveScopeDir()
|
|
1216
1292
|
|
|
1217
1293
|
const { command, flags, positional } = parseArgs(process.argv)
|
|
1218
1294
|
|
|
1295
|
+
if (
|
|
1296
|
+
flags['connect-url'] !== undefined ||
|
|
1297
|
+
flags.channel !== undefined ||
|
|
1298
|
+
flags['profile-dir'] !== undefined
|
|
1299
|
+
) {
|
|
1300
|
+
error(
|
|
1301
|
+
'--connect-url, --channel, and --profile-dir are no longer supported. Use --cdp-url, --browser real, --profile, --user-data-dir, and --browser-path instead.'
|
|
1302
|
+
)
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1219
1305
|
if (command === 'sessions') {
|
|
1220
1306
|
output({ ok: true, sessions: listSessions() })
|
|
1221
1307
|
return
|
package/dist/{browser-profile-client-DK9qa_Dj.d.cts → browser-profile-client-D6PuRefA.d.cts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as OpensteerAuthScheme } from './types-
|
|
1
|
+
import { O as OpensteerAuthScheme } from './types-BWItZPl_.cjs';
|
|
2
2
|
|
|
3
3
|
type ActionFailureCode = 'TARGET_NOT_FOUND' | 'TARGET_UNAVAILABLE' | 'TARGET_STALE' | 'TARGET_AMBIGUOUS' | 'BLOCKED_BY_INTERCEPTOR' | 'NOT_VISIBLE' | 'NOT_ENABLED' | 'NOT_EDITABLE' | 'INVALID_TARGET' | 'INVALID_OPTIONS' | 'ACTION_TIMEOUT' | 'UNKNOWN';
|
|
4
4
|
type ActionFailureClassificationSource = 'typed_error' | 'playwright_call_log' | 'dom_probe' | 'message_heuristic' | 'unknown';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as OpensteerAuthScheme } from './types-
|
|
1
|
+
import { O as OpensteerAuthScheme } from './types-BWItZPl_.js';
|
|
2
2
|
|
|
3
3
|
type ActionFailureCode = 'TARGET_NOT_FOUND' | 'TARGET_UNAVAILABLE' | 'TARGET_STALE' | 'TARGET_AMBIGUOUS' | 'BLOCKED_BY_INTERCEPTOR' | 'NOT_VISIBLE' | 'NOT_ENABLED' | 'NOT_EDITABLE' | 'INVALID_TARGET' | 'INVALID_OPTIONS' | 'ACTION_TIMEOUT' | 'UNKNOWN';
|
|
4
4
|
type ActionFailureClassificationSource = 'typed_error' | 'playwright_call_log' | 'dom_probe' | 'message_heuristic' | 'unknown';
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_CLOUD_BASE_URL,
|
|
3
|
-
createKeychainStore,
|
|
4
3
|
normalizeCloudBaseUrl,
|
|
5
4
|
resolveCloudSelection,
|
|
6
5
|
resolveConfigWithEnv,
|
|
7
6
|
selectCloudCredential,
|
|
8
7
|
stripTrailingSlashes
|
|
9
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-KPPOTU3D.js";
|
|
10
9
|
|
|
11
10
|
// src/cli/auth.ts
|
|
12
11
|
import open from "open";
|
|
@@ -80,6 +79,145 @@ import { createHash } from "crypto";
|
|
|
80
79
|
import fs from "fs";
|
|
81
80
|
import os from "os";
|
|
82
81
|
import path from "path";
|
|
82
|
+
|
|
83
|
+
// src/auth/keychain-store.ts
|
|
84
|
+
import { spawnSync } from "child_process";
|
|
85
|
+
function commandExists(command) {
|
|
86
|
+
const result = spawnSync(command, ["--help"], {
|
|
87
|
+
encoding: "utf8",
|
|
88
|
+
stdio: "ignore"
|
|
89
|
+
});
|
|
90
|
+
return result.error == null;
|
|
91
|
+
}
|
|
92
|
+
function commandFailed(result) {
|
|
93
|
+
return typeof result.status === "number" && result.status !== 0;
|
|
94
|
+
}
|
|
95
|
+
function sanitizeCommandArgs(command, args) {
|
|
96
|
+
if (command !== "security") {
|
|
97
|
+
return args;
|
|
98
|
+
}
|
|
99
|
+
const sanitized = [];
|
|
100
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
101
|
+
const value = args[index];
|
|
102
|
+
sanitized.push(value);
|
|
103
|
+
if (value === "-w" && index + 1 < args.length) {
|
|
104
|
+
sanitized.push("[REDACTED]");
|
|
105
|
+
index += 1;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return sanitized;
|
|
109
|
+
}
|
|
110
|
+
function buildCommandError(command, args, result) {
|
|
111
|
+
const stderr = typeof result.stderr === "string" && result.stderr.trim() ? result.stderr.trim() : `Command "${command}" failed with status ${String(result.status)}.`;
|
|
112
|
+
const sanitizedArgs = sanitizeCommandArgs(command, args);
|
|
113
|
+
return new Error(
|
|
114
|
+
[
|
|
115
|
+
`Unable to persist credential via ${command}.`,
|
|
116
|
+
`${command} ${sanitizedArgs.join(" ")}`,
|
|
117
|
+
stderr
|
|
118
|
+
].join(" ")
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
function createMacosSecurityStore() {
|
|
122
|
+
return {
|
|
123
|
+
backend: "macos-security",
|
|
124
|
+
get(service, account) {
|
|
125
|
+
const result = spawnSync(
|
|
126
|
+
"security",
|
|
127
|
+
["find-generic-password", "-s", service, "-a", account, "-w"],
|
|
128
|
+
{ encoding: "utf8" }
|
|
129
|
+
);
|
|
130
|
+
if (commandFailed(result)) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
const secret = result.stdout.trim();
|
|
134
|
+
return secret.length ? secret : null;
|
|
135
|
+
},
|
|
136
|
+
set(service, account, secret) {
|
|
137
|
+
const args = [
|
|
138
|
+
"add-generic-password",
|
|
139
|
+
"-U",
|
|
140
|
+
"-s",
|
|
141
|
+
service,
|
|
142
|
+
"-a",
|
|
143
|
+
account,
|
|
144
|
+
"-w",
|
|
145
|
+
secret
|
|
146
|
+
];
|
|
147
|
+
const result = spawnSync("security", args, { encoding: "utf8" });
|
|
148
|
+
if (commandFailed(result)) {
|
|
149
|
+
throw buildCommandError("security", args, result);
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
delete(service, account) {
|
|
153
|
+
const args = ["delete-generic-password", "-s", service, "-a", account];
|
|
154
|
+
const result = spawnSync("security", args, { encoding: "utf8" });
|
|
155
|
+
if (commandFailed(result)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function createLinuxSecretToolStore() {
|
|
162
|
+
return {
|
|
163
|
+
backend: "linux-secret-tool",
|
|
164
|
+
get(service, account) {
|
|
165
|
+
const result = spawnSync(
|
|
166
|
+
"secret-tool",
|
|
167
|
+
["lookup", "service", service, "account", account],
|
|
168
|
+
{
|
|
169
|
+
encoding: "utf8"
|
|
170
|
+
}
|
|
171
|
+
);
|
|
172
|
+
if (commandFailed(result)) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
const secret = result.stdout.trim();
|
|
176
|
+
return secret.length ? secret : null;
|
|
177
|
+
},
|
|
178
|
+
set(service, account, secret) {
|
|
179
|
+
const args = [
|
|
180
|
+
"store",
|
|
181
|
+
"--label",
|
|
182
|
+
"Opensteer CLI",
|
|
183
|
+
"service",
|
|
184
|
+
service,
|
|
185
|
+
"account",
|
|
186
|
+
account
|
|
187
|
+
];
|
|
188
|
+
const result = spawnSync("secret-tool", args, {
|
|
189
|
+
encoding: "utf8",
|
|
190
|
+
input: secret
|
|
191
|
+
});
|
|
192
|
+
if (commandFailed(result)) {
|
|
193
|
+
throw buildCommandError("secret-tool", args, result);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
delete(service, account) {
|
|
197
|
+
const args = ["clear", "service", service, "account", account];
|
|
198
|
+
spawnSync("secret-tool", args, {
|
|
199
|
+
encoding: "utf8"
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function createKeychainStore() {
|
|
205
|
+
if (process.platform === "darwin") {
|
|
206
|
+
if (!commandExists("security")) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
return createMacosSecurityStore();
|
|
210
|
+
}
|
|
211
|
+
if (process.platform === "linux") {
|
|
212
|
+
if (!commandExists("secret-tool")) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
return createLinuxSecretToolStore();
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/auth/machine-credential-store.ts
|
|
83
221
|
var METADATA_VERSION = 2;
|
|
84
222
|
var ACTIVE_TARGET_VERSION = 2;
|
|
85
223
|
var KEYCHAIN_SERVICE = "com.opensteer.cli.cloud";
|
|
@@ -1100,6 +1238,7 @@ async function runOpensteerAuthCli(rawArgs, overrideDeps = {}) {
|
|
|
1100
1238
|
}
|
|
1101
1239
|
|
|
1102
1240
|
export {
|
|
1241
|
+
createKeychainStore,
|
|
1103
1242
|
parseOpensteerAuthArgs,
|
|
1104
1243
|
isCloudModeEnabledForRootDir,
|
|
1105
1244
|
ensureCloudCredentialsForOpenCommand,
|