@indigoai-us/hq-cli 5.345.114 → 5.345.115

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 (54) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/assets/scaffold/core/scripts/hq-delegate-send.sh +5 -1
  3. package/dist/commands/bot-jobs.d.ts +1 -11
  4. package/dist/commands/bot-jobs.js +13 -34
  5. package/dist/commands/core-audit-log-native.js +1 -1
  6. package/dist/commands/core-checkpoint-native.d.ts +27 -0
  7. package/dist/commands/core-checkpoint-native.js +85 -2
  8. package/dist/commands/core-dm-bind-native.js +1 -1
  9. package/dist/commands/core-git-pack-extension-check-native.js +1 -1
  10. package/dist/commands/core-job-native-utils.d.ts +2 -2
  11. package/dist/commands/core-job-native-utils.js +3 -11
  12. package/dist/commands/core-job-notify-native.js +1 -2
  13. package/dist/commands/core-job-probe-native.d.ts +2 -3
  14. package/dist/commands/core-job-probe-native.js +14 -22
  15. package/dist/commands/core-job-remediate-native.js +1 -2
  16. package/dist/commands/core-job-run-native.js +58 -54
  17. package/dist/commands/core-jobs-native.d.ts +1 -3
  18. package/dist/commands/core-jobs-native.js +16 -271
  19. package/dist/commands/core-jobs-schedule.d.ts +7 -0
  20. package/dist/commands/core-jobs-schedule.js +243 -0
  21. package/dist/commands/core-native-utilities.d.ts +2 -3
  22. package/dist/commands/core-native-utilities.js +2 -19
  23. package/dist/commands/core-pin-native.js +1 -1
  24. package/dist/commands/core-refresh-vault-access-native.js +1 -1
  25. package/dist/commands/core-resolve-company-command.js +2 -17
  26. package/dist/commands/core-work-mesh-bind-trusted-native.js +1 -1
  27. package/dist/commands/core.js +1 -17
  28. package/dist/fast-scaffold.d.ts +1 -1
  29. package/dist/fast-scaffold.js +0 -38
  30. package/dist/lib/daemon/catalog.d.ts +0 -2
  31. package/dist/lib/daemon/catalog.js +3 -6
  32. package/dist/lib/daemon/run.js +0 -7
  33. package/dist/utils/resident-package-preload.js +2 -7
  34. package/package.json +1 -1
  35. package/assets/scaffold/core/scripts/audit-log.sh +0 -384
  36. package/assets/scaffold/core/scripts/git-pack-extension-check.sh +0 -164
  37. package/assets/scaffold/core/scripts/hq-dm-bind.sh +0 -590
  38. package/assets/scaffold/core/scripts/hq-job-notify.sh +0 -389
  39. package/assets/scaffold/core/scripts/hq-job-probe.sh +0 -865
  40. package/assets/scaffold/core/scripts/hq-job-remediate.sh +0 -359
  41. package/assets/scaffold/core/scripts/hq-job-run.sh +0 -1025
  42. package/assets/scaffold/core/scripts/hq-pin.sh +0 -118
  43. package/assets/scaffold/core/scripts/jobs-schedule-parse.sh +0 -310
  44. package/assets/scaffold/core/scripts/jobs-validate.sh +0 -482
  45. package/assets/scaffold/core/scripts/outpost-jobs-reconcile.sh +0 -836
  46. package/assets/scaffold/core/scripts/refresh-vault-access.sh +0 -188
  47. package/assets/scaffold/core/scripts/resolve-company.sh +0 -331
  48. package/assets/scaffold/core/scripts/work-mesh-live-bind-trusted.sh +0 -184
  49. package/dist/commands/core-job-post-exit-assets.d.ts +0 -8
  50. package/dist/commands/core-job-post-exit-assets.js +0 -37
  51. package/dist/commands/core-native-jobs-flag.d.ts +0 -4
  52. package/dist/commands/core-native-jobs-flag.js +0 -7
  53. package/dist/commands/core-native-utilities-flag.d.ts +0 -4
  54. package/dist/commands/core-native-utilities-flag.js +0 -7
@@ -1,118 +0,0 @@
1
- #!/usr/bin/env bash
2
- # hq-pin.sh — anchor the current session to one goal (the "pin").
3
- #
4
- # A pin is the message, goal, or target the session keeps working toward
5
- # across loops, wakeups, compactions, and hand-offs. It is stored per session
6
- # and re-read at every checkpoint so the session cannot drift.
7
- #
8
- # Usage:
9
- # core/scripts/hq-pin.sh set "<goal>" [--done "<criterion>"]... [--owner <name>] [--channel <dm-channel>]
10
- # core/scripts/hq-pin.sh show # print the pin (goal, done criteria, owner, channel, set-at)
11
- # core/scripts/hq-pin.sh check # print a one-line reminder for loop ticks; exit 3 if no pin
12
- # core/scripts/hq-pin.sh note "<progress>" # append a dated progress line under the pin
13
- # core/scripts/hq-pin.sh clear # remove the pin (the goal is met or withdrawn)
14
- #
15
- # Storage: workspace/sessions/<sid>/pin.md plus `pin: <goal>` in the session's
16
- # meta.yaml (via hq-session.sh) so other tooling can see it.
17
- set -euo pipefail
18
-
19
- HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
20
- SESSION_SH="$HQ_ROOT/core/scripts/hq-session.sh"
21
-
22
- die() { echo "hq-pin: $*" >&2; exit 2; }
23
-
24
- session_id() { bash "$SESSION_SH" current 2>/dev/null || true; }
25
- pin_file() {
26
- local sid; sid="$(session_id)"
27
- [ -n "$sid" ] || die "no current session (hq-session.sh current is empty)"
28
- local d="$HQ_ROOT/workspace/sessions/$sid"; mkdir -p "$d"; echo "$d/pin.md"
29
- }
30
-
31
- cmd_set() {
32
- local goal="${1:-}"; [ -n "$goal" ] || die "set needs the goal text"; shift
33
- local owner="" channel=""; local -a done=()
34
- while [ $# -gt 0 ]; do
35
- case "$1" in
36
- --done) done+=("$2"); shift 2 ;;
37
- --owner) owner="$2"; shift 2 ;;
38
- --channel) channel="$2"; shift 2 ;;
39
- *) die "set: unknown arg $1" ;;
40
- esac
41
- done
42
- local f; f="$(pin_file)"
43
- {
44
- echo "# Pin"
45
- echo
46
- echo "Goal: $goal"
47
- echo
48
- echo "Set: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
49
- [ -n "$owner" ] && echo "Owner: $owner"
50
- [ -n "$channel" ] && echo "Channel: $channel"
51
- if [ ${#done[@]} -gt 0 ]; then
52
- echo
53
- echo "## Done when"
54
- for c in "${done[@]}"; do echo "- [ ] $c"; done
55
- fi
56
- echo
57
- echo "## Progress"
58
- } > "$f"
59
- bash "$SESSION_SH" set pin "$goal" >/dev/null
60
- echo "pinned session $(session_id): $goal"
61
- }
62
-
63
- cmd_show() {
64
- local f; f="$(pin_file)"
65
- [ -f "$f" ] || { echo "no pin for session $(session_id)"; return 3; }
66
- cat "$f"
67
- }
68
-
69
- cmd_check() {
70
- local f; f="$(pin_file)"
71
- [ -f "$f" ] || { echo "no pin"; return 3; }
72
- local goal; goal="$(sed -n 's/^Goal: //p' "$f" | head -1)"
73
- local open; open="$(grep -c '^- \[ \]' "$f" 2>/dev/null || true)"
74
- local closed; closed="$(grep -c '^- \[x\]' "$f" 2>/dev/null || true)"
75
- echo "PIN: $goal (done criteria: ${closed:-0} met, ${open:-0} open)"
76
- }
77
-
78
- cmd_note() {
79
- local text="${1:-}"; [ -n "$text" ] || die "note needs text"
80
- local f; f="$(pin_file)"
81
- [ -f "$f" ] || die "no pin to note against"
82
- printf -- '- %s %s\n' "$(date -u +%H:%MZ)" "$text" >> "$f"
83
- echo "noted"
84
- }
85
-
86
- cmd_done() {
87
- # Mark a done-criterion met by substring match.
88
- local needle="${1:-}"; [ -n "$needle" ] || die "done needs a criterion substring"
89
- local f; f="$(pin_file)"
90
- [ -f "$f" ] || die "no pin"
91
- local tmp; tmp="$(mktemp)"
92
- local hit=0
93
- while IFS= read -r line; do
94
- case "$line" in
95
- "- [ ] "*"$needle"*) echo "- [x] ${line#- [ ] }"; hit=1 ;;
96
- *) echo "$line" ;;
97
- esac
98
- done < "$f" > "$tmp"
99
- mv "$tmp" "$f"
100
- [ "$hit" = 1 ] && echo "marked done: $needle" || die "no open criterion matches: $needle"
101
- }
102
-
103
- cmd_clear() {
104
- local f; f="$(pin_file)"
105
- rm -f "$f"
106
- bash "$SESSION_SH" set pin "" >/dev/null
107
- echo "pin cleared"
108
- }
109
-
110
- case "${1:-}" in
111
- set) shift; cmd_set "$@" ;;
112
- show) cmd_show ;;
113
- check) cmd_check ;;
114
- note) shift; cmd_note "$@" ;;
115
- done) shift; cmd_done "$@" ;;
116
- clear) cmd_clear ;;
117
- *) sed -n '2,15p' "$0"; exit 2 ;;
118
- esac
@@ -1,310 +0,0 @@
1
- #!/usr/bin/env bash
2
- # hq-core: public
3
- # jobs-schedule-parse.sh — resolve natural-language (or raw cron) schedules for /schedule.
4
- #
5
- # Usage:
6
- # core/scripts/jobs-schedule-parse.sh [--tz IANA] [--json] "<schedule text>"
7
- #
8
- # Prints one JSON object on stdout:
9
- # {"ok":true,"cron":"0 9 * * 1-5","timezone":"America/Los_Angeles",
10
- # "human":"Every weekday at 9:00 AM (America/Los_Angeles)","source":"nl"|"cron"}
11
- # {"ok":false,"error":"..."}
12
- #
13
- # Cron is always the canonical 5-field form. NL is never echoed back as storage.
14
- # Timezone defaults to the host IANA zone (macOS /etc/localtime, $TZ, or UTC).
15
- #
16
- # Requires: node. Optional: jq (not required for parse).
17
-
18
- set -euo pipefail
19
-
20
- TZ_OVERRIDE=""
21
-
22
- usage() {
23
- echo "usage: jobs-schedule-parse.sh [--tz IANA] \"<nl or cron schedule>\"" >&2
24
- exit 2
25
- }
26
-
27
- while [ "$#" -gt 0 ]; do
28
- case "$1" in
29
- --tz)
30
- [ "$#" -ge 2 ] || usage
31
- TZ_OVERRIDE="$2"
32
- shift 2
33
- ;;
34
- --json)
35
- # JSON is the only output mode; flag kept for callers/docs symmetry
36
- shift
37
- ;;
38
- -h|--help)
39
- usage
40
- ;;
41
- --)
42
- shift
43
- break
44
- ;;
45
- -*)
46
- echo "jobs-schedule-parse: unknown flag: $1" >&2
47
- usage
48
- ;;
49
- *)
50
- break
51
- ;;
52
- esac
53
- done
54
-
55
- [ "$#" -ge 1 ] || usage
56
- SCHEDULE="$*"
57
- SCHEDULE="$(printf '%s' "$SCHEDULE" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
58
- [ -n "$SCHEDULE" ] || {
59
- printf '%s\n' '{"ok":false,"error":"empty schedule"}'
60
- exit 1
61
- }
62
-
63
- export JOBS_SCHEDULE_PARSE_INPUT="$SCHEDULE"
64
- export JOBS_SCHEDULE_PARSE_TZ="${TZ_OVERRIDE}"
65
-
66
- node <<'JS'
67
- const fs = require("fs");
68
- const path = require("path");
69
- const { execFileSync } = require("child_process");
70
-
71
- const inp = (process.env.JOBS_SCHEDULE_PARSE_INPUT || "").trim();
72
- const tzOverride = (process.env.JOBS_SCHEDULE_PARSE_TZ || "").trim();
73
-
74
- function fail(msg, code = 1) {
75
- process.stdout.write(JSON.stringify({ ok: false, error: msg }));
76
- process.stdout.write("\n");
77
- process.exit(code);
78
- }
79
-
80
- function detectTz() {
81
- if (tzOverride) return tzOverride;
82
- const envTz = (process.env.TZ || "").trim();
83
- if (envTz && envTz.includes("/")) return envTz;
84
- try {
85
- const link = fs.realpathSync("/etc/localtime");
86
- const parts = link.split(path.sep).filter(Boolean);
87
- const i = parts.indexOf("zoneinfo");
88
- if (i >= 0) {
89
- const cand = parts.slice(i + 1).join("/");
90
- if (cand) return cand;
91
- }
92
- } catch (_) {
93
- /* ignore */
94
- }
95
- try {
96
- const out = execFileSync(
97
- "timedatectl",
98
- ["show", "-p", "Timezone", "--value"],
99
- { encoding: "utf8", timeout: 2000, stdio: ["ignore", "pipe", "ignore"] }
100
- ).trim();
101
- if (out && out.includes("/")) return out;
102
- } catch (_) {
103
- /* ignore */
104
- }
105
- return "UTC";
106
- }
107
-
108
- function validateIana(tz) {
109
- const wellFormed = /^(UTC|[A-Za-z0-9_+\-]+(\/[A-Za-z0-9_+\-]+)+)$/;
110
- if (!wellFormed.test(tz)) return false;
111
- try {
112
- Intl.DateTimeFormat(undefined, { timeZone: tz });
113
- return true;
114
- } catch (_) {
115
- // Intl may lack tzdata on some hosts — accept well-formed names
116
- return wellFormed.test(tz);
117
- }
118
- }
119
-
120
- const CRON_RE = /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/;
121
-
122
- const DOW_NAMES = {
123
- sun: 0,
124
- sunday: 0,
125
- mon: 1,
126
- monday: 1,
127
- tue: 2,
128
- tues: 2,
129
- tuesday: 2,
130
- wed: 3,
131
- wednesday: 3,
132
- thu: 4,
133
- thur: 4,
134
- thurs: 4,
135
- thursday: 4,
136
- fri: 5,
137
- friday: 5,
138
- sat: 6,
139
- saturday: 6,
140
- };
141
-
142
- const DOW_LABEL = {
143
- "0": "Sunday",
144
- "1": "Monday",
145
- "2": "Tuesday",
146
- "3": "Wednesday",
147
- "4": "Thursday",
148
- "5": "Friday",
149
- "6": "Saturday",
150
- "1-5": "weekday",
151
- "*": "day",
152
- };
153
-
154
- function parseClock(fragment) {
155
- const s = fragment.trim().toLowerCase().replace(/ /g, "");
156
- const m = /^(\d{1,2})(?::(\d{2}))?\s*(am|pm)?$/.exec(s);
157
- if (!m) return null;
158
- let hour = parseInt(m[1], 10);
159
- const minute = parseInt(m[2] || "0", 10);
160
- const ampm = m[3];
161
- if (minute > 59) return null;
162
- if (ampm) {
163
- if (hour < 1 || hour > 12) return null;
164
- if (ampm === "am") hour = hour === 12 ? 0 : hour;
165
- else hour = hour === 12 ? 12 : hour + 12;
166
- } else if (hour > 23) {
167
- return null;
168
- }
169
- return [hour, minute];
170
- }
171
-
172
- function fmtClock(hour, minute) {
173
- const suffix = hour < 12 ? "AM" : "PM";
174
- let h12 = hour % 12;
175
- if (h12 === 0) h12 = 12;
176
- return `${h12}:${String(minute).padStart(2, "0")} ${suffix}`;
177
- }
178
-
179
- function humanizeCron(cron, tz) {
180
- const parts = cron.split(/\s+/);
181
- if (parts.length !== 5) return `Cron \`${cron}\` (${tz})`;
182
- const [minute, hour, dom, month, dow] = parts;
183
- if (
184
- /^\d+$/.test(minute) &&
185
- /^\d+$/.test(hour) &&
186
- dom === "*" &&
187
- month === "*" &&
188
- (dow === "*" || dow === "1-5")
189
- ) {
190
- const clock = fmtClock(parseInt(hour, 10), parseInt(minute, 10));
191
- if (dow === "1-5") return `Every weekday at ${clock} (${tz})`;
192
- return `Every day at ${clock} (${tz})`;
193
- }
194
- if (
195
- /^\d+$/.test(minute) &&
196
- /^\d+$/.test(hour) &&
197
- dom === "*" &&
198
- month === "*" &&
199
- /^\d+$/.test(dow)
200
- ) {
201
- const day = DOW_LABEL[dow] || `day ${dow}`;
202
- return `Every ${day} at ${fmtClock(parseInt(hour, 10), parseInt(minute, 10))} (${tz})`;
203
- }
204
- if (minute.startsWith("*/") && hour === "*" && dom === "*" && month === "*" && dow === "*") {
205
- return `Every ${minute.slice(2)} minutes (${tz})`;
206
- }
207
- if (minute === "0" && hour.startsWith("*/") && dom === "*" && month === "*" && dow === "*") {
208
- return `Every ${hour.slice(2)} hours (${tz})`;
209
- }
210
- if (minute === "0" && hour === "*" && dom === "*" && month === "*" && dow === "*") {
211
- return `Every hour on the hour (${tz})`;
212
- }
213
- return `Cron \`${cron}\` (${tz})`;
214
- }
215
-
216
- function parseNl(text) {
217
- const s = text.trim();
218
- const low = s.toLowerCase();
219
- let m = /^every\s+(\d+)\s+minutes?$/.exec(low);
220
- if (m) {
221
- const n = parseInt(m[1], 10);
222
- if (n < 1 || n > 59) return [null, "minute interval must be 1..59"];
223
- return [`*/${n} * * * *`, `Every ${n} minutes`];
224
- }
225
- if (low === "every hour" || low === "hourly") {
226
- return ["0 * * * *", "Every hour on the hour"];
227
- }
228
- m = /^every\s+(\d+)\s+hours?$/.exec(low);
229
- if (m) {
230
- const n = parseInt(m[1], 10);
231
- if (n < 1 || n > 23) return [null, "hour interval must be 1..23"];
232
- return [`0 */${n} * * *`, `Every ${n} hours`];
233
- }
234
- m = /^(?:every\s+)?(weekday|weekdays|day|daily)\s+(?:at\s+)?(.+)$/.exec(low);
235
- if (m) {
236
- const kind = m[1];
237
- const clock = parseClock(m[2]);
238
- if (!clock) return [null, `could not parse time: ${m[2]}`];
239
- const [hour, minute] = clock;
240
- if (kind === "weekday" || kind === "weekdays") {
241
- return [`${minute} ${hour} * * 1-5`, `Every weekday at ${fmtClock(hour, minute)}`];
242
- }
243
- return [`${minute} ${hour} * * *`, `Every day at ${fmtClock(hour, minute)}`];
244
- }
245
- m =
246
- /^(?:every\s+)?(sun(?:day)?|mon(?:day)?|tue(?:s|sday)?|wed(?:nesday)?|thu(?:r|rs|rsday)?|fri(?:day)?|sat(?:urday)?)s?\s+(?:at\s+)?(.+)$/.exec(
247
- low
248
- );
249
- if (m) {
250
- const dow = DOW_NAMES[m[1]];
251
- const clock = parseClock(m[2]);
252
- if (!clock) return [null, `could not parse time: ${m[2]}`];
253
- const [hour, minute] = clock;
254
- return [
255
- `${minute} ${hour} * * ${dow}`,
256
- `Every ${DOW_LABEL[String(dow)]} at ${fmtClock(hour, minute)}`,
257
- ];
258
- }
259
- m = /^at\s+(.+?)\s+every\s+(weekday|weekdays|day|daily)$/.exec(low);
260
- if (m) {
261
- const clock = parseClock(m[1]);
262
- if (!clock) return [null, `could not parse time: ${m[1]}`];
263
- const [hour, minute] = clock;
264
- const kind = m[2];
265
- if (kind === "weekday" || kind === "weekdays") {
266
- return [`${minute} ${hour} * * 1-5`, `Every weekday at ${fmtClock(hour, minute)}`];
267
- }
268
- return [`${minute} ${hour} * * *`, `Every day at ${fmtClock(hour, minute)}`];
269
- }
270
- return [
271
- null,
272
- "unrecognized schedule — try 'every weekday at 9am', " +
273
- "'every day at 14:30', 'every monday at 9am', a 5-field cron, " +
274
- "or 'every 15 minutes'",
275
- ];
276
- }
277
-
278
- const tz = detectTz();
279
- if (!validateIana(tz)) fail(`invalid IANA timezone: ${tz}`);
280
-
281
- if (CRON_RE.test(inp) && !/[A-Za-z]/.test(inp)) {
282
- const cron = inp;
283
- const human = humanizeCron(cron, tz);
284
- process.stdout.write(
285
- JSON.stringify({ ok: true, cron, timezone: tz, human, source: "cron" })
286
- );
287
- process.stdout.write("\n");
288
- process.exit(0);
289
- }
290
-
291
- const named = /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(mon-fri|monday-friday)$/i.exec(inp);
292
- if (named) {
293
- const cron = `${named[1]} ${named[2]} ${named[3]} ${named[4]} 1-5`;
294
- const human = humanizeCron(cron, tz);
295
- process.stdout.write(
296
- JSON.stringify({ ok: true, cron, timezone: tz, human, source: "cron" })
297
- );
298
- process.stdout.write("\n");
299
- process.exit(0);
300
- }
301
-
302
- const [cron, humanOrErr] = parseNl(inp);
303
- if (cron == null) fail(humanOrErr);
304
-
305
- const human = `${humanOrErr} (${tz})`;
306
- process.stdout.write(
307
- JSON.stringify({ ok: true, cron, timezone: tz, human, source: "nl" })
308
- );
309
- process.stdout.write("\n");
310
- JS