@indigoai-us/hq-cli 5.345.121 → 5.345.123
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 +22 -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/dist/command-catalog.generated.d.ts +97 -0
- package/dist/command-catalog.generated.js +116 -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-derive-trigger-facts-native.js +4 -1
- package/dist/commands/core.js +25 -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 +50 -3
- package/dist/fast-scaffold.js +48 -0
- package/dist/lib/capacity/collectors/claude-oauth.d.ts +1 -1
- package/dist/lib/capacity/collectors/claude-oauth.js +48 -4
- package/dist/lib/capacity/ledger.d.ts +7 -0
- package/dist/lib/capacity/ledger.js +17 -1
- package/dist/lib/capacity/sign-in.d.ts +2 -0
- package/dist/lib/capacity/sign-in.js +19 -4
- 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/spawn.d.ts +1 -0
- package/dist/lib/lanes/spawn.js +4 -1
- package/dist/lib/lanes/store.js +11 -0
- package/dist/lib/lanes/types.d.ts +2 -0
- package/dist/lib/lanes/types.js +1 -1
- package/package.json +1 -1
|
@@ -9511,6 +9511,40 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
9511
9511
|
}];
|
|
9512
9512
|
readonly options: readonly [];
|
|
9513
9513
|
readonly subcommands: readonly [];
|
|
9514
|
+
}, {
|
|
9515
|
+
readonly name: "handoff-sync-prefetch";
|
|
9516
|
+
readonly description: "Pull the latest continuity pointer before a session resumes";
|
|
9517
|
+
readonly aliases: readonly [];
|
|
9518
|
+
readonly hidden: false;
|
|
9519
|
+
readonly helpOption: false;
|
|
9520
|
+
readonly helpCommand: false;
|
|
9521
|
+
readonly usage: "[args...]";
|
|
9522
|
+
readonly helpText: readonly [];
|
|
9523
|
+
readonly arguments: readonly [{
|
|
9524
|
+
readonly name: "args";
|
|
9525
|
+
readonly required: false;
|
|
9526
|
+
readonly variadic: true;
|
|
9527
|
+
readonly description: "arguments passed through to the script";
|
|
9528
|
+
}];
|
|
9529
|
+
readonly options: readonly [];
|
|
9530
|
+
readonly subcommands: readonly [];
|
|
9531
|
+
}, {
|
|
9532
|
+
readonly name: "handoff-sync-publish";
|
|
9533
|
+
readonly description: "Publish the session continuity pointer to the personal vault";
|
|
9534
|
+
readonly aliases: readonly [];
|
|
9535
|
+
readonly hidden: false;
|
|
9536
|
+
readonly helpOption: false;
|
|
9537
|
+
readonly helpCommand: false;
|
|
9538
|
+
readonly usage: "[args...]";
|
|
9539
|
+
readonly helpText: readonly [];
|
|
9540
|
+
readonly arguments: readonly [{
|
|
9541
|
+
readonly name: "args";
|
|
9542
|
+
readonly required: false;
|
|
9543
|
+
readonly variadic: true;
|
|
9544
|
+
readonly description: "arguments passed through to the script";
|
|
9545
|
+
}];
|
|
9546
|
+
readonly options: readonly [];
|
|
9547
|
+
readonly subcommands: readonly [];
|
|
9514
9548
|
}, {
|
|
9515
9549
|
readonly name: "hq-task";
|
|
9516
9550
|
readonly description: "List and update tasks on personal or company boards";
|
|
@@ -9528,6 +9562,40 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
9528
9562
|
}];
|
|
9529
9563
|
readonly options: readonly [];
|
|
9530
9564
|
readonly subcommands: readonly [];
|
|
9565
|
+
}, {
|
|
9566
|
+
readonly name: "knowledge-pulse-lock";
|
|
9567
|
+
readonly description: "Atomically claim a company knowledge-pulse run";
|
|
9568
|
+
readonly aliases: readonly [];
|
|
9569
|
+
readonly hidden: false;
|
|
9570
|
+
readonly helpOption: false;
|
|
9571
|
+
readonly helpCommand: false;
|
|
9572
|
+
readonly usage: "[args...]";
|
|
9573
|
+
readonly helpText: readonly [];
|
|
9574
|
+
readonly arguments: readonly [{
|
|
9575
|
+
readonly name: "args";
|
|
9576
|
+
readonly required: false;
|
|
9577
|
+
readonly variadic: true;
|
|
9578
|
+
readonly description: "arguments passed through to the script";
|
|
9579
|
+
}];
|
|
9580
|
+
readonly options: readonly [];
|
|
9581
|
+
readonly subcommands: readonly [];
|
|
9582
|
+
}, {
|
|
9583
|
+
readonly name: "skill-installed";
|
|
9584
|
+
readonly description: "Check whether a company-scoped skill is installed";
|
|
9585
|
+
readonly aliases: readonly [];
|
|
9586
|
+
readonly hidden: false;
|
|
9587
|
+
readonly helpOption: false;
|
|
9588
|
+
readonly helpCommand: false;
|
|
9589
|
+
readonly usage: "[args...]";
|
|
9590
|
+
readonly helpText: readonly [];
|
|
9591
|
+
readonly arguments: readonly [{
|
|
9592
|
+
readonly name: "args";
|
|
9593
|
+
readonly required: false;
|
|
9594
|
+
readonly variadic: true;
|
|
9595
|
+
readonly description: "arguments passed through to the script";
|
|
9596
|
+
}];
|
|
9597
|
+
readonly options: readonly [];
|
|
9598
|
+
readonly subcommands: readonly [];
|
|
9531
9599
|
}, {
|
|
9532
9600
|
readonly name: "checkpoint-stop-gate";
|
|
9533
9601
|
readonly description: "Stop-hook checkpoint + company-scope gate (reads the hook payload on stdin)";
|
|
@@ -13334,6 +13402,10 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
13334
13402
|
readonly flags: "--remote-control";
|
|
13335
13403
|
readonly description: "Open a Claude lane in Remote Control using account a for login and the selected account for inference";
|
|
13336
13404
|
readonly hidden: false;
|
|
13405
|
+
}, {
|
|
13406
|
+
readonly flags: "--title <text>";
|
|
13407
|
+
readonly description: "Human-readable Claude Remote Control session title; required with --remote-control";
|
|
13408
|
+
readonly hidden: false;
|
|
13337
13409
|
}, {
|
|
13338
13410
|
readonly flags: "--account <id>";
|
|
13339
13411
|
readonly description: "Provider account id, or 'auto' to pick the account with the most room (all accounts are one pool across companies)";
|
|
@@ -17176,6 +17248,31 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
17176
17248
|
}];
|
|
17177
17249
|
readonly subcommands: readonly [];
|
|
17178
17250
|
}];
|
|
17251
|
+
}, {
|
|
17252
|
+
readonly name: "list";
|
|
17253
|
+
readonly description: "List deploy apps in your company, optionally filtered by name or subdomain";
|
|
17254
|
+
readonly aliases: readonly [];
|
|
17255
|
+
readonly hidden: false;
|
|
17256
|
+
readonly helpOption: true;
|
|
17257
|
+
readonly helpCommand: false;
|
|
17258
|
+
readonly usage: "[options] [query]";
|
|
17259
|
+
readonly helpText: readonly [];
|
|
17260
|
+
readonly arguments: readonly [{
|
|
17261
|
+
readonly name: "query";
|
|
17262
|
+
readonly required: false;
|
|
17263
|
+
readonly variadic: false;
|
|
17264
|
+
readonly description: "";
|
|
17265
|
+
}];
|
|
17266
|
+
readonly options: readonly [{
|
|
17267
|
+
readonly flags: "--company <slug>";
|
|
17268
|
+
readonly description: "use this company instead of the active company";
|
|
17269
|
+
readonly hidden: false;
|
|
17270
|
+
}, {
|
|
17271
|
+
readonly flags: "--json";
|
|
17272
|
+
readonly description: "print the matching apps as JSON";
|
|
17273
|
+
readonly hidden: false;
|
|
17274
|
+
}];
|
|
17275
|
+
readonly subcommands: readonly [];
|
|
17179
17276
|
}];
|
|
17180
17277
|
}, {
|
|
17181
17278
|
readonly name: "staff";
|
|
@@ -11527,6 +11527,46 @@ export const COMMAND_CATALOG = [
|
|
|
11527
11527
|
"options": [],
|
|
11528
11528
|
"subcommands": []
|
|
11529
11529
|
},
|
|
11530
|
+
{
|
|
11531
|
+
"name": "handoff-sync-prefetch",
|
|
11532
|
+
"description": "Pull the latest continuity pointer before a session resumes",
|
|
11533
|
+
"aliases": [],
|
|
11534
|
+
"hidden": false,
|
|
11535
|
+
"helpOption": false,
|
|
11536
|
+
"helpCommand": false,
|
|
11537
|
+
"usage": "[args...]",
|
|
11538
|
+
"helpText": [],
|
|
11539
|
+
"arguments": [
|
|
11540
|
+
{
|
|
11541
|
+
"name": "args",
|
|
11542
|
+
"required": false,
|
|
11543
|
+
"variadic": true,
|
|
11544
|
+
"description": "arguments passed through to the script"
|
|
11545
|
+
}
|
|
11546
|
+
],
|
|
11547
|
+
"options": [],
|
|
11548
|
+
"subcommands": []
|
|
11549
|
+
},
|
|
11550
|
+
{
|
|
11551
|
+
"name": "handoff-sync-publish",
|
|
11552
|
+
"description": "Publish the session continuity pointer to the personal vault",
|
|
11553
|
+
"aliases": [],
|
|
11554
|
+
"hidden": false,
|
|
11555
|
+
"helpOption": false,
|
|
11556
|
+
"helpCommand": false,
|
|
11557
|
+
"usage": "[args...]",
|
|
11558
|
+
"helpText": [],
|
|
11559
|
+
"arguments": [
|
|
11560
|
+
{
|
|
11561
|
+
"name": "args",
|
|
11562
|
+
"required": false,
|
|
11563
|
+
"variadic": true,
|
|
11564
|
+
"description": "arguments passed through to the script"
|
|
11565
|
+
}
|
|
11566
|
+
],
|
|
11567
|
+
"options": [],
|
|
11568
|
+
"subcommands": []
|
|
11569
|
+
},
|
|
11530
11570
|
{
|
|
11531
11571
|
"name": "hq-task",
|
|
11532
11572
|
"description": "List and update tasks on personal or company boards",
|
|
@@ -11547,6 +11587,46 @@ export const COMMAND_CATALOG = [
|
|
|
11547
11587
|
"options": [],
|
|
11548
11588
|
"subcommands": []
|
|
11549
11589
|
},
|
|
11590
|
+
{
|
|
11591
|
+
"name": "knowledge-pulse-lock",
|
|
11592
|
+
"description": "Atomically claim a company knowledge-pulse run",
|
|
11593
|
+
"aliases": [],
|
|
11594
|
+
"hidden": false,
|
|
11595
|
+
"helpOption": false,
|
|
11596
|
+
"helpCommand": false,
|
|
11597
|
+
"usage": "[args...]",
|
|
11598
|
+
"helpText": [],
|
|
11599
|
+
"arguments": [
|
|
11600
|
+
{
|
|
11601
|
+
"name": "args",
|
|
11602
|
+
"required": false,
|
|
11603
|
+
"variadic": true,
|
|
11604
|
+
"description": "arguments passed through to the script"
|
|
11605
|
+
}
|
|
11606
|
+
],
|
|
11607
|
+
"options": [],
|
|
11608
|
+
"subcommands": []
|
|
11609
|
+
},
|
|
11610
|
+
{
|
|
11611
|
+
"name": "skill-installed",
|
|
11612
|
+
"description": "Check whether a company-scoped skill is installed",
|
|
11613
|
+
"aliases": [],
|
|
11614
|
+
"hidden": false,
|
|
11615
|
+
"helpOption": false,
|
|
11616
|
+
"helpCommand": false,
|
|
11617
|
+
"usage": "[args...]",
|
|
11618
|
+
"helpText": [],
|
|
11619
|
+
"arguments": [
|
|
11620
|
+
{
|
|
11621
|
+
"name": "args",
|
|
11622
|
+
"required": false,
|
|
11623
|
+
"variadic": true,
|
|
11624
|
+
"description": "arguments passed through to the script"
|
|
11625
|
+
}
|
|
11626
|
+
],
|
|
11627
|
+
"options": [],
|
|
11628
|
+
"subcommands": []
|
|
11629
|
+
},
|
|
11550
11630
|
{
|
|
11551
11631
|
"name": "checkpoint-stop-gate",
|
|
11552
11632
|
"description": "Stop-hook checkpoint + company-scope gate (reads the hook payload on stdin)",
|
|
@@ -16206,6 +16286,11 @@ export const COMMAND_CATALOG = [
|
|
|
16206
16286
|
"description": "Open a Claude lane in Remote Control using account a for login and the selected account for inference",
|
|
16207
16287
|
"hidden": false
|
|
16208
16288
|
},
|
|
16289
|
+
{
|
|
16290
|
+
"flags": "--title <text>",
|
|
16291
|
+
"description": "Human-readable Claude Remote Control session title; required with --remote-control",
|
|
16292
|
+
"hidden": false
|
|
16293
|
+
},
|
|
16209
16294
|
{
|
|
16210
16295
|
"flags": "--account <id>",
|
|
16211
16296
|
"description": "Provider account id, or 'auto' to pick the account with the most room (all accounts are one pool across companies)",
|
|
@@ -20903,6 +20988,37 @@ export const COMMAND_CATALOG = [
|
|
|
20903
20988
|
"subcommands": []
|
|
20904
20989
|
}
|
|
20905
20990
|
]
|
|
20991
|
+
},
|
|
20992
|
+
{
|
|
20993
|
+
"name": "list",
|
|
20994
|
+
"description": "List deploy apps in your company, optionally filtered by name or subdomain",
|
|
20995
|
+
"aliases": [],
|
|
20996
|
+
"hidden": false,
|
|
20997
|
+
"helpOption": true,
|
|
20998
|
+
"helpCommand": false,
|
|
20999
|
+
"usage": "[options] [query]",
|
|
21000
|
+
"helpText": [],
|
|
21001
|
+
"arguments": [
|
|
21002
|
+
{
|
|
21003
|
+
"name": "query",
|
|
21004
|
+
"required": false,
|
|
21005
|
+
"variadic": false,
|
|
21006
|
+
"description": ""
|
|
21007
|
+
}
|
|
21008
|
+
],
|
|
21009
|
+
"options": [
|
|
21010
|
+
{
|
|
21011
|
+
"flags": "--company <slug>",
|
|
21012
|
+
"description": "use this company instead of the active company",
|
|
21013
|
+
"hidden": false
|
|
21014
|
+
},
|
|
21015
|
+
{
|
|
21016
|
+
"flags": "--json",
|
|
21017
|
+
"description": "print the matching apps as JSON",
|
|
21018
|
+
"hidden": false
|
|
21019
|
+
}
|
|
21020
|
+
],
|
|
21021
|
+
"subcommands": []
|
|
20906
21022
|
}
|
|
20907
21023
|
]
|
|
20908
21024
|
},
|
|
@@ -509,6 +509,12 @@ export declare const REGISTRATION_PLAN: readonly [{
|
|
|
509
509
|
readonly parent: "deploy";
|
|
510
510
|
readonly module: "./commands/deploy-comments.js";
|
|
511
511
|
readonly exportName: "registerDeployCommentsCommand";
|
|
512
|
+
}, {
|
|
513
|
+
readonly type: "registrar";
|
|
514
|
+
readonly root: "deploy";
|
|
515
|
+
readonly parent: "deploy";
|
|
516
|
+
readonly module: "./commands/deploy-list.js";
|
|
517
|
+
readonly exportName: "registerDeployListCommand";
|
|
512
518
|
}, {
|
|
513
519
|
readonly type: "group";
|
|
514
520
|
readonly root: "staff";
|
|
@@ -87,6 +87,7 @@ export const REGISTRATION_PLAN = [
|
|
|
87
87
|
{ type: "registrar", root: "report", parent: "program", module: "./commands/report.js", exportName: "registerReportCommand" },
|
|
88
88
|
{ type: "group", root: "deploy", id: "deploy", name: "deploy", description: "Manage deployments in hq-deploy" },
|
|
89
89
|
{ type: "registrar", root: "deploy", parent: "deploy", module: "./commands/deploy-comments.js", exportName: "registerDeployCommentsCommand" },
|
|
90
|
+
{ type: "registrar", root: "deploy", parent: "deploy", module: "./commands/deploy-list.js", exportName: "registerDeployListCommand" },
|
|
90
91
|
// onboarding-test-accounts US-007 — super-admin staff CLI wrappers over the
|
|
91
92
|
// hq-pro admin surface. New wrappers land under this group; the reset
|
|
92
93
|
// command mirrors POST /v1/admin/test-account/reset.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function runHandoffSyncPrefetchFast(args: string[], _stdin: string, _cwd: string, root: string): Promise<number>;
|
|
2
|
+
export declare function runHandoffSyncPublishFast(args: string[], _stdin: string, _cwd: string, root: string): Promise<number>;
|
|
3
|
+
//# sourceMappingURL=core-bucket-c-handoff-sync-fast.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { runHandoffSyncPrefetch, runHandoffSyncPublish } from "./core-bucket-c-handoff-sync-native.js";
|
|
2
|
+
async function emit(result) {
|
|
3
|
+
const output = await result;
|
|
4
|
+
if (output.stdout)
|
|
5
|
+
process.stdout.write(output.stdout);
|
|
6
|
+
if (output.stderr)
|
|
7
|
+
process.stderr.write(output.stderr);
|
|
8
|
+
return output.code;
|
|
9
|
+
}
|
|
10
|
+
export function runHandoffSyncPrefetchFast(args, _stdin, _cwd, root) {
|
|
11
|
+
return emit(runHandoffSyncPrefetch(args, root));
|
|
12
|
+
}
|
|
13
|
+
export function runHandoffSyncPublishFast(args, _stdin, _cwd, root) {
|
|
14
|
+
return emit(runHandoffSyncPublish(args, root));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=core-bucket-c-handoff-sync-fast.js.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type ChildProcess, type SpawnOptions } from "node:child_process";
|
|
2
|
+
export declare const HANDOFF_SYNC_PREFETCH_ASSET = "core/scripts/handoff-sync-prefetch.sh";
|
|
3
|
+
export declare const HANDOFF_SYNC_PUBLISH_ASSET = "core/scripts/handoff-sync-publish.sh";
|
|
4
|
+
export type HandoffSyncResult = {
|
|
5
|
+
code: number;
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr: string;
|
|
8
|
+
};
|
|
9
|
+
type ChildResult = {
|
|
10
|
+
code: number;
|
|
11
|
+
timedOut: boolean;
|
|
12
|
+
};
|
|
13
|
+
type Dependencies = {
|
|
14
|
+
spawn: (command: string, args: string[], options: SpawnOptions) => ChildProcess;
|
|
15
|
+
cwd: string;
|
|
16
|
+
env: NodeJS.ProcessEnv;
|
|
17
|
+
pid: number;
|
|
18
|
+
now: () => Date;
|
|
19
|
+
};
|
|
20
|
+
declare function parseArgs(args: readonly string[], kind: "prefetch" | "publish", env?: NodeJS.ProcessEnv): {
|
|
21
|
+
root: string;
|
|
22
|
+
timeout: string;
|
|
23
|
+
log: string;
|
|
24
|
+
sync: boolean;
|
|
25
|
+
child: boolean;
|
|
26
|
+
} | HandoffSyncResult;
|
|
27
|
+
declare function exitCode(code: number | null, signal: NodeJS.Signals | null): number;
|
|
28
|
+
declare function runWithTimeout(deps: Dependencies, logFd: number, timeoutText: string, args: string[]): Promise<ChildResult>;
|
|
29
|
+
declare function openLog(log: string): number | HandoffSyncResult;
|
|
30
|
+
declare function header(deps: Dependencies, root: string, kind: "prefetch" | "publish", timeout: string, mode?: string): string;
|
|
31
|
+
declare function resolveRoot(root: string, deps: Dependencies): string;
|
|
32
|
+
declare function commandOnPath(name: string, env: NodeJS.ProcessEnv): boolean;
|
|
33
|
+
export declare function runHandoffSyncPrefetch(args: readonly string[], hqRoot: string, deps?: Dependencies): Promise<HandoffSyncResult>;
|
|
34
|
+
export declare function runHandoffSyncPublish(args: readonly string[], hqRoot: string, deps?: Dependencies): Promise<HandoffSyncResult>;
|
|
35
|
+
export declare const __handoffSyncTest: {
|
|
36
|
+
parseArgs: typeof parseArgs;
|
|
37
|
+
exitCode: typeof exitCode;
|
|
38
|
+
runWithTimeout: typeof runWithTimeout;
|
|
39
|
+
openLog: typeof openLog;
|
|
40
|
+
header: typeof header;
|
|
41
|
+
resolveRoot: typeof resolveRoot;
|
|
42
|
+
commandOnPath: typeof commandOnPath;
|
|
43
|
+
};
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=core-bucket-c-handoff-sync-native.d.ts.map
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { buildSpawnPlan } from "../utils/windows-spawn.js";
|
|
6
|
+
export const HANDOFF_SYNC_PREFETCH_ASSET = "core/scripts/handoff-sync-prefetch.sh";
|
|
7
|
+
export const HANDOFF_SYNC_PUBLISH_ASSET = "core/scripts/handoff-sync-publish.sh";
|
|
8
|
+
const PREFETCH_HELP = [
|
|
9
|
+
"!/bin/bash",
|
|
10
|
+
"handoff-sync-prefetch.sh - pull the latest session continuity pointer before",
|
|
11
|
+
"a fresh session reads it.",
|
|
12
|
+
"",
|
|
13
|
+
"`/startwork` and `/resumework` both read `workspace/threads/handoff.json`",
|
|
14
|
+
"(and the thread file it references) to decide what to resume. On a second",
|
|
15
|
+
"device those files only exist after a vault pull has landed, so a naive",
|
|
16
|
+
"resume right after sign-in sees stale state. This helper runs that pull",
|
|
17
|
+
"BEFORE the skill reads the pointer.",
|
|
18
|
+
"",
|
|
19
|
+
"Fail-soft:",
|
|
20
|
+
" - no-op when the `hq` CLI is missing",
|
|
21
|
+
" - no-op when offline or not logged in",
|
|
22
|
+
" - timeboxed (default 25s)",
|
|
23
|
+
" - never fails the caller: a successful or failed pull are both exit 0;",
|
|
24
|
+
" the caller falls through to the local pointer either way.",
|
|
25
|
+
"",
|
|
26
|
+
"Usage:",
|
|
27
|
+
" handoff-sync-prefetch.sh [--hq-root PATH] [--timeout SECONDS] [--log PATH]",
|
|
28
|
+
"",
|
|
29
|
+
"Prints one line of status on stdout for the caller to echo (or ignore):",
|
|
30
|
+
" `ok` - pull completed within the timeout",
|
|
31
|
+
" `missing-cli` - `hq` is not on PATH; nothing was attempted",
|
|
32
|
+
" `skipped` - CLI is present but the pull refused to start (no login,",
|
|
33
|
+
" locked, etc.); local pointer is still used",
|
|
34
|
+
" `timed-out` - pull exceeded the timeout and was killed",
|
|
35
|
+
" `error:<rc>` - pull returned a non-zero exit code",
|
|
36
|
+
"",
|
|
37
|
+
"Exits 0 in every case so a shell `|| true` is unnecessary at call sites.",
|
|
38
|
+
"",
|
|
39
|
+
].join("\n");
|
|
40
|
+
const PUBLISH_HELP = [
|
|
41
|
+
"!/bin/bash",
|
|
42
|
+
"handoff-sync-publish.sh - push the session continuity pointer to the personal vault.",
|
|
43
|
+
"",
|
|
44
|
+
"Cross-device handoff depends on `workspace/threads/handoff.json` and the",
|
|
45
|
+
"single thread file it points to reaching the vault before a fresh session on",
|
|
46
|
+
"another machine runs `/startwork` or `/resumework`. The workspace tree is",
|
|
47
|
+
"otherwise machine-local (`PERSONAL_VAULT_EXCLUDED_TOP_LEVEL`), so without a",
|
|
48
|
+
"push run between the two sessions machine B sees stale state or no handoff",
|
|
49
|
+
"at all. See hq-cloud-sync `computeContinuityPointerPaths`.",
|
|
50
|
+
"",
|
|
51
|
+
"This helper is intentionally minimal and fail-soft:",
|
|
52
|
+
" - no-op when the `hq` CLI is missing (fresh install, agent box without CLI)",
|
|
53
|
+
" - no-op when offline or not logged in (vault push will fail; we never",
|
|
54
|
+
" block /handoff on cloud reachability)",
|
|
55
|
+
" - timeboxed (default 25s) so a slow network cannot stall session end",
|
|
56
|
+
" - detached by default; the handoff-finalize payload is already emitted",
|
|
57
|
+
"",
|
|
58
|
+
"Usage:",
|
|
59
|
+
" handoff-sync-publish.sh [--hq-root PATH] [--timeout SECONDS]",
|
|
60
|
+
" [--sync] [--log PATH]",
|
|
61
|
+
"",
|
|
62
|
+
" --sync Run synchronously in the foreground and return the exit code.",
|
|
63
|
+
" Default behaviour forks a backgrounded worker and prints its PID.",
|
|
64
|
+
" --timeout Wall-clock bound in seconds; the push is killed on expiry.",
|
|
65
|
+
" --log Append combined stdout/stderr to this path (default: `/tmp/handoff-sync-publish.log`).",
|
|
66
|
+
"",
|
|
67
|
+
"Exits 0 on dispatch (background mode) or on push success (sync mode).",
|
|
68
|
+
"A sync-mode failure returns the underlying `hq` exit, or 124 on timeout.",
|
|
69
|
+
"",
|
|
70
|
+
].join("\n");
|
|
71
|
+
const result = (code, stdout = "", stderr = "") => ({ code, stdout, stderr });
|
|
72
|
+
const fail = (message, code = 1) => result(code, "", message + "\n");
|
|
73
|
+
const defaults = () => ({ spawn: (command, args, options) => spawn(command, args, options), cwd: process.cwd(), env: process.env, pid: process.pid, now: () => new Date() });
|
|
74
|
+
function parseArgs(args, kind, env = process.env) {
|
|
75
|
+
let root = "";
|
|
76
|
+
let timeout = kind === "prefetch"
|
|
77
|
+
? (env.HQ_HANDOFF_PREFETCH_TIMEOUT ?? "25")
|
|
78
|
+
: (env.HQ_HANDOFF_PUBLISH_TIMEOUT ?? "25");
|
|
79
|
+
let log = kind === "prefetch" ? "/tmp/handoff-sync-prefetch.log" : "/tmp/handoff-sync-publish.log";
|
|
80
|
+
let sync = false;
|
|
81
|
+
let child = false;
|
|
82
|
+
for (let index = 0; index < args.length;) {
|
|
83
|
+
const token = args[index];
|
|
84
|
+
if (token === "--hq-root" || token === "--timeout" || token === "--log") {
|
|
85
|
+
if (index + 1 >= args.length) {
|
|
86
|
+
const script = kind === "prefetch" ? "handoff-sync-prefetch.sh" : "handoff-sync-publish.sh";
|
|
87
|
+
const line = kind === "prefetch"
|
|
88
|
+
? { "--hq-root": 39, "--timeout": 40, "--log": 41 }[token]
|
|
89
|
+
: { "--hq-root": 39, "--timeout": 40, "--log": 42 }[token];
|
|
90
|
+
const scriptPath = shellScriptPath(fileURLToPath(new URL(`../../assets/scaffold/core/scripts/${script}`, import.meta.url)));
|
|
91
|
+
return result(1, "", `${scriptPath}: line ${line}: $2: unbound variable\n`);
|
|
92
|
+
}
|
|
93
|
+
const value = args[index + 1];
|
|
94
|
+
if (token === "--hq-root")
|
|
95
|
+
root = value;
|
|
96
|
+
else if (token === "--timeout")
|
|
97
|
+
timeout = value;
|
|
98
|
+
else
|
|
99
|
+
log = value;
|
|
100
|
+
index += 2;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (token === "--sync" && kind === "publish") {
|
|
104
|
+
sync = true;
|
|
105
|
+
index += 1;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (token === "--child" && kind === "publish") {
|
|
109
|
+
sync = true;
|
|
110
|
+
child = true;
|
|
111
|
+
index += 1;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (token === "-h" || token === "--help")
|
|
115
|
+
return result(0, `${kind === "prefetch" ? PREFETCH_HELP : PUBLISH_HELP}\n`);
|
|
116
|
+
return fail(`handoff-sync-${kind}: unknown arg: ${token}`, 2);
|
|
117
|
+
}
|
|
118
|
+
return { root, timeout, log, sync, child };
|
|
119
|
+
}
|
|
120
|
+
function shellScriptPath(value) {
|
|
121
|
+
if (process.platform !== "win32")
|
|
122
|
+
return value;
|
|
123
|
+
const normalized = value.replaceAll("\\", "/");
|
|
124
|
+
const drivePath = normalized.match(/^([A-Za-z]):\/(.*)$/);
|
|
125
|
+
return drivePath ? `/${drivePath[1].toLowerCase()}/${drivePath[2]}` : normalized;
|
|
126
|
+
}
|
|
127
|
+
function exitCode(code, signal) {
|
|
128
|
+
if (code !== null)
|
|
129
|
+
return code;
|
|
130
|
+
if (signal === "SIGTERM")
|
|
131
|
+
return 143;
|
|
132
|
+
if (signal === "SIGKILL")
|
|
133
|
+
return 137;
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
|
+
function runWithTimeout(deps, logFd, timeoutText, args) {
|
|
137
|
+
return new Promise((resolve) => {
|
|
138
|
+
let child;
|
|
139
|
+
try {
|
|
140
|
+
const plan = buildSpawnPlan("hq", args);
|
|
141
|
+
child = deps.spawn(plan.cmd, plan.args, {
|
|
142
|
+
cwd: deps.cwd, env: deps.env, stdio: ["ignore", logFd, logFd], windowsHide: true,
|
|
143
|
+
shell: plan.shell,
|
|
144
|
+
...(plan.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
fs.writeSync(logFd, "spawn hq failed\n");
|
|
149
|
+
resolve({ code: 127, timedOut: false });
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const seconds = Number(timeoutText);
|
|
153
|
+
let timedOut = false;
|
|
154
|
+
let killTimer;
|
|
155
|
+
let timeoutTimer;
|
|
156
|
+
if (Number.isFinite(seconds)) {
|
|
157
|
+
timeoutTimer = setTimeout(() => {
|
|
158
|
+
timedOut = true;
|
|
159
|
+
child.kill("SIGTERM");
|
|
160
|
+
killTimer = setTimeout(() => child.kill("SIGKILL"), 1000);
|
|
161
|
+
}, Math.max(0, seconds) * 1000);
|
|
162
|
+
timeoutTimer.unref();
|
|
163
|
+
}
|
|
164
|
+
child.once("error", () => {
|
|
165
|
+
if (timeoutTimer)
|
|
166
|
+
clearTimeout(timeoutTimer);
|
|
167
|
+
if (killTimer)
|
|
168
|
+
clearTimeout(killTimer);
|
|
169
|
+
fs.writeSync(logFd, "hq: command not found\n");
|
|
170
|
+
resolve({ code: 127, timedOut });
|
|
171
|
+
});
|
|
172
|
+
child.once("exit", (code, signal) => {
|
|
173
|
+
if (timeoutTimer)
|
|
174
|
+
clearTimeout(timeoutTimer);
|
|
175
|
+
if (killTimer)
|
|
176
|
+
clearTimeout(killTimer);
|
|
177
|
+
resolve({ code: exitCode(code, signal), timedOut });
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function openLog(log) {
|
|
182
|
+
try {
|
|
183
|
+
fs.mkdirSync(path.dirname(log), { recursive: true });
|
|
184
|
+
}
|
|
185
|
+
catch { /* the shell ignores mkdir failure */ }
|
|
186
|
+
try {
|
|
187
|
+
return fs.openSync(log, "a");
|
|
188
|
+
}
|
|
189
|
+
catch (cause) {
|
|
190
|
+
return fail(String(cause.message));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function header(deps, root, kind, timeout, mode = "") {
|
|
194
|
+
return `\n--- handoff-sync-${kind} ${deps.now().toISOString().replace(/\.\d{3}Z$/, "Z")} hq_root=${root} ${mode ? `mode=${mode} ` : ""}timeout=${timeout}s ---\n`;
|
|
195
|
+
}
|
|
196
|
+
function resolveRoot(root, deps) {
|
|
197
|
+
return root || (deps.env.HQ_ROOT ?? deps.cwd);
|
|
198
|
+
}
|
|
199
|
+
function commandOnPath(name, env) {
|
|
200
|
+
const pathKey = Object.keys(env).find((key) => key.toUpperCase() === "PATH");
|
|
201
|
+
const searchPath = pathKey ? env[pathKey] ?? "" : "";
|
|
202
|
+
const windows = process.platform === "win32";
|
|
203
|
+
const pathExtKey = Object.keys(env).find((key) => key.toUpperCase() === "PATHEXT");
|
|
204
|
+
const extensions = windows
|
|
205
|
+
? (pathExtKey ? env[pathExtKey] ?? ".COM;.EXE;.BAT;.CMD" : ".COM;.EXE;.BAT;.CMD").split(";")
|
|
206
|
+
: [""];
|
|
207
|
+
const names = windows && path.extname(name) ? [name] : extensions.map((extension) => `${name}${extension}`);
|
|
208
|
+
for (const directory of searchPath.split(path.delimiter)) {
|
|
209
|
+
for (const executable of names) {
|
|
210
|
+
try {
|
|
211
|
+
const target = path.join(directory || ".", executable);
|
|
212
|
+
fs.accessSync(target, windows ? fs.constants.F_OK : fs.constants.X_OK);
|
|
213
|
+
if (fs.statSync(target).isFile())
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// command -v advances through the path when an entry is absent or unusable.
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
export async function runHandoffSyncPrefetch(args, hqRoot, deps = defaults()) {
|
|
224
|
+
const parsed = parseArgs(args, "prefetch", deps.env);
|
|
225
|
+
if ("code" in parsed)
|
|
226
|
+
return parsed;
|
|
227
|
+
if (!commandOnPath("hq", deps.env))
|
|
228
|
+
return result(0, "missing-cli\n");
|
|
229
|
+
const root = resolveRoot(parsed.root || hqRoot, deps);
|
|
230
|
+
const fd = openLog(parsed.log);
|
|
231
|
+
if (typeof fd !== "number")
|
|
232
|
+
return fd;
|
|
233
|
+
try {
|
|
234
|
+
fs.writeSync(fd, header(deps, root, "prefetch", parsed.timeout));
|
|
235
|
+
const run = await runWithTimeout(deps, fd, parsed.timeout, ["sync", "pull", "--personal", "--hq-root", root, "--lock-timeout", "0"]);
|
|
236
|
+
fs.writeSync(fd, `exit=${run.timedOut ? 124 : run.code}\n`);
|
|
237
|
+
const text = fs.readFileSync(parsed.log, "utf8");
|
|
238
|
+
if (run.timedOut)
|
|
239
|
+
return result(0, "timed-out\n");
|
|
240
|
+
if (run.code === 0)
|
|
241
|
+
return result(0, "ok\n");
|
|
242
|
+
return result(0, /not logged in|no cached session|refused immediately|requires login/i.test(text) ? "skipped\n" : `error:${run.code}\n`);
|
|
243
|
+
}
|
|
244
|
+
finally {
|
|
245
|
+
fs.closeSync(fd);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
export async function runHandoffSyncPublish(args, hqRoot, deps = defaults()) {
|
|
249
|
+
const parsed = parseArgs(args, "publish", deps.env);
|
|
250
|
+
if ("code" in parsed)
|
|
251
|
+
return parsed;
|
|
252
|
+
if (!commandOnPath("hq", deps.env))
|
|
253
|
+
return result(0);
|
|
254
|
+
const root = resolveRoot(parsed.root || hqRoot, deps);
|
|
255
|
+
const fd = openLog(parsed.log);
|
|
256
|
+
if (typeof fd !== "number")
|
|
257
|
+
return fd;
|
|
258
|
+
if (!parsed.child)
|
|
259
|
+
fs.writeSync(fd, header(deps, root, "publish", parsed.timeout, parsed.sync ? "sync" : "background"));
|
|
260
|
+
if (!parsed.sync) {
|
|
261
|
+
fs.closeSync(fd);
|
|
262
|
+
let output;
|
|
263
|
+
try {
|
|
264
|
+
output = fs.openSync(parsed.log, "a");
|
|
265
|
+
}
|
|
266
|
+
catch (cause) {
|
|
267
|
+
return fail(String(cause.message));
|
|
268
|
+
}
|
|
269
|
+
let child;
|
|
270
|
+
try {
|
|
271
|
+
const args = ["core", "--hq-root", root, "handoff-sync-publish", "--timeout", parsed.timeout, "--log", parsed.log, "--child"];
|
|
272
|
+
const plan = buildSpawnPlan("hq", args);
|
|
273
|
+
child = deps.spawn(plan.cmd, plan.args, {
|
|
274
|
+
cwd: deps.cwd, env: deps.env, detached: true, windowsHide: true, stdio: ["ignore", output, output],
|
|
275
|
+
shell: plan.shell,
|
|
276
|
+
...(plan.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}),
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
if (typeof output === "number")
|
|
281
|
+
fs.closeSync(output);
|
|
282
|
+
return fail("handoff-sync-publish: failed to detach hq");
|
|
283
|
+
}
|
|
284
|
+
fs.closeSync(output);
|
|
285
|
+
return new Promise((resolve) => {
|
|
286
|
+
child.once("spawn", () => { child.unref(); resolve(result(0, `${child.pid ?? 0}\n`)); });
|
|
287
|
+
child.once("error", () => resolve(result(0, `${child.pid ?? 0}\n`)));
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
try {
|
|
291
|
+
const run = await runWithTimeout(deps, fd, parsed.timeout, ["sync", "push", "--personal", "--hq-root", root, "--lock-timeout", "0", "--message", "handoff continuity pointer"]);
|
|
292
|
+
fs.writeSync(fd, `exit=${run.timedOut ? 124 : run.code}\n`);
|
|
293
|
+
return result(run.timedOut ? 124 : run.code);
|
|
294
|
+
}
|
|
295
|
+
finally {
|
|
296
|
+
fs.closeSync(fd);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
export const __handoffSyncTest = { parseArgs, exitCode, runWithTimeout, openLog, header, resolveRoot, commandOnPath };
|
|
300
|
+
//# sourceMappingURL=core-bucket-c-handoff-sync-native.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { KNOWLEDGE_PULSE_LOCK_ASSET, runKnowledgePulseLock, runSkillInstalled, SKILL_INSTALLED_ASSET } from "./core-bucket-c-small-native.js";
|
|
2
|
+
export { KNOWLEDGE_PULSE_LOCK_ASSET, SKILL_INSTALLED_ASSET, runKnowledgePulseLock, runSkillInstalled };
|
|
3
|
+
export declare function runKnowledgePulseLockFast(args: string[], _stdin: string, _cwd: string, _root: string): number;
|
|
4
|
+
export declare function runSkillInstalledFast(args: string[], _stdin: string, _cwd: string, root: string): Promise<number>;
|
|
5
|
+
//# sourceMappingURL=core-bucket-c-small-fast.d.ts.map
|