@takodotid/circuit 0.34.2 → 0.34.3

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/dist/cli/index.js CHANGED
@@ -5601,7 +5601,15 @@ async function consoleShell(device) {
5601
5601
  async function read3(device, _network = [], options = {}) {
5602
5602
  const { channel, close } = await open(device, options);
5603
5603
  try {
5604
- const dump = await send(channel, "show running-config", 150000, 6000);
5604
+ let dump = "";
5605
+ for (let attempt = 1;; attempt++) {
5606
+ dump = await send(channel, "show running-config", 150000, 6000);
5607
+ if (/[#>]\s*$/.test(dump.replace(/\r/g, "").trimEnd()))
5608
+ break;
5609
+ if (attempt === 3)
5610
+ throw new Error(`${device.name} returned an incomplete configuration three times`);
5611
+ await send(channel, "", 30000, 6000);
5612
+ }
5605
5613
  const lines = dump.replace(/\r/g, "").split(`
5606
5614
  `);
5607
5615
  const start = lines.findIndex((line) => line.trim().startsWith("!ROS version"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takodotid/circuit",
3
- "version": "0.34.2",
3
+ "version": "0.34.3",
4
4
  "description": "Declarative, vendor-neutral network configuration: describe each device in TypeScript, and Circuit makes the device match. Alpha.",
5
5
  "keywords": [
6
6
  "network",
@@ -23,3 +23,4 @@ Behaviour that looks like something else. Each one has been hit on a RAX721 runn
23
23
  - OSPF settings for an interface sit on the interface, `ip ospf cost`, `ip ospf network ptp`, `ip ospf passive-interface enable`; passive is undone with `... disable`, not `no`.
24
24
  - `create vlan <list> active` has every VLAN on one line. A change creates only the new VLANs and removes each one that is gone with `no vlan <id>`.
25
25
  - An access-list rule is not replaced by one with the same number: the device answers `Set unsuccessfully.` and keeps the old rule. The old one is removed first. `no rule N` answers slowly, after a second or more.
26
+ - `show running-config` can stop partway even with paging off and six seconds of silence, with no error: on 2026-10-23 three reads of an RAX721 in a row gave plans of 62, 0 and 158 commands against an unchanged switch. A dump that does not end at the prompt is read again, and after three the read fails rather than planning against a part.
@@ -398,8 +398,15 @@ export async function read(device: Device, _network: readonly Device[] = [], opt
398
398
  const { channel, close } = await open(device, options);
399
399
 
400
400
  try {
401
- // Without paging off and a long wait for silence, the dump stops halfway with no error.
402
- const dump = await send(channel, "show running-config", 150_000, 6000);
401
+ // Without paging off and a long wait for silence, the dump stops halfway with no error. Even then a pause of the device's own can end it early: a complete dump ends at the prompt, and one that does not is read again rather than planned against.
402
+ let dump = "";
403
+ for (let attempt = 1; ; attempt++) {
404
+ dump = await send(channel, "show running-config", 150_000, 6000);
405
+ if (/[#>]\s*$/.test(dump.replace(/\r/g, "").trimEnd())) break;
406
+ if (attempt === 3) throw new Error(`${device.name} returned an incomplete configuration three times`);
407
+ // What the device still prints of the cut dump ends before the next one starts.
408
+ await send(channel, "", 30_000, 6000);
409
+ }
403
410
  const lines = dump.replace(/\r/g, "").split("\n");
404
411
  const start = lines.findIndex((line) => line.trim().startsWith("!ROS version"));
405
412
  if (start < 0) throw new Error(`${device.name} returned no configuration`);