@indigoai-us/hq-cli 5.345.122 → 5.345.124
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/CHANGELOG.md +25 -0
- package/README.md +15 -0
- package/assets/scaffold/core/scripts/handoff-sync-prefetch.sh +121 -0
- package/assets/scaffold/core/scripts/handoff-sync-publish.sh +124 -0
- package/assets/scaffold/core/scripts/knowledge-pulse-lock.sh +27 -0
- package/assets/scaffold/core/scripts/lib/session-skill-catalog.sh +226 -0
- package/assets/scaffold/core/scripts/skill-installed.sh +43 -0
- package/assets/scaffold/core/scripts/work-mesh-project-registration-offer.sh +77 -0
- package/assets/scaffold/core/scripts/workflow-gate.sh +247 -0
- package/dist/command-catalog.generated.d.ts +332 -0
- package/dist/command-catalog.generated.js +402 -0
- package/dist/command-registration-plan.d.ts +6 -0
- package/dist/command-registration-plan.js +1 -0
- package/dist/commands/core-bucket-c-handoff-sync-fast.d.ts +3 -0
- package/dist/commands/core-bucket-c-handoff-sync-fast.js +16 -0
- package/dist/commands/core-bucket-c-handoff-sync-native.d.ts +45 -0
- package/dist/commands/core-bucket-c-handoff-sync-native.js +300 -0
- package/dist/commands/core-bucket-c-small-fast.d.ts +5 -0
- package/dist/commands/core-bucket-c-small-fast.js +19 -0
- package/dist/commands/core-bucket-c-small-native.d.ts +11 -0
- package/dist/commands/core-bucket-c-small-native.js +197 -0
- package/dist/commands/core-bucket-c-work-mesh-offer-native.d.ts +7 -0
- package/dist/commands/core-bucket-c-work-mesh-offer-native.js +147 -0
- package/dist/commands/core-bucket-c-workflow-gate-fast.d.ts +3 -0
- package/dist/commands/core-bucket-c-workflow-gate-fast.js +17 -0
- package/dist/commands/core-bucket-c-workflow-gate-native.d.ts +7 -0
- package/dist/commands/core-bucket-c-workflow-gate-native.js +250 -0
- package/dist/commands/core-derive-trigger-facts-native.js +4 -1
- package/dist/commands/core.js +37 -0
- package/dist/commands/deploy-comments.d.ts +2 -0
- package/dist/commands/deploy-comments.js +2 -2
- package/dist/commands/deploy-list.d.ts +22 -0
- package/dist/commands/deploy-list.js +153 -0
- package/dist/commands/lanes.js +41 -2
- package/dist/commands/mesh.js +457 -16
- package/dist/fast-scaffold.js +74 -0
- package/dist/lib/core-utils/session-company.d.ts +3 -0
- package/dist/lib/core-utils/session-company.js +78 -0
- package/dist/lib/lanes/quota-notice.d.ts +24 -0
- package/dist/lib/lanes/quota-notice.js +61 -0
- package/dist/lib/lanes/quota.d.ts +44 -8
- package/dist/lib/lanes/quota.js +187 -45
- package/dist/lib/lanes/reconcile.js +17 -1
- package/dist/lib/lanes/watcher.js +13 -1
- package/dist/lib/mesh/api.d.ts +2 -0
- package/dist/lib/mesh/api.js +3 -0
- package/dist/lib/mesh/client.d.ts +6 -1
- package/dist/lib/mesh/client.js +18 -5
- package/dist/lib/mesh/team-coordination.d.ts +106 -0
- package/dist/lib/mesh/team-coordination.js +297 -0
- package/dist/lib/work-context/auto-bind.d.ts +75 -0
- package/dist/lib/work-context/auto-bind.js +245 -0
- package/package.json +1 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { DEPLOY_API_URL, deployApiRequest } from "../lib/deploy-api.js";
|
|
2
|
+
import { listDeployApps } from "../lib/deploy-apps.js";
|
|
3
|
+
import { DEFAULT_HQ_ROOT, ensureCognitoToken } from "../utils/cognito-session.js";
|
|
4
|
+
import { displayText, safeJson } from "./deploy-comments.js";
|
|
5
|
+
import { readActiveCompanySlug } from "./skill.js";
|
|
6
|
+
class DeployListError extends Error {
|
|
7
|
+
}
|
|
8
|
+
const SLUG_PATTERN = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
9
|
+
function resolveCompany(companyFlag) {
|
|
10
|
+
const slug = companyFlag ?? readActiveCompanySlug(DEFAULT_HQ_ROOT);
|
|
11
|
+
if (slug === undefined) {
|
|
12
|
+
throw new DeployListError("No active company. Pass --company <slug>.");
|
|
13
|
+
}
|
|
14
|
+
if (!SLUG_PATTERN.test(slug))
|
|
15
|
+
throw new DeployListError("The company slug is not valid.");
|
|
16
|
+
return slug;
|
|
17
|
+
}
|
|
18
|
+
function str(value) {
|
|
19
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
20
|
+
}
|
|
21
|
+
/** Public app base domain, derived from the deploy API host (api.<base>). */
|
|
22
|
+
export function appBaseDomain(apiUrl = DEPLOY_API_URL) {
|
|
23
|
+
try {
|
|
24
|
+
const host = new URL(apiUrl).hostname;
|
|
25
|
+
return host.startsWith("api.") ? host.slice(4) : null;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function appUrl(app, subdomain) {
|
|
32
|
+
const url = str(app.url);
|
|
33
|
+
if (url)
|
|
34
|
+
return url;
|
|
35
|
+
const base = appBaseDomain();
|
|
36
|
+
return subdomain && base ? `https://${subdomain}.${base}` : null;
|
|
37
|
+
}
|
|
38
|
+
export function summarizeApp(app) {
|
|
39
|
+
const subdomain = str(app.subdomain);
|
|
40
|
+
return {
|
|
41
|
+
id: str(app.id),
|
|
42
|
+
name: str(app.name),
|
|
43
|
+
title: str(app.title),
|
|
44
|
+
subdomain,
|
|
45
|
+
url: appUrl(app, subdomain),
|
|
46
|
+
type: str(app.type),
|
|
47
|
+
accessMode: str(app.accessMode),
|
|
48
|
+
status: str(app.status),
|
|
49
|
+
createdAt: str(app.createdAt),
|
|
50
|
+
updatedAt: str(app.updatedAt),
|
|
51
|
+
lastVisitAt: str(app.lastVisitAt),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function matchesQuery(app, query) {
|
|
55
|
+
if (!query)
|
|
56
|
+
return true;
|
|
57
|
+
const needle = query.toLowerCase();
|
|
58
|
+
return [app.name, app.subdomain, app.title].some((field) => field?.toLowerCase().includes(needle) ?? false);
|
|
59
|
+
}
|
|
60
|
+
async function responseError(response, slug) {
|
|
61
|
+
const body = await response.json().catch(() => ({}));
|
|
62
|
+
const raw = body.error?.code;
|
|
63
|
+
const code = typeof raw === "string" && /^[A-Z0-9_]+$/.test(raw) ? raw : `HTTP_${response.status}`;
|
|
64
|
+
if (response.status === 401) {
|
|
65
|
+
return new DeployListError(`hq-deploy rejected your sign-in. Run 'hq login' and retry. (${code})`);
|
|
66
|
+
}
|
|
67
|
+
if (response.status === 403) {
|
|
68
|
+
return new DeployListError(`Company '${slug}' was not found in hq-deploy, or you do not have access to it. (${code})`);
|
|
69
|
+
}
|
|
70
|
+
if (response.status === 404) {
|
|
71
|
+
return new DeployListError(`Company '${slug}' was not found in hq-deploy. (${code})`);
|
|
72
|
+
}
|
|
73
|
+
return new DeployListError(`Could not list deploy apps (HTTP ${response.status}, ${code}).`);
|
|
74
|
+
}
|
|
75
|
+
async function fetchPage(token, slug, cursor) {
|
|
76
|
+
const route = cursor ? `/api/apps?cursor=${encodeURIComponent(cursor)}` : "/api/apps";
|
|
77
|
+
let response;
|
|
78
|
+
try {
|
|
79
|
+
response = await deployApiRequest(token, route, "GET", undefined, { "X-Org-Slug": slug });
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
throw new DeployListError("Could not reach hq-deploy.");
|
|
83
|
+
}
|
|
84
|
+
if (!response.ok)
|
|
85
|
+
throw await responseError(response, slug);
|
|
86
|
+
try {
|
|
87
|
+
return await response.json();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
throw new DeployListError("hq-deploy returned an invalid response.");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function printApp(app) {
|
|
94
|
+
const updated = app.updatedAt ?? app.lastVisitAt ?? app.createdAt;
|
|
95
|
+
console.log([
|
|
96
|
+
displayText(app.name ?? app.subdomain ?? app.id ?? "unnamed"),
|
|
97
|
+
displayText(app.url ?? "-"),
|
|
98
|
+
displayText(app.type ?? "-"),
|
|
99
|
+
displayText(app.accessMode ?? "-"),
|
|
100
|
+
displayText(updated ?? "-"),
|
|
101
|
+
].join(" | "));
|
|
102
|
+
}
|
|
103
|
+
async function listAction(query, options) {
|
|
104
|
+
const slug = resolveCompany(options.company);
|
|
105
|
+
const token = await ensureCognitoToken();
|
|
106
|
+
let raw;
|
|
107
|
+
try {
|
|
108
|
+
raw = await listDeployApps((cursor) => fetchPage(token, slug, cursor));
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
if (error instanceof DeployListError)
|
|
112
|
+
throw error;
|
|
113
|
+
throw new DeployListError(error instanceof Error ? error.message : "Could not list deploy apps.");
|
|
114
|
+
}
|
|
115
|
+
const apps = raw
|
|
116
|
+
.filter((app) => typeof app === "object" && app !== null)
|
|
117
|
+
.map(summarizeApp)
|
|
118
|
+
.filter((app) => matchesQuery(app, query));
|
|
119
|
+
if (options.json) {
|
|
120
|
+
console.log(safeJson({ company: slug, query: query ?? null, apps }));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (apps.length === 0) {
|
|
124
|
+
if (query) {
|
|
125
|
+
console.log(`No deploy apps in '${slug}' matched '${displayText(query)}'.`);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
console.log(`hq-deploy returned no apps for '${slug}'.`);
|
|
129
|
+
console.log("Hint: this list can come back empty while the org still has apps. "
|
|
130
|
+
+ "Check the HQ console before concluding none exist.");
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
for (const app of apps)
|
|
135
|
+
printApp(app);
|
|
136
|
+
}
|
|
137
|
+
export function registerDeployListCommand(deploy) {
|
|
138
|
+
deploy
|
|
139
|
+
.command("list [query]")
|
|
140
|
+
.description("List deploy apps in your company, optionally filtered by name or subdomain")
|
|
141
|
+
.option("--company <slug>", "use this company instead of the active company")
|
|
142
|
+
.option("--json", "print the matching apps as JSON")
|
|
143
|
+
.action(async (query, options) => {
|
|
144
|
+
try {
|
|
145
|
+
await listAction(query, options);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
console.error(error instanceof DeployListError ? error.message : "Deploy list command failed.");
|
|
149
|
+
process.exitCode = 1;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=deploy-list.js.map
|
package/dist/commands/lanes.js
CHANGED
|
@@ -38,6 +38,7 @@ import { registerLanesLinkCommand } from "./lanes-link.js";
|
|
|
38
38
|
import { laneDepthCap } from "../lib/lanes/depth-cap.js";
|
|
39
39
|
import { isSsmRunCommandProcess } from "../lib/lanes/ssm-command-context.js";
|
|
40
40
|
import { runResidentCommandWithPackageLease } from "../utils/resident-package-preload.js";
|
|
41
|
+
import { codexEnvEvidence, grokEnvEvidence } from "../lib/doctor/platform.js";
|
|
41
42
|
import { readLanesFlagLocalOverride, readLanesRegistryFlag, readLanesRegistryFlagFailOff, readLanesRegistryFlagFailOpen } from "../lib/lanes/registry-flag.js";
|
|
42
43
|
import { readLaneStatusRowFields } from "../lib/lanes/status-fields.js";
|
|
43
44
|
import { appendProjectFocusOverride, readProjectStoryFocusData, removeProjectFocusOverride } from "../lib/lanes/story-ledger.js";
|
|
@@ -74,7 +75,7 @@ import { sessionIdFromEnv } from "../lib/mesh/live/session-identity.js";
|
|
|
74
75
|
import { listLaneReviews } from "../lib/lanes/reviews.js";
|
|
75
76
|
import { effectiveAccountHome } from "../lib/lanes/account-home.js";
|
|
76
77
|
import { remoteControlSelectionConfig, remoteControlSessionHome } from "../lib/lanes/remote-control-lane.js";
|
|
77
|
-
import { AccountResolutionError, compareLaneQueueOrder, LANE_PROVIDERS, LANE_STATES, QUESTION_STATUSES, SENIOR_KINDS, accountStatus, appendCappedHistory, canonicalizeHome, createLane, decideAdmission, defaultLivenessDeps, defaultSystemdUserDir, defaultThrottleDeps, installReconcileTimer, providerPathEnv, probeDrainHookRegistration, isLanesError, isLaneVersionConflict, isTerminalLaneState, isFinishedResumableHireChild, childrenHoldingHireGrantCarve, laneHoldsHireGrantCarve, assignedChildHireGrants, hireGrantCapacityError, planHireGrantBackfill, terminalChildResumeHireGrantError, withHireGrantAdmission, laneStoryLedgerEnabled, syncLaneToProjectStoryLedger, removeLaneFromProjectStoryLedger, validateProjectStories, buildLaneStatusSnapshot, formatLaneStatusHuman, listLaneIds, listQuestionIds, loadLanesConfig, laneRunsHere, MAX_LANE_DEPTH, MONITOR_ERROR_EXIT_CODE, readLiveMonitorEvidence, resolveMachineIdentity as lookupMachineIdentity, loadLivenessIndex, parseLaneProvider, parseLaneRecord, parseLaneState, parseQuestionRecord, parseSeniorKind, readAllLanes, readLane, sanitizeHostComponent, retryUpdateLane, syncLaneRecordFromOwner, readQuestion, resolveAccount, resolveLaneWorker, ignoredWorkerProfileFields, loadWorkerProfile, loadWorkerProfileWithRegistry, registryWorkerRecord, runReconcilePass, DEAD_HOST_MS, sessionLiveness, tryReadLane, uninstallReconcileTimer, updateLane, updateQuestion, dropboxDir, laneDeliveryMechanism, hasActiveAdmissionReservation, hasActivePendingResume, hasRecordedSessionId, hasEarlierEligibleQueuedLane, laneAdmissionCapReason, providerSupportsSessionResume, providerSessionPortable, isFailedQuotaKeepAliveLane, sessionNotPortableMessage, withLaneAdmissionLock, withAllLaneAdmissionLocks, readWorkerRunResult, resumeCommandRefusal, withLaneHireLocks, raiseLaneQuestion, sha256Text, } from "../lib/lanes/index.js";
|
|
78
|
+
import { AccountResolutionError, compareLaneQueueOrder, LANE_PROVIDERS, LANE_STATES, QUESTION_STATUSES, SENIOR_KINDS, accountStatus, appendCappedHistory, canonicalizeHome, createLane, decideAdmission, defaultLivenessDeps, defaultSystemdUserDir, defaultThrottleDeps, installReconcileTimer, providerPathEnv, probeDrainHookRegistration, isLanesError, isLaneVersionConflict, isTerminalLaneState, isFinishedResumableHireChild, childrenHoldingHireGrantCarve, laneHoldsHireGrantCarve, assignedChildHireGrants, hireGrantCapacityError, planHireGrantBackfill, terminalChildResumeHireGrantError, withHireGrantAdmission, laneStoryLedgerEnabled, syncLaneToProjectStoryLedger, removeLaneFromProjectStoryLedger, validateProjectStories, buildLaneStatusSnapshot, formatLaneStatusHuman, listLaneIds, listQuestionIds, loadLanesConfig, laneRunsHere, MAX_LANE_DEPTH, MONITOR_ERROR_EXIT_CODE, readLiveMonitorEvidence, resolveMachineIdentity as lookupMachineIdentity, loadLivenessIndex, parseLaneProvider, isLaneProvider, parseLaneRecord, parseLaneState, parseQuestionRecord, parseSeniorKind, readAllLanes, readLane, sanitizeHostComponent, retryUpdateLane, syncLaneRecordFromOwner, readQuestion, resolveAccount, resolveLaneWorker, ignoredWorkerProfileFields, loadWorkerProfile, loadWorkerProfileWithRegistry, registryWorkerRecord, runReconcilePass, DEAD_HOST_MS, sessionLiveness, tryReadLane, uninstallReconcileTimer, updateLane, updateQuestion, dropboxDir, laneDeliveryMechanism, hasActiveAdmissionReservation, hasActivePendingResume, hasRecordedSessionId, hasEarlierEligibleQueuedLane, laneAdmissionCapReason, providerSupportsSessionResume, providerSessionPortable, isFailedQuotaKeepAliveLane, sessionNotPortableMessage, withLaneAdmissionLock, withAllLaneAdmissionLocks, readWorkerRunResult, resumeCommandRefusal, withLaneHireLocks, raiseLaneQuestion, sha256Text, } from "../lib/lanes/index.js";
|
|
78
79
|
import { laneStories, storyWarning, } from "../lib/lanes/stories.js";
|
|
79
80
|
import { resolveLaneKeepAlive } from "../lib/lanes/profile.js";
|
|
80
81
|
import { laneCompanyUidSource, resolveLaneCompany } from "../lib/lanes/lane-company.js";
|
|
@@ -2295,6 +2296,41 @@ function callerDepth(hqRoot, ctx) {
|
|
|
2295
2296
|
}
|
|
2296
2297
|
return 0;
|
|
2297
2298
|
}
|
|
2299
|
+
/**
|
|
2300
|
+
* Engine of the orchestrator that is creating a lane, used as the provider
|
|
2301
|
+
* fallback when neither --provider nor the worker profile names one. Order:
|
|
2302
|
+
* the senior lane's provider, the senior session's `conduct_engine` metadata,
|
|
2303
|
+
* then the harness markers in the environment (`HQ_HARNESS`, Codex/Grok
|
|
2304
|
+
* runtime variables, `CLAUDECODE=1`). Returns undefined when none apply.
|
|
2305
|
+
*/
|
|
2306
|
+
function orchestratorEngine(hqRoot, senior, ctx) {
|
|
2307
|
+
if (senior.kind === "lane" && senior.id) {
|
|
2308
|
+
try {
|
|
2309
|
+
const provider = readLane(hqRoot, senior.id).provider;
|
|
2310
|
+
if (isLaneProvider(provider))
|
|
2311
|
+
return provider;
|
|
2312
|
+
}
|
|
2313
|
+
catch {
|
|
2314
|
+
// Fall through to the environment markers.
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
if (senior.kind === "session" && senior.id) {
|
|
2318
|
+
const engine = readSessionMeta(hqRoot, senior.id, ctx)?.conduct_engine;
|
|
2319
|
+
const value = typeof engine === "string" ? engine.trim().toLowerCase() : "";
|
|
2320
|
+
if (isLaneProvider(value))
|
|
2321
|
+
return value;
|
|
2322
|
+
}
|
|
2323
|
+
const harness = ctx.env.HQ_HARNESS?.trim().toLowerCase() ?? "";
|
|
2324
|
+
if (isLaneProvider(harness))
|
|
2325
|
+
return harness;
|
|
2326
|
+
if (codexEnvEvidence(ctx.env).length > 0)
|
|
2327
|
+
return "codex";
|
|
2328
|
+
if (grokEnvEvidence(ctx.env).length > 0)
|
|
2329
|
+
return "grok";
|
|
2330
|
+
if (ctx.env.CLAUDECODE?.trim() === "1")
|
|
2331
|
+
return "claude";
|
|
2332
|
+
return undefined;
|
|
2333
|
+
}
|
|
2298
2334
|
function defaultSenior(ctx) {
|
|
2299
2335
|
const parent = ctx.env.HQ_PARENT_SESSION_ID?.trim();
|
|
2300
2336
|
if (parent)
|
|
@@ -3450,7 +3486,10 @@ async function runCreate(ctx, opts) {
|
|
|
3450
3486
|
const profile = resolvedWorker?.profile;
|
|
3451
3487
|
const provider = explicitProvider ??
|
|
3452
3488
|
profile?.meta.provider ??
|
|
3453
|
-
|
|
3489
|
+
(opts.remoteControl === true ? parseLaneProvider("claude") : orchestratorEngine(hqRoot, senior, ctx));
|
|
3490
|
+
if (provider === undefined) {
|
|
3491
|
+
throw new LanesError("provider_required", "Cannot tell which engine runs the orchestrator session, so no lane provider was chosen. Pass --provider claude, --provider codex, or --provider grok.", { accepted: [...LANE_PROVIDERS] });
|
|
3492
|
+
}
|
|
3454
3493
|
if (opts.remoteControl === true && provider !== "claude") {
|
|
3455
3494
|
throw new LanesError("remote_control_requires_claude", "--remote-control requires a Claude lane", { provider });
|
|
3456
3495
|
}
|