@hera-al/server 1.6.12 → 1.6.13

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.
Files changed (61) hide show
  1. package/bundled/a2ui/SKILL.md +339 -0
  2. package/bundled/buongiorno/SKILL.md +151 -0
  3. package/bundled/council/SKILL.md +168 -0
  4. package/bundled/council/scripts/council.mjs +202 -0
  5. package/bundled/dreaming/SKILL.md +177 -0
  6. package/bundled/google-workspace/SKILL.md +229 -0
  7. package/bundled/google-workspace/scripts/auth.sh +87 -0
  8. package/bundled/google-workspace/scripts/calendar.sh +508 -0
  9. package/bundled/google-workspace/scripts/drive.sh +459 -0
  10. package/bundled/google-workspace/scripts/gmail.sh +452 -0
  11. package/bundled/humanizer/SKILL.md +488 -0
  12. package/bundled/librarian/SKILL.md +155 -0
  13. package/bundled/plasma/SKILL.md +1417 -0
  14. package/bundled/sera/SKILL.md +143 -0
  15. package/bundled/the-skill-guardian/SKILL.md +103 -0
  16. package/bundled/the-skill-guardian/scripts/scan.sh +314 -0
  17. package/bundled/unix-time/SKILL.md +58 -0
  18. package/bundled/wandering/SKILL.md +174 -0
  19. package/bundled/xai-search/SKILL.md +91 -0
  20. package/bundled/xai-search/scripts/search.sh +197 -0
  21. package/dist/a2ui/parser.d.ts +76 -0
  22. package/dist/a2ui/parser.js +1 -0
  23. package/dist/a2ui/types.d.ts +147 -0
  24. package/dist/a2ui/types.js +1 -0
  25. package/dist/a2ui/validator.d.ts +32 -0
  26. package/dist/a2ui/validator.js +1 -0
  27. package/dist/agent/agent-service.d.ts +17 -11
  28. package/dist/agent/agent-service.js +1 -1
  29. package/dist/agent/session-agent.d.ts +1 -1
  30. package/dist/agent/session-agent.js +1 -1
  31. package/dist/agent/session-error-handler.js +1 -1
  32. package/dist/commands/debuga2ui.d.ts +13 -0
  33. package/dist/commands/debuga2ui.js +1 -0
  34. package/dist/commands/debugdynamic.d.ts +13 -0
  35. package/dist/commands/debugdynamic.js +1 -0
  36. package/dist/commands/mcp.d.ts +6 -3
  37. package/dist/commands/mcp.js +1 -1
  38. package/dist/gateway/node-registry.d.ts +29 -1
  39. package/dist/gateway/node-registry.js +1 -1
  40. package/dist/installer/hera.js +1 -1
  41. package/dist/memory/concept-store.d.ts +109 -0
  42. package/dist/memory/concept-store.js +1 -0
  43. package/dist/nostromo/nostromo.js +1 -1
  44. package/dist/server.d.ts +3 -2
  45. package/dist/server.js +1 -1
  46. package/dist/tools/a2ui-tools.d.ts +23 -0
  47. package/dist/tools/a2ui-tools.js +1 -0
  48. package/dist/tools/concept-tools.d.ts +3 -0
  49. package/dist/tools/concept-tools.js +1 -0
  50. package/dist/tools/dynamic-ui-tools.d.ts +25 -0
  51. package/dist/tools/dynamic-ui-tools.js +1 -0
  52. package/dist/tools/node-tools.js +1 -1
  53. package/dist/tools/plasma-client-tools.d.ts +28 -0
  54. package/dist/tools/plasma-client-tools.js +1 -0
  55. package/installationPkg/AGENTS.md +168 -22
  56. package/installationPkg/SOUL.md +56 -0
  57. package/installationPkg/TOOLS.md +126 -0
  58. package/installationPkg/USER.md +54 -1
  59. package/installationPkg/config.example.yaml +145 -34
  60. package/installationPkg/default-jobs.json +77 -0
  61. package/package.json +3 -2
@@ -0,0 +1,508 @@
1
+ #!/usr/bin/env bash
2
+ # Google Calendar API client — OAuth2 REST API v3
3
+ # Usage: calendar.sh <command> [options]
4
+ #
5
+ # Commands:
6
+ # list [--max N] [--cal ID] List today's events
7
+ # upcoming [--days N] [--max N] [--cal ID] List upcoming events
8
+ # search "query" [--max N] [--cal ID] Search events by text
9
+ # get <eventId> [--cal ID] Get event details
10
+ # create --summary TITLE --start ISO --end ISO Create event
11
+ # update <eventId> [--summary T] [--start ISO] Update event
12
+ # delete <eventId> [--cal ID] Delete event
13
+ # calendars List available calendars
14
+ # today [--cal ID] Alias for list (today's events)
15
+ # week [--cal ID] Events for this week
16
+
17
+ set -euo pipefail
18
+
19
+ # --- Config ---
20
+ API_BASE="https://www.googleapis.com/calendar/v3"
21
+ TOKEN_FILE="${HOME}/.gmab-google-token.json"
22
+
23
+ # --- Token management (shared pattern) ---
24
+ get_access_token() {
25
+ local client_id="${GOOGLE_CLIENT_ID:-}"
26
+ local client_secret="${GOOGLE_CLIENT_SECRET:-}"
27
+ local refresh_token="${GOOGLE_REFRESH_TOKEN:-}"
28
+
29
+ if [[ -z "$refresh_token" && -f "$TOKEN_FILE" ]]; then
30
+ client_id=$(jq -r '.client_id // empty' "$TOKEN_FILE" 2>/dev/null || true)
31
+ client_secret=$(jq -r '.client_secret // empty' "$TOKEN_FILE" 2>/dev/null || true)
32
+ refresh_token=$(jq -r '.refresh_token // empty' "$TOKEN_FILE" 2>/dev/null || true)
33
+ fi
34
+
35
+ if [[ -z "$client_id" || -z "$client_secret" || -z "$refresh_token" ]]; then
36
+ echo "ERROR: Google credentials not configured." >&2
37
+ echo "Set GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REFRESH_TOKEN" >&2
38
+ echo "Or run auth.sh to set up OAuth2." >&2
39
+ exit 1
40
+ fi
41
+
42
+ if [[ -f "$TOKEN_FILE" ]]; then
43
+ local cached_token cached_expiry
44
+ cached_token=$(jq -r '.access_token // empty' "$TOKEN_FILE" 2>/dev/null || true)
45
+ cached_expiry=$(jq -r '.expires_at // 0' "$TOKEN_FILE" 2>/dev/null || true)
46
+ local now
47
+ now=$(date +%s)
48
+ if [[ -n "$cached_token" && "$cached_expiry" -gt "$now" ]]; then
49
+ echo "$cached_token"
50
+ return
51
+ fi
52
+ fi
53
+
54
+ local response
55
+ response=$(curl -s "https://oauth2.googleapis.com/token" \
56
+ -d "client_id=$client_id" \
57
+ -d "client_secret=$client_secret" \
58
+ -d "refresh_token=$refresh_token" \
59
+ -d "grant_type=refresh_token")
60
+
61
+ local access_token
62
+ access_token=$(echo "$response" | jq -r '.access_token // empty')
63
+ local expires_in
64
+ expires_in=$(echo "$response" | jq -r '.expires_in // 3600')
65
+
66
+ if [[ -z "$access_token" ]]; then
67
+ echo "ERROR: Failed to refresh access token" >&2
68
+ echo "$response" >&2
69
+ exit 1
70
+ fi
71
+
72
+ local expires_at
73
+ expires_at=$(($(date +%s) + expires_in - 60))
74
+
75
+ if [[ -f "$TOKEN_FILE" ]]; then
76
+ local tmp
77
+ tmp=$(jq --arg at "$access_token" --argjson ea "$expires_at" \
78
+ '. + {access_token: $at, expires_at: $ea}' "$TOKEN_FILE")
79
+ echo "$tmp" > "$TOKEN_FILE"
80
+ else
81
+ jq -n \
82
+ --arg ci "$client_id" \
83
+ --arg cs "$client_secret" \
84
+ --arg rt "$refresh_token" \
85
+ --arg at "$access_token" \
86
+ --argjson ea "$expires_at" \
87
+ '{client_id: $ci, client_secret: $cs, refresh_token: $rt, access_token: $at, expires_at: $ea}' \
88
+ > "$TOKEN_FILE"
89
+ fi
90
+ chmod 600 "$TOKEN_FILE"
91
+
92
+ echo "$access_token"
93
+ }
94
+
95
+ # --- API helpers ---
96
+ api_get() {
97
+ local path="$1"
98
+ local token
99
+ token=$(get_access_token)
100
+ curl -s -H "Authorization: Bearer $token" "${API_BASE}${path}"
101
+ }
102
+
103
+ api_post() {
104
+ local path="$1"
105
+ local data="${2:-}"
106
+ local token
107
+ token=$(get_access_token)
108
+ if [[ -n "$data" ]]; then
109
+ curl -s -H "Authorization: Bearer $token" \
110
+ -H "Content-Type: application/json" \
111
+ -d "$data" "${API_BASE}${path}"
112
+ else
113
+ curl -s -X POST -H "Authorization: Bearer $token" "${API_BASE}${path}"
114
+ fi
115
+ }
116
+
117
+ api_patch() {
118
+ local path="$1"
119
+ local data="$2"
120
+ local token
121
+ token=$(get_access_token)
122
+ curl -s -X PATCH -H "Authorization: Bearer $token" \
123
+ -H "Content-Type: application/json" \
124
+ -d "$data" "${API_BASE}${path}"
125
+ }
126
+
127
+ api_delete() {
128
+ local path="$1"
129
+ local token
130
+ token=$(get_access_token)
131
+ curl -s -X DELETE -H "Authorization: Bearer $token" "${API_BASE}${path}"
132
+ }
133
+
134
+ # --- Date helpers ---
135
+ # Get ISO date for start of today (local timezone)
136
+ today_start() {
137
+ if date -v0H >/dev/null 2>&1; then
138
+ # BSD date (macOS)
139
+ date -u -v0H -v0M -v0S "+%Y-%m-%dT%H:%M:%SZ"
140
+ else
141
+ # GNU date
142
+ date -u -d "$(date +%Y-%m-%d) 00:00:00" "+%Y-%m-%dT%H:%M:%SZ"
143
+ fi
144
+ }
145
+
146
+ today_end() {
147
+ if date -v0H >/dev/null 2>&1; then
148
+ date -u -v23H -v59M -v59S "+%Y-%m-%dT%H:%M:%SZ"
149
+ else
150
+ date -u -d "$(date +%Y-%m-%d) 23:59:59" "+%Y-%m-%dT%H:%M:%SZ"
151
+ fi
152
+ }
153
+
154
+ days_from_now() {
155
+ local n="$1"
156
+ if date -v0H >/dev/null 2>&1; then
157
+ date -u -v+"${n}d" -v23H -v59M -v59S "+%Y-%m-%dT%H:%M:%SZ"
158
+ else
159
+ date -u -d "+${n} days 23:59:59" "+%Y-%m-%dT%H:%M:%SZ"
160
+ fi
161
+ }
162
+
163
+ week_end() {
164
+ days_from_now 7
165
+ }
166
+
167
+ # --- Format helpers ---
168
+ format_event() {
169
+ jq -r '
170
+ def fmt_time:
171
+ if .dateTime then (.dateTime | split("T") | .[1] | split("+")[0] | split("-")[0] | .[0:5])
172
+ elif .date then "all-day"
173
+ else "?"
174
+ end;
175
+
176
+ " \(.start | fmt_time) — \(.end | fmt_time) \(.summary // "(no title)")" +
177
+ (if .location then "\n 📍 \(.location)" else "" end) +
178
+ (if .description then "\n 📝 \(.description | .[0:100])" else "" end) +
179
+ "\n 🔑 \(.id)"
180
+ '
181
+ }
182
+
183
+ format_events_list() {
184
+ jq -r '
185
+ def fmt_time:
186
+ if .dateTime then (.dateTime | split("T") | .[1] | split("+")[0] | split("-")[0] | .[0:5])
187
+ elif .date then "all-day"
188
+ else "?"
189
+ end;
190
+
191
+ if (.items // []) | length == 0 then
192
+ "No events found."
193
+ else
194
+ (.items[] |
195
+ " \(.start | fmt_time) — \(.end | fmt_time) \(.summary // "(no title)")" +
196
+ (if .location then " 📍 \(.location)" else "" end) +
197
+ " [\(.id)]"
198
+ )
199
+ end
200
+ '
201
+ }
202
+
203
+ # --- Commands ---
204
+
205
+ cmd_calendars() {
206
+ api_get "/users/me/calendarList" | jq -r '
207
+ .items[] |
208
+ " \(.summary)\t(\(.id))" +
209
+ (if .primary then " ⭐" else "" end)
210
+ '
211
+ }
212
+
213
+ cmd_list() {
214
+ local max=10
215
+ local cal="primary"
216
+
217
+ while [[ $# -gt 0 ]]; do
218
+ case "$1" in
219
+ --max) max="$2"; shift 2 ;;
220
+ --cal) cal="$2"; shift 2 ;;
221
+ *) shift ;;
222
+ esac
223
+ done
224
+
225
+ local time_min time_max
226
+ time_min=$(today_start)
227
+ time_max=$(today_end)
228
+
229
+ local encoded_min encoded_max
230
+ encoded_min=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$time_min'))")
231
+ encoded_max=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$time_max'))")
232
+
233
+ api_get "/calendars/${cal}/events?timeMin=${encoded_min}&timeMax=${encoded_max}&maxResults=${max}&singleEvents=true&orderBy=startTime" \
234
+ | format_events_list
235
+ }
236
+
237
+ cmd_today() {
238
+ cmd_list "$@"
239
+ }
240
+
241
+ cmd_upcoming() {
242
+ local max=10
243
+ local days=7
244
+ local cal="primary"
245
+
246
+ while [[ $# -gt 0 ]]; do
247
+ case "$1" in
248
+ --max) max="$2"; shift 2 ;;
249
+ --days) days="$2"; shift 2 ;;
250
+ --cal) cal="$2"; shift 2 ;;
251
+ *) shift ;;
252
+ esac
253
+ done
254
+
255
+ local time_min time_max
256
+ time_min=$(today_start)
257
+ time_max=$(days_from_now "$days")
258
+
259
+ local encoded_min encoded_max
260
+ encoded_min=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$time_min'))")
261
+ encoded_max=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$time_max'))")
262
+
263
+ api_get "/calendars/${cal}/events?timeMin=${encoded_min}&timeMax=${encoded_max}&maxResults=${max}&singleEvents=true&orderBy=startTime" \
264
+ | format_events_list
265
+ }
266
+
267
+ cmd_week() {
268
+ cmd_upcoming --days 7 "$@"
269
+ }
270
+
271
+ cmd_search() {
272
+ local query="${1:-}"
273
+ shift || true
274
+
275
+ if [[ -z "$query" ]]; then
276
+ echo "ERROR: Search query required" >&2
277
+ echo "Usage: calendar.sh search \"query\" [--max N]" >&2
278
+ exit 1
279
+ fi
280
+
281
+ local max=10
282
+ local cal="primary"
283
+
284
+ while [[ $# -gt 0 ]]; do
285
+ case "$1" in
286
+ --max) max="$2"; shift 2 ;;
287
+ --cal) cal="$2"; shift 2 ;;
288
+ *) shift ;;
289
+ esac
290
+ done
291
+
292
+ local encoded_query
293
+ encoded_query=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$query'))")
294
+
295
+ api_get "/calendars/${cal}/events?q=${encoded_query}&maxResults=${max}&singleEvents=true&orderBy=startTime" \
296
+ | format_events_list
297
+ }
298
+
299
+ cmd_get() {
300
+ local event_id="${1:-}"
301
+ shift || true
302
+
303
+ if [[ -z "$event_id" ]]; then
304
+ echo "ERROR: Event ID required" >&2
305
+ exit 1
306
+ fi
307
+
308
+ local cal="primary"
309
+ while [[ $# -gt 0 ]]; do
310
+ case "$1" in
311
+ --cal) cal="$2"; shift 2 ;;
312
+ *) shift ;;
313
+ esac
314
+ done
315
+
316
+ api_get "/calendars/${cal}/events/${event_id}" | format_event
317
+ }
318
+
319
+ cmd_create() {
320
+ local summary="" start="" end="" location="" description="" cal="primary"
321
+ local all_day=false
322
+
323
+ while [[ $# -gt 0 ]]; do
324
+ case "$1" in
325
+ --summary) summary="$2"; shift 2 ;;
326
+ --start) start="$2"; shift 2 ;;
327
+ --end) end="$2"; shift 2 ;;
328
+ --location) location="$2"; shift 2 ;;
329
+ --description) description="$2"; shift 2 ;;
330
+ --cal) cal="$2"; shift 2 ;;
331
+ --all-day) all_day=true; shift ;;
332
+ *) shift ;;
333
+ esac
334
+ done
335
+
336
+ if [[ -z "$summary" ]]; then
337
+ echo "ERROR: --summary is required" >&2
338
+ exit 1
339
+ fi
340
+ if [[ -z "$start" ]]; then
341
+ echo "ERROR: --start is required (ISO 8601 datetime or YYYY-MM-DD for all-day)" >&2
342
+ exit 1
343
+ fi
344
+
345
+ # Build event JSON
346
+ local event_json
347
+ if [[ "$all_day" == true ]]; then
348
+ # All-day event: use date format
349
+ local end_date="${end:-$start}"
350
+ event_json=$(jq -n \
351
+ --arg summary "$summary" \
352
+ --arg start "$start" \
353
+ --arg e "$end_date" \
354
+ '{summary: $summary, start: {date: $start}, "end": {date: $e}}')
355
+ else
356
+ # Timed event: use dateTime
357
+ if [[ -z "$end" ]]; then
358
+ # Default: 1 hour after start
359
+ if date -v0H >/dev/null 2>&1; then
360
+ end=$(date -j -f "%Y-%m-%dT%H:%M:%S" "${start%%[+-]*}" -v+1H "+%Y-%m-%dT%H:%M:%S${start##*[0-9]}" 2>/dev/null || echo "$start")
361
+ else
362
+ end=$(date -d "${start} + 1 hour" --iso-8601=seconds 2>/dev/null || echo "$start")
363
+ fi
364
+ fi
365
+ event_json=$(jq -n \
366
+ --arg summary "$summary" \
367
+ --arg start "$start" \
368
+ --arg e "$end" \
369
+ '{summary: $summary, start: {dateTime: $start}, "end": {dateTime: $e}}')
370
+ fi
371
+
372
+ # Add optional fields
373
+ if [[ -n "$location" ]]; then
374
+ event_json=$(echo "$event_json" | jq --arg loc "$location" '. + {location: $loc}')
375
+ fi
376
+ if [[ -n "$description" ]]; then
377
+ event_json=$(echo "$event_json" | jq --arg desc "$description" '. + {description: $desc}')
378
+ fi
379
+
380
+ local result
381
+ result=$(api_post "/calendars/${cal}/events" "$event_json")
382
+
383
+ local created_id
384
+ created_id=$(echo "$result" | jq -r '.id // empty')
385
+ if [[ -n "$created_id" ]]; then
386
+ echo "Event created: $created_id"
387
+ echo "$result" | format_event
388
+ else
389
+ echo "ERROR: Failed to create event" >&2
390
+ echo "$result" >&2
391
+ exit 1
392
+ fi
393
+ }
394
+
395
+ cmd_update() {
396
+ local event_id="${1:-}"
397
+ shift || true
398
+
399
+ if [[ -z "$event_id" ]]; then
400
+ echo "ERROR: Event ID required" >&2
401
+ exit 1
402
+ fi
403
+
404
+ local summary="" start="" end="" location="" description="" cal="primary"
405
+
406
+ while [[ $# -gt 0 ]]; do
407
+ case "$1" in
408
+ --summary) summary="$2"; shift 2 ;;
409
+ --start) start="$2"; shift 2 ;;
410
+ --end) end="$2"; shift 2 ;;
411
+ --location) location="$2"; shift 2 ;;
412
+ --description) description="$2"; shift 2 ;;
413
+ --cal) cal="$2"; shift 2 ;;
414
+ *) shift ;;
415
+ esac
416
+ done
417
+
418
+ # Build patch JSON with only provided fields
419
+ local patch_json="{}"
420
+ if [[ -n "$summary" ]]; then
421
+ patch_json=$(echo "$patch_json" | jq --arg v "$summary" '. + {summary: $v}')
422
+ fi
423
+ if [[ -n "$start" ]]; then
424
+ patch_json=$(echo "$patch_json" | jq --arg v "$start" '. + {start: {dateTime: $v}}')
425
+ fi
426
+ if [[ -n "$end" ]]; then
427
+ patch_json=$(echo "$patch_json" | jq --arg v "$end" '. + {end: {dateTime: $v}}')
428
+ fi
429
+ if [[ -n "$location" ]]; then
430
+ patch_json=$(echo "$patch_json" | jq --arg v "$location" '. + {location: $v}')
431
+ fi
432
+ if [[ -n "$description" ]]; then
433
+ patch_json=$(echo "$patch_json" | jq --arg v "$description" '. + {description: $v}')
434
+ fi
435
+
436
+ if [[ "$patch_json" == "{}" ]]; then
437
+ echo "ERROR: No fields to update. Use --summary, --start, --end, --location, --description" >&2
438
+ exit 1
439
+ fi
440
+
441
+ local result
442
+ result=$(api_patch "/calendars/${cal}/events/${event_id}" "$patch_json")
443
+
444
+ local updated_id
445
+ updated_id=$(echo "$result" | jq -r '.id // empty')
446
+ if [[ -n "$updated_id" ]]; then
447
+ echo "Event updated: $updated_id"
448
+ echo "$result" | format_event
449
+ else
450
+ echo "ERROR: Failed to update event" >&2
451
+ echo "$result" >&2
452
+ exit 1
453
+ fi
454
+ }
455
+
456
+ cmd_delete() {
457
+ local event_id="${1:-}"
458
+ shift || true
459
+
460
+ if [[ -z "$event_id" ]]; then
461
+ echo "ERROR: Event ID required" >&2
462
+ exit 1
463
+ fi
464
+
465
+ local cal="primary"
466
+ while [[ $# -gt 0 ]]; do
467
+ case "$1" in
468
+ --cal) cal="$2"; shift 2 ;;
469
+ *) shift ;;
470
+ esac
471
+ done
472
+
473
+ api_delete "/calendars/${cal}/events/${event_id}"
474
+ echo "Event deleted: $event_id"
475
+ }
476
+
477
+ # --- Dispatch ---
478
+ COMMAND="${1:-}"
479
+ shift || true
480
+
481
+ case "$COMMAND" in
482
+ list) cmd_list "$@" ;;
483
+ today) cmd_today "$@" ;;
484
+ upcoming) cmd_upcoming "$@" ;;
485
+ week) cmd_week "$@" ;;
486
+ search) cmd_search "$@" ;;
487
+ get) cmd_get "$@" ;;
488
+ create) cmd_create "$@" ;;
489
+ update) cmd_update "$@" ;;
490
+ delete) cmd_delete "$@" ;;
491
+ calendars) cmd_calendars "$@" ;;
492
+ *)
493
+ echo "Usage: calendar.sh <command> [options]" >&2
494
+ echo "" >&2
495
+ echo "Commands:" >&2
496
+ echo " list [--max N] [--cal ID] Today's events" >&2
497
+ echo " today [--cal ID] Alias for list" >&2
498
+ echo " upcoming [--days N] [--max N] [--cal ID] Upcoming events" >&2
499
+ echo " week [--cal ID] This week's events" >&2
500
+ echo " search \"query\" [--max N] [--cal ID] Search events" >&2
501
+ echo " get <eventId> [--cal ID] Event details" >&2
502
+ echo " create --summary T --start ISO [--end ISO] Create event" >&2
503
+ echo " update <eventId> [--summary T] [--start ISO] Update event" >&2
504
+ echo " delete <eventId> [--cal ID] Delete event" >&2
505
+ echo " calendars List calendars" >&2
506
+ exit 1
507
+ ;;
508
+ esac