@sppg2001/atomize 5.1.1 → 5.1.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.
Files changed (3) hide show
  1. package/README.md +53 -17
  2. package/dist/cli/index.js +270 -43
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,11 +1,23 @@
1
1
  # Atomize CLI
2
2
 
3
- Atomize CLI turns stories into consistent child tasks using reusable YAML templates. It supports template validation, safe previews, confirmed task generation, connection profile management, template catalog operations, and CI/CD automation.
3
+ **Break down stories, build up velocity.**
4
4
 
5
- Atomize is designed around platform adapters. Today, connected generation supports Azure DevOps. Mock is available for offline testing.
5
+ Atomize turns Stories into consistent child Tasks using reusable YAML Templates. Capture your team's task breakdown once, then validate, preview, and reuse it from your terminal or CI/CD pipeline.
6
+
7
+ - Try built-in Templates offline with Mock Stories.
8
+ - Customize task titles, descriptions, conditions, dependencies, and estimation rules in YAML.
9
+ - Reuse Templates and Mixins from built-in, user, and project Catalogs.
10
+ - Draft and improve Templates with your GitHub Copilot account.
11
+ - Preview real Azure DevOps Stories before confirming task creation.
12
+
13
+ Connected generation currently supports **Azure DevOps**. Offline Validation and Mock Preview require no platform account or Connection Profile.
14
+
15
+ [Website and documentation](https://atomize-docs.pages.dev/) · [CLI quickstart](https://atomize-docs.pages.dev/getting-started/cli/) · [Source and issues](https://github.com/Simao-Pereira-Gomes/atomize)
6
16
 
7
17
  ## Install
8
18
 
19
+ Requires [Node.js](https://nodejs.org/) **22 or later** and npm.
20
+
9
21
  ```bash
10
22
  npm install -g @sppg2001/atomize
11
23
  ```
@@ -25,21 +37,28 @@ npx @sppg2001/atomize --help
25
37
 
26
38
  ## Quick Start
27
39
 
28
- Try Atomize without credentials:
40
+ ### Try it offline
41
+
42
+ The `backend-api` Template ships with the CLI. Validate it, then preview a task breakdown using a Mock Story:
29
43
 
30
44
  ```bash
31
45
  atomize validate template:backend-api
32
- atomize generate template:backend-api --platform mock
46
+ atomize preview template:backend-api \
47
+ --mock-story '{"id":"123","title":"Add password reset","estimation":8}'
33
48
  ```
34
49
 
35
- Connect Azure DevOps:
50
+ The preview returns three Tasks: define API behavior, implement the change, and verify it. The example Template converts the Story Estimate of 8 into a 32-hour budget and splits it 20% / 50% / 30%. Change the title or estimate and run it again to see the breakdown change. No Work Items are created.
51
+
52
+ ### Connect Azure DevOps
53
+
54
+ Add a Connection Profile using an Azure DevOps PAT with **Work Items read/write** access:
36
55
 
37
56
  ```bash
38
57
  atomize auth add work-ado
39
58
  atomize auth test work-ado
40
59
  ```
41
60
 
42
- Preview and then create tasks:
61
+ Preview real Stories, then create Tasks after reviewing the plan:
43
62
 
44
63
  ```bash
45
64
  # Dry run, no tasks created
@@ -49,6 +68,8 @@ atomize generate template:backend-api --profile work-ado
49
68
  atomize generate template:backend-api --profile work-ado --execute
50
69
  ```
51
70
 
71
+ Use `--story 123 456` to select specific Stories. See the [Auth Guide](https://atomize-docs.pages.dev/connections/profiles/) for PAT permissions, credential storage, and profile setup.
72
+
52
73
  ## Safety Model
53
74
 
54
75
  `atomize generate` is a dry run by default. It calculates the task plan but does not create tasks.
@@ -103,6 +124,20 @@ atomize fields list --type Task
103
124
  atomize queries list
104
125
  ```
105
126
 
127
+ ## AI-Assisted Authoring
128
+
129
+ Use your signed-in GitHub Copilot account to draft a Template from prose or review a proposed improvement to an existing one:
130
+
131
+ ```bash
132
+ atomize template create --ai
133
+ atomize template improve template:backend-api
134
+
135
+ # Draft with your team's written process as reference material
136
+ atomize template create --ai --reference docs/how-we-work.md
137
+ ```
138
+
139
+ AI authoring uses a separate Copilot Session; it does not require an Azure DevOps Connection Profile. You can explicitly add project context with `--ground --profile work-ado`. See [AI authoring](https://atomize-docs.pages.dev/cli/ai/) for sign-in, Reference Documents, and review workflows.
140
+
106
141
  ## CI/CD
107
142
 
108
143
  Validate first, then run live generation with explicit acknowledgement:
@@ -134,22 +169,23 @@ Validate first, then run live generation with explicit acknowledgement:
134
169
  --output report.json
135
170
  ```
136
171
 
137
- ## VS Code Extension
172
+ ## Desktop and Editor Workflows
138
173
 
139
- Prefer an editor workflow? Atomize also has a VS Code extension for YAML authoring, validation, mock/live preview, profile management, catalog browsing, and confirmed generation.
174
+ - **[Atomize Studio](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/Atomize-Studio.md)** is a standalone desktop app for visual Template authoring, Catalog management, and confirmed task generation. Download an installer via [Studio Releases](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/Studio-Releases.md).
175
+ - **[VS Code extension](https://atomize-docs.pages.dev/getting-started/vscode/)** provides YAML completions, schema hovers, diagnostics, Mock and Live Preview, and confirmed generation in your editor.
140
176
 
141
- See the [VS Code Extension Guide](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/VS-Code-Extension.md).
177
+ The CLI and Studio share Connection Profile metadata and compatible OS-keyring-backed tokens. VS Code manages its own profiles. See the [Auth Guide](https://atomize-docs.pages.dev/connections/profiles/#shared-between-the-cli-and-atomize-studio) for details.
142
178
 
143
179
  ## Documentation
144
180
 
145
- - [Product README](https://github.com/Simao-Pereira-Gomes/atomize#readme) - VS Code-first onboarding and product overview
146
- - [Documentation Index](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/README.md)
147
- - [Workflows](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/Workflows.md)
148
- - [CLI Reference](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/Cli-Reference.md)
149
- - [Template Creation](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/Template-Creation.md)
150
- - [Template Reference](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/Template-Reference.md)
151
- - [Auth Guide](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/Auth-Guide.md)
152
- - [Platform Guide](https://github.com/Simao-Pereira-Gomes/atomize/blob/main/docs/Platform-Guide.md)
181
+ - [Website and Documentation](https://atomize-docs.pages.dev/)
182
+ - [Workflows](https://atomize-docs.pages.dev/workflows/)
183
+ - [CLI Reference](https://atomize-docs.pages.dev/cli/reference/)
184
+ - [Template Creation](https://atomize-docs.pages.dev/catalog/create/)
185
+ - [Schema Reference](https://atomize-docs.pages.dev/reference/templates/schema/)
186
+ - [Template Reference](https://atomize-docs.pages.dev/reference/templates/)
187
+ - [Auth Guide](https://atomize-docs.pages.dev/connections/profiles/)
188
+ - [Platform Guide](https://atomize-docs.pages.dev/connections/)
153
189
 
154
190
  ## License
155
191
 
package/dist/cli/index.js CHANGED
@@ -24217,13 +24217,14 @@ var require_side_channel = __commonJS((exports, module) => {
24217
24217
  };
24218
24218
  });
24219
24219
 
24220
- // ../../node_modules/.bun/qs@6.16.0/node_modules/qs/lib/formats.js
24220
+ // ../../node_modules/.bun/qs@6.17.1/node_modules/qs/lib/formats.js
24221
24221
  var require_formats = __commonJS((exports, module) => {
24222
24222
  var replace = String.prototype.replace;
24223
24223
  var percentTwenties = /%20/g;
24224
24224
  var Format = {
24225
24225
  RFC1738: "RFC1738",
24226
- RFC3986: "RFC3986"
24226
+ RFC3986: "RFC3986",
24227
+ WHATWG: "WHATWG"
24227
24228
  };
24228
24229
  module.exports = {
24229
24230
  default: Format.RFC3986,
@@ -24233,14 +24234,18 @@ var require_formats = __commonJS((exports, module) => {
24233
24234
  },
24234
24235
  RFC3986: function(value) {
24235
24236
  return String(value);
24237
+ },
24238
+ WHATWG: function(value) {
24239
+ return replace.call(value, percentTwenties, "+");
24236
24240
  }
24237
24241
  },
24238
24242
  RFC1738: Format.RFC1738,
24239
- RFC3986: Format.RFC3986
24243
+ RFC3986: Format.RFC3986,
24244
+ WHATWG: Format.WHATWG
24240
24245
  };
24241
24246
  });
24242
24247
 
24243
- // ../../node_modules/.bun/qs@6.16.0/node_modules/qs/lib/utils.js
24248
+ // ../../node_modules/.bun/qs@6.17.1/node_modules/qs/lib/utils.js
24244
24249
  var require_utils = __commonJS((exports, module) => {
24245
24250
  var formats = require_formats();
24246
24251
  var getSideChannel = require_side_channel();
@@ -24261,6 +24266,17 @@ var require_utils = __commonJS((exports, module) => {
24261
24266
  var setMaxIndex = function setMaxIndex2(obj, maxIndex) {
24262
24267
  overflowChannel.set(obj, maxIndex);
24263
24268
  };
24269
+ var conflictChannel = getSideChannel();
24270
+ var markConflict = function markConflict2(obj, maxIndex) {
24271
+ conflictChannel.set(obj, maxIndex);
24272
+ return obj;
24273
+ };
24274
+ var isConflict = function isConflict2(obj) {
24275
+ return conflictChannel.has(obj);
24276
+ };
24277
+ var getConflictIndex = function getConflictIndex2(obj) {
24278
+ return conflictChannel.get(obj);
24279
+ };
24264
24280
  var hexTable = function() {
24265
24281
  var array2 = [];
24266
24282
  for (var i2 = 0;i2 < 256; ++i2) {
@@ -24304,6 +24320,36 @@ var require_utils = __commonJS((exports, module) => {
24304
24320
  obj[key] = value;
24305
24321
  }
24306
24322
  };
24323
+ var maxNumericIndex = function maxNumericIndex2(obj, min) {
24324
+ var max = min;
24325
+ var keys = Object.keys(obj);
24326
+ for (var i2 = 0;i2 < keys.length; ++i2) {
24327
+ var num = parseInt(keys[i2], 10);
24328
+ if (String(num) === keys[i2] && num > max) {
24329
+ max = num;
24330
+ }
24331
+ }
24332
+ return max;
24333
+ };
24334
+ var countElements = function countElements2(arr) {
24335
+ var count = 0;
24336
+ for (var i2 = 0;i2 < arr.length; ++i2) {
24337
+ if (has.call(arr, i2)) {
24338
+ count += 1;
24339
+ }
24340
+ }
24341
+ return count;
24342
+ };
24343
+ var limitedPair = function limitedPair2(first, second, options) {
24344
+ var pair = [first, second];
24345
+ if (options && typeof options.arrayLimit === "number" && pair.length > options.arrayLimit) {
24346
+ if (options.throwOnLimitExceeded) {
24347
+ throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array.");
24348
+ }
24349
+ return markOverflow(arrayToObject(pair, options), 1);
24350
+ }
24351
+ return pair;
24352
+ };
24307
24353
  var merge2 = function merge3(target, source, options) {
24308
24354
  if (!source) {
24309
24355
  return target;
@@ -24311,7 +24357,7 @@ var require_utils = __commonJS((exports, module) => {
24311
24357
  if (typeof source !== "object" && typeof source !== "function") {
24312
24358
  if (isArray(target)) {
24313
24359
  var nextIndex = target.length;
24314
- if (options && typeof options.arrayLimit === "number" && nextIndex >= options.arrayLimit) {
24360
+ if (options && typeof options.arrayLimit === "number" && countElements(target) >= options.arrayLimit) {
24315
24361
  if (options.throwOnLimitExceeded) {
24316
24362
  throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array.");
24317
24363
  }
@@ -24323,13 +24369,21 @@ var require_utils = __commonJS((exports, module) => {
24323
24369
  var newIndex = getMaxIndex(target) + 1;
24324
24370
  target[newIndex] = source;
24325
24371
  setMaxIndex(target, newIndex);
24372
+ } else if (options && options.strictMerge && isConflict(target)) {
24373
+ var nextConflict = getConflictIndex(target) + 1;
24374
+ if (options.throwOnLimitExceeded && typeof options.arrayLimit === "number" && nextConflict >= options.arrayLimit) {
24375
+ throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array.");
24376
+ }
24377
+ target[nextConflict] = source;
24378
+ markConflict(target, nextConflict);
24326
24379
  } else if (options && options.strictMerge) {
24327
- return [target, source];
24380
+ var conflict = limitedPair(target, source, options);
24381
+ return isArray(conflict) ? markConflict(conflict, 1) : conflict;
24328
24382
  } else if (options && (options.plainObjects || options.allowPrototypes) || !has.call(Object.prototype, source)) {
24329
24383
  target[source] = true;
24330
24384
  }
24331
24385
  } else {
24332
- return [target, source];
24386
+ return limitedPair(target, source, options);
24333
24387
  }
24334
24388
  return target;
24335
24389
  }
@@ -24355,6 +24409,9 @@ var require_utils = __commonJS((exports, module) => {
24355
24409
  var mergeTarget = target;
24356
24410
  if (isArray(target) && !isArray(source)) {
24357
24411
  mergeTarget = arrayToObject(target, options);
24412
+ if (isConflict(target)) {
24413
+ markConflict(mergeTarget, target.length - 1);
24414
+ }
24358
24415
  }
24359
24416
  if (isArray(target) && isArray(source)) {
24360
24417
  source.forEach(function(item, i2) {
@@ -24369,7 +24426,7 @@ var require_utils = __commonJS((exports, module) => {
24369
24426
  target[i2] = item;
24370
24427
  }
24371
24428
  });
24372
- if (options && typeof options.arrayLimit === "number" && target.length > options.arrayLimit) {
24429
+ if (options && typeof options.arrayLimit === "number" && countElements(target) > options.arrayLimit) {
24373
24430
  if (options.throwOnLimitExceeded) {
24374
24431
  throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array.");
24375
24432
  }
@@ -24385,7 +24442,7 @@ var require_utils = __commonJS((exports, module) => {
24385
24442
  setProperty(acc, key, value);
24386
24443
  }
24387
24444
  if (isOverflow(source) && !isOverflow(acc)) {
24388
- markOverflow(acc, getMaxIndex(source));
24445
+ markOverflow(acc, maxNumericIndex(acc, getMaxIndex(source)));
24389
24446
  }
24390
24447
  if (isOverflow(acc)) {
24391
24448
  var keyNum = parseInt(key, 10);
@@ -24393,6 +24450,12 @@ var require_utils = __commonJS((exports, module) => {
24393
24450
  setMaxIndex(acc, keyNum);
24394
24451
  }
24395
24452
  }
24453
+ if (isConflict(acc)) {
24454
+ var conflictKey = parseInt(key, 10);
24455
+ if (String(conflictKey) === key && conflictKey > getConflictIndex(acc)) {
24456
+ markConflict(acc, conflictKey);
24457
+ }
24458
+ }
24396
24459
  return acc;
24397
24460
  }, mergeTarget);
24398
24461
  };
@@ -24403,6 +24466,9 @@ var require_utils = __commonJS((exports, module) => {
24403
24466
  }, target);
24404
24467
  };
24405
24468
  var decode3 = function(str, defaultDecoder, charset) {
24469
+ if (typeof str === "string" && str.indexOf("%") === -1) {
24470
+ return str.indexOf("+") === -1 ? str : str.replace(/\+/g, " ");
24471
+ }
24406
24472
  var strWithoutPlus = str.replace(/\+/g, " ");
24407
24473
  if (charset === "iso-8859-1") {
24408
24474
  return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
@@ -24413,6 +24479,52 @@ var require_utils = __commonJS((exports, module) => {
24413
24479
  return strWithoutPlus;
24414
24480
  }
24415
24481
  };
24482
+ var hasToPrimitive = typeof Symbol === "function" && typeof Symbol.toPrimitive === "symbol";
24483
+ var arrayJoin = Array.prototype.join;
24484
+ var arrayToString = Array.prototype.toString;
24485
+ var objectToString = Object.prototype.toString;
24486
+ var toCoercible = function toCoercible2(value, joining) {
24487
+ if (!value || typeof value !== "object" && typeof value !== "function") {
24488
+ return value;
24489
+ }
24490
+ if (hasToPrimitive && value[Symbol.toPrimitive] != null) {
24491
+ return value;
24492
+ }
24493
+ if (isArray(value) && value.toString === arrayToString && value.join === arrayJoin) {
24494
+ var ancestors = joining || getSideChannel();
24495
+ if (ancestors.has(value)) {
24496
+ return "";
24497
+ }
24498
+ ancestors.set(value, true);
24499
+ var copy;
24500
+ for (var i2 = 0;i2 < value.length; i2 += 1) {
24501
+ var item = value[i2];
24502
+ var coerced = toCoercible2(item, ancestors);
24503
+ if (!copy && coerced !== item) {
24504
+ copy = [];
24505
+ for (var j2 = 0;j2 < i2; j2 += 1) {
24506
+ copy[j2] = value[j2];
24507
+ }
24508
+ }
24509
+ if (copy) {
24510
+ copy[i2] = coerced;
24511
+ }
24512
+ }
24513
+ ancestors["delete"](value);
24514
+ return copy || value;
24515
+ }
24516
+ if (typeof value.toString === "function") {
24517
+ return value;
24518
+ }
24519
+ var valueOf = value.valueOf;
24520
+ if (typeof valueOf === "function") {
24521
+ var primitive = valueOf.call(value);
24522
+ if (!primitive || typeof primitive !== "object" && typeof primitive !== "function") {
24523
+ return String(primitive);
24524
+ }
24525
+ }
24526
+ return objectToString.call(value);
24527
+ };
24416
24528
  var limit = 1024;
24417
24529
  var encode3 = function encode4(str, defaultEncoder, charset, kind, format) {
24418
24530
  if (str.length === 0) {
@@ -24422,12 +24534,12 @@ var require_utils = __commonJS((exports, module) => {
24422
24534
  if (typeof str === "symbol") {
24423
24535
  string4 = Symbol.prototype.toString.call(str);
24424
24536
  } else if (typeof str !== "string") {
24425
- string4 = String(str);
24537
+ string4 = String(toCoercible(str));
24426
24538
  }
24427
24539
  if (charset === "iso-8859-1") {
24428
24540
  return escape(string4).replace(/%u[0-9a-f]{4}/gi, function($0) {
24429
24541
  return "%26%23" + parseInt($0.slice(2), 16) + "%3B";
24430
- });
24542
+ }).replace(/\+/g, "%2B");
24431
24543
  }
24432
24544
  var out = "";
24433
24545
  for (var j2 = 0;j2 < string4.length; j2 += limit) {
@@ -24442,7 +24554,7 @@ var require_utils = __commonJS((exports, module) => {
24442
24554
  var arr = [];
24443
24555
  for (var i2 = 0;i2 < segment.length; ++i2) {
24444
24556
  var c2 = segment.charCodeAt(i2);
24445
- if (c2 === 45 || c2 === 46 || c2 === 95 || c2 === 126 || c2 >= 48 && c2 <= 57 || c2 >= 65 && c2 <= 90 || c2 >= 97 && c2 <= 122 || format === formats.RFC1738 && (c2 === 40 || c2 === 41)) {
24557
+ if (c2 === 45 || c2 === 46 || c2 === 95 || c2 === 126 && format !== formats.WHATWG || c2 >= 48 && c2 <= 57 || c2 >= 65 && c2 <= 90 || c2 >= 97 && c2 <= 122 || format === formats.RFC1738 && (c2 === 40 || c2 === 41) || format === formats.WHATWG && c2 === 42) {
24446
24558
  arr[arr.length] = segment.charAt(i2);
24447
24559
  continue;
24448
24560
  }
@@ -24458,9 +24570,14 @@ var require_utils = __commonJS((exports, module) => {
24458
24570
  arr[arr.length] = hexTable[224 | c2 >> 12] + hexTable[128 | c2 >> 6 & 63] + hexTable[128 | c2 & 63];
24459
24571
  continue;
24460
24572
  }
24461
- i2 += 1;
24462
- c2 = 65536 + ((c2 & 1023) << 10 | segment.charCodeAt(i2) & 1023);
24463
- arr[arr.length] = hexTable[240 | c2 >> 18] + hexTable[128 | c2 >> 12 & 63] + hexTable[128 | c2 >> 6 & 63] + hexTable[128 | c2 & 63];
24573
+ var next = segment.charCodeAt(i2 + 1);
24574
+ if (c2 <= 56319 && next >= 56320 && next <= 57343) {
24575
+ i2 += 1;
24576
+ c2 = 65536 + ((c2 & 1023) << 10 | next & 1023);
24577
+ arr[arr.length] = hexTable[240 | c2 >> 18] + hexTable[128 | c2 >> 12 & 63] + hexTable[128 | c2 >> 6 & 63] + hexTable[128 | c2 & 63];
24578
+ } else {
24579
+ arr[arr.length] = "%EF%BF%BD";
24580
+ }
24464
24581
  }
24465
24582
  out += arr.join("");
24466
24583
  }
@@ -24539,11 +24656,13 @@ var require_utils = __commonJS((exports, module) => {
24539
24656
  isRegExp,
24540
24657
  markOverflow,
24541
24658
  maybeMap,
24542
- merge: merge2
24659
+ merge: merge2,
24660
+ setProperty,
24661
+ toCoercible
24543
24662
  };
24544
24663
  });
24545
24664
 
24546
- // ../../node_modules/.bun/qs@6.16.0/node_modules/qs/lib/stringify.js
24665
+ // ../../node_modules/.bun/qs@6.17.1/node_modules/qs/lib/stringify.js
24547
24666
  var require_stringify = __commonJS((exports, module) => {
24548
24667
  var getSideChannel = require_side_channel();
24549
24668
  var utils = require_utils();
@@ -24650,20 +24769,20 @@ var require_stringify = __commonJS((exports, module) => {
24650
24769
  if (generateArrayPrefix === "comma" && isArray(obj)) {
24651
24770
  if (encodeValuesOnly && encoder) {
24652
24771
  obj = utils.maybeMap(obj, function(v2) {
24653
- return v2 == null ? v2 : encoder(v2);
24772
+ return v2 == null ? v2 : encoder(v2, defaults.encoder, charset, "value", format);
24654
24773
  });
24655
24774
  }
24656
- objKeys = [{ value: obj.length > 0 ? obj.join(",") || null : undefined }];
24775
+ objKeys = [{ value: obj.length > 0 ? utils.toCoercible(obj).join(",") || null : undefined }];
24657
24776
  } else if (isArray(filter)) {
24658
24777
  objKeys = filter;
24659
24778
  } else {
24660
24779
  var keys = Object.keys(obj);
24661
24780
  objKeys = sort ? keys.sort(sort) : keys;
24662
24781
  }
24663
- var encodedPrefix = encodeDotInKeys ? String(prefix).replace(/\./g, "%2E") : String(prefix);
24782
+ var encodedPrefix = String(prefix);
24664
24783
  var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encodedPrefix + "[]" : encodedPrefix;
24665
24784
  if (allowEmptyArrays && isArray(obj) && obj.length === 0 && Object.keys(obj).length === 0) {
24666
- return adjustedPrefix + "[]";
24785
+ return formatter(encoder && !encodeValuesOnly ? encoder(adjustedPrefix, defaults.encoder, charset, "key", format) : adjustedPrefix) + "[]";
24667
24786
  }
24668
24787
  for (var j2 = 0;j2 < objKeys.length; ++j2) {
24669
24788
  var key = objKeys[j2];
@@ -24710,7 +24829,7 @@ var require_stringify = __commonJS((exports, module) => {
24710
24829
  filter = opts.filter;
24711
24830
  }
24712
24831
  var arrayFormat;
24713
- if (opts.arrayFormat in arrayPrefixGenerators) {
24832
+ if (has.call(arrayPrefixGenerators, opts.arrayFormat)) {
24714
24833
  arrayFormat = opts.arrayFormat;
24715
24834
  } else if ("indices" in opts) {
24716
24835
  arrayFormat = opts.indices ? "indices" : "repeat";
@@ -24753,7 +24872,7 @@ var require_stringify = __commonJS((exports, module) => {
24753
24872
  filter = options.filter;
24754
24873
  obj = filter("", obj);
24755
24874
  } else if (isArray(options.filter)) {
24756
- filter = options.filter;
24875
+ filter = options.filter.slice();
24757
24876
  objKeys = filter;
24758
24877
  }
24759
24878
  var keys = [];
@@ -24779,7 +24898,7 @@ var require_stringify = __commonJS((exports, module) => {
24779
24898
  continue;
24780
24899
  }
24781
24900
  var encodedKey = options.encodeDotInKeys ? String(key).replace(/\./g, "%2E") : String(key);
24782
- pushToArray(keys, stringify(value, encodedKey, generateArrayPrefix, commaRoundTrip, options.allowEmptyArrays, options.strictNullHandling, options.skipNulls, options.encodeDotInKeys, options.encode ? options.encoder : null, options.filter, options.sort, options.allowDots, options.serializeDate, options.format, options.formatter, options.encodeValuesOnly, options.charset, sideChannel, options.depth, 0));
24901
+ pushToArray(keys, stringify(value, encodedKey, generateArrayPrefix, commaRoundTrip, options.allowEmptyArrays, options.strictNullHandling, options.skipNulls, options.encodeDotInKeys, options.encode ? options.encoder : null, filter, options.sort, options.allowDots, options.serializeDate, options.format, options.formatter, options.encodeValuesOnly, options.charset, sideChannel, options.depth, 0));
24783
24902
  }
24784
24903
  var joined = keys.join(options.delimiter);
24785
24904
  var prefix = options.addQueryPrefix === true ? "?" : "";
@@ -24794,11 +24913,56 @@ var require_stringify = __commonJS((exports, module) => {
24794
24913
  };
24795
24914
  });
24796
24915
 
24797
- // ../../node_modules/.bun/qs@6.16.0/node_modules/qs/lib/parse.js
24916
+ // ../../node_modules/.bun/qs@6.17.1/node_modules/qs/lib/parse.js
24798
24917
  var require_parse = __commonJS((exports, module) => {
24918
+ var getSideChannel = require_side_channel();
24799
24919
  var utils = require_utils();
24800
24920
  var has = Object.prototype.hasOwnProperty;
24801
24921
  var isArray = Array.isArray;
24922
+ var getPrototypeOf = Object.getPrototypeOf;
24923
+ var fromCharCode = String.fromCharCode;
24924
+ var isPlainContainer = function isPlainContainer2(value) {
24925
+ if (!value || typeof value !== "object") {
24926
+ return false;
24927
+ }
24928
+ if (isArray(value)) {
24929
+ return true;
24930
+ }
24931
+ var proto = getPrototypeOf(value);
24932
+ return proto === Object.prototype || proto === null;
24933
+ };
24934
+ var emptyCopyOf = function emptyCopyOf2(value) {
24935
+ if (isArray(value)) {
24936
+ var arr = [];
24937
+ arr.length = value.length;
24938
+ return arr;
24939
+ }
24940
+ return getPrototypeOf(value) === null ? { __proto__: null } : {};
24941
+ };
24942
+ var copyInput = function copyInput2(input2) {
24943
+ var copies = getSideChannel();
24944
+ var result = {};
24945
+ var queue = [{ source: input2, target: result }];
24946
+ for (var i2 = 0;i2 < queue.length; ++i2) {
24947
+ var source = queue[i2].source;
24948
+ var target = queue[i2].target;
24949
+ var keys = Object.keys(source);
24950
+ for (var j2 = 0;j2 < keys.length; ++j2) {
24951
+ var value = source[keys[j2]];
24952
+ if (isPlainContainer(value)) {
24953
+ if (!copies.has(value)) {
24954
+ var copy = emptyCopyOf(value);
24955
+ copies.set(value, copy);
24956
+ queue[queue.length] = { source: value, target: copy };
24957
+ }
24958
+ utils.setProperty(target, keys[j2], copies.get(value));
24959
+ } else {
24960
+ utils.setProperty(target, keys[j2], value);
24961
+ }
24962
+ }
24963
+ }
24964
+ return result;
24965
+ };
24802
24966
  var defaults = {
24803
24967
  allowDots: false,
24804
24968
  allowEmptyArrays: false,
@@ -24825,7 +24989,12 @@ var require_parse = __commonJS((exports, module) => {
24825
24989
  };
24826
24990
  var interpretNumericEntities = function(str) {
24827
24991
  return str.replace(/&#(\d+);/g, function($0, numberStr) {
24828
- return String.fromCharCode(parseInt(numberStr, 10));
24992
+ var c2 = parseInt(numberStr, 10);
24993
+ if (c2 > 65535 && c2 <= 1114111) {
24994
+ c2 -= 65536;
24995
+ return fromCharCode(55296 | c2 >> 10, 56320 | c2 & 1023);
24996
+ }
24997
+ return fromCharCode(c2);
24829
24998
  });
24830
24999
  };
24831
25000
  var parseArrayValue = function(val, options, currentArrayLength) {
@@ -24843,7 +25012,7 @@ var require_parse = __commonJS((exports, module) => {
24843
25012
  }
24844
25013
  return val.split(",");
24845
25014
  }
24846
- if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit) {
25015
+ if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit && currentArrayLength > 0) {
24847
25016
  throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array.");
24848
25017
  }
24849
25018
  return val;
@@ -24882,6 +25051,7 @@ var require_parse = __commonJS((exports, module) => {
24882
25051
  var part = parts[i2];
24883
25052
  var bracketEqualsPos = part.indexOf("]=");
24884
25053
  var pos = bracketEqualsPos === -1 ? part.indexOf("=") : bracketEqualsPos + 1;
25054
+ var isEmptyBracketKey = pos > 1 && part.slice(pos - 2, pos) === "[]";
24885
25055
  var key;
24886
25056
  var val;
24887
25057
  if (pos === -1) {
@@ -24890,15 +25060,17 @@ var require_parse = __commonJS((exports, module) => {
24890
25060
  } else {
24891
25061
  key = options.decoder(part.slice(0, pos), defaults.decoder, charset, "key");
24892
25062
  if (key !== null) {
24893
- val = utils.maybeMap(parseArrayValue(part.slice(pos + 1), options, isArray(obj[key]) ? obj[key].length : 0), function(encodedVal) {
25063
+ val = utils.maybeMap(parseArrayValue(part.slice(pos + 1), options, isArray(obj[key]) && (options.duplicates === "combine" || isEmptyBracketKey) ? obj[key].length : 0), function(encodedVal) {
24894
25064
  return options.decoder(encodedVal, defaults.decoder, charset, "value");
24895
25065
  });
24896
25066
  }
24897
25067
  }
24898
25068
  if (val && options.interpretNumericEntities && charset === "iso-8859-1") {
24899
- val = interpretNumericEntities(String(val));
25069
+ val = utils.maybeMap(val, function(value) {
25070
+ return value ? interpretNumericEntities(String(value)) : value;
25071
+ });
24900
25072
  }
24901
- if (part.indexOf("[]=") > -1) {
25073
+ if (isEmptyBracketKey) {
24902
25074
  val = isArray(val) ? [val] : val;
24903
25075
  }
24904
25076
  if (options.comma && isArray(val) && val.length > options.arrayLimit) {
@@ -24906,7 +25078,7 @@ var require_parse = __commonJS((exports, module) => {
24906
25078
  }
24907
25079
  if (key !== null) {
24908
25080
  var existing = has.call(obj, key);
24909
- if (existing && (options.duplicates === "combine" || part.indexOf("[]=") > -1)) {
25081
+ if (existing && (options.duplicates === "combine" || isEmptyBracketKey)) {
24910
25082
  obj[key] = utils.combine(obj[key], val, options.arrayLimit, options.plainObjects, options.throwOnLimitExceeded);
24911
25083
  } else if (!existing || options.duplicates === "last") {
24912
25084
  obj[key] = val;
@@ -24915,6 +25087,9 @@ var require_parse = __commonJS((exports, module) => {
24915
25087
  }
24916
25088
  return obj;
24917
25089
  };
25090
+ var stripWrappingBrackets = function stripWrappingBrackets2(key) {
25091
+ return key.charAt(0) === "[" && key.charAt(key.length - 1) === "]" ? key.slice(1, -1) : key;
25092
+ };
24918
25093
  var parseObject = function(chain, val, options, valuesParsed) {
24919
25094
  var currentArrayLength = 0;
24920
25095
  if (chain.length > 0 && chain[chain.length - 1] === "[]") {
@@ -24933,12 +25108,12 @@ var require_parse = __commonJS((exports, module) => {
24933
25108
  }
24934
25109
  } else {
24935
25110
  obj = options.plainObjects ? { __proto__: null } : {};
24936
- var cleanRoot = root.charAt(0) === "[" && root.charAt(root.length - 1) === "]" ? root.slice(1, -1) : root;
24937
- var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/g, ".") : cleanRoot;
25111
+ var cleanRoot = stripWrappingBrackets(root);
25112
+ var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/gi, ".") : cleanRoot;
24938
25113
  var index = parseInt(decodedRoot, 10);
24939
25114
  var isValidArrayIndex = !isNaN(index) && root !== decodedRoot && String(index) === decodedRoot && index >= 0 && options.parseArrays;
24940
25115
  if (!options.parseArrays && decodedRoot === "") {
24941
- obj = { 0: leaf };
25116
+ obj[0] = leaf;
24942
25117
  } else if (isValidArrayIndex && index < options.arrayLimit) {
24943
25118
  obj = [];
24944
25119
  obj[index] = leaf;
@@ -24955,10 +25130,37 @@ var require_parse = __commonJS((exports, module) => {
24955
25130
  }
24956
25131
  return leaf;
24957
25132
  };
25133
+ var topLevelDotsToBrackets = function topLevelDotsToBrackets2(key) {
25134
+ var result = "";
25135
+ var depth = 0;
25136
+ for (var i2 = 0;i2 < key.length; i2 += 1) {
25137
+ var cu = key.charCodeAt(i2);
25138
+ if (cu === 91) {
25139
+ depth += 1;
25140
+ result += "[";
25141
+ } else if (cu === 93) {
25142
+ if (depth > 0) {
25143
+ depth -= 1;
25144
+ }
25145
+ result += "]";
25146
+ } else if (cu === 46 && depth === 0 && i2 + 1 < key.length && key.charCodeAt(i2 + 1) !== 46 && key.charCodeAt(i2 + 1) !== 91) {
25147
+ var start = i2 + 1;
25148
+ var j2 = start;
25149
+ while (j2 < key.length && key.charCodeAt(j2) !== 46 && key.charCodeAt(j2) !== 91) {
25150
+ j2 += 1;
25151
+ }
25152
+ result += "[" + key.slice(start, j2) + "]";
25153
+ i2 = j2 - 1;
25154
+ } else {
25155
+ result += key.charAt(i2);
25156
+ }
25157
+ }
25158
+ return result;
25159
+ };
24958
25160
  var splitKeyIntoSegments = function splitKeyIntoSegments2(originalKey, options) {
24959
- var key = options.allowDots ? originalKey.replace(/\.([^.[]+)/g, "[$1]") : originalKey;
25161
+ var key = options.allowDots ? topLevelDotsToBrackets(originalKey) : originalKey;
24960
25162
  if (options.depth <= 0) {
24961
- if (!options.plainObjects && has.call(Object.prototype, key)) {
25163
+ if (!options.plainObjects && has.call(Object.prototype, stripWrappingBrackets(key))) {
24962
25164
  if (!options.allowPrototypes) {
24963
25165
  return;
24964
25166
  }
@@ -25081,7 +25283,7 @@ var require_parse = __commonJS((exports, module) => {
25081
25283
  if (str === "" || str === null || typeof str === "undefined") {
25082
25284
  return options.plainObjects ? { __proto__: null } : {};
25083
25285
  }
25084
- var tempObj = typeof str === "string" ? parseValues(str, options) : str;
25286
+ var tempObj = typeof str === "string" ? parseValues(str, options) : copyInput(str);
25085
25287
  var obj = options.plainObjects ? { __proto__: null } : {};
25086
25288
  var keys = Object.keys(tempObj);
25087
25289
  for (var i2 = 0;i2 < keys.length; ++i2) {
@@ -25096,7 +25298,7 @@ var require_parse = __commonJS((exports, module) => {
25096
25298
  };
25097
25299
  });
25098
25300
 
25099
- // ../../node_modules/.bun/qs@6.16.0/node_modules/qs/lib/index.js
25301
+ // ../../node_modules/.bun/qs@6.17.1/node_modules/qs/lib/index.js
25100
25302
  var require_lib = __commonJS((exports, module) => {
25101
25303
  var stringify = require_stringify();
25102
25304
  var parse5 = require_parse();
@@ -99784,7 +99986,7 @@ var program = new Command;
99784
99986
 
99785
99987
  // package.json
99786
99988
  var name = "@sppg2001/atomize";
99787
- var version2 = "5.1.1";
99989
+ var version2 = "5.1.3";
99788
99990
 
99789
99991
  // src/cli/commands/auth/auth-add.command.ts
99790
99992
  init_dist6();
@@ -105180,7 +105382,9 @@ function applyProposalToYaml(sourceYaml, proposal) {
105180
105382
  const doc2 = $parseDocument(sourceYaml);
105181
105383
  if (deepEqual2(doc2.toJS(), proposal))
105182
105384
  return sourceYaml;
105183
- doc2.contents = merge2(doc2, doc2.contents, proposal);
105385
+ const aliases = new Map;
105386
+ doc2.contents = merge2(doc2, doc2.contents, proposal, aliases);
105387
+ expandStaleAliases(doc2, aliases);
105184
105388
  return doc2.toString(detectIndentation(sourceYaml));
105185
105389
  }
105186
105390
  function deriveImprovedCopy(proposal, source) {
@@ -105191,7 +105395,11 @@ function deriveImprovedCopy(proposal, source) {
105191
105395
  ...source.catalogRef ? { origin: source.catalogRef } : {}
105192
105396
  };
105193
105397
  }
105194
- function merge2(doc2, node2, value) {
105398
+ function merge2(doc2, node2, value, aliases) {
105399
+ if ($isAlias(node2)) {
105400
+ aliases.set(node2, value);
105401
+ return node2;
105402
+ }
105195
105403
  if (isPlainObject4(value) && $isMap(node2)) {
105196
105404
  for (const pair of [...node2.items]) {
105197
105405
  const key = $isScalar(pair.key) ? pair.key.value : pair.key;
@@ -105202,7 +105410,7 @@ function merge2(doc2, node2, value) {
105202
105410
  if (child === undefined)
105203
105411
  continue;
105204
105412
  const existing = node2.get(key, true);
105205
- node2.set(key, existing === undefined ? doc2.createNode(child) : merge2(doc2, existing, child));
105413
+ node2.set(key, existing === undefined ? doc2.createNode(child) : merge2(doc2, existing, child, aliases));
105206
105414
  }
105207
105415
  return node2;
105208
105416
  }
@@ -105218,7 +105426,7 @@ function merge2(doc2, node2, value) {
105218
105426
  if (index < 0)
105219
105427
  return doc2.createNode(item);
105220
105428
  const [match] = unused.splice(index, 1);
105221
- return merge2(doc2, match, item);
105429
+ return merge2(doc2, match, item, aliases);
105222
105430
  });
105223
105431
  return node2;
105224
105432
  }
@@ -105229,6 +105437,25 @@ function merge2(doc2, node2, value) {
105229
105437
  }
105230
105438
  return doc2.createNode(value);
105231
105439
  }
105440
+ function expandStaleAliases(doc2, aliases) {
105441
+ if (aliases.size === 0)
105442
+ return;
105443
+ const anchors = new Map;
105444
+ $visit(doc2, {
105445
+ Node(_key, node2) {
105446
+ if (!$isAlias(node2)) {
105447
+ if (node2.anchor)
105448
+ anchors.set(node2.anchor, node2);
105449
+ return;
105450
+ }
105451
+ if (!aliases.has(node2))
105452
+ return;
105453
+ const value = aliases.get(node2);
105454
+ const target = anchors.get(node2.source);
105455
+ return target && deepEqual2(target.toJS(doc2), value) ? undefined : doc2.createNode(value);
105456
+ }
105457
+ });
105458
+ }
105232
105459
  function sameItem(node2, value) {
105233
105460
  if ($isScalar(node2))
105234
105461
  return node2.value === value;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sppg2001/atomize",
3
- "version": "5.1.1",
3
+ "version": "5.1.3",
4
4
  "description": "Automatically generate tasks from user stories with smart templates",
5
5
  "type": "module",
6
6
  "main": "./dist/cli/index.js",