@oneworks/cli 0.1.0-alpha.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/LICENSE +21 -0
- package/channel.js +7 -0
- package/cli.js +5 -0
- package/mem.js +7 -0
- package/package.json +59 -0
- package/postinstall.js +75 -0
- package/src/AGENTS.md +169 -0
- package/src/channel-cli.ts +19 -0
- package/src/cli-argv.ts +27 -0
- package/src/cli.ts +63 -0
- package/src/commands/@core/adapter-option.ts +85 -0
- package/src/commands/@core/extra-options.ts +12 -0
- package/src/commands/@core/plugin-install.ts +1 -0
- package/src/commands/@core/plugin-source.ts +1 -0
- package/src/commands/accounts.ts +204 -0
- package/src/commands/adapter/prepare-selection.ts +181 -0
- package/src/commands/adapter/prepare.ts +104 -0
- package/src/commands/adapter.ts +48 -0
- package/src/commands/agent/actions.ts +176 -0
- package/src/commands/agent/runtime-store-commands.ts +56 -0
- package/src/commands/agent/runtime-store-events.ts +23 -0
- package/src/commands/agent/runtime-store-session.ts +170 -0
- package/src/commands/agent/runtime-store-shared.ts +139 -0
- package/src/commands/agent/runtime-store.ts +4 -0
- package/src/commands/agent.ts +81 -0
- package/src/commands/benchmark.ts +198 -0
- package/src/commands/channel.ts +594 -0
- package/src/commands/clear.ts +140 -0
- package/src/commands/config/actions.ts +196 -0
- package/src/commands/config/display-state.ts +108 -0
- package/src/commands/config/index.ts +135 -0
- package/src/commands/config/interactive.ts +121 -0
- package/src/commands/config/read-state.ts +56 -0
- package/src/commands/config/section-state.ts +109 -0
- package/src/commands/config/shared.ts +195 -0
- package/src/commands/kill.ts +41 -0
- package/src/commands/list.ts +224 -0
- package/src/commands/memory/context.ts +76 -0
- package/src/commands/memory/entries.ts +131 -0
- package/src/commands/memory/shared.ts +89 -0
- package/src/commands/memory/store.ts +69 -0
- package/src/commands/memory/target.ts +54 -0
- package/src/commands/memory.ts +97 -0
- package/src/commands/plugin.ts +62 -0
- package/src/commands/report-targets.ts +149 -0
- package/src/commands/report.ts +232 -0
- package/src/commands/run/adapter-cli-version.ts +65 -0
- package/src/commands/run/command.ts +982 -0
- package/src/commands/run/input-bridge.ts +108 -0
- package/src/commands/run/input-control.ts +112 -0
- package/src/commands/run/input-decision.ts +88 -0
- package/src/commands/run/options.ts +104 -0
- package/src/commands/run/output.ts +179 -0
- package/src/commands/run/permission-decision.ts +19 -0
- package/src/commands/run/permission-recovery.ts +194 -0
- package/src/commands/run/permission-state.ts +177 -0
- package/src/commands/run/print-idle-timeout.ts +47 -0
- package/src/commands/run/protocol-envelope.ts +111 -0
- package/src/commands/run/protocol-stdio.ts +71 -0
- package/src/commands/run/protocol.ts +391 -0
- package/src/commands/run/runtime-command-bridge.ts +190 -0
- package/src/commands/run/runtime-event-sink.ts +560 -0
- package/src/commands/run/session-exit-controller.ts +45 -0
- package/src/commands/run/types.ts +65 -0
- package/src/commands/run.ts +62 -0
- package/src/commands/session-control.ts +133 -0
- package/src/commands/skills/add-command.ts +88 -0
- package/src/commands/skills/install-command.ts +105 -0
- package/src/commands/skills/install.ts +216 -0
- package/src/commands/skills/progress.ts +126 -0
- package/src/commands/skills/publish-command.ts +85 -0
- package/src/commands/skills/register.ts +17 -0
- package/src/commands/skills/remove-command.ts +102 -0
- package/src/commands/skills/shared.ts +117 -0
- package/src/commands/skills/sync.ts +571 -0
- package/src/commands/skills/types.ts +33 -0
- package/src/commands/skills.ts +1 -0
- package/src/commands/stop.ts +41 -0
- package/src/config.ts +1 -0
- package/src/default-skill-plugin.ts +29 -0
- package/src/env.ts +1 -0
- package/src/hooks/plugins/index.ts +66 -0
- package/src/mem-cli.ts +19 -0
- package/src/session-cache.ts +250 -0
- package/src/session-permission-cache.ts +40 -0
- package/src/utils.ts +25 -0
- package/src/workspace.ts +12 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { HookContext, HookInputs, HookOutputs, Plugin } from '@oneworks/hooks'
|
|
2
|
+
|
|
3
|
+
export const callPluginHook = async <K extends keyof HookInputs>(
|
|
4
|
+
eventName: K,
|
|
5
|
+
context: HookContext,
|
|
6
|
+
input: HookInputs[K],
|
|
7
|
+
plugins: Partial<Plugin>[] = []
|
|
8
|
+
): Promise<HookOutputs[K]> => {
|
|
9
|
+
const { logger } = context
|
|
10
|
+
const filterPlugins = plugins.filter(
|
|
11
|
+
(
|
|
12
|
+
item
|
|
13
|
+
): item is
|
|
14
|
+
& {
|
|
15
|
+
name?: string
|
|
16
|
+
}
|
|
17
|
+
& {
|
|
18
|
+
[k in K]: NonNullable<Plugin[k]>
|
|
19
|
+
} => !!item && !!item[eventName]
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
// 创建中间件链
|
|
23
|
+
let index = 0
|
|
24
|
+
|
|
25
|
+
const next = async (): Promise<HookOutputs[K]> => {
|
|
26
|
+
if (index >= filterPlugins.length) {
|
|
27
|
+
// 如果没有更多插件,返回默认结果
|
|
28
|
+
return { continue: true }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const currentPlugin = filterPlugins[index]
|
|
32
|
+
const { name = '<anonymous>', [eventName]: hook } = currentPlugin
|
|
33
|
+
|
|
34
|
+
// 增加索引,防止重复调用导致死循环或错误逻辑
|
|
35
|
+
index++
|
|
36
|
+
|
|
37
|
+
const withNameLogger = {
|
|
38
|
+
...logger,
|
|
39
|
+
info: logger.info.bind(logger, `[plugin.${name}]`),
|
|
40
|
+
warn: logger.warn.bind(logger, `[plugin.${name}]`),
|
|
41
|
+
debug: logger.debug.bind(logger, `[plugin.${name}]`),
|
|
42
|
+
error: logger.error.bind(logger, `[plugin.${name}]`)
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
return await hook(
|
|
46
|
+
{
|
|
47
|
+
...context,
|
|
48
|
+
logger: withNameLogger
|
|
49
|
+
},
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
input,
|
|
52
|
+
next
|
|
53
|
+
)
|
|
54
|
+
} catch (e) {
|
|
55
|
+
if (e instanceof Error) {
|
|
56
|
+
// 只有第一个插件抛出的错误才需要添加对应的插件名
|
|
57
|
+
if (!e.name.includes('[plugin.')) {
|
|
58
|
+
e.name = `${e.name}[plugin.${name}]`
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
throw e
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return next()
|
|
66
|
+
}
|
package/src/mem-cli.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander'
|
|
4
|
+
|
|
5
|
+
import { getCliVersion } from '#~/utils.js'
|
|
6
|
+
|
|
7
|
+
import { registerMemorySubcommands } from './commands/memory'
|
|
8
|
+
|
|
9
|
+
const program = new Command()
|
|
10
|
+
|
|
11
|
+
program
|
|
12
|
+
.name('oneworks mem')
|
|
13
|
+
.description('Read and write OneWorks channel memory from agent sessions')
|
|
14
|
+
.version(getCliVersion())
|
|
15
|
+
.showHelpAfterError()
|
|
16
|
+
|
|
17
|
+
registerMemorySubcommands(program)
|
|
18
|
+
|
|
19
|
+
program.parse(process.argv)
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import process from 'node:process'
|
|
4
|
+
|
|
5
|
+
import type { RunTaskOptions } from '@oneworks/app-runtime'
|
|
6
|
+
import type { AdapterQueryOptions, Cache, TaskDetail } from '@oneworks/types'
|
|
7
|
+
import { migrateProjectHomeSegment, resolveProjectOoPath } from '@oneworks/utils'
|
|
8
|
+
import { getCache, getCachePath, setCache } from '@oneworks/utils/cache'
|
|
9
|
+
|
|
10
|
+
export type CliOutputFormat = 'text' | 'json' | 'stream-json'
|
|
11
|
+
|
|
12
|
+
export interface CliSessionResumeRecord {
|
|
13
|
+
version: 1
|
|
14
|
+
ctxId: string
|
|
15
|
+
sessionId: string
|
|
16
|
+
cwd: string
|
|
17
|
+
description?: string
|
|
18
|
+
createdAt: number
|
|
19
|
+
updatedAt: number
|
|
20
|
+
resolvedAdapter?: string
|
|
21
|
+
taskOptions: RunTaskOptions
|
|
22
|
+
adapterOptions: Omit<AdapterQueryOptions, 'description' | 'onEvent' | 'type'>
|
|
23
|
+
outputFormat: CliOutputFormat
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CliSessionRecord {
|
|
27
|
+
resume?: CliSessionResumeRecord
|
|
28
|
+
detail?: TaskDetail
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface CliSessionControlRecord {
|
|
32
|
+
signal: 'SIGTERM' | 'SIGKILL'
|
|
33
|
+
requestedAt: number
|
|
34
|
+
expiresAt: number
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare module '@oneworks/types' {
|
|
38
|
+
interface Cache {
|
|
39
|
+
'cli-session': CliSessionResumeRecord
|
|
40
|
+
'cli-session-control': CliSessionControlRecord
|
|
41
|
+
detail: TaskDetail
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const readDirSafe = async (target: string) => {
|
|
46
|
+
try {
|
|
47
|
+
return await fs.readdir(target, { withFileTypes: true })
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return []
|
|
50
|
+
throw error
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const readCacheFileAtPath = async <K extends keyof Cache>(target: string): Promise<Cache[K] | undefined> => {
|
|
55
|
+
try {
|
|
56
|
+
const content = await fs.readFile(target, 'utf-8')
|
|
57
|
+
if (content.trim() === '') return undefined
|
|
58
|
+
return JSON.parse(content) as Cache[K]
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (
|
|
61
|
+
(error as NodeJS.ErrnoException).code === 'ENOENT' ||
|
|
62
|
+
error instanceof SyntaxError
|
|
63
|
+
) {
|
|
64
|
+
return undefined
|
|
65
|
+
}
|
|
66
|
+
throw error
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const getCacheFromRoot = async <K extends keyof Cache>(
|
|
71
|
+
cacheRoot: string,
|
|
72
|
+
ctxId: string,
|
|
73
|
+
sessionId: string,
|
|
74
|
+
key: K
|
|
75
|
+
) => readCacheFileAtPath<K>(path.resolve(cacheRoot, ctxId, sessionId, `${String(key)}.json`))
|
|
76
|
+
|
|
77
|
+
const resolveCliSessionCacheRoot = (cwd: string) => resolveProjectOoPath(cwd, process.env, 'caches')
|
|
78
|
+
|
|
79
|
+
const getRecordUpdatedAt = (record: CliSessionRecord) =>
|
|
80
|
+
record.resume?.updatedAt ??
|
|
81
|
+
record.detail?.endTime ??
|
|
82
|
+
record.detail?.startTime ??
|
|
83
|
+
0
|
|
84
|
+
|
|
85
|
+
const getRecordCreatedAt = (record: CliSessionRecord) =>
|
|
86
|
+
record.resume?.createdAt ??
|
|
87
|
+
record.detail?.startTime ??
|
|
88
|
+
0
|
|
89
|
+
|
|
90
|
+
const isSessionDirNameMatch = (value: string, target: string) => value === target || value.startsWith(target)
|
|
91
|
+
|
|
92
|
+
const normalizeResumeCommandPrefix = (prefix: string | undefined) => {
|
|
93
|
+
const normalizedPrefix = prefix?.trim()
|
|
94
|
+
return normalizedPrefix == null || normalizedPrefix === '' ? 'oneworks' : normalizedPrefix
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const formatResumeCommand = (sessionId: string, prefix = process.env.__ONEWORKS_CLI_RESUME_COMMAND_PREFIX__) =>
|
|
98
|
+
`${normalizeResumeCommandPrefix(prefix)} --resume ${sessionId}`
|
|
99
|
+
export const formatStopCommand = (sessionId: string) => `oneworks stop ${sessionId}`
|
|
100
|
+
export const formatKillCommand = (sessionId: string) => `oneworks kill ${sessionId}`
|
|
101
|
+
export const formatListCommand = (params?: {
|
|
102
|
+
running?: boolean
|
|
103
|
+
view?: string
|
|
104
|
+
}) => {
|
|
105
|
+
const args = ['oneworks', 'list']
|
|
106
|
+
if (params?.running) args.push('--running')
|
|
107
|
+
if (params?.view != null && params.view !== '') args.push('--view', params.view)
|
|
108
|
+
return args.join(' ')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const resolveCliSessionId = (record: CliSessionRecord) =>
|
|
112
|
+
record.resume?.sessionId ?? record.detail?.sessionId ?? ''
|
|
113
|
+
|
|
114
|
+
export const resolveCliSessionCtxId = (record: CliSessionRecord) => record.resume?.ctxId ?? record.detail?.ctxId ?? ''
|
|
115
|
+
|
|
116
|
+
export const resolveCliSessionAdapter = (record: CliSessionRecord) =>
|
|
117
|
+
record.resume?.resolvedAdapter ??
|
|
118
|
+
record.detail?.adapter ??
|
|
119
|
+
record.resume?.taskOptions.adapter ??
|
|
120
|
+
''
|
|
121
|
+
|
|
122
|
+
export const resolveCliSessionModel = (record: CliSessionRecord) =>
|
|
123
|
+
record.detail?.model ?? record.resume?.adapterOptions.model ?? ''
|
|
124
|
+
|
|
125
|
+
export const resolveCliSessionDescription = (record: CliSessionRecord) =>
|
|
126
|
+
record.detail?.description ?? record.resume?.description ?? ''
|
|
127
|
+
|
|
128
|
+
export const resolveCliSessionUpdatedAt = (record: CliSessionRecord) => getRecordUpdatedAt(record)
|
|
129
|
+
|
|
130
|
+
export const listCliSessions = async (cwd: string): Promise<CliSessionRecord[]> => {
|
|
131
|
+
const sessions: CliSessionRecord[] = []
|
|
132
|
+
const seen = new Set<string>()
|
|
133
|
+
await migrateProjectHomeSegment(cwd, process.env, 'caches')
|
|
134
|
+
|
|
135
|
+
const cacheRoot = resolveCliSessionCacheRoot(cwd)
|
|
136
|
+
const ctxEntries = await readDirSafe(cacheRoot)
|
|
137
|
+
|
|
138
|
+
for (const ctxEntry of ctxEntries) {
|
|
139
|
+
if (!ctxEntry.isDirectory()) continue
|
|
140
|
+
|
|
141
|
+
const ctxId = ctxEntry.name
|
|
142
|
+
const sessionEntries = await readDirSafe(path.resolve(cacheRoot, ctxId))
|
|
143
|
+
|
|
144
|
+
for (const sessionEntry of sessionEntries) {
|
|
145
|
+
if (!sessionEntry.isDirectory()) continue
|
|
146
|
+
|
|
147
|
+
const sessionId = sessionEntry.name
|
|
148
|
+
const sessionKey = `${ctxId}\0${sessionId}`
|
|
149
|
+
if (seen.has(sessionKey)) continue
|
|
150
|
+
|
|
151
|
+
const [resume, detail] = await Promise.all([
|
|
152
|
+
getCacheFromRoot(cacheRoot, ctxId, sessionId, 'cli-session'),
|
|
153
|
+
getCacheFromRoot(cacheRoot, ctxId, sessionId, 'detail')
|
|
154
|
+
])
|
|
155
|
+
|
|
156
|
+
if (resume == null && detail == null) continue
|
|
157
|
+
seen.add(sessionKey)
|
|
158
|
+
sessions.push({ resume, detail })
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return sessions.sort((left, right) => getRecordUpdatedAt(right) - getRecordUpdatedAt(left))
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export const resolveCliSession = async (cwd: string, id?: string): Promise<CliSessionRecord> => {
|
|
166
|
+
const sessions = await listCliSessions(cwd)
|
|
167
|
+
if (id == null || id.trim() === '') {
|
|
168
|
+
const latest = [...sessions].sort((left, right) => getRecordCreatedAt(right) - getRecordCreatedAt(left))[0]
|
|
169
|
+
if (latest != null) return latest
|
|
170
|
+
throw new Error(`No sessions found. Start a session first or use "${formatListCommand({ view: 'full' })}".`)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const normalizedId = id.trim()
|
|
174
|
+
|
|
175
|
+
const exactSessionMatch = sessions.find((record) =>
|
|
176
|
+
(record.resume?.sessionId ?? record.detail?.sessionId) === normalizedId
|
|
177
|
+
)
|
|
178
|
+
if (exactSessionMatch != null) return exactSessionMatch
|
|
179
|
+
|
|
180
|
+
const exactCtxMatches = sessions.filter((record) => (record.resume?.ctxId ?? record.detail?.ctxId) === normalizedId)
|
|
181
|
+
if (exactCtxMatches.length === 1) return exactCtxMatches[0]!
|
|
182
|
+
if (exactCtxMatches.length > 1) {
|
|
183
|
+
throw new Error(`Session id "${id}" matches multiple task contexts. Use a session id instead.`)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const prefixMatches = sessions.filter((record) => {
|
|
187
|
+
const sessionId = record.resume?.sessionId ?? record.detail?.sessionId
|
|
188
|
+
const ctxId = record.resume?.ctxId ?? record.detail?.ctxId
|
|
189
|
+
return (
|
|
190
|
+
(sessionId != null && isSessionDirNameMatch(sessionId, normalizedId)) ||
|
|
191
|
+
(ctxId != null && isSessionDirNameMatch(ctxId, normalizedId))
|
|
192
|
+
)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
if (prefixMatches.length === 1) return prefixMatches[0]!
|
|
196
|
+
if (prefixMatches.length > 1) {
|
|
197
|
+
const candidates = prefixMatches
|
|
198
|
+
.map(resolveCliSessionId)
|
|
199
|
+
.filter((value): value is string => value != null)
|
|
200
|
+
.slice(0, 5)
|
|
201
|
+
.join(', ')
|
|
202
|
+
throw new Error(`Session id "${id}" is ambiguous: ${candidates}`)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
throw new Error(
|
|
206
|
+
`Session "${id}" not found. Use "${formatListCommand({ view: 'full' })}" to inspect available sessions.`
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export const writeCliSessionRecord = async (
|
|
211
|
+
cwd: string,
|
|
212
|
+
ctxId: string,
|
|
213
|
+
sessionId: string,
|
|
214
|
+
record: CliSessionRecord
|
|
215
|
+
) => {
|
|
216
|
+
await Promise.all([
|
|
217
|
+
record.resume == null
|
|
218
|
+
? Promise.resolve()
|
|
219
|
+
: setCache(cwd, ctxId, sessionId, 'cli-session', record.resume),
|
|
220
|
+
record.detail == null
|
|
221
|
+
? Promise.resolve()
|
|
222
|
+
: setCache(cwd, ctxId, sessionId, 'detail', record.detail)
|
|
223
|
+
])
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export const readCliSessionControl = (
|
|
227
|
+
cwd: string,
|
|
228
|
+
ctxId: string,
|
|
229
|
+
sessionId: string
|
|
230
|
+
) => getCache(cwd, ctxId, sessionId, 'cli-session-control')
|
|
231
|
+
|
|
232
|
+
export const writeCliSessionControl = (
|
|
233
|
+
cwd: string,
|
|
234
|
+
ctxId: string,
|
|
235
|
+
sessionId: string,
|
|
236
|
+
control: CliSessionControlRecord
|
|
237
|
+
) => setCache(cwd, ctxId, sessionId, 'cli-session-control', control)
|
|
238
|
+
|
|
239
|
+
export const clearCliSessionControl = async (
|
|
240
|
+
cwd: string,
|
|
241
|
+
ctxId: string,
|
|
242
|
+
sessionId: string
|
|
243
|
+
) => {
|
|
244
|
+
await fs.rm(getCachePath(cwd, ctxId, sessionId, 'cli-session-control'), { force: true })
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export const isCliSessionStopActive = (
|
|
248
|
+
control: CliSessionControlRecord | undefined,
|
|
249
|
+
endedAt: number
|
|
250
|
+
) => control != null && endedAt <= control.expiresAt
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
2
|
+
|
|
3
|
+
import type { AskUserQuestionParams, SessionPermissionMode } from '@oneworks/types'
|
|
4
|
+
import { getCache, getCachePath, setCache } from '@oneworks/utils/cache'
|
|
5
|
+
|
|
6
|
+
export interface CliSessionPermissionRecoveryRecord {
|
|
7
|
+
version: 1
|
|
8
|
+
sessionId: string
|
|
9
|
+
adapter?: string
|
|
10
|
+
permissionMode?: SessionPermissionMode
|
|
11
|
+
subjectKeys: string[]
|
|
12
|
+
payload: AskUserQuestionParams
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare module '@oneworks/types' {
|
|
16
|
+
interface Cache {
|
|
17
|
+
'cli-session-permission-recovery': CliSessionPermissionRecoveryRecord
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const readCliSessionPermissionRecovery = (
|
|
22
|
+
cwd: string,
|
|
23
|
+
ctxId: string,
|
|
24
|
+
sessionId: string
|
|
25
|
+
) => getCache(cwd, ctxId, sessionId, 'cli-session-permission-recovery')
|
|
26
|
+
|
|
27
|
+
export const writeCliSessionPermissionRecovery = (
|
|
28
|
+
cwd: string,
|
|
29
|
+
ctxId: string,
|
|
30
|
+
sessionId: string,
|
|
31
|
+
record: CliSessionPermissionRecoveryRecord
|
|
32
|
+
) => setCache(cwd, ctxId, sessionId, 'cli-session-permission-recovery', record)
|
|
33
|
+
|
|
34
|
+
export const clearCliSessionPermissionRecovery = async (
|
|
35
|
+
cwd: string,
|
|
36
|
+
ctxId: string,
|
|
37
|
+
sessionId: string
|
|
38
|
+
) => {
|
|
39
|
+
await fs.rm(getCachePath(cwd, ctxId, sessionId, 'cli-session-permission-recovery'), { force: true })
|
|
40
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
let packageJson: Record<string, any> | undefined
|
|
2
|
+
|
|
3
|
+
function getPackageJson() {
|
|
4
|
+
if (!packageJson) {
|
|
5
|
+
try {
|
|
6
|
+
// eslint-disable-next-line ts/no-require-imports
|
|
7
|
+
packageJson = require('@oneworks/cli/package.json')
|
|
8
|
+
} catch {
|
|
9
|
+
packageJson = {}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return packageJson!
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getPackageConfig(key: string, defaultValue = ''): string {
|
|
16
|
+
return getPackageJson()[key] ?? defaultValue
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getCliVersion() {
|
|
20
|
+
return getPackageConfig('version', '0.0.0')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getCliDescription() {
|
|
24
|
+
return getPackageConfig('description', 'One Works CLI')
|
|
25
|
+
}
|
package/src/workspace.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
|
|
3
|
+
import { resolveProjectWorkspaceFolder } from '@oneworks/utils'
|
|
4
|
+
|
|
5
|
+
export const resolveCliWorkspaceCwd = (
|
|
6
|
+
cwd: string = process.cwd(),
|
|
7
|
+
env: NodeJS.ProcessEnv = process.env
|
|
8
|
+
) => {
|
|
9
|
+
const workspaceCwd = resolveProjectWorkspaceFolder(cwd, env)
|
|
10
|
+
env.__ONEWORKS_PROJECT_WORKSPACE_FOLDER__ = workspaceCwd
|
|
11
|
+
return workspaceCwd
|
|
12
|
+
}
|