@indigoai-us/hq-cli 5.275.0 → 5.277.0

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 (120) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +12 -0
  3. package/assets/bot-workers/setup/context/USER-GUIDE.md +4 -4
  4. package/assets/scaffold/core/scripts/hq-delegate-pickup.sh +99 -0
  5. package/assets/scaffold/core/scripts/hq-delegate-repo.sh +158 -0
  6. package/assets/scaffold/core/scripts/hq-delegate-resolve.sh +145 -0
  7. package/assets/scaffold/core/scripts/hq-delegate-secrets.sh +129 -0
  8. package/assets/scaffold/core/scripts/hq-delegate-transfer.sh +175 -0
  9. package/assets/scaffold/core/scripts/lib/secret-patterns.sh +58 -0
  10. package/dist/command-catalog.generated.d.ts +239 -1
  11. package/dist/command-catalog.generated.js +302 -1
  12. package/dist/commands/core-checkpoint.d.ts +4 -2
  13. package/dist/commands/core-checkpoint.js +34 -3
  14. package/dist/commands/core-command-catalog.d.ts +4 -2
  15. package/dist/commands/core-command-catalog.js +5 -2
  16. package/dist/commands/core-delegate.d.ts +6 -0
  17. package/dist/commands/core-delegate.js +987 -0
  18. package/dist/commands/core-ontology.js +3 -3
  19. package/dist/commands/core.js +11 -1
  20. package/dist/commands/daemon.d.ts +4 -0
  21. package/dist/commands/daemon.js +175 -2
  22. package/dist/commands/dm.d.ts +2 -0
  23. package/dist/commands/dm.js +11 -4
  24. package/dist/commands/feedback.d.ts +6 -0
  25. package/dist/commands/feedback.js +86 -37
  26. package/dist/commands/lanes-accounts.js +44 -2
  27. package/dist/commands/lanes-message.js +69 -12
  28. package/dist/commands/lanes-resume.js +2 -0
  29. package/dist/commands/lanes-shared.d.ts +3 -0
  30. package/dist/commands/lanes-shared.js +12 -2
  31. package/dist/commands/lanes.d.ts +5 -1
  32. package/dist/commands/lanes.js +402 -49
  33. package/dist/commands/run-feature-telemetry.d.ts +3 -0
  34. package/dist/commands/run-feature-telemetry.js +6 -0
  35. package/dist/commands/run.js +3 -2
  36. package/dist/commands/secrets.d.ts +16 -1
  37. package/dist/commands/secrets.js +80 -45
  38. package/dist/commands/sync-mode.d.ts +11 -0
  39. package/dist/commands/sync-mode.js +30 -0
  40. package/dist/commands/whoami.d.ts +4 -6
  41. package/dist/commands/whoami.js +39 -8
  42. package/dist/fast-core.d.ts +6 -7
  43. package/dist/fast-core.js +22 -8
  44. package/dist/fast-scaffold.d.ts +33 -7
  45. package/dist/fast-scaffold.js +104 -8
  46. package/dist/index.js +32 -1
  47. package/dist/lanes-drain-hook.js +154 -7
  48. package/dist/lib/agent-kit/run/inbox.js +3 -2
  49. package/dist/lib/billing/plan-lock.d.ts +3 -1
  50. package/dist/lib/billing/plan-lock.js +7 -1
  51. package/dist/lib/checkpoint-ontology/apply.d.ts +6 -0
  52. package/dist/lib/checkpoint-ontology/apply.js +60 -3
  53. package/dist/lib/checkpoint-ontology/company.d.ts +8 -4
  54. package/dist/lib/checkpoint-ontology/company.js +15 -7
  55. package/dist/lib/checkpoint-ontology/plan.d.ts +36 -0
  56. package/dist/lib/checkpoint-ontology/plan.js +66 -4
  57. package/dist/lib/checkpoint-ontology/queued-touches.d.ts +32 -0
  58. package/dist/lib/checkpoint-ontology/queued-touches.js +193 -0
  59. package/dist/lib/checkpoint-ontology/tree.d.ts +2 -0
  60. package/dist/lib/checkpoint-ontology/tree.js +34 -0
  61. package/dist/lib/core-utils/jq-json-serializer.d.ts +5 -0
  62. package/dist/lib/core-utils/jq-json-serializer.js +10 -0
  63. package/dist/lib/core-utils/secret-patterns.d.ts +41 -0
  64. package/dist/lib/core-utils/secret-patterns.js +33 -0
  65. package/dist/lib/core-utils/timeout-guard-native.d.ts +7 -0
  66. package/dist/lib/core-utils/timeout-guard-native.js +40 -0
  67. package/dist/lib/core-utils/timeout-guard.d.ts +3 -3
  68. package/dist/lib/core-utils/timeout-guard.js +28 -13
  69. package/dist/lib/daemon/catalog.d.ts +18 -2
  70. package/dist/lib/daemon/catalog.js +18 -2
  71. package/dist/lib/daemon/config.d.ts +6 -0
  72. package/dist/lib/daemon/config.js +15 -2
  73. package/dist/lib/daemon/requests.d.ts +4 -0
  74. package/dist/lib/daemon/requests.js +2 -0
  75. package/dist/lib/daemon/run.js +94 -8
  76. package/dist/lib/daemon/supervisor.d.ts +8 -0
  77. package/dist/lib/daemon/supervisor.js +101 -1
  78. package/dist/lib/daemon/sync-runner.d.ts +58 -0
  79. package/dist/lib/daemon/sync-runner.js +277 -0
  80. package/dist/lib/doctor/__testing__/run-doctor.d.ts +8 -0
  81. package/dist/lib/doctor/__testing__/run-doctor.js +52 -0
  82. package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
  83. package/dist/lib/flag-registry-worker-source.generated.js +1 -1
  84. package/dist/lib/flag-registry.d.ts +12 -7
  85. package/dist/lib/flag-registry.js +66 -75
  86. package/dist/lib/flag-snapshot-file.d.ts +20 -0
  87. package/dist/lib/flag-snapshot-file.js +91 -0
  88. package/dist/lib/lanes/claude-balance.d.ts +6 -1
  89. package/dist/lib/lanes/claude-balance.js +46 -8
  90. package/dist/lib/lanes/config.js +15 -0
  91. package/dist/lib/lanes/hire-grant-dispatch.d.ts +2 -0
  92. package/dist/lib/lanes/hire-grant-dispatch.js +41 -0
  93. package/dist/lib/lanes/index.d.ts +1 -1
  94. package/dist/lib/lanes/keep-alive.d.ts +3 -0
  95. package/dist/lib/lanes/keep-alive.js +3 -0
  96. package/dist/lib/lanes/outpost-dispatch.d.ts +4 -0
  97. package/dist/lib/lanes/outpost-dispatch.js +11 -2
  98. package/dist/lib/lanes/reconcile.js +20 -4
  99. package/dist/lib/lanes/spawn.js +17 -10
  100. package/dist/lib/lanes/store.js +45 -1
  101. package/dist/lib/lanes/types.d.ts +30 -1
  102. package/dist/lib/lanes/types.js +2 -2
  103. package/dist/lib/lanes/watcher.js +3 -2
  104. package/dist/lib/process-flag-company-context.d.ts +8 -0
  105. package/dist/lib/process-flag-company-context.js +67 -0
  106. package/dist/main.js +3 -1
  107. package/dist/native-fast-route.d.ts +3 -0
  108. package/dist/native-fast-route.js +39 -0
  109. package/dist/secrets-env-fast-path.d.ts +5 -0
  110. package/dist/secrets-env-fast-path.js +16 -0
  111. package/dist/secrets-env-fast-route.d.ts +18 -0
  112. package/dist/secrets-env-fast-route.js +54 -0
  113. package/dist/utils/cli-telemetry.d.ts +26 -2
  114. package/dist/utils/cli-telemetry.js +178 -3
  115. package/dist/utils/hq-root-resolver.d.ts +13 -0
  116. package/dist/utils/hq-root-resolver.js +103 -0
  117. package/dist/utils/scaffold-fast-import-guard.js +6 -1
  118. package/dist/utils/vault-api.d.ts +8 -0
  119. package/dist/utils/vault-api.js +13 -1
  120. package/package.json +2 -2
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env bash
2
+ # hq-core: public
3
+ # hq-delegate-secrets.sh — grant a delegation recipient access to the secrets
4
+ # a project needs, BY NAME ONLY. No command in this helper ever reads,
5
+ # prints, logs, or interpolates a secret value.
6
+ #
7
+ # Usage:
8
+ # core/scripts/hq-delegate-secrets.sh --manifest <path> [--yes] [--no-secrets]
9
+ # [--env-schema <path>]
10
+ #
11
+ # Behavior:
12
+ # - derives required secret NAMES from the project's / repo's .env.schema
13
+ # (--env-schema overrides discovery); no schema -> records secrets: []
14
+ # and says so plainly rather than guessing at credentials
15
+ # - without --yes: prints a full-prose confirmation listing every name and
16
+ # the principal, then exits 2 granting nothing — this step is a privilege
17
+ # handover and gets its own confirmation, separate from the file grants
18
+ # - with --yes: hq secrets share <NAME> --with <principal> --permission read
19
+ # per name, then records the names (and only the names) in the manifest
20
+ # - --no-secrets: skips everything, records {secrets: [], secretsSkipped: true}
21
+ #
22
+ # Consumption on the recipient's side is via `hq run` / `hq secrets exec` —
23
+ # documented in the brief; values never appear in any delegation artifact
24
+ # (policy hq-delegate-never-inlines-secrets-or-share-urls).
25
+ #
26
+ # Env: HQ_ROOT — HQ root override (default: resolved from script location)
27
+
28
+ set -euo pipefail
29
+
30
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
31
+ HQ_ROOT="${HQ_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
32
+
33
+ usage() { sed -n '3,24p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; }
34
+ die() { echo "hq-delegate-secrets: $*" >&2; exit 1; }
35
+
36
+ command -v jq >/dev/null 2>&1 || die "jq is required but not installed"
37
+
38
+ MANIFEST="" YES=0 NO_SECRETS=0 ENV_SCHEMA=""
39
+ while [ $# -gt 0 ]; do
40
+ case "$1" in
41
+ --manifest) MANIFEST="${2:-}"; shift 2 ;;
42
+ --yes) YES=1; shift ;;
43
+ --no-secrets) NO_SECRETS=1; shift ;;
44
+ --env-schema) ENV_SCHEMA="${2:-}"; shift 2 ;;
45
+ -h|--help) usage; exit 0 ;;
46
+ *) die "unknown argument: $1" ;;
47
+ esac
48
+ done
49
+
50
+ [ -n "$MANIFEST" ] || die "--manifest is required"
51
+ [ -f "$MANIFEST" ] || die "manifest not found: $MANIFEST"
52
+ jq -e . "$MANIFEST" >/dev/null 2>&1 || die "manifest is not valid JSON: $MANIFEST"
53
+
54
+ COMPANY="$(jq -r '.company // empty' "$MANIFEST")"
55
+ PRINCIPAL="$(jq -r '.to.principal // empty' "$MANIFEST")"
56
+ PROJECT="$(jq -r '.project.name // empty' "$MANIFEST")"
57
+ [ -n "$COMPANY" ] || die "manifest has no company"
58
+ [ -n "$PRINCIPAL" ] || die "manifest has no to.principal"
59
+
60
+ update_manifest() { # jq-filter
61
+ local tmp
62
+ tmp="$(mktemp)"
63
+ jq "$1" "$MANIFEST" > "$tmp" && mv "$tmp" "$MANIFEST"
64
+ }
65
+
66
+ # --- explicit skip ------------------------------------------------------------
67
+
68
+ if [ "$NO_SECRETS" -eq 1 ]; then
69
+ update_manifest '.secrets = [] | .secretsSkipped = true'
70
+ echo "hq-delegate-secrets: skipped (--no-secrets) — no credential access granted"
71
+ exit 0
72
+ fi
73
+
74
+ # --- discover the env schema --------------------------------------------------
75
+
76
+ if [ -z "$ENV_SCHEMA" ]; then
77
+ REPO_REL="$(jq -r '.repo.path // empty' "$MANIFEST")"
78
+ for candidate in \
79
+ "$HQ_ROOT/companies/$COMPANY/projects/$PROJECT/.env.schema" \
80
+ "${REPO_REL:+$HQ_ROOT/$REPO_REL/.env.schema}"; do
81
+ [ -n "$candidate" ] && [ -f "$candidate" ] && { ENV_SCHEMA="$candidate"; break; }
82
+ done
83
+ fi
84
+
85
+ if [ -z "$ENV_SCHEMA" ] || [ ! -f "$ENV_SCHEMA" ]; then
86
+ update_manifest '.secrets = [] | .secretsSkipped = false'
87
+ echo "hq-delegate-secrets: no .env.schema found for this project or its repo — no secret names to grant. If the project needs credentials, add an .env.schema and re-run, or grant them manually with 'hq secrets share'."
88
+ exit 0
89
+ fi
90
+
91
+ # --- parse names (KEY= lines; comments and blanks ignored) --------------------
92
+
93
+ NAMES="$(grep -E '^[A-Za-z_][A-Za-z0-9_]*=' "$ENV_SCHEMA" | cut -d= -f1 | sort -u)"
94
+ if [ -z "$NAMES" ]; then
95
+ update_manifest '.secrets = [] | .secretsSkipped = false'
96
+ echo "hq-delegate-secrets: $ENV_SCHEMA declares no secret names — nothing to grant"
97
+ exit 0
98
+ fi
99
+ NAME_COUNT="$(printf '%s\n' "$NAMES" | wc -l | tr -d ' ')"
100
+
101
+ # --- confirmation gate (full prose; separate from the file-grant confirm) ----
102
+
103
+ echo "Secret access handover — this grants the recipient the ability to use these credentials."
104
+ echo
105
+ echo "The following $NAME_COUNT secret name(s), declared by $(basename "$ENV_SCHEMA") for project '$PROJECT', will be shared with read permission to '$PRINCIPAL' in company '$COMPANY':"
106
+ echo
107
+ printf '%s\n' "$NAMES" | sed 's/^/ - /'
108
+ echo
109
+ echo "Only the names are granted and recorded; no secret value is read, printed, or transmitted by this step. The recipient consumes them through 'hq run' / 'hq secrets exec'."
110
+
111
+ if [ "$YES" -ne 1 ]; then
112
+ echo
113
+ echo "hq-delegate-secrets: confirmation required — re-run with --yes after the user approves (or --no-secrets to skip)" >&2
114
+ exit 2
115
+ fi
116
+
117
+ # --- grant each name (names only — never a value read) ------------------------
118
+
119
+ printf '%s\n' "$NAMES" | while IFS= read -r name; do
120
+ hq secrets share "$name" --with "$PRINCIPAL" --permission read --company "$COMPANY" \
121
+ || die "failed to grant '$name' to '$PRINCIPAL' — aborting; manifest not updated"
122
+ echo "hq-delegate-secrets: granted read on '$name' to '$PRINCIPAL'"
123
+ done
124
+
125
+ NAMES_JSON="$(printf '%s\n' "$NAMES" | jq -R . | jq -cs .)"
126
+ NOW="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
127
+ update_manifest ".secrets = $NAMES_JSON | .secretsSkipped = false | .secretsGrantedAt = \"$NOW\""
128
+
129
+ echo "hq-delegate-secrets: $NAME_COUNT secret name(s) granted and recorded (names only)"
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env bash
2
+ # hq-core: public
3
+ # hq-delegate-transfer.sh — make a delegation real everywhere HQ tracks
4
+ # ownership: board entry, PRD metadata, work mesh, and the project journal.
5
+ #
6
+ # Usage:
7
+ # core/scripts/hq-delegate-transfer.sh --manifest <path>
8
+ #
9
+ # Behavior (mode "transfer"; mode "share" skips every mutation):
10
+ # 1. companies/<co>/board.json — the project's entry gets owner=<recipient>
11
+ # and a bumped updated_at; created (once) if absent
12
+ # 2. prd.json metadata gains owner, delegatedFrom, delegatedAt
13
+ # 3. work-mesh: `done` event closes the delegator's in-progress thread and
14
+ # broadcasts the reassignment; silently skipped when the helper is
15
+ # unavailable (local/offline installs) — the transfer still succeeds
16
+ # 4. a dated "Delegated" stanza is appended to the project journal naming
17
+ # the recipient, delegation id, and transferred scope
18
+ #
19
+ # Idempotent: re-running updates owner/timestamps in place — never a
20
+ # duplicate board entry, never a duplicated journal stanza.
21
+ #
22
+ # The delegator's own vault access is untouched (granting the recipient
23
+ # write does not revoke anything).
24
+ #
25
+ # Env: HQ_ROOT — HQ root override (default: resolved from script location)
26
+
27
+ set -euo pipefail
28
+
29
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
30
+ HQ_ROOT="${HQ_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
31
+
32
+ usage() { sed -n '3,25p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; }
33
+ die() { echo "hq-delegate-transfer: $*" >&2; exit 1; }
34
+
35
+ command -v jq >/dev/null 2>&1 || die "jq is required but not installed"
36
+
37
+ MANIFEST=""
38
+ while [ $# -gt 0 ]; do
39
+ case "$1" in
40
+ --manifest) MANIFEST="${2:-}"; shift 2 ;;
41
+ -h|--help) usage; exit 0 ;;
42
+ *) die "unknown argument: $1" ;;
43
+ esac
44
+ done
45
+
46
+ [ -n "$MANIFEST" ] || die "--manifest is required"
47
+ [ -f "$MANIFEST" ] || die "manifest not found: $MANIFEST"
48
+ jq -e . "$MANIFEST" >/dev/null 2>&1 || die "manifest is not valid JSON: $MANIFEST"
49
+
50
+ MODE="$(jq -r '.mode // "transfer"' "$MANIFEST")"
51
+ COMPANY="$(jq -r '.company // empty' "$MANIFEST")"
52
+ PROJECT="$(jq -r '.project.name // empty' "$MANIFEST")"
53
+ PRINCIPAL="$(jq -r '.to.principal // empty' "$MANIFEST")"
54
+ DISPLAY="$(jq -r '.to.displayName // .to.principal // empty' "$MANIFEST")"
55
+ DELEGATION_ID="$(jq -r '.delegationId // empty' "$MANIFEST")"
56
+ FROM="$(jq -r '.from.email // .from.personUid // "unknown"' "$MANIFEST")"
57
+ [ -n "$COMPANY" ] || die "manifest has no company"
58
+ [ -n "$PROJECT" ] || die "manifest has no project.name"
59
+ [ -n "$PRINCIPAL" ] || die "manifest has no to.principal"
60
+
61
+ if [ "$MODE" = "share" ]; then
62
+ echo "hq-delegate-transfer: mode is 'share' — ownership stays with the delegator, nothing mutated"
63
+ exit 0
64
+ fi
65
+
66
+ jq -e '.status == "granted"' "$MANIFEST" >/dev/null || die "transfer requires confirmed grants (status granted)"
67
+ [ "$FROM" != "unknown" ] && [ -n "$FROM" ] || die "sender identity missing; rebuild the bundle"
68
+ NOW="$(jq -r '.ownershipTransferredAt // empty' "$MANIFEST")"
69
+ [ -n "$NOW" ] || NOW="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
70
+ TODAY="$(date -u +%Y-%m-%d)"
71
+ PRD_PATH="companies/$COMPANY/projects/$PROJECT/prd.json"
72
+ PRD_ABS="$HQ_ROOT/$PRD_PATH"
73
+ PROJECT_DIR="$HQ_ROOT/companies/$COMPANY/projects/$PROJECT"
74
+ BOARD="$HQ_ROOT/companies/$COMPANY/board.json"
75
+
76
+ [ -f "$PRD_ABS" ] || die "prd not found: $PRD_PATH"
77
+
78
+ # --- 1. board entry: update in place, create once if absent ------------------
79
+
80
+ if [ -f "$BOARD" ]; then
81
+ jq -e . "$BOARD" >/dev/null 2>&1 || die "board.json is not valid JSON: $BOARD"
82
+ else
83
+ echo '{"projects": []}' > "$BOARD"
84
+ fi
85
+
86
+ TITLE="$(jq -r '.name // empty' "$PRD_ABS")"
87
+ DESC="$(jq -r '.description // ""' "$PRD_ABS" | head -c 300)"
88
+
89
+ TMP_BOARD="$(mktemp)"
90
+ jq \
91
+ --arg prd "$PRD_PATH" \
92
+ --arg owner "$PRINCIPAL" \
93
+ --arg now "$NOW" \
94
+ --arg title "$TITLE" \
95
+ --arg desc "$DESC" \
96
+ --arg project "$PROJECT" \
97
+ '
98
+ if ([.projects // [] | .[] | select(.prd_path == $prd)] | length) > 0 then
99
+ .projects = [.projects[] |
100
+ if .prd_path == $prd then .owner = $owner | .updated_at = $now else . end]
101
+ else
102
+ .projects = (.projects // []) + [{
103
+ id: ("proj-" + $project),
104
+ title: $title,
105
+ description: $desc,
106
+ status: "in_progress",
107
+ owner: $owner,
108
+ prd_path: $prd,
109
+ created_at: $now,
110
+ updated_at: $now
111
+ }]
112
+ end
113
+ | .updated_at = $now
114
+ ' "$BOARD" > "$TMP_BOARD" && mv "$TMP_BOARD" "$BOARD"
115
+
116
+ # --- 2. prd metadata ----------------------------------------------------------
117
+
118
+ TMP_PRD="$(mktemp)"
119
+ jq \
120
+ --arg owner "$PRINCIPAL" \
121
+ --arg from "$FROM" \
122
+ --arg now "$NOW" \
123
+ '.metadata.owner = $owner
124
+ | .metadata.delegatedFrom = $from
125
+ | .metadata.delegatedAt = $now' \
126
+ "$PRD_ABS" > "$TMP_PRD" && mv "$TMP_PRD" "$PRD_ABS"
127
+
128
+ # --- 3. work mesh: close the delegator's thread, broadcast reassignment ------
129
+ # Silently tolerated when unavailable (local/offline installs no-op).
130
+
131
+ if command -v hq >/dev/null 2>&1; then
132
+ # `--session-id` is the CLI option (hq-cli 5.157+ rejects `--session` with
133
+ # "unknown option"); --company-slug/--project attribute the note to the
134
+ # delegated project.
135
+ hq mesh session note --enqueue --session-id "${HQ_SESSION_ID:-delegate}" --seq 1 \
136
+ --harness claude-code --adapter-version 1.0.0 \
137
+ --company-slug "$COMPANY" --project "$PROJECT" \
138
+ --summary "Delegated to $DISPLAY ($PRINCIPAL) — delegation $DELEGATION_ID; ownership transferred" \
139
+ || echo "hq-delegate-transfer: mesh note failed; authoritative mesh ownership remains unconfirmed" >&2
140
+ fi
141
+
142
+ # --- 4. journal: one dated stanza per delegation id --------------------------
143
+
144
+ JOURNAL_DIR="$PROJECT_DIR/journal"
145
+ JOURNAL_FILE="$JOURNAL_DIR/delegations.md"
146
+ mkdir -p "$JOURNAL_DIR"
147
+ if [ ! -f "$JOURNAL_FILE" ]; then
148
+ {
149
+ echo "# Delegation log — $PROJECT"
150
+ echo
151
+ echo "Ownership handoffs for this project, appended by /delegate."
152
+ } > "$JOURNAL_FILE"
153
+ fi
154
+
155
+ if ! grep -qF "$DELEGATION_ID" "$JOURNAL_FILE"; then
156
+ SCOPE="$(jq -r '[.vaultPrefixes // [] | .[] | .prefix] | join(", ")' "$MANIFEST")"
157
+ {
158
+ echo
159
+ echo "## $TODAY — Delegated to $DISPLAY"
160
+ echo
161
+ echo "- Delegation: \`$DELEGATION_ID\`"
162
+ echo "- From: $FROM"
163
+ echo "- To: $DISPLAY ($PRINCIPAL)"
164
+ echo "- Transferred scope: $SCOPE"
165
+ echo "- Local board and PRD ownership updated; Work Mesh ownership is unconfirmed. Existing delegator access is unchanged."
166
+ } >> "$JOURNAL_FILE"
167
+ fi
168
+
169
+ # --- record on the manifest ---------------------------------------------------
170
+
171
+ TMP_MANIFEST="$(mktemp)"
172
+ jq --arg now "$NOW" '.ownershipTransferredAt = $now | .workMeshOwnership = "unconfirmed"' "$MANIFEST" > "$TMP_MANIFEST" \
173
+ && mv "$TMP_MANIFEST" "$MANIFEST"
174
+
175
+ echo "hq-delegate-transfer: ownership of '$PROJECT' transferred to $DISPLAY ($PRINCIPAL) — local board, PRD, and journal updated; Work Mesh ownership unconfirmed"
@@ -0,0 +1,58 @@
1
+ # shellcheck shell=bash
2
+ # hq-core: public
3
+ # secret-patterns.sh — shared secret-detection patterns for hq-core shell scripts.
4
+ #
5
+ # SOURCED, never executed: . "$ROOT/core/scripts/lib/secret-patterns.sh"
6
+ # bash 3.2 safe; no associative arrays.
7
+ #
8
+ # Single source of truth for the secret-shaped patterns that generated
9
+ # artifacts (delegation manifests, briefs, pickup prompts, DM payloads) are
10
+ # scanned against before they are written to disk or transmitted. Mirrors the
11
+ # runtime PreToolUse hook at .claude/hooks/detect-secrets.sh — a regression
12
+ # test (core/scripts/tests/hq-delegate-bundle.test.sh) asserts this list stays
13
+ # a superset of the hook's, so the two cannot silently drift.
14
+ #
15
+ # Entries are "<extended-regex>:<human name>". The regex part may not contain
16
+ # a colon; the name may.
17
+ #
18
+ # Entries are the bare token patterns. SECRET_PATTERN_BOUNDARY below is
19
+ # prepended at match time -- keep them in this form so they stay comparable
20
+ # verbatim with the runtime hook's array (see the drift test named above).
21
+
22
+ # Left token boundary. Without it the sk- pattern matches mid-word and ordinary
23
+ # HQ filenames (a-ri|sk-..., hq-ta|sk-..., controller-di|sk-...) scan as
24
+ # credentials. Mirrors SECRET_BOUNDARY in .claude/hooks/detect-secrets.sh.
25
+ SECRET_PATTERN_BOUNDARY='(^|[^a-zA-Z0-9])'
26
+
27
+ SECRET_PATTERNS=(
28
+ "sk-[a-zA-Z0-9._-]{20,}:OpenAI/Stripe key"
29
+ "ghp_[a-zA-Z0-9]{36,}:GitHub PAT"
30
+ "AKIA[0-9A-Z]{16}:AWS access key"
31
+ "xox[bpsa]-[a-zA-Z0-9-]+:Slack token"
32
+ "Bearer [a-zA-Z0-9._-]{20,}:Bearer token"
33
+ "-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----:Private key"
34
+ "glpat-[a-zA-Z0-9_-]{20,}:GitLab PAT"
35
+ "gho_[a-zA-Z0-9]{36,}:GitHub OAuth token"
36
+ "github_pat_[a-zA-Z0-9_]{22,}:Fine-grained GitHub PAT"
37
+ "eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{10,}:JWT"
38
+ )
39
+
40
+ # hq_scan_secrets <file>...
41
+ # Scan files for secret-shaped content. Prints "pattern: <name> in <file>"
42
+ # to stderr for every hit (never the matched value itself) and returns 1 if
43
+ # anything matched, 0 when all files are clean. Missing files are skipped.
44
+ hq_scan_secrets() {
45
+ local hit=0 f entry pattern name
46
+ for f in "$@"; do
47
+ [ -f "$f" ] || continue
48
+ for entry in "${SECRET_PATTERNS[@]}"; do
49
+ pattern="${SECRET_PATTERN_BOUNDARY}${entry%%:*}"
50
+ name="${entry#*:}"
51
+ if grep -Eq -- "$pattern" "$f" 2>/dev/null; then
52
+ echo "secret-scan: pattern '$name' matched in $f" >&2
53
+ hit=1
54
+ fi
55
+ done
56
+ done
57
+ return "$hit"
58
+ }
@@ -5224,6 +5224,80 @@ export declare const COMMAND_CATALOG: readonly [{
5224
5224
  readonly description: "print the result as JSON";
5225
5225
  }];
5226
5226
  readonly subcommands: readonly [];
5227
+ }, {
5228
+ readonly name: "delegate";
5229
+ readonly description: "Delegation handover helpers";
5230
+ readonly aliases: readonly [];
5231
+ readonly hidden: false;
5232
+ readonly usage: "[options] [command]";
5233
+ readonly arguments: readonly [];
5234
+ readonly options: readonly [];
5235
+ readonly subcommands: readonly [{
5236
+ readonly name: "resolve";
5237
+ readonly description: "Resolve a delegation recipient to a confirmed principal";
5238
+ readonly aliases: readonly [];
5239
+ readonly hidden: false;
5240
+ readonly usage: "[args...]";
5241
+ readonly arguments: readonly [{
5242
+ readonly name: "args";
5243
+ readonly required: false;
5244
+ readonly variadic: true;
5245
+ }];
5246
+ readonly options: readonly [];
5247
+ readonly subcommands: readonly [];
5248
+ }, {
5249
+ readonly name: "pickup";
5250
+ readonly description: "Record or check evidence that a recipient picked up a delegation";
5251
+ readonly aliases: readonly [];
5252
+ readonly hidden: false;
5253
+ readonly usage: "[args...]";
5254
+ readonly arguments: readonly [{
5255
+ readonly name: "args";
5256
+ readonly required: false;
5257
+ readonly variadic: true;
5258
+ }];
5259
+ readonly options: readonly [];
5260
+ readonly subcommands: readonly [];
5261
+ }, {
5262
+ readonly name: "repo";
5263
+ readonly description: "Prepare and record repository handover state";
5264
+ readonly aliases: readonly [];
5265
+ readonly hidden: false;
5266
+ readonly usage: "[args...]";
5267
+ readonly arguments: readonly [{
5268
+ readonly name: "args";
5269
+ readonly required: false;
5270
+ readonly variadic: true;
5271
+ }];
5272
+ readonly options: readonly [];
5273
+ readonly subcommands: readonly [];
5274
+ }, {
5275
+ readonly name: "secrets";
5276
+ readonly description: "Grant a recipient access to declared secret names";
5277
+ readonly aliases: readonly [];
5278
+ readonly hidden: false;
5279
+ readonly usage: "[args...]";
5280
+ readonly arguments: readonly [{
5281
+ readonly name: "args";
5282
+ readonly required: false;
5283
+ readonly variadic: true;
5284
+ }];
5285
+ readonly options: readonly [];
5286
+ readonly subcommands: readonly [];
5287
+ }, {
5288
+ readonly name: "transfer";
5289
+ readonly description: "Transfer local project ownership to a delegation recipient";
5290
+ readonly aliases: readonly [];
5291
+ readonly hidden: false;
5292
+ readonly usage: "[args...]";
5293
+ readonly arguments: readonly [{
5294
+ readonly name: "args";
5295
+ readonly required: false;
5296
+ readonly variadic: true;
5297
+ }];
5298
+ readonly options: readonly [];
5299
+ readonly subcommands: readonly [];
5300
+ }];
5227
5301
  }, {
5228
5302
  readonly name: "generate-workers-registry";
5229
5303
  readonly description: "Regenerate the derived workers registry";
@@ -7447,6 +7521,31 @@ export declare const COMMAND_CATALOG: readonly [{
7447
7521
  readonly description: "Emit JSON on stdout (default)";
7448
7522
  }];
7449
7523
  readonly subcommands: readonly [];
7524
+ }, {
7525
+ readonly name: "set";
7526
+ readonly description: "Change the model or effort a lane uses from its next resume";
7527
+ readonly aliases: readonly [];
7528
+ readonly hidden: false;
7529
+ readonly usage: "[options] <lane-id>";
7530
+ readonly arguments: readonly [{
7531
+ readonly name: "lane-id";
7532
+ readonly required: true;
7533
+ readonly variadic: false;
7534
+ }];
7535
+ readonly options: readonly [{
7536
+ readonly flags: "--model <model>";
7537
+ readonly description: "Model for the lane's next and later turns";
7538
+ }, {
7539
+ readonly flags: "--effort <level>";
7540
+ readonly description: "Effort for the lane's next and later turns";
7541
+ }, {
7542
+ readonly flags: "--reason <text>";
7543
+ readonly description: "Why the settings changed; recorded in settings_history";
7544
+ }, {
7545
+ readonly flags: "--json";
7546
+ readonly description: "Emit JSON on stdout (default)";
7547
+ }];
7548
+ readonly subcommands: readonly [];
7450
7549
  }, {
7451
7550
  readonly name: "grant";
7452
7551
  readonly description: "Set a lane's alive child-lane grant as its senior";
@@ -7509,6 +7608,12 @@ export declare const COMMAND_CATALOG: readonly [{
7509
7608
  }, {
7510
7609
  readonly flags: "--senior <ref>";
7511
7610
  readonly description: "Filter by senior ref";
7611
+ }, {
7612
+ readonly flags: "--lane <id>";
7613
+ readonly description: "Filter by lane id (repeatable)";
7614
+ }, {
7615
+ readonly flags: "--active";
7616
+ readonly description: "Include only lanes that are not terminal";
7512
7617
  }, {
7513
7618
  readonly flags: "--json";
7514
7619
  readonly description: "Emit JSON on stdout (default)";
@@ -8062,7 +8167,7 @@ export declare const COMMAND_CATALOG: readonly [{
8062
8167
  readonly subcommands: readonly [];
8063
8168
  }, {
8064
8169
  readonly name: "stop";
8065
- readonly description: "Cancel a queued lane or kill a running one";
8170
+ readonly description: "Cancel a queued lane or kill a running one (terminal; use interrupt to keep it resumable)";
8066
8171
  readonly aliases: readonly [];
8067
8172
  readonly hidden: false;
8068
8173
  readonly usage: "[options] <lane-id>";
@@ -8079,6 +8184,25 @@ export declare const COMMAND_CATALOG: readonly [{
8079
8184
  readonly description: "JSON on stdout (always)";
8080
8185
  }];
8081
8186
  readonly subcommands: readonly [];
8187
+ }, {
8188
+ readonly name: "interrupt";
8189
+ readonly description: "Stop a running lane's turn and keep it resumable with hq lanes resume";
8190
+ readonly aliases: readonly [];
8191
+ readonly hidden: false;
8192
+ readonly usage: "[options] <lane-id>";
8193
+ readonly arguments: readonly [{
8194
+ readonly name: "lane-id";
8195
+ readonly required: true;
8196
+ readonly variadic: false;
8197
+ }];
8198
+ readonly options: readonly [{
8199
+ readonly flags: "--reason <text>";
8200
+ readonly description: "Record the reason in the lane's stop history";
8201
+ }, {
8202
+ readonly flags: "--json";
8203
+ readonly description: "JSON on stdout (always)";
8204
+ }];
8205
+ readonly subcommands: readonly [];
8082
8206
  }, {
8083
8207
  readonly name: "approve";
8084
8208
  readonly description: "Record senior approval for a registry worker checkpoint";
@@ -8732,6 +8856,120 @@ export declare const COMMAND_CATALOG: readonly [{
8732
8856
  readonly description: "Print machine-readable JSON";
8733
8857
  }];
8734
8858
  readonly subcommands: readonly [];
8859
+ }, {
8860
+ readonly name: "sync";
8861
+ readonly description: "Inspect and control the daemon's company sync runner";
8862
+ readonly aliases: readonly [];
8863
+ readonly hidden: false;
8864
+ readonly usage: "[options] [command]";
8865
+ readonly arguments: readonly [];
8866
+ readonly options: readonly [];
8867
+ readonly subcommands: readonly [{
8868
+ readonly name: "status";
8869
+ readonly description: "Show sync ownership, heartbeat, last pass and log path";
8870
+ readonly aliases: readonly [];
8871
+ readonly hidden: false;
8872
+ readonly usage: "[options]";
8873
+ readonly arguments: readonly [];
8874
+ readonly options: readonly [{
8875
+ readonly flags: "--json";
8876
+ readonly description: "Print machine-readable JSON";
8877
+ }];
8878
+ readonly subcommands: readonly [];
8879
+ }, {
8880
+ readonly name: "now";
8881
+ readonly description: "Start a fresh sync pass immediately";
8882
+ readonly aliases: readonly [];
8883
+ readonly hidden: false;
8884
+ readonly usage: "[options]";
8885
+ readonly arguments: readonly [];
8886
+ readonly options: readonly [{
8887
+ readonly flags: "--json";
8888
+ readonly description: "Print machine-readable JSON";
8889
+ }];
8890
+ readonly subcommands: readonly [];
8891
+ }, {
8892
+ readonly name: "pause";
8893
+ readonly description: "Pause daemon sync until resumed";
8894
+ readonly aliases: readonly [];
8895
+ readonly hidden: false;
8896
+ readonly usage: "[options]";
8897
+ readonly arguments: readonly [];
8898
+ readonly options: readonly [{
8899
+ readonly flags: "--json";
8900
+ readonly description: "Print machine-readable JSON";
8901
+ }];
8902
+ readonly subcommands: readonly [];
8903
+ }, {
8904
+ readonly name: "resume";
8905
+ readonly description: "Resume daemon sync after a pause";
8906
+ readonly aliases: readonly [];
8907
+ readonly hidden: false;
8908
+ readonly usage: "[options]";
8909
+ readonly arguments: readonly [];
8910
+ readonly options: readonly [{
8911
+ readonly flags: "--json";
8912
+ readonly description: "Print machine-readable JSON";
8913
+ }];
8914
+ readonly subcommands: readonly [];
8915
+ }, {
8916
+ readonly name: "take-ownership";
8917
+ readonly description: "Persist daemon ownership of desktop sync and reconcile";
8918
+ readonly aliases: readonly [];
8919
+ readonly hidden: false;
8920
+ readonly usage: "[options]";
8921
+ readonly arguments: readonly [];
8922
+ readonly options: readonly [{
8923
+ readonly flags: "--json";
8924
+ readonly description: "Print machine-readable JSON";
8925
+ }];
8926
+ readonly subcommands: readonly [];
8927
+ }, {
8928
+ readonly name: "mode";
8929
+ readonly description: "Read or change a company's sync footprint";
8930
+ readonly aliases: readonly [];
8931
+ readonly hidden: false;
8932
+ readonly usage: "[options] [command]";
8933
+ readonly arguments: readonly [];
8934
+ readonly options: readonly [];
8935
+ readonly subcommands: readonly [{
8936
+ readonly name: "get";
8937
+ readonly description: "Read a company's current all/shared sync mode";
8938
+ readonly aliases: readonly [];
8939
+ readonly hidden: false;
8940
+ readonly usage: "[options] <company>";
8941
+ readonly arguments: readonly [{
8942
+ readonly name: "company";
8943
+ readonly required: true;
8944
+ readonly variadic: false;
8945
+ }];
8946
+ readonly options: readonly [{
8947
+ readonly flags: "--json";
8948
+ readonly description: "Print machine-readable JSON";
8949
+ }];
8950
+ readonly subcommands: readonly [];
8951
+ }, {
8952
+ readonly name: "set";
8953
+ readonly description: "Set a company's sync mode to all or shared";
8954
+ readonly aliases: readonly [];
8955
+ readonly hidden: false;
8956
+ readonly usage: "[options] <company> <mode>";
8957
+ readonly arguments: readonly [{
8958
+ readonly name: "company";
8959
+ readonly required: true;
8960
+ readonly variadic: false;
8961
+ }, {
8962
+ readonly name: "mode";
8963
+ readonly required: true;
8964
+ readonly variadic: false;
8965
+ }];
8966
+ readonly options: readonly [{
8967
+ readonly flags: "--json";
8968
+ readonly description: "Print machine-readable JSON";
8969
+ }];
8970
+ readonly subcommands: readonly [];
8971
+ }];
8972
+ }];
8735
8973
  }, {
8736
8974
  readonly name: "logs";
8737
8975
  readonly description: "Print the supervisor log, or one service's log";