ticlawk 0.1.15 → 0.1.16-dev.10
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 +96 -212
- package/bin/ticlawk.mjs +223 -46
- package/package.json +2 -5
- package/src/adapters/ticlawk/api.mjs +308 -43
- package/src/adapters/ticlawk/credentials.mjs +1 -2
- package/src/adapters/ticlawk/index.mjs +310 -119
- package/src/cli/agent-commands.mjs +876 -0
- package/src/core/adapter-registry.mjs +12 -28
- package/src/core/agent-cli-handlers.mjs +731 -0
- package/src/core/agent-home.mjs +85 -0
- package/src/core/config.mjs +0 -15
- package/src/core/http.mjs +211 -18
- package/src/core/reminder-ticker.mjs +70 -0
- package/src/core/runtime-contract.mjs +1 -1
- package/src/core/runtime-env.mjs +41 -5
- package/src/core/runtime-support.mjs +31 -44
- package/src/core/ticlawk-control.mjs +7 -6
- package/src/migrate/write-initial-memory.mjs +101 -0
- package/src/runtimes/_shared/standing-prompt.mjs +308 -0
- package/src/runtimes/claude-code/index.mjs +49 -133
- package/src/runtimes/claude-code/session.mjs +15 -7
- package/src/runtimes/codex/index.mjs +29 -41
- package/src/runtimes/codex/session.mjs +9 -5
- package/src/runtimes/openclaw/index.mjs +59 -31
- package/src/runtimes/openclaw/target.mjs +0 -30
- package/src/runtimes/opencode/index.mjs +34 -56
- package/src/runtimes/opencode/session.mjs +11 -2
- package/src/runtimes/pi/index.mjs +31 -51
- package/src/runtimes/pi/session.mjs +8 -2
- package/ticlawk.mjs +37 -10
- package/assets/ticlawk-concept.svg +0 -137
- package/src/adapters/telegram/index.mjs +0 -359
- package/src/adapters/ticlawk/cards.mjs +0 -149
- package/src/core/media/outbound.mjs +0 -163
package/bin/ticlawk.mjs
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
import { request } from 'node:http';
|
|
4
4
|
import { installProcessDiagnostics } from '../src/core/diagnostics.mjs';
|
|
5
5
|
import {
|
|
6
|
-
AF_ADAPTER_KEY,
|
|
7
|
-
getConfiguredAdapter,
|
|
8
6
|
loadPersistentConfig,
|
|
9
7
|
getStreamingConfigView,
|
|
10
8
|
normalizeAdapterConfigTarget,
|
|
@@ -20,7 +18,7 @@ import {
|
|
|
20
18
|
getActiveProfile,
|
|
21
19
|
listProfiles,
|
|
22
20
|
} from '../src/core/profiles.mjs';
|
|
23
|
-
import {
|
|
21
|
+
import { runAdapterAuth } from '../src/core/adapter-registry.mjs';
|
|
24
22
|
import { runTiclawkConnect } from '../src/core/ticlawk-control.mjs';
|
|
25
23
|
import {
|
|
26
24
|
RUNTIME_DEFINITIONS,
|
|
@@ -30,12 +28,39 @@ import { runSelfUpdate, readPkgVersion } from '../src/core/update.mjs';
|
|
|
30
28
|
import { getUninstallHelp, runSelfUninstall } from '../src/core/uninstall.mjs';
|
|
31
29
|
import { getInstallDaemonHelp, runInstallDaemon } from '../src/core/daemon-install.mjs';
|
|
32
30
|
import { runSetupReadiness } from '../src/core/setup-readiness.mjs';
|
|
31
|
+
import {
|
|
32
|
+
AGENT_COMMAND_HELP,
|
|
33
|
+
runAttachmentViewCommand,
|
|
34
|
+
runGroupCreateCommand,
|
|
35
|
+
runGroupMembersAddCommand,
|
|
36
|
+
runGroupMembersCommand,
|
|
37
|
+
runGroupMembersRemoveCommand,
|
|
38
|
+
runMessageCheckCommand,
|
|
39
|
+
runMessageReactCommand,
|
|
40
|
+
runMessageReadCommand,
|
|
41
|
+
runMessageSearchCommand,
|
|
42
|
+
runMessageSendCommand,
|
|
43
|
+
runProfileShowCommand,
|
|
44
|
+
runProfileUpdateCommand,
|
|
45
|
+
runReminderCancelCommand,
|
|
46
|
+
runReminderListCommand,
|
|
47
|
+
runReminderLogCommand,
|
|
48
|
+
runReminderScheduleCommand,
|
|
49
|
+
runReminderSnoozeCommand,
|
|
50
|
+
runReminderUpdateCommand,
|
|
51
|
+
runServerInfoCommand,
|
|
52
|
+
runTaskClaimCommand,
|
|
53
|
+
runTaskCreateCommand,
|
|
54
|
+
runTaskListCommand,
|
|
55
|
+
runTaskUnclaimCommand,
|
|
56
|
+
runTaskUpdateCommand,
|
|
57
|
+
} from '../src/cli/agent-commands.mjs';
|
|
33
58
|
|
|
34
59
|
const TICLAWK_PORT = Number(process.env.FEED_RELAY_PORT || 8741);
|
|
35
60
|
|
|
36
61
|
function getConfigKeyUsage() {
|
|
37
62
|
const runtimeKeys = getRuntimeExecutableDefinitions().map((runtime) => runtime.executableCliKey);
|
|
38
|
-
return ['
|
|
63
|
+
return ['streaming...', ...runtimeKeys, 'ticlawk.connector-api-key', 'ticlawk.api-url', 'ticlawk.connector-ws-url'].join('|');
|
|
39
64
|
}
|
|
40
65
|
|
|
41
66
|
function getRuntimeConfigExamples() {
|
|
@@ -56,7 +81,7 @@ Usage:
|
|
|
56
81
|
ticlawk config
|
|
57
82
|
ticlawk config get <${configKeys}>
|
|
58
83
|
ticlawk config set <${configKeys}> <value>
|
|
59
|
-
ticlawk auth <
|
|
84
|
+
ticlawk auth --code <6-digit-code> [--api-url <url>]
|
|
60
85
|
ticlawk connect
|
|
61
86
|
ticlawk profile list
|
|
62
87
|
ticlawk profile current
|
|
@@ -66,44 +91,50 @@ Usage:
|
|
|
66
91
|
ticlawk uninstall [-y]
|
|
67
92
|
ticlawk version
|
|
68
93
|
|
|
94
|
+
Agent CLI (run inside an agent runtime; requires TICLAWK_RUNTIME_AGENT_ID):
|
|
95
|
+
ticlawk message send --target <t> # body on stdin
|
|
96
|
+
ticlawk message read --target <t> [opts]
|
|
97
|
+
ticlawk task claim --message-id <id>
|
|
98
|
+
ticlawk task update --task-id <id> --status <s>
|
|
99
|
+
ticlawk task list [--target <t>]
|
|
100
|
+
ticlawk group members --target <t>
|
|
101
|
+
ticlawk server info [--refresh]
|
|
102
|
+
|
|
69
103
|
Commands:
|
|
70
|
-
auth store
|
|
71
|
-
connect connect
|
|
104
|
+
auth store the ticlawk app pairing code locally
|
|
105
|
+
connect connect ticlawk to a local runtime
|
|
72
106
|
profile list or switch saved local identities
|
|
107
|
+
message send/read chat messages (agent CLI surface)
|
|
108
|
+
task claim/update/list tasks (agent CLI surface)
|
|
109
|
+
group list members of a group conversation (agent CLI surface)
|
|
110
|
+
server server-info introspection (agent CLI surface)
|
|
73
111
|
install-daemon install or refresh the background daemon
|
|
74
112
|
update update the npm package and refresh the daemon
|
|
75
113
|
uninstall remove service and managed install files, preserving ~/.ticlawk
|
|
76
114
|
|
|
77
115
|
Config examples:
|
|
78
|
-
ticlawk config get adapter
|
|
79
|
-
ticlawk config set adapter telegram
|
|
80
|
-
ticlawk config set adapter ticlawk
|
|
81
116
|
ticlawk config set streaming off # turn streaming off for all runtimes
|
|
82
117
|
ticlawk config set streaming.codex default # clear the codex-specific override and inherit the global streaming setting
|
|
83
118
|
${getRuntimeConfigExamples()}
|
|
84
|
-
ticlawk config set telegram.bot-token <bot-token> # advanced/manual
|
|
85
119
|
ticlawk config set ticlawk.connector-api-key <key> # advanced/manual
|
|
86
120
|
ticlawk config set ticlawk.api-url <api-url> # advanced/manual
|
|
87
121
|
ticlawk config set ticlawk.connector-ws-url <url> # advanced/manual
|
|
88
122
|
|
|
89
123
|
Examples:
|
|
90
124
|
ticlawk connect
|
|
91
|
-
ticlawk auth
|
|
125
|
+
ticlawk auth --code <6-digit-code>
|
|
92
126
|
`;
|
|
93
127
|
}
|
|
94
128
|
|
|
95
129
|
function getAuthHelp() {
|
|
96
|
-
return `ticlawk auth
|
|
130
|
+
return `ticlawk auth --code <6-digit-code> [--api-url <url>]
|
|
97
131
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
without changing the top-level CLI.
|
|
101
|
-
|
|
102
|
-
Examples:
|
|
103
|
-
ticlawk auth telegram --bot-token <bot-token>
|
|
132
|
+
Store the ticlawk app pairing code locally. The daemon picks it up on the
|
|
133
|
+
next start and exchanges it for an API key.
|
|
104
134
|
|
|
105
|
-
|
|
106
|
-
|
|
135
|
+
Options:
|
|
136
|
+
--code <code> 6-digit setup code from the ticlawk app
|
|
137
|
+
--api-url <url> optional ticlawk API base URL override
|
|
107
138
|
`;
|
|
108
139
|
}
|
|
109
140
|
|
|
@@ -132,11 +163,6 @@ function printHelp(helpPath, args = {}) {
|
|
|
132
163
|
return;
|
|
133
164
|
}
|
|
134
165
|
if (head === 'auth') {
|
|
135
|
-
const adapterValue = helpPath[1] || args._?.[1];
|
|
136
|
-
if (adapterValue) {
|
|
137
|
-
console.log(getAdapterAuthHelp(requireAdapter(adapterValue)));
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
166
|
console.log(getAuthHelp());
|
|
141
167
|
return;
|
|
142
168
|
}
|
|
@@ -169,7 +195,6 @@ function parseConfigBoolean(value) {
|
|
|
169
195
|
}
|
|
170
196
|
|
|
171
197
|
function printConfigView(config = loadPersistentConfig()) {
|
|
172
|
-
console.log(`adapter=${getConfiguredAdapter(config)}`);
|
|
173
198
|
const view = getStreamingConfigView(config);
|
|
174
199
|
console.log(`streaming=${formatStreamingValue(view.streaming.value, view.streaming.inherited)}`);
|
|
175
200
|
for (const runtime of RUNTIME_DEFINITIONS) {
|
|
@@ -180,7 +205,6 @@ function printConfigView(config = loadPersistentConfig()) {
|
|
|
180
205
|
for (const runtime of getRuntimeExecutableDefinitions()) {
|
|
181
206
|
console.log(`${runtime.executableCliKey}=${config[runtime.executableConfigKey] || ''}`);
|
|
182
207
|
}
|
|
183
|
-
console.log(`telegram.bot-token=${config.TELEGRAM_BOT_TOKEN ? 'set' : 'unset'}`);
|
|
184
208
|
console.log(`ticlawk.connector-api-key=${config[TICLAWK_CONNECTOR_API_KEY] ? 'set' : 'unset'}`);
|
|
185
209
|
console.log(`ticlawk.api-url=${config.TICLAWK_API_URL || ''}`);
|
|
186
210
|
console.log(`ticlawk.connector-ws-url=${config[TICLAWK_CONNECTOR_WS_URL] || ''}`);
|
|
@@ -211,7 +235,7 @@ function getLocal(path) {
|
|
|
211
235
|
}
|
|
212
236
|
|
|
213
237
|
function formatSecretConfigValue(configKey, value) {
|
|
214
|
-
if (configKey ===
|
|
238
|
+
if (configKey === TICLAWK_CONNECTOR_API_KEY) {
|
|
215
239
|
return value ? 'set' : 'unset';
|
|
216
240
|
}
|
|
217
241
|
return value || '';
|
|
@@ -302,6 +326,174 @@ async function main() {
|
|
|
302
326
|
return;
|
|
303
327
|
}
|
|
304
328
|
|
|
329
|
+
// ── Agent-facing subcommands (run inside a runtime; talk to local daemon) ──
|
|
330
|
+
if (command === 'message') {
|
|
331
|
+
const sub = args._[1];
|
|
332
|
+
if (args.help || args.h || !sub) {
|
|
333
|
+
console.log(AGENT_COMMAND_HELP.message);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
if (sub === 'send') {
|
|
337
|
+
process.exitCode = await runMessageSendCommand(args);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
if (sub === 'read') {
|
|
341
|
+
process.exitCode = await runMessageReadCommand(args);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (sub === 'react') {
|
|
345
|
+
process.exitCode = await runMessageReactCommand(args);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (sub === 'check') {
|
|
349
|
+
process.exitCode = await runMessageCheckCommand(args);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (sub === 'search') {
|
|
353
|
+
process.exitCode = await runMessageSearchCommand(args);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
console.error(`unknown message subcommand: ${sub}`);
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (command === 'profile') {
|
|
361
|
+
const sub = args._[1];
|
|
362
|
+
if (args.help || args.h || !sub) {
|
|
363
|
+
console.log(AGENT_COMMAND_HELP.profile);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (sub === 'show') {
|
|
367
|
+
process.exitCode = await runProfileShowCommand(args);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
if (sub === 'update') {
|
|
371
|
+
process.exitCode = await runProfileUpdateCommand(args);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
console.error(`unknown profile subcommand: ${sub}`);
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (command === 'reminder') {
|
|
379
|
+
const sub = args._[1];
|
|
380
|
+
if (args.help || args.h || !sub) {
|
|
381
|
+
console.log(AGENT_COMMAND_HELP.reminder);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (sub === 'schedule') {
|
|
385
|
+
process.exitCode = await runReminderScheduleCommand(args);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (sub === 'list') {
|
|
389
|
+
process.exitCode = await runReminderListCommand(args);
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
if (sub === 'snooze') {
|
|
393
|
+
process.exitCode = await runReminderSnoozeCommand(args);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (sub === 'update') {
|
|
397
|
+
process.exitCode = await runReminderUpdateCommand(args);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (sub === 'cancel') {
|
|
401
|
+
process.exitCode = await runReminderCancelCommand(args);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (sub === 'log') {
|
|
405
|
+
process.exitCode = await runReminderLogCommand(args);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
console.error(`unknown reminder subcommand: ${sub}`);
|
|
409
|
+
process.exit(1);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (command === 'attachment') {
|
|
413
|
+
const sub = args._[1];
|
|
414
|
+
if (args.help || args.h || !sub) {
|
|
415
|
+
console.log(AGENT_COMMAND_HELP.attachment);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (sub === 'view') {
|
|
419
|
+
process.exitCode = await runAttachmentViewCommand(args);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
console.error(`unknown attachment subcommand: ${sub}`);
|
|
423
|
+
process.exit(1);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (command === 'task') {
|
|
427
|
+
const sub = args._[1];
|
|
428
|
+
if (args.help || args.h || !sub) {
|
|
429
|
+
console.log(AGENT_COMMAND_HELP.task);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
if (sub === 'create') {
|
|
433
|
+
process.exitCode = await runTaskCreateCommand(args);
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
if (sub === 'claim') {
|
|
437
|
+
process.exitCode = await runTaskClaimCommand(args);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (sub === 'unclaim') {
|
|
441
|
+
process.exitCode = await runTaskUnclaimCommand(args);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
if (sub === 'update') {
|
|
445
|
+
process.exitCode = await runTaskUpdateCommand(args);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
if (sub === 'list') {
|
|
449
|
+
process.exitCode = await runTaskListCommand(args);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
console.error(`unknown task subcommand: ${sub}`);
|
|
453
|
+
process.exit(1);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (command === 'group') {
|
|
457
|
+
const sub = args._[1];
|
|
458
|
+
if (args.help || args.h || !sub) {
|
|
459
|
+
console.log(AGENT_COMMAND_HELP.group);
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (sub === 'create') {
|
|
463
|
+
process.exitCode = await runGroupCreateCommand(args);
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
if (sub === 'members') {
|
|
467
|
+
// Same subcommand handles list / add / remove based on flags.
|
|
468
|
+
if (args.add) {
|
|
469
|
+
process.exitCode = await runGroupMembersAddCommand(args);
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
if (args.remove) {
|
|
473
|
+
process.exitCode = await runGroupMembersRemoveCommand(args);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
process.exitCode = await runGroupMembersCommand(args);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
console.error(`unknown group subcommand: ${sub}`);
|
|
480
|
+
process.exit(1);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (command === 'server') {
|
|
484
|
+
const sub = args._[1];
|
|
485
|
+
if (args.help || args.h || !sub) {
|
|
486
|
+
console.log(AGENT_COMMAND_HELP.server);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
if (sub === 'info') {
|
|
490
|
+
process.exitCode = await runServerInfoCommand(args);
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
console.error(`unknown server subcommand: ${sub}`);
|
|
494
|
+
process.exit(1);
|
|
495
|
+
}
|
|
496
|
+
|
|
305
497
|
if (command === 'config') {
|
|
306
498
|
const subcommand = args._[1];
|
|
307
499
|
const config = loadPersistentConfig();
|
|
@@ -312,10 +504,6 @@ async function main() {
|
|
|
312
504
|
|
|
313
505
|
if (subcommand === 'get') {
|
|
314
506
|
const key = args._[2];
|
|
315
|
-
if (key === 'adapter') {
|
|
316
|
-
console.log(getConfiguredAdapter(config));
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
507
|
const adapterTarget = normalizeAdapterConfigTarget(key);
|
|
320
508
|
if (adapterTarget) {
|
|
321
509
|
console.log(formatSecretConfigValue(adapterTarget.configKey, config[adapterTarget.configKey]));
|
|
@@ -340,16 +528,6 @@ async function main() {
|
|
|
340
528
|
if (subcommand === 'set') {
|
|
341
529
|
const key = args._[2];
|
|
342
530
|
const rawValue = args._[3];
|
|
343
|
-
if (key === 'adapter') {
|
|
344
|
-
if (!rawValue) {
|
|
345
|
-
console.error('config set adapter requires a value');
|
|
346
|
-
process.exit(1);
|
|
347
|
-
}
|
|
348
|
-
const adapterId = requireAdapter(rawValue);
|
|
349
|
-
persistConfig({ [AF_ADAPTER_KEY]: adapterId });
|
|
350
|
-
console.log(`adapter=${adapterId}`);
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
531
|
const adapterTarget = normalizeAdapterConfigTarget(key);
|
|
354
532
|
if (adapterTarget) {
|
|
355
533
|
if (!rawValue) {
|
|
@@ -464,9 +642,8 @@ async function main() {
|
|
|
464
642
|
printHelp(['auth'], args);
|
|
465
643
|
return;
|
|
466
644
|
}
|
|
467
|
-
const
|
|
468
|
-
const
|
|
469
|
-
const res = await runAdapterAuth(adapterId, adapterArgv);
|
|
645
|
+
const adapterArgv = rawArgv.slice(1);
|
|
646
|
+
const res = await runAdapterAuth('ticlawk', adapterArgv);
|
|
470
647
|
printCommandResult(res);
|
|
471
648
|
process.exitCode = res.statusCode >= 400 ? 1 : 0;
|
|
472
649
|
return;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ticlawk",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.16-dev.10",
|
|
4
|
+
"description": "Local connector that links agent harnesses (Claude Code, Codex, OpenClaw, opencode, Pi) to the Ticlawk mobile app.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "ticlawk.mjs",
|
|
7
7
|
"exports": {
|
|
@@ -48,9 +48,6 @@
|
|
|
48
48
|
"codex",
|
|
49
49
|
"agent",
|
|
50
50
|
"ai-agent",
|
|
51
|
-
"telegram",
|
|
52
|
-
"telegram-bot",
|
|
53
|
-
"chatops",
|
|
54
51
|
"remote-agent",
|
|
55
52
|
"mobile",
|
|
56
53
|
"bridge",
|