ticlawk 0.1.16-dev.15 → 0.1.16-dev.17

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
@@ -216,8 +216,12 @@ Agent CLI (run inside an agent runtime; requires TICLAWK_RUNTIME_AGENT_ID):
216
216
  ticlawk message read --target <t> [opts]
217
217
  ticlawk task claim --message-id <id>
218
218
  ticlawk task update --task-id <id> --status <s>
219
- ticlawk task list [--target <t>]
219
+ ticlawk task list [--target <t>] # group admins see the full task board
220
+ ticlawk charter get --target <t>
220
221
  ticlawk group members --target <t>
222
+ ticlawk group list
223
+ ticlawk agent list
224
+ ticlawk dashboard get --conversation-id <id>
221
225
  ticlawk server info [--refresh]
222
226
 
223
227
  Commands:
@@ -226,7 +230,15 @@ Commands:
226
230
  profile list or switch saved local identities
227
231
  message send/read chat messages (agent CLI surface)
228
232
  task claim/update/list tasks (agent CLI surface)
229
- group list members of a group conversation (agent CLI surface)
233
+ charter get/set conversation goal and role spec (agent CLI surface)
234
+ group create/list/delete groups, manage charters/members (agent CLI surface)
235
+ dashboard set/get conversation dashboards (agent CLI surface)
236
+ briefing publish/get owner briefings (agent CLI surface)
237
+ agent list/create/delete owned agent slots (agent CLI surface)
238
+ service publish/list/call shared services (agent CLI surface)
239
+ credential request owner-filled credentials (agent CLI surface)
240
+ reminder schedule/list/snooze/cancel reminders (agent CLI surface)
241
+ attachment view private chat assets (agent CLI surface)
230
242
  server server-info introspection (agent CLI surface)
231
243
  install-daemon install or refresh the background daemon
232
244
  update update the npm package and refresh the daemon
package/bin/ticlawk.mjs CHANGED
@@ -37,6 +37,7 @@ import {
37
37
  runWorkstreamCreateCommand,
38
38
  runWorkstreamDeleteCommand,
39
39
  runWorkstreamListCommand,
40
+ runAgentListCommand,
40
41
  runAgentCreateCommand,
41
42
  runAgentDeleteCommand,
42
43
  runDashboardSetCommand,
@@ -114,8 +115,12 @@ Agent CLI (run inside an agent runtime; requires TICLAWK_RUNTIME_AGENT_ID):
114
115
  ticlawk message read --target <t> [opts]
115
116
  ticlawk task claim --message-id <id>
116
117
  ticlawk task update --task-id <id> --status <s>
117
- ticlawk task list [--target <t>]
118
+ ticlawk task list [--target <t>] # group admins see the full task board
119
+ ticlawk charter get --target <t>
118
120
  ticlawk group members --target <t>
121
+ ticlawk group list
122
+ ticlawk agent list
123
+ ticlawk dashboard get --conversation-id <id>
119
124
  ticlawk server info [--refresh]
120
125
 
121
126
  Commands:
@@ -124,7 +129,15 @@ Commands:
124
129
  profile list or switch saved local identities
125
130
  message send/read chat messages (agent CLI surface)
126
131
  task claim/update/list tasks (agent CLI surface)
127
- group list members of a group conversation (agent CLI surface)
132
+ charter get/set conversation goal and role spec (agent CLI surface)
133
+ group create/list/delete groups, manage charters/members (agent CLI surface)
134
+ dashboard set/get conversation dashboards (agent CLI surface)
135
+ briefing publish/get owner briefings (agent CLI surface)
136
+ agent list/create/delete owned agent slots (agent CLI surface)
137
+ service publish/list/call shared services (agent CLI surface)
138
+ credential request owner-filled credentials (agent CLI surface)
139
+ reminder schedule/list/snooze/cancel reminders (agent CLI surface)
140
+ attachment view private chat assets (agent CLI surface)
128
141
  server server-info introspection (agent CLI surface)
129
142
  install-daemon install or refresh the background daemon
130
143
  update update the npm package and refresh the daemon
@@ -196,6 +209,10 @@ function printHelp(helpPath, args = {}) {
196
209
  console.log(getInstallDaemonHelp());
197
210
  return;
198
211
  }
212
+ if (AGENT_COMMAND_HELP[head]) {
213
+ console.log(AGENT_COMMAND_HELP[head]);
214
+ return;
215
+ }
199
216
  printUsage();
200
217
  }
201
218
 
@@ -375,24 +392,6 @@ async function main() {
375
392
  process.exit(1);
376
393
  }
377
394
 
378
- if (command === 'profile') {
379
- const sub = args._[1];
380
- if (args.help || args.h || !sub) {
381
- console.log(AGENT_COMMAND_HELP.profile);
382
- return;
383
- }
384
- if (sub === 'show') {
385
- process.exitCode = await runProfileShowCommand(args);
386
- return;
387
- }
388
- if (sub === 'update') {
389
- process.exitCode = await runProfileUpdateCommand(args);
390
- return;
391
- }
392
- console.error(`unknown profile subcommand: ${sub}`);
393
- process.exit(1);
394
- }
395
-
396
395
  if (command === 'reminder') {
397
396
  const sub = args._[1];
398
397
  if (args.help || args.h || !sub) {
@@ -512,6 +511,10 @@ async function main() {
512
511
  console.log(AGENT_COMMAND_HELP.agent);
513
512
  return;
514
513
  }
514
+ if (sub === 'list') {
515
+ process.exitCode = await runAgentListCommand(args);
516
+ return;
517
+ }
515
518
  if (sub === 'create') {
516
519
  process.exitCode = await runAgentCreateCommand(args);
517
520
  return;
@@ -590,6 +593,24 @@ async function main() {
590
593
  process.exit(1);
591
594
  }
592
595
 
596
+ if (command === 'charter') {
597
+ const sub = args._[1];
598
+ if (args.help || args.h || !sub) {
599
+ console.log(AGENT_COMMAND_HELP.charter);
600
+ return;
601
+ }
602
+ if (sub === 'get') {
603
+ process.exitCode = await runWorkstreamCharterGetCommand(args);
604
+ return;
605
+ }
606
+ if (sub === 'set') {
607
+ process.exitCode = await runWorkstreamCharterSetCommand(args);
608
+ return;
609
+ }
610
+ console.error(`unknown charter subcommand: ${sub}`);
611
+ process.exit(1);
612
+ }
613
+
593
614
  if (command === 'group') {
594
615
  const sub = args._[1];
595
616
  if (args.help || args.h || !sub) {
@@ -600,6 +621,27 @@ async function main() {
600
621
  process.exitCode = await runGroupCreateCommand(args);
601
622
  return;
602
623
  }
624
+ if (sub === 'list') {
625
+ process.exitCode = await runWorkstreamListCommand(args);
626
+ return;
627
+ }
628
+ if (sub === 'delete') {
629
+ process.exitCode = await runWorkstreamDeleteCommand(args);
630
+ return;
631
+ }
632
+ if (sub === 'charter') {
633
+ const op = args._[2];
634
+ if (op === 'get') {
635
+ process.exitCode = await runWorkstreamCharterGetCommand(args);
636
+ return;
637
+ }
638
+ if (op === 'set') {
639
+ process.exitCode = await runWorkstreamCharterSetCommand(args);
640
+ return;
641
+ }
642
+ console.error(`unknown group charter op: ${op}`);
643
+ process.exit(1);
644
+ }
603
645
  if (sub === 'members') {
604
646
  // Same subcommand handles list / add / remove based on flags.
605
647
  if (args.add) {
@@ -742,6 +784,14 @@ async function main() {
742
784
  console.log('Restart ticlawk for the daemon to use the selected profile.');
743
785
  return;
744
786
  }
787
+ if (subcommand === 'show') {
788
+ process.exitCode = await runProfileShowCommand(args);
789
+ return;
790
+ }
791
+ if (subcommand === 'update') {
792
+ process.exitCode = await runProfileUpdateCommand(args);
793
+ return;
794
+ }
745
795
  console.error(`unknown profile subcommand: ${subcommand}`);
746
796
  process.exit(1);
747
797
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ticlawk",
3
- "version": "0.1.16-dev.15",
3
+ "version": "0.1.16-dev.17",
4
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",
@@ -486,7 +486,7 @@ export async function removeAgentGroupMember({
486
486
  );
487
487
  }
488
488
 
489
- // ── Workstreams (CoS-managed groups) ──
489
+ // ── Workstreams (managed groups) ──
490
490
 
491
491
  export async function createWorkstream({
492
492
  actingAgentId, name, description, charter, memberAgentIds,
@@ -520,7 +520,14 @@ export async function listWorkstreams({ actingAgentId }) {
520
520
  return data || [];
521
521
  }
522
522
 
523
- // ── Agents (CoS pre-allocation) ──
523
+ // ── Agents ──
524
+
525
+ export async function listAgentSlots({ actingAgentId }) {
526
+ const params = new URLSearchParams();
527
+ params.set('acting_as_agent_id', actingAgentId);
528
+ const { data } = await apiFetch(`/api/agent/agents?${params}`);
529
+ return data || [];
530
+ }
524
531
 
525
532
  export async function createAgentSlot({
526
533
  actingAgentId, name, runtime, description, displayName, model,
@@ -610,7 +617,7 @@ export async function callService({ actingAgentId, name, input }) {
610
617
  );
611
618
  }
612
619
 
613
- // ── Briefings (CoS publish) ──
620
+ // ── Briefings ──
614
621
 
615
622
  export async function getBriefing({actingAgentId, briefingId}) {
616
623
  const params = new URLSearchParams();
@@ -618,17 +625,22 @@ export async function getBriefing({actingAgentId, briefingId}) {
618
625
  return apiFetch(`/api/agent/briefings/${encodeURIComponent(briefingId)}?${params}`);
619
626
  }
620
627
 
621
- export async function publishBriefing({actingAgentId, bodyText, bodyHtml}) {
628
+ export async function publishBriefing({actingAgentId, bodyText, attachmentAssetId, currentConversationId}) {
622
629
  const body = { acting_as_agent_id: actingAgentId };
623
630
  if (bodyText != null) body.body_text = bodyText;
624
- if (bodyHtml != null) body.body_html = bodyHtml;
631
+ if (attachmentAssetId != null) body.attachment_asset_id = attachmentAssetId;
632
+ if (currentConversationId != null) body.current_conversation_id = currentConversationId;
625
633
  return apiFetch('/api/agent/briefings', {
626
634
  method: 'POST',
627
635
  body: JSON.stringify(body),
628
636
  });
629
637
  }
630
638
 
631
- // ── Credentials (CoS slot creation) ──
639
+ // ── Credentials (slot creation + daemon sync) ──
640
+
641
+ export async function fetchCredentials() {
642
+ return apiFetch('/api/agent/credentials', { method: 'GET' });
643
+ }
632
644
 
633
645
  export async function requestCredential({
634
646
  actingAgentId, name, description, workstreamId,
@@ -6,7 +6,20 @@
6
6
  * using the connector-specific env name.
7
7
  */
8
8
 
9
- import { AF_CONFIG_PATH, persistConfig, TICLAWK_CONNECTOR_API_KEY } from '../../core/config.mjs';
9
+ import { AF_CONFIG_PATH, loadPersistentConfig, persistConfig, TICLAWK_CONNECTOR_API_KEY } from '../../core/config.mjs';
10
+
11
+ export const TICLAWK_CREDENTIAL_NAMES = 'TICLAWK_CREDENTIAL_NAMES';
12
+
13
+ function isRuntimeCredentialName(value) {
14
+ return /^[A-Z][A-Z0-9_]*$/.test(String(value || '').trim());
15
+ }
16
+
17
+ function parseCredentialNames(value) {
18
+ return String(value || '')
19
+ .split(',')
20
+ .map((name) => name.trim())
21
+ .filter(isRuntimeCredentialName);
22
+ }
10
23
 
11
24
  export function persistApiCredential(apiKey) {
12
25
  if (!apiKey || !apiKey.startsWith('tk_')) return;
@@ -19,3 +32,30 @@ export function persistApiCredential(apiKey) {
19
32
  delete process.env.TICLAWK_SETUP_CODE;
20
33
  console.log(`[connect] saved ${TICLAWK_CONNECTOR_API_KEY} to ${AF_CONFIG_PATH}`);
21
34
  }
35
+
36
+ export function persistRuntimeCredentials(credentials = []) {
37
+ const current = loadPersistentConfig();
38
+ const previousNames = new Set(parseCredentialNames(current[TICLAWK_CREDENTIAL_NAMES]));
39
+ const nextNames = [];
40
+ const updates = {};
41
+
42
+ for (const credential of Array.isArray(credentials) ? credentials : []) {
43
+ const name = String(credential?.name || '').trim();
44
+ const value = typeof credential?.value === 'string' ? credential.value : '';
45
+ if (!isRuntimeCredentialName(name) || !value) continue;
46
+ updates[name] = value;
47
+ nextNames.push(name);
48
+ }
49
+
50
+ const nextNameSet = new Set(nextNames);
51
+ for (const name of previousNames) {
52
+ if (!nextNameSet.has(name)) updates[name] = '';
53
+ }
54
+ updates[TICLAWK_CREDENTIAL_NAMES] = nextNames.join(',');
55
+
56
+ persistConfig(updates);
57
+ return {
58
+ saved: nextNames.length,
59
+ removed: [...previousNames].filter((name) => !nextNameSet.has(name)).length,
60
+ };
61
+ }