@indigoai-us/hq-cli 5.345.53 → 5.345.55
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 +24 -0
- package/assets/bot-workers/setup/context/USER-GUIDE.md +1 -1
- package/assets/bot-workers/setup/skills/agents-and-team.md +1 -1
- package/assets/bot-workers/setup/skills/pricing.md +1 -1
- package/dist/command-catalog.generated.d.ts +103 -2
- package/dist/command-catalog.generated.js +124 -2
- package/dist/command-registration-plan.d.ts +6 -1
- package/dist/command-registration-plan.js +2 -1
- package/dist/commands/cloud.d.ts +7 -0
- package/dist/commands/cloud.js +92 -16
- package/dist/commands/daemon.js +16 -0
- package/dist/commands/import-scan.d.ts +24 -0
- package/dist/commands/import-scan.js +75 -0
- package/dist/commands/lanes-session-start.d.ts +22 -0
- package/dist/commands/lanes-session-start.js +215 -0
- package/dist/commands/lanes-watch.d.ts +2 -0
- package/dist/commands/lanes-watch.js +2 -1
- package/dist/commands/lanes.js +4 -2
- package/dist/lib/billing/plan-lock.d.ts +2 -2
- package/dist/lib/billing/plan-lock.js +2 -2
- package/dist/lib/daemon/conflict-notices.d.ts +4 -0
- package/dist/lib/daemon/conflict-notices.js +80 -0
- package/dist/lib/import-scan/events.d.ts +135 -0
- package/dist/lib/import-scan/events.js +71 -0
- package/dist/lib/import-scan/run.d.ts +84 -0
- package/dist/lib/import-scan/run.js +308 -0
- package/dist/lib/import-scan/scan-event.schema.json +127 -0
- package/dist/lib/import-scan/validate.d.ts +31 -0
- package/dist/lib/import-scan/validate.js +111 -0
- package/dist/lib/lanes/flag-keys.d.ts +2 -0
- package/dist/lib/lanes/flag-keys.js +2 -0
- package/dist/lib/lanes/monitor.js +1 -1
- package/dist/lib/lanes/registry-flag.d.ts +2 -0
- package/dist/lib/lanes/registry-flag.js +1 -1
- package/dist/utils/manifest.d.ts +7 -1
- package/dist/utils/manifest.js +14 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.345.55] — 2026-10-08
|
|
6
|
+
- Added `hq daemon sync conflicts acknowledge <id>` so the desktop can clear a parked-conflict notice without writing runner-owned sync state.
|
|
7
|
+
- Add `hq import scan`, which runs the HQ import-context scanner on this
|
|
8
|
+
machine (local only) and reports conversation history, repositories,
|
|
9
|
+
companies and projects. `--json --stream` prints the scan as v1 JSON Lines
|
|
10
|
+
events (`start`, `source`, `count`, `company`, `project`, `error`, `done`)
|
|
11
|
+
for the HQ desktop first-run setup; `--json` prints only the final `done`
|
|
12
|
+
object. Each scanner line is validated against a schema and rebuilt from its
|
|
13
|
+
v1 fields; invalid lines are dropped with a warning. Scanner diagnostics are
|
|
14
|
+
shown with paths and token-like strings redacted. The HQ folder comes from
|
|
15
|
+
`--hq-root` or the HQ installer's record only. When the scan cannot run,
|
|
16
|
+
fails or is cancelled, the command emits an `error` event and a `done` and
|
|
17
|
+
exits non-zero; cancelling stops the whole scanner process group. Event
|
|
18
|
+
types are exported from `dist/lib/import-scan/events.js`. Needs an hq-core
|
|
19
|
+
release whose import-context scanner supports `--progress-json`.
|
|
20
|
+
- Exit with actionable recovery steps when a vault upload is refused.
|
|
21
|
+
|
|
22
|
+
## [5.345.54] — 2026-10-08
|
|
23
|
+
- Add `hq lanes session-start` for conduct-mode SessionStart bootstrapping. `HQ_LANE_ENGINE` is the preferred engine environment variable; `HQ_CONDUCT_ENGINE` remains a deprecated fallback alias. Show `hq lanes` in root help.
|
|
24
|
+
|
|
25
|
+
- Prevents `hq` commands run outside an HQ tree on Windows from hanging while searching parent directories for an HQ root.
|
|
26
|
+
|
|
5
27
|
## [5.345.53] — 2026-10-08
|
|
28
|
+
- Starter plan-limit notices quote 3 integrations when the server sends no integration limit, up from 1. The setup guide, pricing skill, and agents-and-team skill now say Starter includes 3 integrations (connected apps).
|
|
29
|
+
|
|
6
30
|
- `hq meetings live` now also lists live meetings you were invited to but did not record, such as a standup a teammate's notetaker is recording, so you can read their live transcript.
|
|
7
31
|
|
|
8
32
|
## [5.345.52] — 2026-10-08
|
|
@@ -323,7 +323,7 @@ HQ/
|
|
|
323
323
|
HQ has three plans: **Starter**, **HQ Workforce** ($500/month per workspace), and
|
|
324
324
|
**Enterprise**.
|
|
325
325
|
|
|
326
|
-
Starter is free. It holds up to 5 members and includes
|
|
326
|
+
Starter is free. It holds up to 5 members and includes 3 integrations. MCP,
|
|
327
327
|
Atlas, and telemetry are not included. Everything else — knowledge, projects,
|
|
328
328
|
policies, workers, secrets, vault storage, `hq deploy`, and `hq share` — works
|
|
329
329
|
the same as on the paid plans.
|
|
@@ -29,7 +29,7 @@ Run `hq whoami` and `hq companies list`, and read the "Owner context" block.
|
|
|
29
29
|
3. **Their plan, when the flow depends on it.** Check it as
|
|
30
30
|
`skills/pricing.md` says; never guess it. Inviting people, sharing a
|
|
31
31
|
connected app and sharing a key are included in every plan (within
|
|
32
|
-
Starter's limits of 5 people,
|
|
32
|
+
Starter's limits of 5 people, 3 connected apps and 10 keys). Hosted agents,
|
|
33
33
|
Slack agents included, are not part of Starter: they need HQ Workforce
|
|
34
34
|
($500 a month for the company), and then each agent is $100 a month on
|
|
35
35
|
top. If HQ refuses something or quotes a price, pass that answer on.
|
|
@@ -36,7 +36,7 @@ often empty; when it is empty it tells you nothing about the plan.
|
|
|
36
36
|
**Starter, free.** For a company getting started:
|
|
37
37
|
|
|
38
38
|
- up to 5 people (invitations not yet accepted count toward the 5)
|
|
39
|
-
-
|
|
39
|
+
- 3 connected apps
|
|
40
40
|
- 10 keys
|
|
41
41
|
- 10 GB of files and 500 site deploys
|
|
42
42
|
- no hosted agents (see "Agents" below)
|
|
@@ -5144,6 +5144,62 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
5144
5144
|
}];
|
|
5145
5145
|
readonly subcommands: readonly [];
|
|
5146
5146
|
}];
|
|
5147
|
+
}, {
|
|
5148
|
+
readonly name: "import";
|
|
5149
|
+
readonly description: "Import existing AI context (Claude Code, Codex, repos) into HQ";
|
|
5150
|
+
readonly aliases: readonly [];
|
|
5151
|
+
readonly hidden: false;
|
|
5152
|
+
readonly helpOption: true;
|
|
5153
|
+
readonly helpCommand: true;
|
|
5154
|
+
readonly usage: "[options] [command]";
|
|
5155
|
+
readonly helpText: readonly [];
|
|
5156
|
+
readonly arguments: readonly [];
|
|
5157
|
+
readonly options: readonly [];
|
|
5158
|
+
readonly subcommands: readonly [{
|
|
5159
|
+
readonly name: "scan";
|
|
5160
|
+
readonly description: "Scan this machine for AI context (sessions, repos, companies, projects); local only";
|
|
5161
|
+
readonly aliases: readonly [];
|
|
5162
|
+
readonly hidden: false;
|
|
5163
|
+
readonly helpOption: true;
|
|
5164
|
+
readonly helpCommand: false;
|
|
5165
|
+
readonly usage: "[options]";
|
|
5166
|
+
readonly helpText: readonly [{
|
|
5167
|
+
readonly position: "after";
|
|
5168
|
+
readonly text: "\nThe desktop app runs: hq import scan --json --stream\nEvents (v1): start, source, count, company, project, error, done. See docs/import-scan-stream.md.";
|
|
5169
|
+
}];
|
|
5170
|
+
readonly arguments: readonly [];
|
|
5171
|
+
readonly options: readonly [{
|
|
5172
|
+
readonly flags: "--json";
|
|
5173
|
+
readonly description: "Print only the final done event as JSON";
|
|
5174
|
+
readonly hidden: false;
|
|
5175
|
+
}, {
|
|
5176
|
+
readonly flags: "--stream";
|
|
5177
|
+
readonly description: "With --json, print every scan event as JSON Lines while scanning";
|
|
5178
|
+
readonly hidden: false;
|
|
5179
|
+
}, {
|
|
5180
|
+
readonly flags: "--hq-root <path>";
|
|
5181
|
+
readonly description: "HQ folder (default: the folder the HQ installer recorded)";
|
|
5182
|
+
readonly hidden: false;
|
|
5183
|
+
}, {
|
|
5184
|
+
readonly flags: "--output <path>";
|
|
5185
|
+
readonly description: "Where to write report.json (default: <hq>/workspace/imports/<scan id>/report.json)";
|
|
5186
|
+
readonly hidden: false;
|
|
5187
|
+
}, {
|
|
5188
|
+
readonly flags: "--scope <dir>";
|
|
5189
|
+
readonly description: "Also scan this folder (repeatable)";
|
|
5190
|
+
readonly hidden: false;
|
|
5191
|
+
readonly defaultValue: readonly [];
|
|
5192
|
+
}, {
|
|
5193
|
+
readonly flags: "--claude-export <path>";
|
|
5194
|
+
readonly description: "Include a claude.ai data export (unzipped folder or conversations.json)";
|
|
5195
|
+
readonly hidden: false;
|
|
5196
|
+
}, {
|
|
5197
|
+
readonly flags: "--no-default-scopes";
|
|
5198
|
+
readonly description: "Scan only --scope folders, not the default code folders";
|
|
5199
|
+
readonly hidden: false;
|
|
5200
|
+
}];
|
|
5201
|
+
readonly subcommands: readonly [];
|
|
5202
|
+
}];
|
|
5147
5203
|
}, {
|
|
5148
5204
|
readonly name: "reindex";
|
|
5149
5205
|
readonly description: "Surface namespaced skills, materialize legacy knowledge repos, regenerate the workers registry, and trust HQ hooks for Codex, Grok, and Claude Code";
|
|
@@ -10929,7 +10985,7 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
10929
10985
|
readonly name: "lanes";
|
|
10930
10986
|
readonly description: "Create, supervise, and steer worker lanes; routed decision queue";
|
|
10931
10987
|
readonly aliases: readonly [];
|
|
10932
|
-
readonly hidden:
|
|
10988
|
+
readonly hidden: false;
|
|
10933
10989
|
readonly helpOption: true;
|
|
10934
10990
|
readonly helpCommand: true;
|
|
10935
10991
|
readonly usage: "[options] [command]";
|
|
@@ -10937,6 +10993,22 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
10937
10993
|
readonly arguments: readonly [];
|
|
10938
10994
|
readonly options: readonly [];
|
|
10939
10995
|
readonly subcommands: readonly [{
|
|
10996
|
+
readonly name: "session-start";
|
|
10997
|
+
readonly description: "Internal SessionStart bootstrap";
|
|
10998
|
+
readonly aliases: readonly [];
|
|
10999
|
+
readonly hidden: true;
|
|
11000
|
+
readonly helpOption: true;
|
|
11001
|
+
readonly helpCommand: false;
|
|
11002
|
+
readonly usage: "[options]";
|
|
11003
|
+
readonly helpText: readonly [];
|
|
11004
|
+
readonly arguments: readonly [];
|
|
11005
|
+
readonly options: readonly [{
|
|
11006
|
+
readonly flags: "--json";
|
|
11007
|
+
readonly description: "JSON on stdout (always)";
|
|
11008
|
+
readonly hidden: false;
|
|
11009
|
+
}];
|
|
11010
|
+
readonly subcommands: readonly [];
|
|
11011
|
+
}, {
|
|
10940
11012
|
readonly name: "checks";
|
|
10941
11013
|
readonly description: "Evaluate tracker and lane health checks";
|
|
10942
11014
|
readonly aliases: readonly [];
|
|
@@ -12184,7 +12256,7 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
12184
12256
|
readonly hidden: false;
|
|
12185
12257
|
}, {
|
|
12186
12258
|
readonly flags: "--engine <engine>";
|
|
12187
|
-
readonly description: "claude | codex | grok; defaults to HQ_CONDUCT_ENGINE or claude";
|
|
12259
|
+
readonly description: "claude | codex | grok; defaults to HQ_LANE_ENGINE (HQ_CONDUCT_ENGINE is deprecated) or claude";
|
|
12188
12260
|
readonly hidden: false;
|
|
12189
12261
|
}, {
|
|
12190
12262
|
readonly flags: "--reminder";
|
|
@@ -13756,6 +13828,35 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
13756
13828
|
readonly arguments: readonly [];
|
|
13757
13829
|
readonly options: readonly [];
|
|
13758
13830
|
readonly subcommands: readonly [{
|
|
13831
|
+
readonly name: "conflicts";
|
|
13832
|
+
readonly description: "Manage parked conflict copy notices";
|
|
13833
|
+
readonly aliases: readonly [];
|
|
13834
|
+
readonly hidden: false;
|
|
13835
|
+
readonly helpOption: true;
|
|
13836
|
+
readonly helpCommand: true;
|
|
13837
|
+
readonly usage: "[options] [command]";
|
|
13838
|
+
readonly helpText: readonly [];
|
|
13839
|
+
readonly arguments: readonly [];
|
|
13840
|
+
readonly options: readonly [];
|
|
13841
|
+
readonly subcommands: readonly [{
|
|
13842
|
+
readonly name: "acknowledge";
|
|
13843
|
+
readonly description: "Acknowledge a parked conflict copy notice";
|
|
13844
|
+
readonly aliases: readonly [];
|
|
13845
|
+
readonly hidden: false;
|
|
13846
|
+
readonly helpOption: true;
|
|
13847
|
+
readonly helpCommand: false;
|
|
13848
|
+
readonly usage: "[options] <noticeId>";
|
|
13849
|
+
readonly helpText: readonly [];
|
|
13850
|
+
readonly arguments: readonly [{
|
|
13851
|
+
readonly name: "noticeId";
|
|
13852
|
+
readonly required: true;
|
|
13853
|
+
readonly variadic: false;
|
|
13854
|
+
readonly description: "";
|
|
13855
|
+
}];
|
|
13856
|
+
readonly options: readonly [];
|
|
13857
|
+
readonly subcommands: readonly [];
|
|
13858
|
+
}];
|
|
13859
|
+
}, {
|
|
13759
13860
|
readonly name: "status";
|
|
13760
13861
|
readonly description: "Show sync ownership, heartbeat, last pass and log path";
|
|
13761
13862
|
readonly aliases: readonly [];
|
|
@@ -6253,6 +6253,75 @@ export const COMMAND_CATALOG = [
|
|
|
6253
6253
|
}
|
|
6254
6254
|
]
|
|
6255
6255
|
},
|
|
6256
|
+
{
|
|
6257
|
+
"name": "import",
|
|
6258
|
+
"description": "Import existing AI context (Claude Code, Codex, repos) into HQ",
|
|
6259
|
+
"aliases": [],
|
|
6260
|
+
"hidden": false,
|
|
6261
|
+
"helpOption": true,
|
|
6262
|
+
"helpCommand": true,
|
|
6263
|
+
"usage": "[options] [command]",
|
|
6264
|
+
"helpText": [],
|
|
6265
|
+
"arguments": [],
|
|
6266
|
+
"options": [],
|
|
6267
|
+
"subcommands": [
|
|
6268
|
+
{
|
|
6269
|
+
"name": "scan",
|
|
6270
|
+
"description": "Scan this machine for AI context (sessions, repos, companies, projects); local only",
|
|
6271
|
+
"aliases": [],
|
|
6272
|
+
"hidden": false,
|
|
6273
|
+
"helpOption": true,
|
|
6274
|
+
"helpCommand": false,
|
|
6275
|
+
"usage": "[options]",
|
|
6276
|
+
"helpText": [
|
|
6277
|
+
{
|
|
6278
|
+
"position": "after",
|
|
6279
|
+
"text": "\nThe desktop app runs: hq import scan --json --stream\nEvents (v1): start, source, count, company, project, error, done. See docs/import-scan-stream.md."
|
|
6280
|
+
}
|
|
6281
|
+
],
|
|
6282
|
+
"arguments": [],
|
|
6283
|
+
"options": [
|
|
6284
|
+
{
|
|
6285
|
+
"flags": "--json",
|
|
6286
|
+
"description": "Print only the final done event as JSON",
|
|
6287
|
+
"hidden": false
|
|
6288
|
+
},
|
|
6289
|
+
{
|
|
6290
|
+
"flags": "--stream",
|
|
6291
|
+
"description": "With --json, print every scan event as JSON Lines while scanning",
|
|
6292
|
+
"hidden": false
|
|
6293
|
+
},
|
|
6294
|
+
{
|
|
6295
|
+
"flags": "--hq-root <path>",
|
|
6296
|
+
"description": "HQ folder (default: the folder the HQ installer recorded)",
|
|
6297
|
+
"hidden": false
|
|
6298
|
+
},
|
|
6299
|
+
{
|
|
6300
|
+
"flags": "--output <path>",
|
|
6301
|
+
"description": "Where to write report.json (default: <hq>/workspace/imports/<scan id>/report.json)",
|
|
6302
|
+
"hidden": false
|
|
6303
|
+
},
|
|
6304
|
+
{
|
|
6305
|
+
"flags": "--scope <dir>",
|
|
6306
|
+
"description": "Also scan this folder (repeatable)",
|
|
6307
|
+
"hidden": false,
|
|
6308
|
+
"defaultValue": []
|
|
6309
|
+
},
|
|
6310
|
+
{
|
|
6311
|
+
"flags": "--claude-export <path>",
|
|
6312
|
+
"description": "Include a claude.ai data export (unzipped folder or conversations.json)",
|
|
6313
|
+
"hidden": false
|
|
6314
|
+
},
|
|
6315
|
+
{
|
|
6316
|
+
"flags": "--no-default-scopes",
|
|
6317
|
+
"description": "Scan only --scope folders, not the default code folders",
|
|
6318
|
+
"hidden": false
|
|
6319
|
+
}
|
|
6320
|
+
],
|
|
6321
|
+
"subcommands": []
|
|
6322
|
+
}
|
|
6323
|
+
]
|
|
6324
|
+
},
|
|
6256
6325
|
{
|
|
6257
6326
|
"name": "reindex",
|
|
6258
6327
|
"description": "Surface namespaced skills, materialize legacy knowledge repos, regenerate the workers registry, and trust HQ hooks for Codex, Grok, and Claude Code",
|
|
@@ -13278,7 +13347,7 @@ export const COMMAND_CATALOG = [
|
|
|
13278
13347
|
"name": "lanes",
|
|
13279
13348
|
"description": "Create, supervise, and steer worker lanes; routed decision queue",
|
|
13280
13349
|
"aliases": [],
|
|
13281
|
-
"hidden":
|
|
13350
|
+
"hidden": false,
|
|
13282
13351
|
"helpOption": true,
|
|
13283
13352
|
"helpCommand": true,
|
|
13284
13353
|
"usage": "[options] [command]",
|
|
@@ -13286,6 +13355,25 @@ export const COMMAND_CATALOG = [
|
|
|
13286
13355
|
"arguments": [],
|
|
13287
13356
|
"options": [],
|
|
13288
13357
|
"subcommands": [
|
|
13358
|
+
{
|
|
13359
|
+
"name": "session-start",
|
|
13360
|
+
"description": "Internal SessionStart bootstrap",
|
|
13361
|
+
"aliases": [],
|
|
13362
|
+
"hidden": true,
|
|
13363
|
+
"helpOption": true,
|
|
13364
|
+
"helpCommand": false,
|
|
13365
|
+
"usage": "[options]",
|
|
13366
|
+
"helpText": [],
|
|
13367
|
+
"arguments": [],
|
|
13368
|
+
"options": [
|
|
13369
|
+
{
|
|
13370
|
+
"flags": "--json",
|
|
13371
|
+
"description": "JSON on stdout (always)",
|
|
13372
|
+
"hidden": false
|
|
13373
|
+
}
|
|
13374
|
+
],
|
|
13375
|
+
"subcommands": []
|
|
13376
|
+
},
|
|
13289
13377
|
{
|
|
13290
13378
|
"name": "checks",
|
|
13291
13379
|
"description": "Evaluate tracker and lane health checks",
|
|
@@ -14811,7 +14899,7 @@ export const COMMAND_CATALOG = [
|
|
|
14811
14899
|
},
|
|
14812
14900
|
{
|
|
14813
14901
|
"flags": "--engine <engine>",
|
|
14814
|
-
"description": "claude | codex | grok; defaults to HQ_CONDUCT_ENGINE or claude",
|
|
14902
|
+
"description": "claude | codex | grok; defaults to HQ_LANE_ENGINE (HQ_CONDUCT_ENGINE is deprecated) or claude",
|
|
14815
14903
|
"hidden": false
|
|
14816
14904
|
},
|
|
14817
14905
|
{
|
|
@@ -16736,6 +16824,40 @@ export const COMMAND_CATALOG = [
|
|
|
16736
16824
|
"arguments": [],
|
|
16737
16825
|
"options": [],
|
|
16738
16826
|
"subcommands": [
|
|
16827
|
+
{
|
|
16828
|
+
"name": "conflicts",
|
|
16829
|
+
"description": "Manage parked conflict copy notices",
|
|
16830
|
+
"aliases": [],
|
|
16831
|
+
"hidden": false,
|
|
16832
|
+
"helpOption": true,
|
|
16833
|
+
"helpCommand": true,
|
|
16834
|
+
"usage": "[options] [command]",
|
|
16835
|
+
"helpText": [],
|
|
16836
|
+
"arguments": [],
|
|
16837
|
+
"options": [],
|
|
16838
|
+
"subcommands": [
|
|
16839
|
+
{
|
|
16840
|
+
"name": "acknowledge",
|
|
16841
|
+
"description": "Acknowledge a parked conflict copy notice",
|
|
16842
|
+
"aliases": [],
|
|
16843
|
+
"hidden": false,
|
|
16844
|
+
"helpOption": true,
|
|
16845
|
+
"helpCommand": false,
|
|
16846
|
+
"usage": "[options] <noticeId>",
|
|
16847
|
+
"helpText": [],
|
|
16848
|
+
"arguments": [
|
|
16849
|
+
{
|
|
16850
|
+
"name": "noticeId",
|
|
16851
|
+
"required": true,
|
|
16852
|
+
"variadic": false,
|
|
16853
|
+
"description": ""
|
|
16854
|
+
}
|
|
16855
|
+
],
|
|
16856
|
+
"options": [],
|
|
16857
|
+
"subcommands": []
|
|
16858
|
+
}
|
|
16859
|
+
]
|
|
16860
|
+
},
|
|
16739
16861
|
{
|
|
16740
16862
|
"name": "status",
|
|
16741
16863
|
"description": "Show sync ownership, heartbeat, last pass and log path",
|
|
@@ -346,6 +346,12 @@ export declare const REGISTRATION_PLAN: readonly [{
|
|
|
346
346
|
readonly parent: "program";
|
|
347
347
|
readonly module: "./commands/integrations.js";
|
|
348
348
|
readonly exportName: "registerIntegrationsCommand";
|
|
349
|
+
}, {
|
|
350
|
+
readonly type: "registrar";
|
|
351
|
+
readonly root: "import";
|
|
352
|
+
readonly parent: "program";
|
|
353
|
+
readonly module: "./commands/import-scan.js";
|
|
354
|
+
readonly exportName: "registerImportCommand";
|
|
349
355
|
}, {
|
|
350
356
|
readonly type: "registrar";
|
|
351
357
|
readonly root: "reindex";
|
|
@@ -442,7 +448,6 @@ export declare const REGISTRATION_PLAN: readonly [{
|
|
|
442
448
|
readonly parent: "program";
|
|
443
449
|
readonly module: "./commands/lanes.js";
|
|
444
450
|
readonly exportName: "registerLanesCommand";
|
|
445
|
-
readonly hidden: true;
|
|
446
451
|
}, {
|
|
447
452
|
readonly type: "registrar";
|
|
448
453
|
readonly root: "monitor";
|
|
@@ -60,6 +60,7 @@ export const REGISTRATION_PLAN = [
|
|
|
60
60
|
{ type: "registrar", root: "sources", parent: "program", module: "./commands/sources.js", exportName: "registerSourcesCommand" },
|
|
61
61
|
{ type: "registrar", root: "signals", parent: "program", module: "./commands/signals.js", exportName: "registerSignalsCommand" },
|
|
62
62
|
{ type: "registrar", root: "integrations", parent: "program", module: "./commands/integrations.js", exportName: "registerIntegrationsCommand" },
|
|
63
|
+
{ type: "registrar", root: "import", parent: "program", module: "./commands/import-scan.js", exportName: "registerImportCommand" },
|
|
63
64
|
{ type: "registrar", root: "reindex", parent: "program", module: "./commands/reindex.js", exportName: "registerReindexCommand" },
|
|
64
65
|
{ type: "registrar", root: "rescue", parent: "program", module: "./commands/rescue.js", exportName: "registerRescueCommand" },
|
|
65
66
|
{ type: "registrar", root: "mcp", parent: "program", module: "./commands/mcp-status.js", exportName: "registerMcpCommand" },
|
|
@@ -75,7 +76,7 @@ export const REGISTRATION_PLAN = [
|
|
|
75
76
|
{ type: "registrar", root: "index", parent: "program", module: "./commands/index-cmd.js", exportName: "registerIndexCommand" },
|
|
76
77
|
{ type: "registrar", root: "doctor", parent: "program", module: "./commands/doctor.js", exportName: "registerDoctorCommand" },
|
|
77
78
|
{ type: "registrar", root: "mesh", parent: "program", module: "./commands/mesh.js", exportName: "registerMeshCommand" },
|
|
78
|
-
{ type: "registrar", root: "lanes", parent: "program", module: "./commands/lanes.js", exportName: "registerLanesCommand"
|
|
79
|
+
{ type: "registrar", root: "lanes", parent: "program", module: "./commands/lanes.js", exportName: "registerLanesCommand" },
|
|
79
80
|
{ type: "registrar", root: "monitor", parent: "program", module: "./commands/monitor.js", exportName: "registerMonitorCommand" },
|
|
80
81
|
{ type: "registrar", root: "daemon", parent: "program", module: "./commands/daemon.js", exportName: "registerDaemonCommand", hidden: true },
|
|
81
82
|
{ type: "registrar", root: "bot", parent: "program", module: "./commands/bot.js", exportName: "registerBotCommand" },
|
package/dist/commands/cloud.d.ts
CHANGED
|
@@ -65,7 +65,10 @@ export declare function withSyncHealthReport<T>(run: () => Promise<T>): Promise<
|
|
|
65
65
|
* nothing was scope-excluded. Keeping this pure makes the "never silently
|
|
66
66
|
* succeed when files were dropped" guarantee unit-testable.
|
|
67
67
|
*/
|
|
68
|
+
export declare function scopeExcludedExitCode(count: number): 0 | 1;
|
|
68
69
|
export declare function scopeExcludedWarning(count: number): string | null;
|
|
70
|
+
/** Actionable recovery for files refused because the vault baseline is stale. */
|
|
71
|
+
export declare function staleUploadRefusalLines(count: number, paths?: readonly string[]): string[];
|
|
69
72
|
/**
|
|
70
73
|
* Optional detail line listing the effective write prefixes when a push
|
|
71
74
|
* dropped files — helps debug ACL vs scope-excluded mismatches (feedback_7e9c535e).
|
|
@@ -231,6 +234,8 @@ export interface ShareCallResult {
|
|
|
231
234
|
filesSkipped: number;
|
|
232
235
|
filesDeleted: number;
|
|
233
236
|
filesExcludedByScope: number;
|
|
237
|
+
filesRefusedStale?: number;
|
|
238
|
+
filesRefusedStalePaths?: string[];
|
|
234
239
|
conflictPaths: string[];
|
|
235
240
|
aborted: boolean;
|
|
236
241
|
/** Files this leg's plan limit refused; absent or null when none were. */
|
|
@@ -272,6 +277,8 @@ export interface PushAllResult {
|
|
|
272
277
|
bytesUploaded: number;
|
|
273
278
|
filesDeleted: number;
|
|
274
279
|
filesExcludedByScope: number;
|
|
280
|
+
filesRefusedStale?: number;
|
|
281
|
+
filesRefusedStalePaths?: string[];
|
|
275
282
|
errors: Array<{
|
|
276
283
|
company: string;
|
|
277
284
|
message: string;
|
package/dist/commands/cloud.js
CHANGED
|
@@ -139,6 +139,9 @@ export async function withSyncHealthReport(run) {
|
|
|
139
139
|
* nothing was scope-excluded. Keeping this pure makes the "never silently
|
|
140
140
|
* succeed when files were dropped" guarantee unit-testable.
|
|
141
141
|
*/
|
|
142
|
+
export function scopeExcludedExitCode(count) {
|
|
143
|
+
return count > 0 ? 1 : 0;
|
|
144
|
+
}
|
|
142
145
|
export function scopeExcludedWarning(count) {
|
|
143
146
|
if (count <= 0)
|
|
144
147
|
return null;
|
|
@@ -147,6 +150,19 @@ export function scopeExcludedWarning(count) {
|
|
|
147
150
|
`They were skipped, not synced. Re-run with --json to list them, or ` +
|
|
148
151
|
`ask an admin to grant you write on those paths.`);
|
|
149
152
|
}
|
|
153
|
+
/** Actionable recovery for files refused because the vault baseline is stale. */
|
|
154
|
+
export function staleUploadRefusalLines(count, paths = []) {
|
|
155
|
+
if (count <= 0)
|
|
156
|
+
return [];
|
|
157
|
+
const lines = [
|
|
158
|
+
`⚠ ${count} file(s) were NOT uploaded because the vault copy changed after your edit. ` +
|
|
159
|
+
`Pull the current vault copy, merge your edit, and push again.`,
|
|
160
|
+
];
|
|
161
|
+
if (paths.length > 0) {
|
|
162
|
+
lines.push(" Not uploaded:", ...paths.map((filePath) => ` - ${filePath}`));
|
|
163
|
+
}
|
|
164
|
+
return lines;
|
|
165
|
+
}
|
|
150
166
|
/**
|
|
151
167
|
* Optional detail line listing the effective write prefixes when a push
|
|
152
168
|
* dropped files — helps debug ACL vs scope-excluded mismatches (feedback_7e9c535e).
|
|
@@ -176,7 +192,7 @@ export function scopeExcludedLines(count, prefixSet) {
|
|
|
176
192
|
`⚠ ${count} file(s) were NOT uploaded — the server refused them. ` +
|
|
177
193
|
`A common cause is a file someone else created in a private folder ` +
|
|
178
194
|
`(foo/): only its creator can change it. They were skipped, not ` +
|
|
179
|
-
`synced. Re-run with --json to list them.`,
|
|
195
|
+
`synced. Re-run with --json to list them, or ask its creator to grant access.`,
|
|
180
196
|
];
|
|
181
197
|
}
|
|
182
198
|
const lines = [scopeExcludedWarning(count)];
|
|
@@ -527,6 +543,12 @@ export async function pushAll(options, deps) {
|
|
|
527
543
|
result.bytesUploaded += r.bytesUploaded;
|
|
528
544
|
result.filesDeleted += r.filesDeleted;
|
|
529
545
|
result.filesExcludedByScope += r.filesExcludedByScope;
|
|
546
|
+
if ((r.filesRefusedStale ?? 0) > 0) {
|
|
547
|
+
result.filesRefusedStale =
|
|
548
|
+
(result.filesRefusedStale ?? 0) + (r.filesRefusedStale ?? 0);
|
|
549
|
+
result.filesRefusedStalePaths ??= [];
|
|
550
|
+
result.filesRefusedStalePaths.push(...(r.filesRefusedStalePaths ?? []));
|
|
551
|
+
}
|
|
530
552
|
result.perCompany.push({
|
|
531
553
|
slug: entry.slug,
|
|
532
554
|
result: r,
|
|
@@ -977,6 +999,17 @@ export function registerCloudCommands(program) {
|
|
|
977
999
|
...(pushPrefixSet !== undefined ? { prefixSet: pushPrefixSet } : {}),
|
|
978
1000
|
});
|
|
979
1001
|
const planLimitRefused = planLimitTracker.summary();
|
|
1002
|
+
const staleRefusalCount = result.filesRefusedStale ?? 0;
|
|
1003
|
+
const refusalRecovery = [
|
|
1004
|
+
result.filesExcludedByScope > 0
|
|
1005
|
+
? "Check write access for the refused path; ask its creator or a company admin to grant access."
|
|
1006
|
+
: null,
|
|
1007
|
+
staleRefusalCount > 0
|
|
1008
|
+
? "Pull the current vault copy, merge your edit, and push again."
|
|
1009
|
+
: null,
|
|
1010
|
+
]
|
|
1011
|
+
.filter((message) => message !== null)
|
|
1012
|
+
.join(" ");
|
|
980
1013
|
if (jsonMode) {
|
|
981
1014
|
// Synthetic terminal event so subprocess consumers can read final
|
|
982
1015
|
// counts without summing per-file events. Distinguished from
|
|
@@ -991,6 +1024,10 @@ export function registerCloudCommands(program) {
|
|
|
991
1024
|
filesSkipped: result.filesSkipped,
|
|
992
1025
|
conflictPaths: result.conflictPaths,
|
|
993
1026
|
aborted: result.aborted,
|
|
1027
|
+
filesExcludedByScope: result.filesExcludedByScope,
|
|
1028
|
+
filesRefusedStale: staleRefusalCount,
|
|
1029
|
+
filesRefusedStalePaths: result.filesRefusedStalePaths ?? [],
|
|
1030
|
+
...(refusalRecovery ? { refusalRecovery } : {}),
|
|
994
1031
|
...(planLimitRefused ? { planLimitRefused } : {}),
|
|
995
1032
|
});
|
|
996
1033
|
}
|
|
@@ -1019,22 +1056,32 @@ export function registerCloudCommands(program) {
|
|
|
1019
1056
|
for (const line of scopeExcludedLines(result.filesExcludedByScope, pushPrefixSet)) {
|
|
1020
1057
|
log(chalk.yellow(line));
|
|
1021
1058
|
}
|
|
1059
|
+
for (const line of staleUploadRefusalLines(result.filesRefusedStale ?? 0, result.filesRefusedStalePaths)) {
|
|
1060
|
+
log(chalk.yellow(line));
|
|
1061
|
+
}
|
|
1022
1062
|
await syncHealth.succeeded();
|
|
1023
|
-
|
|
1024
|
-
process.exit(1);
|
|
1063
|
+
process.exit(1);
|
|
1025
1064
|
return;
|
|
1026
1065
|
}
|
|
1027
|
-
if (result.filesExcludedByScope > 0) {
|
|
1066
|
+
if (result.filesExcludedByScope > 0 || staleRefusalCount > 0) {
|
|
1028
1067
|
log(chalk.yellow(`\n⚠ Pushed ${result.filesUploaded} file(s) (${formatBytes(result.bytesUploaded)}, ` +
|
|
1029
|
-
`${result.filesSkipped} skipped, ${result.filesExcludedByScope}
|
|
1068
|
+
`${result.filesSkipped} skipped, ${result.filesExcludedByScope + staleRefusalCount} files not uploaded)`));
|
|
1030
1069
|
for (const line of scopeExcludedLines(result.filesExcludedByScope, pushPrefixSet)) {
|
|
1031
1070
|
log(chalk.yellow(line));
|
|
1032
1071
|
}
|
|
1072
|
+
for (const line of staleUploadRefusalLines(staleRefusalCount, result.filesRefusedStalePaths)) {
|
|
1073
|
+
log(chalk.yellow(line));
|
|
1074
|
+
}
|
|
1033
1075
|
}
|
|
1034
1076
|
else {
|
|
1035
1077
|
log(chalk.green(`\n✓ Pushed ${result.filesUploaded} file(s) (${formatBytes(result.bytesUploaded)}, ${result.filesSkipped} skipped)`));
|
|
1036
1078
|
}
|
|
1037
1079
|
await syncHealth.succeeded();
|
|
1080
|
+
const exitCode = scopeExcludedExitCode(result.filesExcludedByScope + staleRefusalCount);
|
|
1081
|
+
if (exitCode !== 0) {
|
|
1082
|
+
process.exit(exitCode);
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1038
1085
|
}
|
|
1039
1086
|
catch (err) {
|
|
1040
1087
|
if (syncHealth)
|
|
@@ -1630,13 +1677,13 @@ async function runPushAll(hqRoot, message, onConflict, skipPersonal) {
|
|
|
1630
1677
|
else if (row.result) {
|
|
1631
1678
|
const r = row.result;
|
|
1632
1679
|
const legRefused = r.planLimit ?? null;
|
|
1633
|
-
const status = r.aborted || r.filesExcludedByScope > 0 || legRefused
|
|
1680
|
+
const status = r.aborted || r.filesExcludedByScope > 0 || (r.filesRefusedStale ?? 0) > 0 || legRefused
|
|
1634
1681
|
? chalk.yellow("⚠")
|
|
1635
1682
|
: chalk.green("✓");
|
|
1636
1683
|
console.log(` ${status} ${row.slug}: ${r.filesUploaded} file(s), ` +
|
|
1637
1684
|
`${formatBytes(r.bytesUploaded)}, ${r.filesSkipped} skipped, ` +
|
|
1638
1685
|
`${r.filesDeleted} deleted, ${r.filesExcludedByScope} scope-excluded, ` +
|
|
1639
|
-
`${r.conflictPaths.length} conflict(s)` +
|
|
1686
|
+
`${r.filesRefusedStale ?? 0} stale-refused, ${r.conflictPaths.length} conflict(s)` +
|
|
1640
1687
|
(r.aborted ? " — aborted" : "") +
|
|
1641
1688
|
(legRefused
|
|
1642
1689
|
? ` — ${describeRefusedCount(legRefused)} refused by plan limit`
|
|
@@ -1652,7 +1699,8 @@ async function runPushAll(hqRoot, message, onConflict, skipPersonal) {
|
|
|
1652
1699
|
const summary = `\nPushed ${result.filesUploaded} file(s) ` +
|
|
1653
1700
|
`(${formatBytes(result.bytesUploaded)}) across ${result.attempted} ` +
|
|
1654
1701
|
`target(s); ${result.filesDeleted} deleted; ${errored} error(s); ` +
|
|
1655
|
-
`${result.filesExcludedByScope} scope-excluded` +
|
|
1702
|
+
`${result.filesExcludedByScope} scope-excluded; ` +
|
|
1703
|
+
`${result.filesRefusedStale ?? 0} stale-refused` +
|
|
1656
1704
|
(refusedTargets > 0
|
|
1657
1705
|
? `; new files refused by a plan limit on ${refusedTargets} target(s)`
|
|
1658
1706
|
: "");
|
|
@@ -1673,10 +1721,24 @@ async function runPushAll(hqRoot, message, onConflict, skipPersonal) {
|
|
|
1673
1721
|
for (const line of scopeExcludedLines(excluded, row.prefixSet)) {
|
|
1674
1722
|
console.log(chalk.yellow(`${row.slug}: ${line}`));
|
|
1675
1723
|
}
|
|
1724
|
+
const staleCount = row.result?.filesRefusedStale ?? 0;
|
|
1725
|
+
for (const line of staleUploadRefusalLines(staleCount, row.result?.filesRefusedStalePaths)) {
|
|
1726
|
+
console.log(chalk.yellow(`${row.slug}: ${line}`));
|
|
1727
|
+
}
|
|
1676
1728
|
}
|
|
1677
1729
|
if (errored > 0)
|
|
1678
1730
|
throw new SyncExitError(1);
|
|
1679
|
-
|
|
1731
|
+
const refusalSummary = {
|
|
1732
|
+
planLimitRefused: refused,
|
|
1733
|
+
filesExcludedByScope: result.filesExcludedByScope,
|
|
1734
|
+
filesRefusedStale: result.filesRefusedStale ?? 0,
|
|
1735
|
+
filesRefusedStalePaths: [...new Set(result.filesRefusedStalePaths ?? [])],
|
|
1736
|
+
};
|
|
1737
|
+
return (refusalSummary.planLimitRefused ||
|
|
1738
|
+
refusalSummary.filesExcludedByScope > 0 ||
|
|
1739
|
+
refusalSummary.filesRefusedStale > 0
|
|
1740
|
+
? refusalSummary
|
|
1741
|
+
: null);
|
|
1680
1742
|
}
|
|
1681
1743
|
async function runNowSingle(hqRoot, company, personal, message, onConflict, modeAllOverride, forceScopeShrink) {
|
|
1682
1744
|
console.log(chalk.bold("\nHQ Sync — Now"));
|
|
@@ -1763,7 +1825,10 @@ async function runNowSingle(hqRoot, company, personal, message, onConflict, mode
|
|
|
1763
1825
|
...(nowPushPrefixSet !== undefined ? { prefixSet: nowPushPrefixSet } : {}),
|
|
1764
1826
|
});
|
|
1765
1827
|
const pushRefused = planLimitTracker.summary();
|
|
1766
|
-
const pushStatus = pushResult.aborted ||
|
|
1828
|
+
const pushStatus = pushResult.aborted ||
|
|
1829
|
+
pushResult.filesExcludedByScope > 0 ||
|
|
1830
|
+
(pushResult.filesRefusedStale ?? 0) > 0 ||
|
|
1831
|
+
pushRefused
|
|
1767
1832
|
? chalk.yellow("⚠")
|
|
1768
1833
|
: chalk.green("✓");
|
|
1769
1834
|
console.log(` ${pushStatus} ` +
|
|
@@ -1780,6 +1845,9 @@ async function runNowSingle(hqRoot, company, personal, message, onConflict, mode
|
|
|
1780
1845
|
console.log(chalk.yellow(line));
|
|
1781
1846
|
}
|
|
1782
1847
|
}
|
|
1848
|
+
for (const line of staleUploadRefusalLines(pushResult.filesRefusedStale ?? 0, pushResult.filesRefusedStalePaths)) {
|
|
1849
|
+
console.log(chalk.yellow(line));
|
|
1850
|
+
}
|
|
1783
1851
|
if (pushResult.aborted) {
|
|
1784
1852
|
console.log(chalk.yellow("\n⚠ Sync now aborted on push leg; pull skipped."));
|
|
1785
1853
|
throw new SyncExitError(1);
|
|
@@ -1900,6 +1968,11 @@ async function runNowSingle(hqRoot, company, personal, message, onConflict, mode
|
|
|
1900
1968
|
"refused by your plan limit (listed above)."));
|
|
1901
1969
|
throw new SyncExitError(1, { health: "succeeded" });
|
|
1902
1970
|
}
|
|
1971
|
+
if (pushResult.filesExcludedByScope > 0 ||
|
|
1972
|
+
(pushResult.filesRefusedStale ?? 0) > 0) {
|
|
1973
|
+
console.log(chalk.yellow("\n⚠ Sync now finished, but one or more requested uploads were refused."));
|
|
1974
|
+
throw new SyncExitError(1, { health: "succeeded" });
|
|
1975
|
+
}
|
|
1903
1976
|
console.log(chalk.green("\n✓ Sync now complete"));
|
|
1904
1977
|
if (!personalMode &&
|
|
1905
1978
|
nudgeResolvedCompanyUid &&
|
|
@@ -1943,13 +2016,16 @@ async function runNowAll(hqRoot, message, onConflict, modeAllOverride, skipPerso
|
|
|
1943
2016
|
// pull-side).
|
|
1944
2017
|
await runPullAll(hqRoot, onConflict, modeAllOverride, skipPersonal, forceScopeShrink);
|
|
1945
2018
|
if (refused) {
|
|
1946
|
-
// A
|
|
1947
|
-
//
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
2019
|
+
// A refused push does not stop the pull, but the run must not end looking
|
|
2020
|
+
// like a clean sync. Its per-target details were printed above.
|
|
2021
|
+
if (refused.planLimitRefused) {
|
|
2022
|
+
console.log(chalk.yellow(`\n⚠ Sync finished, but ${describeRefusedFiles(refused.planLimitRefused)} refused ` +
|
|
2023
|
+
"by your plan limit (listed under push --all above)."));
|
|
2024
|
+
if (refused.planLimitRefused.upgradeUrl) {
|
|
2025
|
+
console.log(chalk.yellow(` Upgrade: ${refused.planLimitRefused.upgradeUrl}`));
|
|
2026
|
+
}
|
|
1952
2027
|
}
|
|
2028
|
+
console.log(chalk.yellow("\n⚠ Sync finished, but one or more requested uploads were refused."));
|
|
1953
2029
|
throw new SyncExitError(1, { health: "succeeded" });
|
|
1954
2030
|
}
|
|
1955
2031
|
}
|