ticlawk 0.1.15-dev.5 → 0.1.15-dev.6

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/README.md CHANGED
@@ -321,11 +321,6 @@ Usage:
321
321
  ticlawk config set <adapter|streaming...|runtimes.claude_code.path|runtimes.codex.path|runtimes.opencode.path|runtimes.pi.path|telegram.bot-token|ticlawk.connector-api-key|ticlawk.api-url|ticlawk.connector-ws-url> <value>
322
322
  ticlawk auth <adapter> [adapter-auth-args...]
323
323
  ticlawk connect
324
- ticlawk connect [--adapter <adapter>] [--session-id <id>] [--workdir <dir>] [--switch-user]
325
- ticlawk connect [--adapter <adapter>] --type codex [--session-id <id>] [--workdir <dir>] [--name <name>] [--runtime-path <path>] [--switch-user]
326
- ticlawk connect [--adapter <adapter>] --type openclaw --agent-id <id> [--name <name>] [--runtime-path <path>] [--switch-user]
327
- ticlawk connect [--adapter <adapter>] --type opencode [--session-id <id>] [--workdir <dir>] [--name <name>] [--runtime-path <path>] [--switch-user]
328
- ticlawk connect [--adapter <adapter>] --type pi [--session-id <id>] [--workdir <dir>] [--name <name>] [--runtime-path <path>] [--switch-user]
329
324
  ticlawk profile list
330
325
  ticlawk profile current
331
326
  ticlawk profile use ticlawk:<user-id>
@@ -359,15 +354,7 @@ Config examples:
359
354
 
360
355
  Examples:
361
356
  ticlawk connect
362
- ticlawk connect --type codex --workdir /path/to/project
363
- ticlawk connect --type openclaw --agent-id main
364
357
  ticlawk auth telegram --bot-token <bot-token>
365
- ticlawk connect --adapter telegram --workdir /path/to/project
366
- ticlawk connect --adapter telegram --session-id <claude-session-id>
367
- ticlawk connect --adapter telegram --type codex --workdir /path/to/project
368
- ticlawk connect --adapter telegram --type openclaw --agent-id main
369
- ticlawk connect --adapter telegram --type opencode --workdir /path/to/project
370
- ticlawk connect --adapter telegram --type pi --workdir /path/to/project
371
358
  ```
372
359
  <!-- usage:end -->
373
360
 
package/bin/ticlawk.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { request } from 'node:http';
4
- import { resolve } from 'node:path';
5
4
  import { installProcessDiagnostics } from '../src/core/diagnostics.mjs';
6
5
  import {
7
6
  AF_ADAPTER_KEY,
@@ -9,11 +8,9 @@ import {
9
8
  loadPersistentConfig,
10
9
  getStreamingConfigView,
11
10
  normalizeAdapterConfigTarget,
12
- normalizeAdapterName,
13
11
  normalizeRuntimeConfigTarget,
14
12
  normalizeStreamingTarget,
15
13
  persistConfig,
16
- SUPPORTED_ADAPTERS,
17
14
  TICLAWK_CONNECTOR_API_KEY,
18
15
  TICLAWK_CONNECTOR_WS_URL,
19
16
  } from '../src/core/config.mjs';
@@ -27,10 +24,7 @@ import { getAdapterAuthHelp, runAdapterAuth } from '../src/core/adapter-registry
27
24
  import { runTiclawkConnect } from '../src/core/ticlawk-control.mjs';
28
25
  import {
29
26
  RUNTIME_DEFINITIONS,
30
- getRuntimeDefinition,
31
- getRuntimeDisplayName,
32
27
  getRuntimeExecutableDefinitions,
33
- normalizeServiceType,
34
28
  } from '../src/core/runtime-registry.mjs';
35
29
  import { runSelfUpdate, readPkgVersion } from '../src/core/update.mjs';
36
30
  import { getUninstallHelp, runSelfUninstall } from '../src/core/uninstall.mjs';
@@ -44,40 +38,12 @@ function getConfigKeyUsage() {
44
38
  return ['adapter', 'streaming...', ...runtimeKeys, 'telegram.bot-token', 'ticlawk.connector-api-key', 'ticlawk.api-url', 'ticlawk.connector-ws-url'].join('|');
45
39
  }
46
40
 
47
- function getRuntimeConnectUsageLines() {
48
- return RUNTIME_DEFINITIONS
49
- .filter((runtime) => !runtime.aliases.includes(''))
50
- .map((runtime) => {
51
- if (runtime.connect?.locator === 'agentId') {
52
- return ` ticlawk connect [--adapter <adapter>] --type ${runtime.name} --agent-id <id> [--name <name>] [--runtime-path <path>] [--switch-user]`;
53
- }
54
- return ` ticlawk connect [--adapter <adapter>] --type ${runtime.name} [--session-id <id>] [--workdir <dir>] [--name <name>] [--runtime-path <path>] [--switch-user]`;
55
- })
56
- .join('\n');
57
- }
58
-
59
41
  function getRuntimeConfigExamples() {
60
42
  return getRuntimeExecutableDefinitions()
61
43
  .map((runtime) => ` ticlawk config set ${runtime.executableCliKey} /path/to/${runtime.name} # advanced/manual`)
62
44
  .join('\n');
63
45
  }
64
46
 
65
- function getRuntimeConnectExamples() {
66
- return [
67
- ' ticlawk connect --adapter telegram --workdir /path/to/project',
68
- ' ticlawk connect --adapter telegram --session-id <claude-session-id>',
69
- ...RUNTIME_DEFINITIONS
70
- .filter((runtime) => !runtime.aliases.includes(''))
71
- .slice(0, 4)
72
- .map((runtime) => {
73
- if (runtime.connect?.locator === 'agentId') {
74
- return ` ticlawk connect --adapter telegram --type ${runtime.name} --agent-id main`;
75
- }
76
- return ` ticlawk connect --adapter telegram --type ${runtime.name} --workdir /path/to/project`;
77
- }),
78
- ].join('\n');
79
- }
80
-
81
47
  function getUsageText() {
82
48
  const configKeys = getConfigKeyUsage();
83
49
  return `ticlawk
@@ -92,8 +58,6 @@ Usage:
92
58
  ticlawk config set <${configKeys}> <value>
93
59
  ticlawk auth <adapter> [adapter-auth-args...]
94
60
  ticlawk connect
95
- ticlawk connect [--adapter <adapter>] [--session-id <id>] [--workdir <dir>] [--switch-user]
96
- ${getRuntimeConnectUsageLines()}
97
61
  ticlawk profile list
98
62
  ticlawk profile current
99
63
  ticlawk profile use ticlawk:<user-id>
@@ -124,10 +88,7 @@ ${getRuntimeConfigExamples()}
124
88
 
125
89
  Examples:
126
90
  ticlawk connect
127
- ticlawk connect --type codex --workdir /path/to/project
128
- ticlawk connect --type openclaw --agent-id main
129
91
  ticlawk auth telegram --bot-token <bot-token>
130
- ${getRuntimeConnectExamples()}
131
92
  `;
132
93
  }
133
94
 
@@ -153,14 +114,10 @@ Use \`connect\` to connect the selected adapter to a local runtime.
153
114
  For ticlawk, connect starts the QR pairing flow when no local credential exists.
154
115
  Run \`ticlawk connect\` from a project directory to auto-detect
155
116
  Codex, Claude Code, opencode, and pi, then choose the runtime in ticlawk.
156
- By default connect records the runtime binary found in your current terminal.
157
- Use \`--runtime-path <path>\` only when you need to override that discovery.
117
+ No pairing QR code is shown when no local agent harness is detected.
158
118
 
159
119
  Examples:
160
120
  ticlawk connect
161
- ticlawk connect --type codex --workdir /path/to/project
162
- ticlawk connect --type openclaw --agent-id main
163
- ${getRuntimeConnectExamples()}
164
121
  `;
165
122
  }
166
123
 
@@ -260,84 +217,35 @@ function formatSecretConfigValue(configKey, value) {
260
217
  return value || '';
261
218
  }
262
219
 
263
- function requireAdapter(value) {
264
- const adapterId = normalizeAdapterName(value);
265
- if (!adapterId) {
266
- const supported = SUPPORTED_ADAPTERS.join(', ');
267
- console.error(`invalid adapter: ${value || ''} (supported: ${supported})`);
268
- process.exit(1);
269
- }
270
- return adapterId;
271
- }
272
-
273
- function getConnectAdapter(value) {
274
- if (value === undefined || value === null || value === '') {
275
- return getConfiguredAdapter();
276
- }
277
- return requireAdapter(value);
278
- }
279
-
280
220
  function buildConnectPayload(args) {
221
+ const legacyArgs = [
222
+ 'adapter',
223
+ 'type',
224
+ 'session-id',
225
+ 'workdir',
226
+ 'cwd',
227
+ 'project-dir',
228
+ 'agent-id',
229
+ 'runtime-path',
230
+ 'code',
231
+ ].filter((key) => args[key] !== undefined);
281
232
  const positionalRuntime = args._?.[1];
282
- const serviceType = normalizeServiceType(args.type || positionalRuntime);
283
- const explicitWorkdir = args.workdir || args.cwd || args['project-dir'];
284
- const workdir = explicitWorkdir ? resolve(explicitWorkdir) : process.cwd();
285
- const hasExplicitAdapter = Boolean(args.adapter);
286
- const adapter = (!serviceType && !hasExplicitAdapter)
287
- ? 'ticlawk'
288
- : getConnectAdapter(args.adapter);
289
- if (!serviceType) {
290
- if (adapter === 'ticlawk' && !args.type && !positionalRuntime) {
291
- return {
292
- adapter,
293
- autoRuntime: true,
294
- switchUser: Boolean(args['switch-user']),
295
- workdir,
296
- ...(args.name ? { name: args.name } : {}),
297
- };
298
- }
299
- console.error(`invalid runtime type: ${args.type || positionalRuntime || ''}`);
233
+ if (positionalRuntime || legacyArgs.length > 0) {
234
+ const suffix = positionalRuntime ? ` ${positionalRuntime}` : '';
235
+ console.error(`ticlawk connect${suffix} no longer accepts explicit runtime, adapter, session, or workdir arguments.`);
236
+ console.error('Run `ticlawk connect` from the directory you want to offer to local agent harnesses.');
237
+ console.error('Ticlawk will detect Codex, Claude Code, opencode, and pi locally, then let you choose in the app.');
300
238
  process.exit(1);
301
239
  }
302
-
303
- const runtimeDefinition = getRuntimeDefinition(serviceType);
304
- if (runtimeDefinition?.connect?.locator === 'agentId') {
305
- return {
306
- adapter,
307
- serviceType,
308
- agentId: args['agent-id'],
309
- ...(explicitWorkdir ? { workdir } : {}),
310
- ...(args['runtime-path'] ? { runtimePath: resolve(args['runtime-path']) } : {}),
311
- name: args.name || args['agent-id'],
312
- switchUser: Boolean(args['switch-user']),
313
- };
314
- }
315
-
316
240
  return {
317
- adapter,
318
- serviceType,
319
- sessionId: args['session-id'],
241
+ adapter: 'ticlawk',
242
+ autoRuntime: true,
320
243
  switchUser: Boolean(args['switch-user']),
321
- workdir,
244
+ workdir: process.cwd(),
322
245
  ...(args.name ? { name: args.name } : {}),
323
- ...(args['runtime-path'] ? { runtimePath: resolve(args['runtime-path']) } : {}),
324
246
  };
325
247
  }
326
248
 
327
- function validateConnectPayload(payload) {
328
- if (payload.autoRuntime) return;
329
- const runtimeDefinition = getRuntimeDefinition(payload.serviceType);
330
- if (runtimeDefinition?.connect?.locator === 'agentId' && !payload.agentId) {
331
- console.error(`--agent-id is required for ${getRuntimeDisplayName(payload.serviceType)} connect`);
332
- process.exit(1);
333
- }
334
- if (runtimeDefinition?.connect?.locator !== 'agentId' && !payload.sessionId && !payload.workdir) {
335
- const runtimeName = getRuntimeDisplayName(payload.serviceType);
336
- console.error(`either --session-id or --workdir is required for ${runtimeName} connect`);
337
- process.exit(1);
338
- }
339
- }
340
-
341
249
  function printCommandResult(result) {
342
250
  if (result?.body?.help) {
343
251
  console.log(result.body.help);
@@ -570,7 +478,6 @@ async function main() {
570
478
  return;
571
479
  }
572
480
  const payload = buildConnectPayload(args);
573
- validateConnectPayload(payload);
574
481
  const res = await runTiclawkConnect(payload);
575
482
  printCommandResult(res);
576
483
  if (res.statusCode < 400) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ticlawk",
3
- "version": "0.1.15-dev.5",
3
+ "version": "0.1.15-dev.6",
4
4
  "description": "Connect local agent harnesses to Ticlawk, Telegram, and other mobile clients.",
5
5
  "type": "module",
6
6
  "main": "ticlawk.mjs",
@@ -193,8 +193,11 @@ function runtimeLabel(runtime) {
193
193
  }
194
194
 
195
195
  function printDetectedRuntimeOptions(runtimeOptions = []) {
196
- if (!runtimeOptions.length) return;
197
196
  console.log('Detected agent harness:');
197
+ if (!runtimeOptions.length) {
198
+ console.log(' none');
199
+ return;
200
+ }
198
201
  for (const option of runtimeOptions) {
199
202
  const label = option.runtime_label || runtimeLabel(option.runtime);
200
203
  const workdir = option.workdir ? ` (${option.workdir})` : '';
@@ -885,11 +888,11 @@ export function createTiclawkAdapter(ctx) {
885
888
  async function connectWithQrPairing(payload) {
886
889
  const autoRuntime = Boolean(payload?.autoRuntime);
887
890
  const runtimeOptions = autoRuntime ? await buildAutoRuntimeOptions(ctx, payload) : [];
888
- if (autoRuntime && runtimeOptions.length === 0) {
889
- throw new Error('No supported local agent runtime found in this terminal. Install or sign in to Codex, Claude Code, OpenCode, or pi, then try again.');
890
- }
891
891
  if (autoRuntime) {
892
892
  printDetectedRuntimeOptions(runtimeOptions);
893
+ if (runtimeOptions.length === 0) {
894
+ return connectError(400, 'No supported local agent harness detected in this terminal. Install or sign in to Codex, Claude Code, OpenCode, or pi, then run `ticlawk connect` again.');
895
+ }
893
896
  }
894
897
  const resolved = autoRuntime ? null : await ctx.resolveRuntimeBinding(payload);
895
898
  const runtimeMeta = resolved?.runtimeMeta || {};
@@ -1009,15 +1012,24 @@ export function createTiclawkAdapter(ctx) {
1009
1012
 
1010
1013
  async connect(payload) {
1011
1014
  const config = loadPersistentConfig();
1012
- const connectCode = String(payload?.code || config.TICLAWK_SETUP_CODE || '').trim();
1013
- if (!connectCode) {
1015
+ if (!payload?.__legacyConnect) {
1014
1016
  try {
1015
- return await connectWithQrPairing.call(this, payload);
1017
+ return await connectWithQrPairing.call(this, {
1018
+ ...payload,
1019
+ autoRuntime: true,
1020
+ });
1016
1021
  } catch (err) {
1017
1022
  return connectError(err?.status || 500, err.message);
1018
1023
  }
1019
1024
  }
1020
1025
 
1026
+ // Archived setup-code connect path. It is intentionally not reachable
1027
+ // from the public CLI; keep it here only until the old flow is deleted.
1028
+ const connectCode = String(payload?.code || config.TICLAWK_SETUP_CODE || '').trim();
1029
+ if (!connectCode) {
1030
+ return connectError(400, 'legacy ticlawk setup-code connect requires code');
1031
+ }
1032
+
1021
1033
  try {
1022
1034
  const resolved = await ctx.resolveRuntimeBinding(payload);
1023
1035
  const runtimeMeta = resolved.runtimeMeta;