@oneworks/cli 0.1.0-alpha.0 → 0.1.0-beta.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/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@oneworks/cli",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.0-beta.0",
4
+ "description": "One Works CLI",
4
5
  "repository": {
5
6
  "type": "git",
6
7
  "url": "https://github.com/oneworks-ai/app.git",
7
8
  "directory": "apps/cli"
8
9
  },
9
- "description": "One Works CLI",
10
10
  "imports": {
11
11
  "#~/*.js": {
12
12
  "__oneworks__": {
@@ -35,19 +35,19 @@
35
35
  "commander": "^12.1.0",
36
36
  "fast-glob": "^3.3.3",
37
37
  "node-notifier": "^10.0.1",
38
- "@oneworks/app-runtime": "0.1.0-alpha.0",
39
- "@oneworks/cli-helper": "0.1.0-alpha.0",
40
- "@oneworks/config": "0.1.0-alpha.0",
41
- "@oneworks/hooks": "0.1.0-alpha.0",
42
- "@oneworks/core": "0.1.0-alpha.0",
43
- "@oneworks/managed-plugins": "0.1.0-alpha.0",
44
- "@oneworks/plugin-cli-skills": "0.1.0-alpha.0",
45
- "@oneworks/runtime-protocol": "0.1.0-alpha.0",
46
- "@oneworks/types": "0.1.0-alpha.0",
47
- "@oneworks/register": "0.1.0-alpha.0",
48
- "@oneworks/runtime-store": "0.1.0-alpha.0",
49
- "@oneworks/utils": "0.1.0-alpha.0",
50
- "@oneworks/workspace-assets": "0.1.0-alpha.0"
38
+ "@oneworks/app-runtime": "0.1.0-beta.0",
39
+ "@oneworks/cli-helper": "0.1.0-beta.0",
40
+ "@oneworks/config": "0.1.0-beta.0",
41
+ "@oneworks/core": "0.1.0-beta.0",
42
+ "@oneworks/hooks": "0.1.0-beta.0",
43
+ "@oneworks/managed-plugins": "0.1.0-beta.0",
44
+ "@oneworks/plugin-cli-skills": "0.1.0-beta.0",
45
+ "@oneworks/register": "0.1.0-beta.0",
46
+ "@oneworks/types": "0.1.0-beta.0",
47
+ "@oneworks/runtime-protocol": "0.1.0-beta.0",
48
+ "@oneworks/runtime-store": "0.1.0-beta.0",
49
+ "@oneworks/workspace-assets": "0.1.0-beta.0",
50
+ "@oneworks/utils": "0.1.0-beta.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node-notifier": "^8.0.5"
package/src/cli-argv.ts CHANGED
@@ -13,7 +13,8 @@ const ROOT_SUBCOMMANDS = new Set([
13
13
  'plugin',
14
14
  'report',
15
15
  'skills',
16
- 'stop'
16
+ 'stop',
17
+ '__run'
17
18
  ])
18
19
 
19
20
  export const normalizeCliArgs = (args: string[]) => {
@@ -1,8 +1,8 @@
1
1
  import process from 'node:process'
2
2
 
3
- import { buildConfigJsonVariables, loadConfig } from '@oneworks/config'
3
+ import { buildConfigJsonVariables, loadConfigState, resolveRuntimeAdapterConfigState } from '@oneworks/config'
4
4
  import type { AdapterCtx, AdapterManageAccountProgressEvent } from '@oneworks/types'
5
- import { loadAdapter } from '@oneworks/types'
5
+ import { loadAdapter, resolveAdapterRuntimeTarget } from '@oneworks/types'
6
6
  import {
7
7
  mergeProcessEnvWithProjectEnv,
8
8
  persistAdapterAccountArtifacts,
@@ -28,19 +28,32 @@ const createTransientCache = (): AdapterCtx['cache'] => {
28
28
 
29
29
  const loadCliAdapterContext = async (adapterKey: string, cwd: string) => {
30
30
  const env = mergeProcessEnvWithProjectEnv(undefined, { workspaceFolder: cwd })
31
- const [projectConfig, userConfig] = await loadConfig({
31
+ const configState = await loadConfigState({
32
32
  cwd,
33
33
  env,
34
34
  jsonVariables: buildConfigJsonVariables(cwd, env)
35
35
  })
36
- const adapter = await loadAdapter(adapterKey)
36
+ const adapterTarget = resolveAdapterRuntimeTarget(adapterKey, {
37
+ config: configState.mergedConfig,
38
+ cwd
39
+ })
40
+ const runtimeConfigState = resolveRuntimeAdapterConfigState(
41
+ configState,
42
+ adapterKey,
43
+ adapterTarget.runtimeAdapter
44
+ )
45
+ const adapter = await loadAdapter(adapterTarget.loadSpecifier)
37
46
  const adapterCtx = {
38
47
  ctxId: `cli-adapter-accounts-${adapterKey}`,
39
48
  cwd,
40
49
  env,
41
50
  cache: createTransientCache(),
42
51
  logger: createLogger(cwd, `cli/adapter-accounts/${adapterKey}`, 'cli', '', 'info', env),
43
- configs: [projectConfig, userConfig]
52
+ configs: [
53
+ runtimeConfigState.effectiveProjectConfig ?? runtimeConfigState.projectConfig,
54
+ runtimeConfigState.userConfig
55
+ ],
56
+ configState: runtimeConfigState
44
57
  } satisfies AdapterCtx
45
58
 
46
59
  return {
@@ -1,5 +1,7 @@
1
- import { loadAdapterCliPreparer, normalizeAdapterPackageId } from '@oneworks/types'
2
- import type { AdapterCliPrepareTarget, AdapterCliPreparer, Config } from '@oneworks/types'
1
+ /* eslint-disable max-lines -- prepare selection keeps parsing and runtime adapter aliasing together. */
2
+ import { resolveConfigState, resolveRuntimeAdapterConfigState } from '@oneworks/config'
3
+ import { loadAdapterCliPreparer, normalizeAdapterPackageId, resolveAdapterRuntimeTarget } from '@oneworks/types'
4
+ import type { AdapterCliPrepareContext, AdapterCliPrepareTarget, AdapterCliPreparer, Config } from '@oneworks/types'
3
5
 
4
6
  const KNOWN_PREPARE_ADAPTERS = [
5
7
  'codex',
@@ -87,6 +89,50 @@ const pushUniqueRequest = (
87
89
  requests.push(request)
88
90
  }
89
91
 
92
+ const createRuntimePrepareContext = (
93
+ ctx: AdapterCliPrepareContext,
94
+ instanceKey: string,
95
+ runtimeKey: string
96
+ ): AdapterCliPrepareContext => {
97
+ const configState = resolveConfigState({
98
+ configState: ctx.configState,
99
+ configs: ctx.configs
100
+ })
101
+ const runtimeConfigState = resolveRuntimeAdapterConfigState(configState, instanceKey, runtimeKey)
102
+
103
+ return {
104
+ ...ctx,
105
+ configs: [
106
+ runtimeConfigState.effectiveProjectConfig ?? runtimeConfigState.projectConfig,
107
+ runtimeConfigState.userConfig
108
+ ],
109
+ configState: runtimeConfigState
110
+ }
111
+ }
112
+
113
+ const wrapRuntimePreparer = (
114
+ preparer: AdapterCliPreparer,
115
+ instanceKey: string,
116
+ runtimeKey: string
117
+ ): AdapterCliPreparer => {
118
+ if (preparer.adapter === instanceKey && instanceKey === runtimeKey) return preparer
119
+
120
+ return {
121
+ ...preparer,
122
+ adapter: instanceKey,
123
+ prepare: async (ctx, options) => {
124
+ const result = await preparer.prepare(
125
+ createRuntimePrepareContext(ctx, instanceKey, runtimeKey),
126
+ options
127
+ )
128
+ return {
129
+ ...result,
130
+ adapter: instanceKey
131
+ }
132
+ }
133
+ }
134
+ }
135
+
90
136
  export const resolveAdapterPrepareRequests = (params: {
91
137
  all?: boolean
92
138
  config: Config
@@ -159,6 +205,7 @@ export const resolveAdapterPrepareRequests = (params: {
159
205
 
160
206
  export const loadAdapterPreparePreparers = async (params: {
161
207
  config: Config
208
+ cwd?: string
162
209
  requiredTargets: string[]
163
210
  }) => {
164
211
  const configuredAdapters = Object.keys(params.config.adapters ?? {})
@@ -171,7 +218,12 @@ export const loadAdapterPreparePreparers = async (params: {
171
218
 
172
219
  for (const adapterId of adapterIds) {
173
220
  try {
174
- preparers.push(await loadAdapterCliPreparer(adapterId))
221
+ const adapterTarget = resolveAdapterRuntimeTarget(adapterId, {
222
+ config: params.config,
223
+ cwd: params.cwd
224
+ })
225
+ const preparer = await loadAdapterCliPreparer(adapterTarget.loadSpecifier)
226
+ preparers.push(wrapRuntimePreparer(preparer, adapterId, adapterTarget.runtimeAdapter))
175
227
  } catch (error) {
176
228
  if (requestedAdapters.includes(adapterId)) throw error
177
229
  }
@@ -71,6 +71,7 @@ export const runAdapterPrepareCommand = async (
71
71
  const ctx = await createPrepareContext(options.quiet)
72
72
  const preparers = await loadAdapterPreparePreparers({
73
73
  config: ctx.configState?.mergedConfig ?? {},
74
+ cwd: ctx.cwd,
74
75
  requiredTargets: targets
75
76
  })
76
77
  const requests = resolveAdapterPrepareRequests({
@@ -76,6 +76,13 @@ type PrintInputCapableSession = ExitControllableSession & {
76
76
  respondInteraction?: (id: string, data: string | string[]) => void | Promise<void>
77
77
  }
78
78
 
79
+ const ADAPTER_CLI_PREPARE_OPERATION_ID = 'adapter-cli-prepare'
80
+ const ADAPTER_CLI_PREPARE_OPERATION_TITLE = 'Adapter CLI'
81
+ const ADAPTER_CLI_PREPARE_STARTED_MESSAGE =
82
+ 'Preparing adapter CLI. If no compatible system installation is available, One Works will install it now.'
83
+ const ADAPTER_CLI_PREPARE_COMPLETED_MESSAGE = 'Adapter CLI is ready.'
84
+ const ADAPTER_CLI_PREPARE_FAILED_MESSAGE = 'Adapter CLI preparation failed.'
85
+
79
86
  const resolveRunPrimaryWorkspaceFolder = (
80
87
  workspaceFolder: string,
81
88
  fallbackWorkspaceFolder: string
@@ -216,6 +223,7 @@ Notes:
216
223
  }
217
224
  | undefined
218
225
  let activeRuntimeEventSink: Awaited<ReturnType<typeof createRuntimeEventSink>> | undefined
226
+ let adapterCliPrepareOperationActive = false
219
227
  try {
220
228
  const description = descriptionArgs.join(' ')
221
229
  opts.permissionMode = resolvePermissionModeOption(opts.permissionMode, opts.yolo)
@@ -799,7 +807,23 @@ Notes:
799
807
  printIdleTimeoutController.start()
800
808
  }
801
809
 
810
+ const recordAdapterCliPrepareOperation = (
811
+ type: 'operation_started' | 'operation_completed' | 'operation_failed',
812
+ message: string,
813
+ error?: string
814
+ ) => {
815
+ adapterCliPrepareOperationActive = type === 'operation_started'
816
+ return runtimeEventSink?.recordOperation({
817
+ type,
818
+ operationId: ADAPTER_CLI_PREPARE_OPERATION_ID,
819
+ title: ADAPTER_CLI_PREPARE_OPERATION_TITLE,
820
+ message,
821
+ ...(error != null ? { error } : {})
822
+ }) ?? Promise.resolve()
823
+ }
824
+
802
825
  const runStartedAt = startupProfiler.now()
826
+ await recordAdapterCliPrepareOperation('operation_started', ADAPTER_CLI_PREPARE_STARTED_MESSAGE)
803
827
  const { session, resolvedAdapter } = await run({
804
828
  adapter: record.resume.resolvedAdapter ?? record.resume.taskOptions.adapter,
805
829
  cwd: record.resume.taskOptions.cwd ?? record.resume.cwd,
@@ -813,6 +837,15 @@ Notes:
813
837
  printIdleTimeoutController?.recordEvent()
814
838
  void runtimeEventSink?.handleAdapterEvent(event)
815
839
  if (event.type === 'init') {
840
+ if (adapterCliPrepareOperationActive) {
841
+ adapterCliPrepareOperationActive = false
842
+ void runtimeEventSink?.recordOperation({
843
+ type: 'operation_completed',
844
+ operationId: ADAPTER_CLI_PREPARE_OPERATION_ID,
845
+ title: ADAPTER_CLI_PREPARE_OPERATION_TITLE,
846
+ message: ADAPTER_CLI_PREPARE_COMPLETED_MESSAGE
847
+ })
848
+ }
816
849
  updateInitRecord(event.data, boundSession?.pid)
817
850
  }
818
851
  if (event.type === 'message') {
@@ -948,6 +981,7 @@ Notes:
948
981
  })
949
982
  }
950
983
  } catch (error) {
984
+ const message = error instanceof Error ? error.message : String(error)
951
985
  const failureSink = activeRuntimeEventSink ??
952
986
  (runtimeConsumerContext == null
953
987
  ? undefined
@@ -959,6 +993,16 @@ Notes:
959
993
  }))
960
994
  if (failureSink != null) {
961
995
  try {
996
+ if (adapterCliPrepareOperationActive) {
997
+ adapterCliPrepareOperationActive = false
998
+ await failureSink.recordOperation({
999
+ type: 'operation_failed',
1000
+ operationId: ADAPTER_CLI_PREPARE_OPERATION_ID,
1001
+ title: ADAPTER_CLI_PREPARE_OPERATION_TITLE,
1002
+ message: ADAPTER_CLI_PREPARE_FAILED_MESSAGE,
1003
+ error: message
1004
+ })
1005
+ }
962
1006
  await failureSink.recordFailure(error)
963
1007
  await failureSink.flush()
964
1008
  } catch (sinkError) {
@@ -966,7 +1010,6 @@ Notes:
966
1010
  console.error(`[runtime-protocol] Failed to record runtime failure: ${message}`)
967
1011
  }
968
1012
  }
969
- const message = error instanceof Error ? error.message : String(error)
970
1013
  console.error(message)
971
1014
  process.exit(1)
972
1015
  }
@@ -24,6 +24,14 @@ type RuntimeEventAppendDraft = Omit<RuntimeEventDraft, 'sessionId'> & {
24
24
  sessionId?: string
25
25
  }
26
26
 
27
+ export interface RuntimeOperationEventInput {
28
+ error?: string
29
+ message: string
30
+ operationId: string
31
+ title: string
32
+ type: 'operation_started' | 'operation_completed' | 'operation_failed'
33
+ }
34
+
27
35
  export interface RuntimeEventSinkOptions {
28
36
  cwd: string
29
37
  env?: NodeJS.ProcessEnv
@@ -267,6 +275,24 @@ export class RuntimeEventSink {
267
275
  })
268
276
  }
269
277
 
278
+ recordOperation(input: RuntimeOperationEventInput) {
279
+ const status = input.type === 'operation_started'
280
+ ? 'running'
281
+ : input.type === 'operation_completed'
282
+ ? 'completed'
283
+ : 'failed'
284
+ return this.append({
285
+ type: input.type,
286
+ status,
287
+ operationId: input.operationId,
288
+ title: input.title,
289
+ message: input.message,
290
+ summary: input.message,
291
+ ...(input.error != null ? { error: input.error } : {}),
292
+ visibility: 'system'
293
+ })
294
+ }
295
+
270
296
  handleAdapterEvent(event: AdapterOutputEvent) {
271
297
  if (event.type === 'init') {
272
298
  return this.append({
@@ -11,6 +11,7 @@ const CLI_DEFAULT_SKILL_NAMES = [
11
11
  'oneworks-cli-print-mode',
12
12
  'oneworks-channel',
13
13
  'oneworks-mem',
14
+ 'oneworks-model-services',
14
15
  'create-entity',
15
16
  'update-entity',
16
17
  'create-plugin'