opensteer 0.3.0 → 0.4.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.
- package/bin/opensteer.mjs +70 -6
- package/dist/cli/server.cjs +1 -1
- package/dist/cli/server.js +1 -1
- package/package.json +1 -1
package/bin/opensteer.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import { createHash } from 'crypto'
|
|
3
4
|
import { spawn } from 'child_process'
|
|
4
|
-
import { existsSync, readFileSync, readdirSync, unlinkSync } from 'fs'
|
|
5
|
+
import { existsSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from 'fs'
|
|
5
6
|
import { connect } from 'net'
|
|
6
7
|
import { tmpdir } from 'os'
|
|
7
8
|
import { basename, dirname, join } from 'path'
|
|
@@ -18,6 +19,15 @@ const SOCKET_SUFFIX = '.sock'
|
|
|
18
19
|
const PID_SUFFIX = '.pid'
|
|
19
20
|
const CLOSE_ALL_REQUEST = { id: 1, command: 'close', args: {} }
|
|
20
21
|
|
|
22
|
+
function getVersion() {
|
|
23
|
+
try {
|
|
24
|
+
const pkgPath = join(__dirname, '..', 'package.json')
|
|
25
|
+
return JSON.parse(readFileSync(pkgPath, 'utf-8')).version
|
|
26
|
+
} catch {
|
|
27
|
+
return 'unknown'
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
21
31
|
function parseArgs(argv) {
|
|
22
32
|
const args = argv.slice(2)
|
|
23
33
|
if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
|
|
@@ -25,6 +35,11 @@ function parseArgs(argv) {
|
|
|
25
35
|
process.exit(0)
|
|
26
36
|
}
|
|
27
37
|
|
|
38
|
+
if (args[0] === '--version' || args[0] === '-v') {
|
|
39
|
+
console.log(getVersion())
|
|
40
|
+
process.exit(0)
|
|
41
|
+
}
|
|
42
|
+
|
|
28
43
|
const command = args[0]
|
|
29
44
|
const flags = {}
|
|
30
45
|
const positional = []
|
|
@@ -69,24 +84,51 @@ function sanitizeNamespace(value) {
|
|
|
69
84
|
return bounded || 'default'
|
|
70
85
|
}
|
|
71
86
|
|
|
87
|
+
function getActiveNamespacePath() {
|
|
88
|
+
const hash = createHash('md5').update(process.cwd()).digest('hex').slice(0, 16)
|
|
89
|
+
return join(tmpdir(), `${RUNTIME_PREFIX}active-${hash}`)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function readActiveNamespace() {
|
|
93
|
+
try {
|
|
94
|
+
const filePath = getActiveNamespacePath()
|
|
95
|
+
if (!existsSync(filePath)) return null
|
|
96
|
+
const ns = readFileSync(filePath, 'utf-8').trim()
|
|
97
|
+
return ns || null
|
|
98
|
+
} catch {
|
|
99
|
+
return null
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function writeActiveNamespace(namespace) {
|
|
104
|
+
try {
|
|
105
|
+
writeFileSync(getActiveNamespacePath(), namespace)
|
|
106
|
+
} catch { /* best-effort */ }
|
|
107
|
+
}
|
|
108
|
+
|
|
72
109
|
function resolveNamespace(flags) {
|
|
73
110
|
if (flags.name !== undefined && String(flags.name).trim().length > 0) {
|
|
74
|
-
return sanitizeNamespace(String(flags.name))
|
|
111
|
+
return { namespace: sanitizeNamespace(String(flags.name)), source: 'flag' }
|
|
75
112
|
}
|
|
76
113
|
|
|
77
114
|
if (
|
|
78
115
|
typeof process.env.OPENSTEER_NAME === 'string' &&
|
|
79
116
|
process.env.OPENSTEER_NAME.trim().length > 0
|
|
80
117
|
) {
|
|
81
|
-
return sanitizeNamespace(process.env.OPENSTEER_NAME)
|
|
118
|
+
return { namespace: sanitizeNamespace(process.env.OPENSTEER_NAME), source: 'env' }
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const active = readActiveNamespace()
|
|
122
|
+
if (active && isServerRunning(active)) {
|
|
123
|
+
return { namespace: active, source: 'active' }
|
|
82
124
|
}
|
|
83
125
|
|
|
84
126
|
const cwdBase = basename(process.cwd())
|
|
85
127
|
if (cwdBase && cwdBase !== '.' && cwdBase !== '/') {
|
|
86
|
-
return sanitizeNamespace(cwdBase)
|
|
128
|
+
return { namespace: sanitizeNamespace(cwdBase), source: 'cwd' }
|
|
87
129
|
}
|
|
88
130
|
|
|
89
|
-
return 'default'
|
|
131
|
+
return { namespace: 'default', source: 'default' }
|
|
90
132
|
}
|
|
91
133
|
|
|
92
134
|
function getSocketPath(namespace) {
|
|
@@ -427,6 +469,7 @@ Navigation:
|
|
|
427
469
|
|
|
428
470
|
Sessions:
|
|
429
471
|
sessions List active namespace-scoped sessions
|
|
472
|
+
status Show resolved namespace and session state
|
|
430
473
|
|
|
431
474
|
Observation:
|
|
432
475
|
snapshot [--mode action] Get page snapshot
|
|
@@ -481,6 +524,7 @@ Global Flags:
|
|
|
481
524
|
--selector <css> Target element by CSS selector
|
|
482
525
|
--description <text> Description for selector persistence
|
|
483
526
|
--help Show this help
|
|
527
|
+
--version, -v Show version
|
|
484
528
|
|
|
485
529
|
Environment:
|
|
486
530
|
OPENSTEER_NAME Default session namespace when --name is omitted
|
|
@@ -492,7 +536,7 @@ Environment:
|
|
|
492
536
|
|
|
493
537
|
async function main() {
|
|
494
538
|
const { command, flags, positional } = parseArgs(process.argv)
|
|
495
|
-
const namespace = resolveNamespace(flags)
|
|
539
|
+
const { namespace, source: namespaceSource } = resolveNamespace(flags)
|
|
496
540
|
const socketPath = getSocketPath(namespace)
|
|
497
541
|
|
|
498
542
|
if (command === 'sessions') {
|
|
@@ -500,6 +544,18 @@ async function main() {
|
|
|
500
544
|
return
|
|
501
545
|
}
|
|
502
546
|
|
|
547
|
+
if (command === 'status') {
|
|
548
|
+
output({
|
|
549
|
+
ok: true,
|
|
550
|
+
namespace,
|
|
551
|
+
namespaceSource,
|
|
552
|
+
serverRunning: isServerRunning(namespace),
|
|
553
|
+
socketPath,
|
|
554
|
+
sessions: listSessions(),
|
|
555
|
+
})
|
|
556
|
+
return
|
|
557
|
+
}
|
|
558
|
+
|
|
503
559
|
if (command === 'close' && flags.all === true) {
|
|
504
560
|
try {
|
|
505
561
|
const closed = await closeAllSessions()
|
|
@@ -515,6 +571,11 @@ async function main() {
|
|
|
515
571
|
const request = buildRequest(command, flags, positional)
|
|
516
572
|
|
|
517
573
|
if (!isServerRunning(namespace)) {
|
|
574
|
+
if (command !== 'open') {
|
|
575
|
+
error(
|
|
576
|
+
`No server running for namespace '${namespace}' (resolved from ${namespaceSource}). Run 'opensteer open' first or use 'opensteer sessions' to see active sessions.`
|
|
577
|
+
)
|
|
578
|
+
}
|
|
518
579
|
if (!existsSync(SERVER_SCRIPT)) {
|
|
519
580
|
error(
|
|
520
581
|
`Server script not found: ${SERVER_SCRIPT}. Run the build script first.`
|
|
@@ -532,6 +593,9 @@ async function main() {
|
|
|
532
593
|
const response = await sendCommand(socketPath, request)
|
|
533
594
|
|
|
534
595
|
if (response.ok) {
|
|
596
|
+
if (command === 'open') {
|
|
597
|
+
writeActiveNamespace(namespace)
|
|
598
|
+
}
|
|
535
599
|
output({ ok: true, ...response.result })
|
|
536
600
|
} else {
|
|
537
601
|
process.stderr.write(
|
package/dist/cli/server.cjs
CHANGED
|
@@ -9856,7 +9856,7 @@ async function handleRequest(request, socket) {
|
|
|
9856
9856
|
sendResponse(socket, {
|
|
9857
9857
|
id,
|
|
9858
9858
|
ok: false,
|
|
9859
|
-
error:
|
|
9859
|
+
error: `No browser session in namespace '${namespace}'. Call 'opensteer open --name ${namespace}' first, or use 'opensteer sessions' to list active sessions.`
|
|
9860
9860
|
});
|
|
9861
9861
|
return;
|
|
9862
9862
|
}
|
package/dist/cli/server.js
CHANGED
|
@@ -365,7 +365,7 @@ async function handleRequest(request, socket) {
|
|
|
365
365
|
sendResponse(socket, {
|
|
366
366
|
id,
|
|
367
367
|
ok: false,
|
|
368
|
-
error:
|
|
368
|
+
error: `No browser session in namespace '${namespace}'. Call 'opensteer open --name ${namespace}' first, or use 'opensteer sessions' to list active sessions.`
|
|
369
369
|
});
|
|
370
370
|
return;
|
|
371
371
|
}
|