@indigoai-us/hq-cli 5.345.120 → 5.345.122
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 +16 -0
- package/dist/command-catalog.generated.d.ts +169 -0
- package/dist/command-catalog.generated.js +199 -0
- package/dist/command-registration-plan.d.ts +6 -0
- package/dist/command-registration-plan.js +1 -0
- package/dist/commands/capture.d.ts +25 -0
- package/dist/commands/capture.js +95 -0
- package/dist/commands/lanes.js +9 -1
- 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/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
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.345.122] — 2026-10-13
|
|
6
|
+
- `hq capacity` now renews Claude sign-ins on machines with a long lane
|
|
7
|
+
history. Its safety check read the lane list with a 1 MB limit, so on busy
|
|
8
|
+
machines every renewal was skipped and accounts showed as expired until
|
|
9
|
+
Claude Code was opened.
|
|
10
|
+
- `hq capacity login --repair` and `hq capacity accounts` now show the right
|
|
11
|
+
fix for a signed-out default account that no HQ account uses: the
|
|
12
|
+
provider's own login (for example `claude auth login`). Before, they named
|
|
13
|
+
`--account default`, which hq refuses.
|
|
14
|
+
- `hq lanes create --remote-control` now requires `--title <text>` and uses that title as the Claude Remote Control session name. Existing Remote Control lanes retain their previous names when resumed.
|
|
15
|
+
|
|
16
|
+
## [5.345.121] — 2026-10-13
|
|
17
|
+
- `hq capture` ships in this release. It was listed under 5.345.120, but that tag was cut before the change merged, so 5.345.120 does not include it. `hq capture` drives HQ Capture, the hq-capture pack's screen recorder: `doctor`, `build`, `start [--record]`, `record`, `status`, `wait`, `stop`, `run` and `resume` run the pack's launcher from the HQ root with the arguments unchanged and pass its JSON and exit code through. `hq capture record` starts a recording without anyone pressing Start (pack 0.1.3 or later).
|
|
18
|
+
|
|
5
19
|
## [5.345.120] — 2026-10-13
|
|
20
|
+
- Add `hq capture` to drive HQ Capture, the hq-capture pack's screen recorder: `doctor`, `build`, `start [--record]`, `record`, `status`, `wait`, `stop`, `run` and `resume` run the pack's launcher from the HQ root with the arguments unchanged and pass its JSON and exit code through. `hq capture record` starts a recording without anyone pressing Start (pack 0.1.3 or later).
|
|
21
|
+
|
|
6
22
|
- `hq dm forward --company <slug|cmp_id>` names the company a person or agent
|
|
7
23
|
destination belongs to. The CLI sends it as `companyUid`, so the server runs
|
|
8
24
|
its destination-side cross-company check. Without it the destination is
|
|
@@ -1352,6 +1352,171 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
1352
1352
|
readonly hidden: false;
|
|
1353
1353
|
}];
|
|
1354
1354
|
readonly subcommands: readonly [];
|
|
1355
|
+
}, {
|
|
1356
|
+
readonly name: "capture";
|
|
1357
|
+
readonly description: "Record your screen with HQ Capture: start, record, stop, status and wait";
|
|
1358
|
+
readonly aliases: readonly [];
|
|
1359
|
+
readonly hidden: false;
|
|
1360
|
+
readonly helpOption: true;
|
|
1361
|
+
readonly helpCommand: true;
|
|
1362
|
+
readonly usage: "[options] [command]";
|
|
1363
|
+
readonly helpText: readonly [];
|
|
1364
|
+
readonly arguments: readonly [];
|
|
1365
|
+
readonly options: readonly [];
|
|
1366
|
+
readonly subcommands: readonly [{
|
|
1367
|
+
readonly name: "doctor";
|
|
1368
|
+
readonly description: "Check this Mac can build and run HQ Capture";
|
|
1369
|
+
readonly aliases: readonly [];
|
|
1370
|
+
readonly hidden: false;
|
|
1371
|
+
readonly helpOption: false;
|
|
1372
|
+
readonly helpCommand: false;
|
|
1373
|
+
readonly usage: "[args...]";
|
|
1374
|
+
readonly helpText: readonly [];
|
|
1375
|
+
readonly arguments: readonly [{
|
|
1376
|
+
readonly name: "args";
|
|
1377
|
+
readonly required: false;
|
|
1378
|
+
readonly variadic: true;
|
|
1379
|
+
readonly description: "";
|
|
1380
|
+
}];
|
|
1381
|
+
readonly options: readonly [];
|
|
1382
|
+
readonly subcommands: readonly [];
|
|
1383
|
+
}, {
|
|
1384
|
+
readonly name: "build";
|
|
1385
|
+
readonly description: "Build HQ Capture if missing or out of date ([--force])";
|
|
1386
|
+
readonly aliases: readonly [];
|
|
1387
|
+
readonly hidden: false;
|
|
1388
|
+
readonly helpOption: false;
|
|
1389
|
+
readonly helpCommand: false;
|
|
1390
|
+
readonly usage: "[args...]";
|
|
1391
|
+
readonly helpText: readonly [];
|
|
1392
|
+
readonly arguments: readonly [{
|
|
1393
|
+
readonly name: "args";
|
|
1394
|
+
readonly required: false;
|
|
1395
|
+
readonly variadic: true;
|
|
1396
|
+
readonly description: "";
|
|
1397
|
+
}];
|
|
1398
|
+
readonly options: readonly [];
|
|
1399
|
+
readonly subcommands: readonly [];
|
|
1400
|
+
}, {
|
|
1401
|
+
readonly name: "start";
|
|
1402
|
+
readonly description: "Open HQ Capture for the session's company ([--company <slug>] [--record])";
|
|
1403
|
+
readonly aliases: readonly [];
|
|
1404
|
+
readonly hidden: false;
|
|
1405
|
+
readonly helpOption: false;
|
|
1406
|
+
readonly helpCommand: false;
|
|
1407
|
+
readonly usage: "[args...]";
|
|
1408
|
+
readonly helpText: readonly [];
|
|
1409
|
+
readonly arguments: readonly [{
|
|
1410
|
+
readonly name: "args";
|
|
1411
|
+
readonly required: false;
|
|
1412
|
+
readonly variadic: true;
|
|
1413
|
+
readonly description: "";
|
|
1414
|
+
}];
|
|
1415
|
+
readonly options: readonly [];
|
|
1416
|
+
readonly subcommands: readonly [];
|
|
1417
|
+
}, {
|
|
1418
|
+
readonly name: "record";
|
|
1419
|
+
readonly description: "Start recording in the open HQ Capture, as if Start was pressed";
|
|
1420
|
+
readonly aliases: readonly [];
|
|
1421
|
+
readonly hidden: false;
|
|
1422
|
+
readonly helpOption: false;
|
|
1423
|
+
readonly helpCommand: false;
|
|
1424
|
+
readonly usage: "[args...]";
|
|
1425
|
+
readonly helpText: readonly [];
|
|
1426
|
+
readonly arguments: readonly [{
|
|
1427
|
+
readonly name: "args";
|
|
1428
|
+
readonly required: false;
|
|
1429
|
+
readonly variadic: true;
|
|
1430
|
+
readonly description: "";
|
|
1431
|
+
}];
|
|
1432
|
+
readonly options: readonly [];
|
|
1433
|
+
readonly subcommands: readonly [];
|
|
1434
|
+
}, {
|
|
1435
|
+
readonly name: "status";
|
|
1436
|
+
readonly description: "Print HQ Capture's current status as JSON";
|
|
1437
|
+
readonly aliases: readonly [];
|
|
1438
|
+
readonly hidden: false;
|
|
1439
|
+
readonly helpOption: false;
|
|
1440
|
+
readonly helpCommand: false;
|
|
1441
|
+
readonly usage: "[args...]";
|
|
1442
|
+
readonly helpText: readonly [];
|
|
1443
|
+
readonly arguments: readonly [{
|
|
1444
|
+
readonly name: "args";
|
|
1445
|
+
readonly required: false;
|
|
1446
|
+
readonly variadic: true;
|
|
1447
|
+
readonly description: "";
|
|
1448
|
+
}];
|
|
1449
|
+
readonly options: readonly [];
|
|
1450
|
+
readonly subcommands: readonly [];
|
|
1451
|
+
}, {
|
|
1452
|
+
readonly name: "wait";
|
|
1453
|
+
readonly description: "Wait until the recording is saved, failed or closed ([--timeout <seconds>])";
|
|
1454
|
+
readonly aliases: readonly [];
|
|
1455
|
+
readonly hidden: false;
|
|
1456
|
+
readonly helpOption: false;
|
|
1457
|
+
readonly helpCommand: false;
|
|
1458
|
+
readonly usage: "[args...]";
|
|
1459
|
+
readonly helpText: readonly [];
|
|
1460
|
+
readonly arguments: readonly [{
|
|
1461
|
+
readonly name: "args";
|
|
1462
|
+
readonly required: false;
|
|
1463
|
+
readonly variadic: true;
|
|
1464
|
+
readonly description: "";
|
|
1465
|
+
}];
|
|
1466
|
+
readonly options: readonly [];
|
|
1467
|
+
readonly subcommands: readonly [];
|
|
1468
|
+
}, {
|
|
1469
|
+
readonly name: "stop";
|
|
1470
|
+
readonly description: "Stop HQ Capture, saving a recording in progress";
|
|
1471
|
+
readonly aliases: readonly [];
|
|
1472
|
+
readonly hidden: false;
|
|
1473
|
+
readonly helpOption: false;
|
|
1474
|
+
readonly helpCommand: false;
|
|
1475
|
+
readonly usage: "[args...]";
|
|
1476
|
+
readonly helpText: readonly [];
|
|
1477
|
+
readonly arguments: readonly [{
|
|
1478
|
+
readonly name: "args";
|
|
1479
|
+
readonly required: false;
|
|
1480
|
+
readonly variadic: true;
|
|
1481
|
+
readonly description: "";
|
|
1482
|
+
}];
|
|
1483
|
+
readonly options: readonly [];
|
|
1484
|
+
readonly subcommands: readonly [];
|
|
1485
|
+
}, {
|
|
1486
|
+
readonly name: "run";
|
|
1487
|
+
readonly description: "Run an agent command on a saved recording (<mode> <package> [args])";
|
|
1488
|
+
readonly aliases: readonly [];
|
|
1489
|
+
readonly hidden: false;
|
|
1490
|
+
readonly helpOption: false;
|
|
1491
|
+
readonly helpCommand: false;
|
|
1492
|
+
readonly usage: "[args...]";
|
|
1493
|
+
readonly helpText: readonly [];
|
|
1494
|
+
readonly arguments: readonly [{
|
|
1495
|
+
readonly name: "args";
|
|
1496
|
+
readonly required: false;
|
|
1497
|
+
readonly variadic: true;
|
|
1498
|
+
readonly description: "";
|
|
1499
|
+
}];
|
|
1500
|
+
readonly options: readonly [];
|
|
1501
|
+
readonly subcommands: readonly [];
|
|
1502
|
+
}, {
|
|
1503
|
+
readonly name: "resume";
|
|
1504
|
+
readonly description: "Check a pasted resume prompt and print its package (<prompt>)";
|
|
1505
|
+
readonly aliases: readonly [];
|
|
1506
|
+
readonly hidden: false;
|
|
1507
|
+
readonly helpOption: false;
|
|
1508
|
+
readonly helpCommand: false;
|
|
1509
|
+
readonly usage: "[args...]";
|
|
1510
|
+
readonly helpText: readonly [];
|
|
1511
|
+
readonly arguments: readonly [{
|
|
1512
|
+
readonly name: "args";
|
|
1513
|
+
readonly required: false;
|
|
1514
|
+
readonly variadic: true;
|
|
1515
|
+
readonly description: "";
|
|
1516
|
+
}];
|
|
1517
|
+
readonly options: readonly [];
|
|
1518
|
+
readonly subcommands: readonly [];
|
|
1519
|
+
}];
|
|
1355
1520
|
}, {
|
|
1356
1521
|
readonly name: "auth";
|
|
1357
1522
|
readonly description: "Manage the local HQ Cognito session";
|
|
@@ -13169,6 +13334,10 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
13169
13334
|
readonly flags: "--remote-control";
|
|
13170
13335
|
readonly description: "Open a Claude lane in Remote Control using account a for login and the selected account for inference";
|
|
13171
13336
|
readonly hidden: false;
|
|
13337
|
+
}, {
|
|
13338
|
+
readonly flags: "--title <text>";
|
|
13339
|
+
readonly description: "Human-readable Claude Remote Control session title; required with --remote-control";
|
|
13340
|
+
readonly hidden: false;
|
|
13172
13341
|
}, {
|
|
13173
13342
|
readonly flags: "--account <id>";
|
|
13174
13343
|
readonly description: "Provider account id, or 'auto' to pick the account with the most room (all accounts are one pool across companies)";
|
|
@@ -1621,6 +1621,200 @@ export const COMMAND_CATALOG = [
|
|
|
1621
1621
|
],
|
|
1622
1622
|
"subcommands": []
|
|
1623
1623
|
},
|
|
1624
|
+
{
|
|
1625
|
+
"name": "capture",
|
|
1626
|
+
"description": "Record your screen with HQ Capture: start, record, stop, status and wait",
|
|
1627
|
+
"aliases": [],
|
|
1628
|
+
"hidden": false,
|
|
1629
|
+
"helpOption": true,
|
|
1630
|
+
"helpCommand": true,
|
|
1631
|
+
"usage": "[options] [command]",
|
|
1632
|
+
"helpText": [],
|
|
1633
|
+
"arguments": [],
|
|
1634
|
+
"options": [],
|
|
1635
|
+
"subcommands": [
|
|
1636
|
+
{
|
|
1637
|
+
"name": "doctor",
|
|
1638
|
+
"description": "Check this Mac can build and run HQ Capture",
|
|
1639
|
+
"aliases": [],
|
|
1640
|
+
"hidden": false,
|
|
1641
|
+
"helpOption": false,
|
|
1642
|
+
"helpCommand": false,
|
|
1643
|
+
"usage": "[args...]",
|
|
1644
|
+
"helpText": [],
|
|
1645
|
+
"arguments": [
|
|
1646
|
+
{
|
|
1647
|
+
"name": "args",
|
|
1648
|
+
"required": false,
|
|
1649
|
+
"variadic": true,
|
|
1650
|
+
"description": ""
|
|
1651
|
+
}
|
|
1652
|
+
],
|
|
1653
|
+
"options": [],
|
|
1654
|
+
"subcommands": []
|
|
1655
|
+
},
|
|
1656
|
+
{
|
|
1657
|
+
"name": "build",
|
|
1658
|
+
"description": "Build HQ Capture if missing or out of date ([--force])",
|
|
1659
|
+
"aliases": [],
|
|
1660
|
+
"hidden": false,
|
|
1661
|
+
"helpOption": false,
|
|
1662
|
+
"helpCommand": false,
|
|
1663
|
+
"usage": "[args...]",
|
|
1664
|
+
"helpText": [],
|
|
1665
|
+
"arguments": [
|
|
1666
|
+
{
|
|
1667
|
+
"name": "args",
|
|
1668
|
+
"required": false,
|
|
1669
|
+
"variadic": true,
|
|
1670
|
+
"description": ""
|
|
1671
|
+
}
|
|
1672
|
+
],
|
|
1673
|
+
"options": [],
|
|
1674
|
+
"subcommands": []
|
|
1675
|
+
},
|
|
1676
|
+
{
|
|
1677
|
+
"name": "start",
|
|
1678
|
+
"description": "Open HQ Capture for the session's company ([--company <slug>] [--record])",
|
|
1679
|
+
"aliases": [],
|
|
1680
|
+
"hidden": false,
|
|
1681
|
+
"helpOption": false,
|
|
1682
|
+
"helpCommand": false,
|
|
1683
|
+
"usage": "[args...]",
|
|
1684
|
+
"helpText": [],
|
|
1685
|
+
"arguments": [
|
|
1686
|
+
{
|
|
1687
|
+
"name": "args",
|
|
1688
|
+
"required": false,
|
|
1689
|
+
"variadic": true,
|
|
1690
|
+
"description": ""
|
|
1691
|
+
}
|
|
1692
|
+
],
|
|
1693
|
+
"options": [],
|
|
1694
|
+
"subcommands": []
|
|
1695
|
+
},
|
|
1696
|
+
{
|
|
1697
|
+
"name": "record",
|
|
1698
|
+
"description": "Start recording in the open HQ Capture, as if Start was pressed",
|
|
1699
|
+
"aliases": [],
|
|
1700
|
+
"hidden": false,
|
|
1701
|
+
"helpOption": false,
|
|
1702
|
+
"helpCommand": false,
|
|
1703
|
+
"usage": "[args...]",
|
|
1704
|
+
"helpText": [],
|
|
1705
|
+
"arguments": [
|
|
1706
|
+
{
|
|
1707
|
+
"name": "args",
|
|
1708
|
+
"required": false,
|
|
1709
|
+
"variadic": true,
|
|
1710
|
+
"description": ""
|
|
1711
|
+
}
|
|
1712
|
+
],
|
|
1713
|
+
"options": [],
|
|
1714
|
+
"subcommands": []
|
|
1715
|
+
},
|
|
1716
|
+
{
|
|
1717
|
+
"name": "status",
|
|
1718
|
+
"description": "Print HQ Capture's current status as JSON",
|
|
1719
|
+
"aliases": [],
|
|
1720
|
+
"hidden": false,
|
|
1721
|
+
"helpOption": false,
|
|
1722
|
+
"helpCommand": false,
|
|
1723
|
+
"usage": "[args...]",
|
|
1724
|
+
"helpText": [],
|
|
1725
|
+
"arguments": [
|
|
1726
|
+
{
|
|
1727
|
+
"name": "args",
|
|
1728
|
+
"required": false,
|
|
1729
|
+
"variadic": true,
|
|
1730
|
+
"description": ""
|
|
1731
|
+
}
|
|
1732
|
+
],
|
|
1733
|
+
"options": [],
|
|
1734
|
+
"subcommands": []
|
|
1735
|
+
},
|
|
1736
|
+
{
|
|
1737
|
+
"name": "wait",
|
|
1738
|
+
"description": "Wait until the recording is saved, failed or closed ([--timeout <seconds>])",
|
|
1739
|
+
"aliases": [],
|
|
1740
|
+
"hidden": false,
|
|
1741
|
+
"helpOption": false,
|
|
1742
|
+
"helpCommand": false,
|
|
1743
|
+
"usage": "[args...]",
|
|
1744
|
+
"helpText": [],
|
|
1745
|
+
"arguments": [
|
|
1746
|
+
{
|
|
1747
|
+
"name": "args",
|
|
1748
|
+
"required": false,
|
|
1749
|
+
"variadic": true,
|
|
1750
|
+
"description": ""
|
|
1751
|
+
}
|
|
1752
|
+
],
|
|
1753
|
+
"options": [],
|
|
1754
|
+
"subcommands": []
|
|
1755
|
+
},
|
|
1756
|
+
{
|
|
1757
|
+
"name": "stop",
|
|
1758
|
+
"description": "Stop HQ Capture, saving a recording in progress",
|
|
1759
|
+
"aliases": [],
|
|
1760
|
+
"hidden": false,
|
|
1761
|
+
"helpOption": false,
|
|
1762
|
+
"helpCommand": false,
|
|
1763
|
+
"usage": "[args...]",
|
|
1764
|
+
"helpText": [],
|
|
1765
|
+
"arguments": [
|
|
1766
|
+
{
|
|
1767
|
+
"name": "args",
|
|
1768
|
+
"required": false,
|
|
1769
|
+
"variadic": true,
|
|
1770
|
+
"description": ""
|
|
1771
|
+
}
|
|
1772
|
+
],
|
|
1773
|
+
"options": [],
|
|
1774
|
+
"subcommands": []
|
|
1775
|
+
},
|
|
1776
|
+
{
|
|
1777
|
+
"name": "run",
|
|
1778
|
+
"description": "Run an agent command on a saved recording (<mode> <package> [args])",
|
|
1779
|
+
"aliases": [],
|
|
1780
|
+
"hidden": false,
|
|
1781
|
+
"helpOption": false,
|
|
1782
|
+
"helpCommand": false,
|
|
1783
|
+
"usage": "[args...]",
|
|
1784
|
+
"helpText": [],
|
|
1785
|
+
"arguments": [
|
|
1786
|
+
{
|
|
1787
|
+
"name": "args",
|
|
1788
|
+
"required": false,
|
|
1789
|
+
"variadic": true,
|
|
1790
|
+
"description": ""
|
|
1791
|
+
}
|
|
1792
|
+
],
|
|
1793
|
+
"options": [],
|
|
1794
|
+
"subcommands": []
|
|
1795
|
+
},
|
|
1796
|
+
{
|
|
1797
|
+
"name": "resume",
|
|
1798
|
+
"description": "Check a pasted resume prompt and print its package (<prompt>)",
|
|
1799
|
+
"aliases": [],
|
|
1800
|
+
"hidden": false,
|
|
1801
|
+
"helpOption": false,
|
|
1802
|
+
"helpCommand": false,
|
|
1803
|
+
"usage": "[args...]",
|
|
1804
|
+
"helpText": [],
|
|
1805
|
+
"arguments": [
|
|
1806
|
+
{
|
|
1807
|
+
"name": "args",
|
|
1808
|
+
"required": false,
|
|
1809
|
+
"variadic": true,
|
|
1810
|
+
"description": ""
|
|
1811
|
+
}
|
|
1812
|
+
],
|
|
1813
|
+
"options": [],
|
|
1814
|
+
"subcommands": []
|
|
1815
|
+
}
|
|
1816
|
+
]
|
|
1817
|
+
},
|
|
1624
1818
|
{
|
|
1625
1819
|
"name": "auth",
|
|
1626
1820
|
"description": "Manage the local HQ Cognito session",
|
|
@@ -16012,6 +16206,11 @@ export const COMMAND_CATALOG = [
|
|
|
16012
16206
|
"description": "Open a Claude lane in Remote Control using account a for login and the selected account for inference",
|
|
16013
16207
|
"hidden": false
|
|
16014
16208
|
},
|
|
16209
|
+
{
|
|
16210
|
+
"flags": "--title <text>",
|
|
16211
|
+
"description": "Human-readable Claude Remote Control session title; required with --remote-control",
|
|
16212
|
+
"hidden": false
|
|
16213
|
+
},
|
|
16015
16214
|
{
|
|
16016
16215
|
"flags": "--account <id>",
|
|
16017
16216
|
"description": "Provider account id, or 'auto' to pick the account with the most room (all accounts are one pool across companies)",
|
|
@@ -213,6 +213,12 @@ export declare const REGISTRATION_PLAN: readonly [{
|
|
|
213
213
|
readonly parent: "program";
|
|
214
214
|
readonly module: "./commands/version.js";
|
|
215
215
|
readonly exportName: "registerVersionCommand";
|
|
216
|
+
}, {
|
|
217
|
+
readonly type: "registrar";
|
|
218
|
+
readonly root: "capture";
|
|
219
|
+
readonly parent: "program";
|
|
220
|
+
readonly module: "./commands/capture.js";
|
|
221
|
+
readonly exportName: "registerCaptureCommand";
|
|
216
222
|
}, {
|
|
217
223
|
readonly type: "registrar";
|
|
218
224
|
readonly root: "auth";
|
|
@@ -38,6 +38,7 @@ export const REGISTRATION_PLAN = [
|
|
|
38
38
|
{ type: "registrar", root: "resolve-company", parent: "program", module: "./commands/link.js", exportName: "registerResolveCompanyCommand" },
|
|
39
39
|
{ type: "registrar", root: "provider", parent: "program", module: "./commands/provider.js", exportName: "registerProviderCommand" },
|
|
40
40
|
{ type: "registrar", root: "version", parent: "program", module: "./commands/version.js", exportName: "registerVersionCommand" },
|
|
41
|
+
{ type: "registrar", root: "capture", parent: "program", module: "./commands/capture.js", exportName: "registerCaptureCommand" },
|
|
41
42
|
{ type: "registrar", root: "auth", parent: "program", module: "./commands/auth.js", exportName: "registerAuthCommands" },
|
|
42
43
|
{ type: "registrar", root: "secrets", parent: "program", module: "./commands/secrets.js", exportName: "registerSecretsCommand" },
|
|
43
44
|
{ type: "registrar", root: "db", parent: "program", module: "./commands/db.js", exportName: "registerDbCommand" },
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hq capture — drive HQ Capture (the hq-capture pack's screen recorder) from the CLI.
|
|
3
|
+
*
|
|
4
|
+
* Every subcommand runs the pack's launcher, `hq-record-process.sh`, from the HQ root with
|
|
5
|
+
* the arguments unchanged. The launcher owns company binding, the app's control folder and
|
|
6
|
+
* its JSON output; this command adds nothing to them, so the pack stays the one source of
|
|
7
|
+
* truth for what each subcommand does. The launcher's exit code becomes the CLI's (3 means
|
|
8
|
+
* `wait` timed out with HQ Capture still open).
|
|
9
|
+
*/
|
|
10
|
+
import { type StdioOptions } from "node:child_process";
|
|
11
|
+
import type { Command } from "commander";
|
|
12
|
+
export declare const CAPTURE_LAUNCHER = "core/packages/hq-pack-hq-capture/scripts/hq-record-process.sh";
|
|
13
|
+
export declare const CAPTURE_SUBCOMMANDS: readonly ["doctor", "build", "start", "record", "status", "wait", "stop", "run", "resume"];
|
|
14
|
+
export interface CaptureRunOptions {
|
|
15
|
+
root: string;
|
|
16
|
+
stdio?: StdioOptions;
|
|
17
|
+
}
|
|
18
|
+
/** Runs the launcher with `args` and returns its exit code. */
|
|
19
|
+
export declare function runCapture(args: readonly string[], opts: CaptureRunOptions): number;
|
|
20
|
+
export interface CaptureRegisterOptions {
|
|
21
|
+
root?: () => string;
|
|
22
|
+
stdio?: StdioOptions;
|
|
23
|
+
}
|
|
24
|
+
export declare function registerCaptureCommand(program: Command, opts?: CaptureRegisterOptions): Command;
|
|
25
|
+
//# sourceMappingURL=capture.d.ts.map
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hq capture — drive HQ Capture (the hq-capture pack's screen recorder) from the CLI.
|
|
3
|
+
*
|
|
4
|
+
* Every subcommand runs the pack's launcher, `hq-record-process.sh`, from the HQ root with
|
|
5
|
+
* the arguments unchanged. The launcher owns company binding, the app's control folder and
|
|
6
|
+
* its JSON output; this command adds nothing to them, so the pack stays the one source of
|
|
7
|
+
* truth for what each subcommand does. The launcher's exit code becomes the CLI's (3 means
|
|
8
|
+
* `wait` timed out with HQ Capture still open).
|
|
9
|
+
*/
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
11
|
+
import * as fs from "node:fs";
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import { resolveDefaultHqRoot } from "../utils/hq-root-resolver.js";
|
|
14
|
+
export const CAPTURE_LAUNCHER = "core/packages/hq-pack-hq-capture/scripts/hq-record-process.sh";
|
|
15
|
+
export const CAPTURE_SUBCOMMANDS = [
|
|
16
|
+
"doctor",
|
|
17
|
+
"build",
|
|
18
|
+
"start",
|
|
19
|
+
"record",
|
|
20
|
+
"status",
|
|
21
|
+
"wait",
|
|
22
|
+
"stop",
|
|
23
|
+
"run",
|
|
24
|
+
"resume",
|
|
25
|
+
];
|
|
26
|
+
const DESCRIPTIONS = {
|
|
27
|
+
doctor: "Check this Mac can build and run HQ Capture",
|
|
28
|
+
build: "Build HQ Capture if missing or out of date ([--force])",
|
|
29
|
+
start: "Open HQ Capture for the session's company ([--company <slug>] [--record])",
|
|
30
|
+
record: "Start recording in the open HQ Capture, as if Start was pressed",
|
|
31
|
+
status: "Print HQ Capture's current status as JSON",
|
|
32
|
+
wait: "Wait until the recording is saved, failed or closed ([--timeout <seconds>])",
|
|
33
|
+
stop: "Stop HQ Capture, saving a recording in progress",
|
|
34
|
+
run: "Run an agent command on a saved recording (<mode> <package> [args])",
|
|
35
|
+
resume: "Check a pasted resume prompt and print its package (<prompt>)",
|
|
36
|
+
};
|
|
37
|
+
/** Runs the launcher with `args` and returns its exit code. */
|
|
38
|
+
export function runCapture(args, opts) {
|
|
39
|
+
const launcher = path.join(opts.root, CAPTURE_LAUNCHER);
|
|
40
|
+
if (!fs.existsSync(launcher)) {
|
|
41
|
+
process.stderr.write("HQ Capture is not installed in this HQ. Install it with: hq install hq-capture\n");
|
|
42
|
+
return 1;
|
|
43
|
+
}
|
|
44
|
+
const result = spawnSync("bash", [launcher, ...args], {
|
|
45
|
+
cwd: opts.root,
|
|
46
|
+
stdio: opts.stdio ?? "inherit",
|
|
47
|
+
env: process.env,
|
|
48
|
+
});
|
|
49
|
+
if (result.error) {
|
|
50
|
+
process.stderr.write(`Could not run HQ Capture: ${result.error.message}\n`);
|
|
51
|
+
return 1;
|
|
52
|
+
}
|
|
53
|
+
if (result.signal)
|
|
54
|
+
return 1;
|
|
55
|
+
return result.status ?? 1;
|
|
56
|
+
}
|
|
57
|
+
export function registerCaptureCommand(program, opts = {}) {
|
|
58
|
+
const capture = program
|
|
59
|
+
.command("capture")
|
|
60
|
+
.description("Record your screen with HQ Capture: start, record, stop, status and wait");
|
|
61
|
+
for (const name of CAPTURE_SUBCOMMANDS) {
|
|
62
|
+
capture
|
|
63
|
+
.command(name)
|
|
64
|
+
.description(DESCRIPTIONS[name])
|
|
65
|
+
.argument("[args...]")
|
|
66
|
+
.allowUnknownOption(true)
|
|
67
|
+
.allowExcessArguments(true)
|
|
68
|
+
.helpOption(false)
|
|
69
|
+
.action((_args, _options, command) => {
|
|
70
|
+
const root = opts.root ? opts.root() : resolveDefaultHqRoot({ onMissing: "throw" });
|
|
71
|
+
const forwarded = rawArgsAfter(command, name) ?? command.args;
|
|
72
|
+
process.exitCode = runCapture([name, ...forwarded], { root, stdio: opts.stdio });
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return capture;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The arguments typed after `capture <name>`, exactly as given. Commander drops a `--`
|
|
79
|
+
* separator from `command.args`, which would change what the launcher receives, so the
|
|
80
|
+
* slice comes from the root command's raw argv. Returns undefined when it can't be found.
|
|
81
|
+
*/
|
|
82
|
+
function rawArgsAfter(command, name) {
|
|
83
|
+
let root = command;
|
|
84
|
+
while (root.parent)
|
|
85
|
+
root = root.parent;
|
|
86
|
+
const raw = root.rawArgs;
|
|
87
|
+
if (!Array.isArray(raw))
|
|
88
|
+
return undefined;
|
|
89
|
+
for (let i = 0; i + 1 < raw.length; i++) {
|
|
90
|
+
if (raw[i] === "capture" && raw[i + 1] === name)
|
|
91
|
+
return raw.slice(i + 2);
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=capture.js.map
|
package/dist/commands/lanes.js
CHANGED
|
@@ -3454,6 +3454,13 @@ async function runCreate(ctx, opts) {
|
|
|
3454
3454
|
if (opts.remoteControl === true && provider !== "claude") {
|
|
3455
3455
|
throw new LanesError("remote_control_requires_claude", "--remote-control requires a Claude lane", { provider });
|
|
3456
3456
|
}
|
|
3457
|
+
const remoteControlTitle = opts.title?.trim();
|
|
3458
|
+
if (opts.remoteControl === true && (!remoteControlTitle || remoteControlTitle.length > 80 || /\p{Cc}/u.test(remoteControlTitle))) {
|
|
3459
|
+
throw new LanesError("remote_control_title_required", "--remote-control requires --title with 1–80 printable characters", {});
|
|
3460
|
+
}
|
|
3461
|
+
if (opts.remoteControl !== true && opts.title !== undefined) {
|
|
3462
|
+
throw new LanesError("lane_title_requires_remote_control", "--title is only supported with --remote-control", {});
|
|
3463
|
+
}
|
|
3457
3464
|
const continuityEnabled = opts.remoteControl !== true && opts.worker !== undefined && await readLanesRegistryFlagFailOpen(LANE_WORKER_CONTINUITY_FLAG, { company: company ?? meshCompany, env: ctx.env, defaultValue: true });
|
|
3458
3465
|
let workerContinuity = continuityEnabled
|
|
3459
3466
|
? findWorkerContinuityLane(loadAllLanes(hqRoot), {
|
|
@@ -4017,7 +4024,7 @@ async function runCreate(ctx, opts) {
|
|
|
4017
4024
|
...(opts.loop === true ? { loop_mode: true } : {}),
|
|
4018
4025
|
...(keepAlive ? { keep_alive_opted_in_at: createdAt } : {}),
|
|
4019
4026
|
provider,
|
|
4020
|
-
...(opts.remoteControl === true ? { remote_control: true } : {}),
|
|
4027
|
+
...(opts.remoteControl === true ? { remote_control: true, remote_control_title: remoteControlTitle } : {}),
|
|
4021
4028
|
...(workerContinuity.resumable && workerContinuity.previous
|
|
4022
4029
|
? {
|
|
4023
4030
|
provider_session_id: workerContinuity.previous.provider_session_id,
|
|
@@ -9732,6 +9739,7 @@ export function registerLanesCommand(parent, deps = {}) {
|
|
|
9732
9739
|
.option("--loop", "Keep one worker lane registered to process queued phase envelopes")
|
|
9733
9740
|
.option("--provider <name>", "claude | codex | grok")
|
|
9734
9741
|
.option("--remote-control", "Open a Claude lane in Remote Control using account a for login and the selected account for inference")
|
|
9742
|
+
.option("--title <text>", "Human-readable Claude Remote Control session title; required with --remote-control")
|
|
9735
9743
|
.option("--account <id>", "Provider account id, or 'auto' to pick the account with the most room (all accounts are one pool across companies)")
|
|
9736
9744
|
.option("--model <id>", "Model id for the provider CLI")
|
|
9737
9745
|
.option("--effort <level>", "Effort level; claude: low|medium|high|xhigh|max, codex: minimal|low|medium|high|xhigh|max|ultra, grok: low|medium|high|xhigh")
|
|
@@ -339,7 +339,7 @@ interface RawAccountRow {
|
|
|
339
339
|
* Falls back to `hq` on PATH when this process is not the hq CLI (tests,
|
|
340
340
|
* embedders). Exported for tests.
|
|
341
341
|
*/
|
|
342
|
-
export declare function resolveHqInvocation(argv?: readonly string[], execPath?: string): {
|
|
342
|
+
export declare function resolveHqInvocation(argv?: readonly string[], execPath?: string, execArgv?: readonly string[]): {
|
|
343
343
|
command: string;
|
|
344
344
|
args: string[];
|
|
345
345
|
};
|
|
@@ -1687,6 +1687,37 @@ const defaultWriteClaudeCredentials = async (request) => {
|
|
|
1687
1687
|
}
|
|
1688
1688
|
};
|
|
1689
1689
|
const HQ_CLI_PACKAGE_NAME = "@indigoai-us/hq-cli";
|
|
1690
|
+
const LOADER_FLAGS_WITH_VALUE = new Set(["--import", "--loader", "--experimental-loader", "--require", "-r", "--conditions", "-C"]);
|
|
1691
|
+
const LOADER_FLAGS_BARE = new Set(["--experimental-strip-types", "--experimental-transform-types"]);
|
|
1692
|
+
/**
|
|
1693
|
+
* Node flags that load a TypeScript runner (tsx and similar). A dev run of the TS
|
|
1694
|
+
* source needs them again in the child or `node src/index.ts` fails; compiled `.js`
|
|
1695
|
+
* entries get none. Other exec flags (`--inspect`, memory limits) are not copied.
|
|
1696
|
+
*/
|
|
1697
|
+
function loaderArgsForSource(entry, execArgv) {
|
|
1698
|
+
if (!/\.(?:[cm]?ts|tsx)$/.test(entry))
|
|
1699
|
+
return [];
|
|
1700
|
+
const out = [];
|
|
1701
|
+
for (let i = 0; i < execArgv.length; i += 1) {
|
|
1702
|
+
const arg = execArgv[i];
|
|
1703
|
+
const eq = arg.indexOf("=");
|
|
1704
|
+
const flag = eq === -1 ? arg : arg.slice(0, eq);
|
|
1705
|
+
if (LOADER_FLAGS_BARE.has(arg)) {
|
|
1706
|
+
out.push(arg);
|
|
1707
|
+
continue;
|
|
1708
|
+
}
|
|
1709
|
+
if (!LOADER_FLAGS_WITH_VALUE.has(flag))
|
|
1710
|
+
continue;
|
|
1711
|
+
if (eq !== -1) {
|
|
1712
|
+
out.push(arg);
|
|
1713
|
+
}
|
|
1714
|
+
else if (i + 1 < execArgv.length) {
|
|
1715
|
+
out.push(arg, execArgv[i + 1]);
|
|
1716
|
+
i += 1;
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
return out;
|
|
1720
|
+
}
|
|
1690
1721
|
/**
|
|
1691
1722
|
* How to re-invoke the running hq CLI without a PATH lookup. When argv[1] is
|
|
1692
1723
|
* the entry of an installed hq-cli package, run it with the same node binary;
|
|
@@ -1694,7 +1725,7 @@ const HQ_CLI_PACKAGE_NAME = "@indigoai-us/hq-cli";
|
|
|
1694
1725
|
* Falls back to `hq` on PATH when this process is not the hq CLI (tests,
|
|
1695
1726
|
* embedders). Exported for tests.
|
|
1696
1727
|
*/
|
|
1697
|
-
export function resolveHqInvocation(argv = process.argv, execPath = process.execPath) {
|
|
1728
|
+
export function resolveHqInvocation(argv = process.argv, execPath = process.execPath, execArgv = process.execArgv) {
|
|
1698
1729
|
const entry = argv[1];
|
|
1699
1730
|
if (entry) {
|
|
1700
1731
|
try {
|
|
@@ -1704,8 +1735,9 @@ export function resolveHqInvocation(argv = process.argv, execPath = process.exec
|
|
|
1704
1735
|
const manifest = path.join(dir, "package.json");
|
|
1705
1736
|
if (fs.existsSync(manifest)) {
|
|
1706
1737
|
const parsed = JSON.parse(fs.readFileSync(manifest, "utf8"));
|
|
1707
|
-
if (parsed.name === HQ_CLI_PACKAGE_NAME)
|
|
1708
|
-
return { command: execPath, args: [real] };
|
|
1738
|
+
if (parsed.name === HQ_CLI_PACKAGE_NAME) {
|
|
1739
|
+
return { command: execPath, args: [...loaderArgsForSource(real, execArgv), real] };
|
|
1740
|
+
}
|
|
1709
1741
|
break;
|
|
1710
1742
|
}
|
|
1711
1743
|
const parent = path.dirname(dir);
|
|
@@ -1720,12 +1752,20 @@ export function resolveHqInvocation(argv = process.argv, execPath = process.exec
|
|
|
1720
1752
|
}
|
|
1721
1753
|
return { command: "hq", args: [] };
|
|
1722
1754
|
}
|
|
1755
|
+
/** Output cap for the `hq ... --json` reads behind the refresh gates. */
|
|
1756
|
+
const HQ_JSON_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
|
|
1757
|
+
const HQ_JSON_TIMEOUT_MS = 15_000;
|
|
1723
1758
|
/** Exported for tests; `invocation` defaults to {@link resolveHqInvocation}. */
|
|
1724
1759
|
export function execHqJson(args, invocation = resolveHqInvocation(), env = process.env) {
|
|
1725
1760
|
const result = spawnSync(invocation.command, [...invocation.args, ...args], {
|
|
1726
1761
|
env,
|
|
1727
1762
|
encoding: "utf8",
|
|
1728
|
-
|
|
1763
|
+
// The lane list takes ~2.5 s on a busy machine and grows with lane history; 5 s left too
|
|
1764
|
+
// little headroom under load, and a timeout fails the gate closed.
|
|
1765
|
+
timeout: HQ_JSON_TIMEOUT_MS,
|
|
1766
|
+
// `hq lanes list --json` grows with lane history (1.7 MB on a busy machine). The spawnSync
|
|
1767
|
+
// default of 1 MiB raised ENOBUFS, which made the live-lane gate fail closed on every collect.
|
|
1768
|
+
maxBuffer: HQ_JSON_MAX_BUFFER_BYTES,
|
|
1729
1769
|
windowsHide: true,
|
|
1730
1770
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1731
1771
|
});
|
|
@@ -1733,6 +1773,8 @@ export function execHqJson(args, invocation = resolveHqInvocation(), env = proce
|
|
|
1733
1773
|
const code = result.error.code;
|
|
1734
1774
|
if (code === "ETIMEDOUT")
|
|
1735
1775
|
throw new Error(`hq ${args.join(" ")} timed out`);
|
|
1776
|
+
if (code === "ENOBUFS")
|
|
1777
|
+
throw new Error(`hq ${args.join(" ")} output exceeded ${HQ_JSON_MAX_BUFFER_BYTES} bytes`);
|
|
1736
1778
|
throw new Error(`hq ${args.join(" ")} failed to spawn: ${result.error.message}`);
|
|
1737
1779
|
}
|
|
1738
1780
|
if (result.signal)
|
|
@@ -1933,6 +1975,8 @@ const defaultListProcesses = async () => {
|
|
|
1933
1975
|
const result = spawnSync("ps", ["-axo", "pid=,command="], {
|
|
1934
1976
|
encoding: "utf8",
|
|
1935
1977
|
timeout: 5_000,
|
|
1978
|
+
// Full command lines for every process can pass the 1 MiB default on a busy machine.
|
|
1979
|
+
maxBuffer: HQ_JSON_MAX_BUFFER_BYTES,
|
|
1936
1980
|
windowsHide: true,
|
|
1937
1981
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1938
1982
|
});
|
|
@@ -386,6 +386,13 @@ export declare function isExpiredReason(reason: string | null | undefined): bool
|
|
|
386
386
|
export declare function isAccountFailureReason(reason: string): boolean;
|
|
387
387
|
/** Exact command for an account that has no usable credential. */
|
|
388
388
|
export declare function capacityLoginCommand(provider: string, label: string): string;
|
|
389
|
+
/**
|
|
390
|
+
* Fix for a signed-out default home that no HQ account is registered on. `hq capacity login
|
|
391
|
+
* <provider> --account default` is refused (reserved id), and without --account it signs a new
|
|
392
|
+
* account into a new home, leaving the default home signed out. The vendor's own login in the
|
|
393
|
+
* default home is the one command that signs that home back in.
|
|
394
|
+
*/
|
|
395
|
+
export declare function defaultHomeLoginCommand(provider: string): string;
|
|
389
396
|
/** Open the vendor CLI so it can refresh its own token. Does not refresh anything. */
|
|
390
397
|
export declare function claudeOpenCommand(home: string | null, userHome?: string): string;
|
|
391
398
|
export declare function redactProviderTokens(text: string): string;
|
|
@@ -211,6 +211,20 @@ export function capacityLoginCommand(provider, label) {
|
|
|
211
211
|
const safe = /^[A-Za-z0-9._-]+$/.test(label) ? label : `'${label.replace(/'/g, `'\\''`)}'`;
|
|
212
212
|
return `hq capacity login ${provider} --account ${safe}`;
|
|
213
213
|
}
|
|
214
|
+
const DEFAULT_HOME_VENDOR_LOGIN = {
|
|
215
|
+
claude: "claude auth login",
|
|
216
|
+
codex: "codex login",
|
|
217
|
+
grok: "grok login",
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Fix for a signed-out default home that no HQ account is registered on. `hq capacity login
|
|
221
|
+
* <provider> --account default` is refused (reserved id), and without --account it signs a new
|
|
222
|
+
* account into a new home, leaving the default home signed out. The vendor's own login in the
|
|
223
|
+
* default home is the one command that signs that home back in.
|
|
224
|
+
*/
|
|
225
|
+
export function defaultHomeLoginCommand(provider) {
|
|
226
|
+
return DEFAULT_HOME_VENDOR_LOGIN[provider] ?? capacityLoginCommand(provider, "default");
|
|
227
|
+
}
|
|
214
228
|
/** Open the vendor CLI so it can refresh its own token. Does not refresh anything. */
|
|
215
229
|
export function claudeOpenCommand(home, userHome = os.homedir()) {
|
|
216
230
|
const fallback = path.resolve(userHome, ".claude");
|
|
@@ -1053,7 +1067,9 @@ function clusterAccounts(provider, events) {
|
|
|
1053
1067
|
fixCommand: expired
|
|
1054
1068
|
? (provider.provider === "claude" ? claudeOpenCommand(home) : null)
|
|
1055
1069
|
: isSignedOut
|
|
1056
|
-
?
|
|
1070
|
+
? (primary === "default"
|
|
1071
|
+
? defaultHomeLoginCommand(provider.provider)
|
|
1072
|
+
: capacityLoginCommand(provider.provider, primary))
|
|
1057
1073
|
: null,
|
|
1058
1074
|
usageStale: usageStale ? true : undefined,
|
|
1059
1075
|
limits,
|
|
@@ -20,6 +20,8 @@ export interface RosterRow {
|
|
|
20
20
|
home: string;
|
|
21
21
|
/** True when the registry account is read for usage and is not used by lanes. */
|
|
22
22
|
usageOnly?: boolean;
|
|
23
|
+
/** The default home with no HQ account registered on it. Only the vendor login fixes it. */
|
|
24
|
+
unregisteredDefault?: boolean;
|
|
23
25
|
}
|
|
24
26
|
/** Sentence printed for an expired Claude credential. Other commands pass through. */
|
|
25
27
|
export declare function formatRefreshLine(provider: string, command: string): string;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import * as fs from "node:fs";
|
|
10
10
|
import * as path from "node:path";
|
|
11
11
|
import { defaultProviderHome } from "./accounts.js";
|
|
12
|
-
import { EXPIRED_REASON, claudeOpenCommand, isExpiredReason, } from "./ledger.js";
|
|
12
|
+
import { EXPIRED_REASON, capacityLoginCommand, claudeOpenCommand, defaultHomeLoginCommand, isExpiredReason, } from "./ledger.js";
|
|
13
13
|
import { effectiveAccountHome } from "../lanes/account-home.js";
|
|
14
14
|
import { canonicalizeHome, loadLanesConfig, writeLanesConfig } from "../lanes/config.js";
|
|
15
15
|
import { LANE_PROVIDERS, parseLaneProvider } from "../lanes/types.js";
|
|
@@ -132,11 +132,18 @@ export function rosterFrom(accounts, view, userHome) {
|
|
|
132
132
|
if (account.label === "default")
|
|
133
133
|
defaultHome.set(account.provider, path.resolve(account.home));
|
|
134
134
|
}
|
|
135
|
+
const registeredDefault = new Set();
|
|
136
|
+
for (const account of accounts) {
|
|
137
|
+
const home = defaultHome.get(account.provider);
|
|
138
|
+
if (account.label !== "default" && home && path.resolve(account.home) === home)
|
|
139
|
+
registeredDefault.add(account.provider);
|
|
140
|
+
}
|
|
135
141
|
const rows = [];
|
|
136
142
|
for (const account of accounts) {
|
|
137
143
|
const folded = defaultHome.get(account.provider);
|
|
138
144
|
if (account.label !== "default" && folded && path.resolve(account.home) === folded)
|
|
139
145
|
continue;
|
|
146
|
+
const unregisteredDefault = account.label === "default" && !registeredDefault.has(account.provider);
|
|
140
147
|
const group = view.providers.find((provider) => provider.provider === account.provider);
|
|
141
148
|
const match = matchAccount(group?.accounts, account);
|
|
142
149
|
const presented = match
|
|
@@ -149,11 +156,14 @@ export function rosterFrom(accounts, view, userHome) {
|
|
|
149
156
|
state: presented.state,
|
|
150
157
|
reason: presented.reason,
|
|
151
158
|
command: presented.state === "signed_out"
|
|
152
|
-
?
|
|
159
|
+
? unregisteredDefault
|
|
160
|
+
? defaultHomeLoginCommand(account.provider)
|
|
161
|
+
: presented.command ?? capacityLoginCommand(account.provider, account.label)
|
|
153
162
|
: presented.command,
|
|
154
163
|
observedAt: match?.observedAt ?? latestLimitAt(match),
|
|
155
164
|
home: account.home,
|
|
156
165
|
usageOnly: account.lanes === false,
|
|
166
|
+
...(unregisteredDefault ? { unregisteredDefault: true } : {}),
|
|
157
167
|
});
|
|
158
168
|
}
|
|
159
169
|
return rows;
|
|
@@ -225,7 +235,7 @@ function formatRepairPlan(plan) {
|
|
|
225
235
|
else {
|
|
226
236
|
lines.push("Signed out (login again):");
|
|
227
237
|
for (const row of plan.signedOut) {
|
|
228
|
-
lines.push(row.command ??
|
|
238
|
+
lines.push(row.command ?? capacityLoginCommand(row.provider, row.label));
|
|
229
239
|
}
|
|
230
240
|
}
|
|
231
241
|
if (plan.expired.length > 0) {
|
|
@@ -322,7 +332,12 @@ async function runRepair(request, deps) {
|
|
|
322
332
|
const fixed = [];
|
|
323
333
|
const skipped = [];
|
|
324
334
|
for (const row of plan.signedOut) {
|
|
325
|
-
const fix = row.command ??
|
|
335
|
+
const fix = row.command ?? capacityLoginCommand(row.provider, row.label);
|
|
336
|
+
if (row.unregisteredDefault) {
|
|
337
|
+
// No HQ account owns this home, so the lane login would refuse it. Name the vendor login.
|
|
338
|
+
skipped.push({ provider: row.provider, label: row.label, reason: "no HQ account uses the default home", fix });
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
326
341
|
let logged;
|
|
327
342
|
try {
|
|
328
343
|
logged = await deps.loginAccount(row.provider, row.label);
|
|
@@ -222,6 +222,7 @@ export interface ProviderResumeInput {
|
|
|
222
222
|
session_id: string;
|
|
223
223
|
prompt: string;
|
|
224
224
|
}
|
|
225
|
+
export declare function remoteControlLaneName(lane: Pick<LaneRecord, "lane_id" | "remote_control_title">): string;
|
|
225
226
|
export declare function buildProviderCommand(provider: LaneProvider, input: {
|
|
226
227
|
hqRoot: string;
|
|
227
228
|
briefPath: string;
|
package/dist/lib/lanes/spawn.js
CHANGED
|
@@ -1528,6 +1528,9 @@ export function envelopeRepairPrompt(input) {
|
|
|
1528
1528
|
`Output only that JSON. Do not add keys the schema does not name, and do not resume the task.`,
|
|
1529
1529
|
].join("\n\n");
|
|
1530
1530
|
}
|
|
1531
|
+
export function remoteControlLaneName(lane) {
|
|
1532
|
+
return lane.remote_control_title ?? `hq/${lane.lane_id}`;
|
|
1533
|
+
}
|
|
1531
1534
|
export function buildProviderCommand(provider, input) {
|
|
1532
1535
|
const parsed = parseLaneProvider(provider);
|
|
1533
1536
|
const command = PROVIDER_COMMAND[parsed];
|
|
@@ -2481,7 +2484,7 @@ export function spawnLaneWorker(hqRoot, lane, deps = {}, launch = {}) {
|
|
|
2481
2484
|
profile: profileLaunch,
|
|
2482
2485
|
workerPolicyDir,
|
|
2483
2486
|
resume,
|
|
2484
|
-
...(remoteSessionId ? { remoteControl: { sessionId: remoteSessionId, name:
|
|
2487
|
+
...(remoteSessionId ? { remoteControl: { sessionId: remoteSessionId, name: remoteControlLaneName(lane) } } : {}),
|
|
2485
2488
|
});
|
|
2486
2489
|
const remoteLaunch = remoteSessionId
|
|
2487
2490
|
? prepareRemoteControlLane({
|
package/dist/lib/lanes/store.js
CHANGED
|
@@ -433,6 +433,17 @@ export function parseLaneRecord(raw, filePath) {
|
|
|
433
433
|
value: raw.remote_control,
|
|
434
434
|
});
|
|
435
435
|
}
|
|
436
|
+
if (raw.remote_control_title !== undefined && (raw.remote_control !== true ||
|
|
437
|
+
typeof raw.remote_control_title !== "string" ||
|
|
438
|
+
raw.remote_control_title.trim() !== raw.remote_control_title ||
|
|
439
|
+
raw.remote_control_title.length < 1 ||
|
|
440
|
+
raw.remote_control_title.length > 80 ||
|
|
441
|
+
/\p{Cc}/u.test(raw.remote_control_title))) {
|
|
442
|
+
throw new LaneSchemaError("remote_control_title requires a Claude Remote Control lane and 1–80 printable characters", {
|
|
443
|
+
path: filePath,
|
|
444
|
+
field: "remote_control_title",
|
|
445
|
+
});
|
|
446
|
+
}
|
|
436
447
|
if (raw.written_by_version !== undefined) {
|
|
437
448
|
const writtenByVersion = requireString(raw.written_by_version, "written_by_version");
|
|
438
449
|
if (!semver.valid(writtenByVersion)) {
|
|
@@ -614,6 +614,8 @@ export interface LaneRecord {
|
|
|
614
614
|
provider: LaneProvider;
|
|
615
615
|
/** Open each Claude turn as a named Remote Control session using account a's login. */
|
|
616
616
|
remote_control?: boolean;
|
|
617
|
+
/** Human-readable Remote Control name, fixed when the lane is created. Older lanes may lack it. */
|
|
618
|
+
remote_control_title?: string;
|
|
617
619
|
/** Whether provider came from an explicit create override, the router (`--account auto`), or the worker profile/default. */
|
|
618
620
|
provider_source?: "cli" | "profile" | "default" | "auto";
|
|
619
621
|
account?: string;
|
package/dist/lib/lanes/types.js
CHANGED
|
@@ -235,7 +235,7 @@ export const LANE_FIELD_WRITERS = {
|
|
|
235
235
|
pickup_validation_pending_since: ["creator", "command", "spawn", "reconcile"],
|
|
236
236
|
priority: ["command"], worker: ["creator", "command"], worker_path: ["creator", "command"], worker_pack: ["creator", "command"], worker_profile: ["creator", "command"], worker_profile_hash: ["creator", "command", "spawn"], registry_worker: ["creator", "command", "spawn"], registry_worker_approval_history: ["command", "watcher", "reconcile"], worker_profile_repin_history: ["command"], worker_profile_ignored: ["creator", "command", "spawn"], worker_policy_delivery: ["command", "spawn"],
|
|
237
237
|
keep_alive: ["creator", "command"], keep_alive_standing: ["command"], keep_alive_opted_in_at: ["creator", "command"], keep_alive_blocked_reason: ["command", "reconcile"], keep_alive_resume_count: ["command", "reconcile", "spawn"], keep_alive_history: ["reconcile"], keep_alive_blocked_resume_streak: ["reconcile", "spawn", "watcher"], keep_alive_last_resume_at: ["command", "reconcile", "spawn"], keep_alive_next_eligible_at: ["command", "reconcile", "spawn"], keep_alive_exhausted_at: ["command", "reconcile", "spawn"], loop_mode: ["creator"],
|
|
238
|
-
provider: ["creator", "command"], remote_control: ["creator"], provider_source: ["creator", "command"], account: ["creator", "spawn", "command", "watcher", "reconcile"], account_source: ["creator", "command"], profile_settings_pinned: ["command"], account_selection: ["creator", "command"], account_pick: ["creator"], admission_accounts: ["creator", "command"], account_history: ["command", "spawn", "watcher", "reconcile"], failed_resume_history: ["command"], fallback_question_cancellation_failures: ["command"], pending_resume: ["command", "spawn", "watcher", "reconcile"], placement_default: ["creator"], host: ["creator", "command"], origin_host: ["creator"], origin_host_source: ["creator"],
|
|
238
|
+
provider: ["creator", "command"], remote_control: ["creator"], remote_control_title: ["creator"], provider_source: ["creator", "command"], account: ["creator", "spawn", "command", "watcher", "reconcile"], account_source: ["creator", "command"], profile_settings_pinned: ["command"], account_selection: ["creator", "command"], account_pick: ["creator"], admission_accounts: ["creator", "command"], account_history: ["command", "spawn", "watcher", "reconcile"], failed_resume_history: ["command"], fallback_question_cancellation_failures: ["command"], pending_resume: ["command", "spawn", "watcher", "reconcile"], placement_default: ["creator"], host: ["creator", "command"], origin_host: ["creator"], origin_host_source: ["creator"],
|
|
239
239
|
version: ["creator"], created_at: ["creator"], updated_at: ["creator"], ended_at: ["reconcile"], envelope_summary: ["reconcile"], attribution_history: ["command", "watcher", "reconcile"], story_switch_pending: ["command", "watcher", "reconcile"], story_switch_unacknowledged: ["command", "watcher", "reconcile"],
|
|
240
240
|
last_envelope: ["watcher", "reconcile"], model: ["creator", "spawn", "command"], model_source: ["creator", "spawn", "command"], effort: ["creator", "spawn", "command"], effort_source: ["creator", "spawn", "command"], fast_mode: ["spawn"],
|
|
241
241
|
last_message_at: ["creator", "command"], status_gate: ["spawn", "watcher"], status_gate_history: ["watcher", "reconcile"], blocker_freshness_state: ["watcher"], kr_freshness_state: ["watcher"], last_compaction: ["spawn"], story_complete: ["watcher", "reconcile"], story_complete_reason: ["watcher", "reconcile"], story_status: ["watcher", "reconcile"],
|