@swmansion/argent 0.32.1-next.8 → 0.33.0

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 (45) hide show
  1. package/README.md +1 -1
  2. package/assets/manifest.json +2 -2
  3. package/bin/argent-android-devtools-0.4.0.apk +0 -0
  4. package/bin/darwin/argent-macos-helper +0 -0
  5. package/bin/darwin/ax-service +0 -0
  6. package/bin/darwin/tvos-ax-service +0 -0
  7. package/bin/darwin/tvos-hid-daemon +0 -0
  8. package/bin/network-inspector/network-inspector.jar +0 -0
  9. package/bin/tcp/ax-service +0 -0
  10. package/dist/cli-cmds.mjs +530 -438
  11. package/dist/client.d.ts +5 -0
  12. package/dist/client.js +60 -9
  13. package/dist/installer.mjs +372 -202
  14. package/dist/mcp-server.mjs +156 -20
  15. package/dist/tool-args.generated.d.ts +87 -51
  16. package/dist/tool-server.cjs +39520 -34927
  17. package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
  18. package/dylibs/libKeyboardPatch.dylib +0 -0
  19. package/dylibs/libNativeDevtoolsIos.dylib +0 -0
  20. package/dylibs/macos/libArgentInjectionBootstrap.dylib +0 -0
  21. package/dylibs/macos/libNativeDevtoolsMacos.dylib +0 -0
  22. package/dylibs/tcp/libArgentInjectionBootstrap.dylib +0 -0
  23. package/dylibs/tcp/libKeyboardPatch.dylib +0 -0
  24. package/dylibs/tcp/libNativeDevtoolsIos.dylib +0 -0
  25. package/dylibs/tvos/libArgentInjectionBootstrap.dylib +0 -0
  26. package/dylibs/tvos/libKeyboardPatch.dylib +0 -0
  27. package/dylibs/tvos/libNativeDevtoolsIos.dylib +0 -0
  28. package/package.json +2 -2
  29. package/rules/argent.md +1 -1
  30. package/skills/argent-create-e2e/references/e2e-yaml.md +4 -4
  31. package/skills/argent-create-e2e/references/reliability-and-recovery.md +3 -3
  32. package/skills/argent-device-interact/SKILL.md +3 -2
  33. package/skills/argent-device-interact/references/chromium.md +1 -1
  34. package/skills/argent-device-interact/references/harmonyos.md +1 -1
  35. package/skills/argent-ios-simulator-setup/SKILL.md +1 -1
  36. package/skills/argent-macos-app-interact/SKILL.md +44 -0
  37. package/skills/argent-macos-app-interact/references/e2e.md +6 -0
  38. package/skills/argent-qa-e2e/SKILL.md +1 -1
  39. package/skills/argent-react-native-app-workflow/SKILL.md +2 -0
  40. package/skills/argent-react-native-optimization/SKILL.md +2 -3
  41. package/skills/argent-react-native-profiler/SKILL.md +8 -8
  42. package/skills/argent-screenshot-diff/SKILL.md +1 -1
  43. package/skills/argent-test-ui-flow/SKILL.md +1 -1
  44. package/skills/argent-tv-interact/SKILL.md +4 -4
  45. package/bin/argent-android-devtools-0.3.0.apk +0 -0
@@ -3652,17 +3652,17 @@ var require_visit = __commonJS({
3652
3652
  visit2.BREAK = BREAK;
3653
3653
  visit2.SKIP = SKIP;
3654
3654
  visit2.REMOVE = REMOVE;
3655
- function visit_(key, node, visitor, path29) {
3656
- const ctrl = callVisitor(key, node, visitor, path29);
3655
+ function visit_(key, node, visitor, path30) {
3656
+ const ctrl = callVisitor(key, node, visitor, path30);
3657
3657
  if (identity2.isNode(ctrl) || identity2.isPair(ctrl)) {
3658
- replaceNode(key, path29, ctrl);
3659
- return visit_(key, ctrl, visitor, path29);
3658
+ replaceNode(key, path30, ctrl);
3659
+ return visit_(key, ctrl, visitor, path30);
3660
3660
  }
3661
3661
  if (typeof ctrl !== "symbol") {
3662
3662
  if (identity2.isCollection(node)) {
3663
- path29 = Object.freeze(path29.concat(node));
3663
+ path30 = Object.freeze(path30.concat(node));
3664
3664
  for (let i2 = 0; i2 < node.items.length; ++i2) {
3665
- const ci = visit_(i2, node.items[i2], visitor, path29);
3665
+ const ci = visit_(i2, node.items[i2], visitor, path30);
3666
3666
  if (typeof ci === "number")
3667
3667
  i2 = ci - 1;
3668
3668
  else if (ci === BREAK)
@@ -3673,13 +3673,13 @@ var require_visit = __commonJS({
3673
3673
  }
3674
3674
  }
3675
3675
  } else if (identity2.isPair(node)) {
3676
- path29 = Object.freeze(path29.concat(node));
3677
- const ck = visit_("key", node.key, visitor, path29);
3676
+ path30 = Object.freeze(path30.concat(node));
3677
+ const ck = visit_("key", node.key, visitor, path30);
3678
3678
  if (ck === BREAK)
3679
3679
  return BREAK;
3680
3680
  else if (ck === REMOVE)
3681
3681
  node.key = null;
3682
- const cv = visit_("value", node.value, visitor, path29);
3682
+ const cv = visit_("value", node.value, visitor, path30);
3683
3683
  if (cv === BREAK)
3684
3684
  return BREAK;
3685
3685
  else if (cv === REMOVE)
@@ -3700,17 +3700,17 @@ var require_visit = __commonJS({
3700
3700
  visitAsync.BREAK = BREAK;
3701
3701
  visitAsync.SKIP = SKIP;
3702
3702
  visitAsync.REMOVE = REMOVE;
3703
- async function visitAsync_(key, node, visitor, path29) {
3704
- const ctrl = await callVisitor(key, node, visitor, path29);
3703
+ async function visitAsync_(key, node, visitor, path30) {
3704
+ const ctrl = await callVisitor(key, node, visitor, path30);
3705
3705
  if (identity2.isNode(ctrl) || identity2.isPair(ctrl)) {
3706
- replaceNode(key, path29, ctrl);
3707
- return visitAsync_(key, ctrl, visitor, path29);
3706
+ replaceNode(key, path30, ctrl);
3707
+ return visitAsync_(key, ctrl, visitor, path30);
3708
3708
  }
3709
3709
  if (typeof ctrl !== "symbol") {
3710
3710
  if (identity2.isCollection(node)) {
3711
- path29 = Object.freeze(path29.concat(node));
3711
+ path30 = Object.freeze(path30.concat(node));
3712
3712
  for (let i2 = 0; i2 < node.items.length; ++i2) {
3713
- const ci = await visitAsync_(i2, node.items[i2], visitor, path29);
3713
+ const ci = await visitAsync_(i2, node.items[i2], visitor, path30);
3714
3714
  if (typeof ci === "number")
3715
3715
  i2 = ci - 1;
3716
3716
  else if (ci === BREAK)
@@ -3721,13 +3721,13 @@ var require_visit = __commonJS({
3721
3721
  }
3722
3722
  }
3723
3723
  } else if (identity2.isPair(node)) {
3724
- path29 = Object.freeze(path29.concat(node));
3725
- const ck = await visitAsync_("key", node.key, visitor, path29);
3724
+ path30 = Object.freeze(path30.concat(node));
3725
+ const ck = await visitAsync_("key", node.key, visitor, path30);
3726
3726
  if (ck === BREAK)
3727
3727
  return BREAK;
3728
3728
  else if (ck === REMOVE)
3729
3729
  node.key = null;
3730
- const cv = await visitAsync_("value", node.value, visitor, path29);
3730
+ const cv = await visitAsync_("value", node.value, visitor, path30);
3731
3731
  if (cv === BREAK)
3732
3732
  return BREAK;
3733
3733
  else if (cv === REMOVE)
@@ -3754,23 +3754,23 @@ var require_visit = __commonJS({
3754
3754
  }
3755
3755
  return visitor;
3756
3756
  }
3757
- function callVisitor(key, node, visitor, path29) {
3757
+ function callVisitor(key, node, visitor, path30) {
3758
3758
  if (typeof visitor === "function")
3759
- return visitor(key, node, path29);
3759
+ return visitor(key, node, path30);
3760
3760
  if (identity2.isMap(node))
3761
- return visitor.Map?.(key, node, path29);
3761
+ return visitor.Map?.(key, node, path30);
3762
3762
  if (identity2.isSeq(node))
3763
- return visitor.Seq?.(key, node, path29);
3763
+ return visitor.Seq?.(key, node, path30);
3764
3764
  if (identity2.isPair(node))
3765
- return visitor.Pair?.(key, node, path29);
3765
+ return visitor.Pair?.(key, node, path30);
3766
3766
  if (identity2.isScalar(node))
3767
- return visitor.Scalar?.(key, node, path29);
3767
+ return visitor.Scalar?.(key, node, path30);
3768
3768
  if (identity2.isAlias(node))
3769
- return visitor.Alias?.(key, node, path29);
3769
+ return visitor.Alias?.(key, node, path30);
3770
3770
  return void 0;
3771
3771
  }
3772
- function replaceNode(key, path29, node) {
3773
- const parent = path29[path29.length - 1];
3772
+ function replaceNode(key, path30, node) {
3773
+ const parent = path30[path30.length - 1];
3774
3774
  if (identity2.isCollection(parent)) {
3775
3775
  parent.items[key] = node;
3776
3776
  } else if (identity2.isPair(parent)) {
@@ -4382,10 +4382,10 @@ var require_Collection = __commonJS({
4382
4382
  var createNode = require_createNode();
4383
4383
  var identity2 = require_identity();
4384
4384
  var Node = require_Node();
4385
- function collectionFromPath(schema, path29, value) {
4385
+ function collectionFromPath(schema, path30, value) {
4386
4386
  let v = value;
4387
- for (let i2 = path29.length - 1; i2 >= 0; --i2) {
4388
- const k = path29[i2];
4387
+ for (let i2 = path30.length - 1; i2 >= 0; --i2) {
4388
+ const k = path30[i2];
4389
4389
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
4390
4390
  const a2 = [];
4391
4391
  a2[k] = v;
@@ -4404,7 +4404,7 @@ var require_Collection = __commonJS({
4404
4404
  sourceObjects: /* @__PURE__ */ new Map()
4405
4405
  });
4406
4406
  }
4407
- var isEmptyPath = (path29) => path29 == null || typeof path29 === "object" && !!path29[Symbol.iterator]().next().done;
4407
+ var isEmptyPath = (path30) => path30 == null || typeof path30 === "object" && !!path30[Symbol.iterator]().next().done;
4408
4408
  var Collection = class extends Node.NodeBase {
4409
4409
  constructor(type, schema) {
4410
4410
  super(type);
@@ -4434,11 +4434,11 @@ var require_Collection = __commonJS({
4434
4434
  * be a Pair instance or a `{ key, value }` object, which may not have a key
4435
4435
  * that already exists in the map.
4436
4436
  */
4437
- addIn(path29, value) {
4438
- if (isEmptyPath(path29))
4437
+ addIn(path30, value) {
4438
+ if (isEmptyPath(path30))
4439
4439
  this.add(value);
4440
4440
  else {
4441
- const [key, ...rest] = path29;
4441
+ const [key, ...rest] = path30;
4442
4442
  const node = this.get(key, true);
4443
4443
  if (identity2.isCollection(node))
4444
4444
  node.addIn(rest, value);
@@ -4452,8 +4452,8 @@ var require_Collection = __commonJS({
4452
4452
  * Removes a value from the collection.
4453
4453
  * @returns `true` if the item was found and removed.
4454
4454
  */
4455
- deleteIn(path29) {
4456
- const [key, ...rest] = path29;
4455
+ deleteIn(path30) {
4456
+ const [key, ...rest] = path30;
4457
4457
  if (rest.length === 0)
4458
4458
  return this.delete(key);
4459
4459
  const node = this.get(key, true);
@@ -4467,8 +4467,8 @@ var require_Collection = __commonJS({
4467
4467
  * scalar values from their surrounding node; to disable set `keepScalar` to
4468
4468
  * `true` (collections are always returned intact).
4469
4469
  */
4470
- getIn(path29, keepScalar) {
4471
- const [key, ...rest] = path29;
4470
+ getIn(path30, keepScalar) {
4471
+ const [key, ...rest] = path30;
4472
4472
  const node = this.get(key, true);
4473
4473
  if (rest.length === 0)
4474
4474
  return !keepScalar && identity2.isScalar(node) ? node.value : node;
@@ -4486,8 +4486,8 @@ var require_Collection = __commonJS({
4486
4486
  /**
4487
4487
  * Checks if the collection includes a value with the key `key`.
4488
4488
  */
4489
- hasIn(path29) {
4490
- const [key, ...rest] = path29;
4489
+ hasIn(path30) {
4490
+ const [key, ...rest] = path30;
4491
4491
  if (rest.length === 0)
4492
4492
  return this.has(key);
4493
4493
  const node = this.get(key, true);
@@ -4497,8 +4497,8 @@ var require_Collection = __commonJS({
4497
4497
  * Sets a value in this collection. For `!!set`, `value` needs to be a
4498
4498
  * boolean to add/remove the item from the set.
4499
4499
  */
4500
- setIn(path29, value) {
4501
- const [key, ...rest] = path29;
4500
+ setIn(path30, value) {
4501
+ const [key, ...rest] = path30;
4502
4502
  if (rest.length === 0) {
4503
4503
  this.set(key, value);
4504
4504
  } else {
@@ -7013,9 +7013,9 @@ var require_Document = __commonJS({
7013
7013
  this.contents.add(value);
7014
7014
  }
7015
7015
  /** Adds a value to the document. */
7016
- addIn(path29, value) {
7016
+ addIn(path30, value) {
7017
7017
  if (assertCollection(this.contents))
7018
- this.contents.addIn(path29, value);
7018
+ this.contents.addIn(path30, value);
7019
7019
  }
7020
7020
  /**
7021
7021
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -7090,14 +7090,14 @@ var require_Document = __commonJS({
7090
7090
  * Removes a value from the document.
7091
7091
  * @returns `true` if the item was found and removed.
7092
7092
  */
7093
- deleteIn(path29) {
7094
- if (Collection.isEmptyPath(path29)) {
7093
+ deleteIn(path30) {
7094
+ if (Collection.isEmptyPath(path30)) {
7095
7095
  if (this.contents == null)
7096
7096
  return false;
7097
7097
  this.contents = null;
7098
7098
  return true;
7099
7099
  }
7100
- return assertCollection(this.contents) ? this.contents.deleteIn(path29) : false;
7100
+ return assertCollection(this.contents) ? this.contents.deleteIn(path30) : false;
7101
7101
  }
7102
7102
  /**
7103
7103
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -7112,10 +7112,10 @@ var require_Document = __commonJS({
7112
7112
  * scalar values from their surrounding node; to disable set `keepScalar` to
7113
7113
  * `true` (collections are always returned intact).
7114
7114
  */
7115
- getIn(path29, keepScalar) {
7116
- if (Collection.isEmptyPath(path29))
7115
+ getIn(path30, keepScalar) {
7116
+ if (Collection.isEmptyPath(path30))
7117
7117
  return !keepScalar && identity2.isScalar(this.contents) ? this.contents.value : this.contents;
7118
- return identity2.isCollection(this.contents) ? this.contents.getIn(path29, keepScalar) : void 0;
7118
+ return identity2.isCollection(this.contents) ? this.contents.getIn(path30, keepScalar) : void 0;
7119
7119
  }
7120
7120
  /**
7121
7121
  * Checks if the document includes a value with the key `key`.
@@ -7126,10 +7126,10 @@ var require_Document = __commonJS({
7126
7126
  /**
7127
7127
  * Checks if the document includes a value at `path`.
7128
7128
  */
7129
- hasIn(path29) {
7130
- if (Collection.isEmptyPath(path29))
7129
+ hasIn(path30) {
7130
+ if (Collection.isEmptyPath(path30))
7131
7131
  return this.contents !== void 0;
7132
- return identity2.isCollection(this.contents) ? this.contents.hasIn(path29) : false;
7132
+ return identity2.isCollection(this.contents) ? this.contents.hasIn(path30) : false;
7133
7133
  }
7134
7134
  /**
7135
7135
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -7146,13 +7146,13 @@ var require_Document = __commonJS({
7146
7146
  * Sets a value in this document. For `!!set`, `value` needs to be a
7147
7147
  * boolean to add/remove the item from the set.
7148
7148
  */
7149
- setIn(path29, value) {
7150
- if (Collection.isEmptyPath(path29)) {
7149
+ setIn(path30, value) {
7150
+ if (Collection.isEmptyPath(path30)) {
7151
7151
  this.contents = value;
7152
7152
  } else if (this.contents == null) {
7153
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path29), value);
7153
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path30), value);
7154
7154
  } else if (assertCollection(this.contents)) {
7155
- this.contents.setIn(path29, value);
7155
+ this.contents.setIn(path30, value);
7156
7156
  }
7157
7157
  }
7158
7158
  /**
@@ -9113,9 +9113,9 @@ var require_cst_visit = __commonJS({
9113
9113
  visit2.BREAK = BREAK;
9114
9114
  visit2.SKIP = SKIP;
9115
9115
  visit2.REMOVE = REMOVE;
9116
- visit2.itemAtPath = (cst, path29) => {
9116
+ visit2.itemAtPath = (cst, path30) => {
9117
9117
  let item = cst;
9118
- for (const [field, index] of path29) {
9118
+ for (const [field, index] of path30) {
9119
9119
  const tok = item?.[field];
9120
9120
  if (tok && "items" in tok) {
9121
9121
  item = tok.items[index];
@@ -9124,23 +9124,23 @@ var require_cst_visit = __commonJS({
9124
9124
  }
9125
9125
  return item;
9126
9126
  };
9127
- visit2.parentCollection = (cst, path29) => {
9128
- const parent = visit2.itemAtPath(cst, path29.slice(0, -1));
9129
- const field = path29[path29.length - 1][0];
9127
+ visit2.parentCollection = (cst, path30) => {
9128
+ const parent = visit2.itemAtPath(cst, path30.slice(0, -1));
9129
+ const field = path30[path30.length - 1][0];
9130
9130
  const coll = parent?.[field];
9131
9131
  if (coll && "items" in coll)
9132
9132
  return coll;
9133
9133
  throw new Error("Parent collection not found");
9134
9134
  };
9135
- function _visit(path29, item, visitor) {
9136
- let ctrl = visitor(item, path29);
9135
+ function _visit(path30, item, visitor) {
9136
+ let ctrl = visitor(item, path30);
9137
9137
  if (typeof ctrl === "symbol")
9138
9138
  return ctrl;
9139
9139
  for (const field of ["key", "value"]) {
9140
9140
  const token = item[field];
9141
9141
  if (token && "items" in token) {
9142
9142
  for (let i2 = 0; i2 < token.items.length; ++i2) {
9143
- const ci = _visit(Object.freeze(path29.concat([[field, i2]])), token.items[i2], visitor);
9143
+ const ci = _visit(Object.freeze(path30.concat([[field, i2]])), token.items[i2], visitor);
9144
9144
  if (typeof ci === "number")
9145
9145
  i2 = ci - 1;
9146
9146
  else if (ci === BREAK)
@@ -9151,10 +9151,10 @@ var require_cst_visit = __commonJS({
9151
9151
  }
9152
9152
  }
9153
9153
  if (typeof ctrl === "function" && field === "key")
9154
- ctrl = ctrl(item, path29);
9154
+ ctrl = ctrl(item, path30);
9155
9155
  }
9156
9156
  }
9157
- return typeof ctrl === "function" ? ctrl(item, path29) : ctrl;
9157
+ return typeof ctrl === "function" ? ctrl(item, path30) : ctrl;
9158
9158
  }
9159
9159
  exports.visit = visit2;
9160
9160
  }
@@ -15012,7 +15012,7 @@ function appendRootPathToUrlIfNeeded(url) {
15012
15012
  return void 0;
15013
15013
  }
15014
15014
  }
15015
- function appendResourcePathToUrl(url, path29) {
15015
+ function appendResourcePathToUrl(url, path30) {
15016
15016
  try {
15017
15017
  new URL(url);
15018
15018
  } catch {
@@ -15022,11 +15022,11 @@ function appendResourcePathToUrl(url, path29) {
15022
15022
  if (!url.endsWith("/")) {
15023
15023
  url = url + "/";
15024
15024
  }
15025
- url += path29;
15025
+ url += path30;
15026
15026
  try {
15027
15027
  new URL(url);
15028
15028
  } catch {
15029
- diag2.warn(`Configuration: Provided URL appended with '${path29}' is not a valid URL, using 'undefined' instead of '${url}'`);
15029
+ diag2.warn(`Configuration: Provided URL appended with '${path30}' is not a valid URL, using 'undefined' instead of '${url}'`);
15030
15030
  return void 0;
15031
15031
  }
15032
15032
  return url;
@@ -15789,6 +15789,8 @@ var FAILURE_CODES = {
15789
15789
  CLI_RUN_ARGS_JSON_INVALID: "CLI_RUN_ARGS_JSON_INVALID",
15790
15790
  CLI_RUN_INPUT_VALIDATION_FAILED: "CLI_RUN_INPUT_VALIDATION_FAILED",
15791
15791
  CLI_RUN_TOOL_CALL_FAILED: "CLI_RUN_TOOL_CALL_FAILED",
15792
+ // The result carried the tool-server's `failure` field.
15793
+ CLI_RUN_TOOL_RESULT_FAILED: "CLI_RUN_TOOL_RESULT_FAILED",
15792
15794
  CLI_RUN_SAVE_IMAGE_FAILED: "CLI_RUN_SAVE_IMAGE_FAILED",
15793
15795
  TOOL_CAPABILITY_UNSUPPORTED_OPERATION: "TOOL_CAPABILITY_UNSUPPORTED_OPERATION",
15794
15796
  TOOL_PLATFORM_NOT_IMPLEMENTED: "TOOL_PLATFORM_NOT_IMPLEMENTED",
@@ -15804,6 +15806,7 @@ var FAILURE_CODES = {
15804
15806
  INSTALL_MODE_FLAG_CONFLICT: "INSTALL_MODE_FLAG_CONFLICT",
15805
15807
  INSTALL_FROM_TAR_PACKAGE_FAILED: "INSTALL_FROM_TAR_PACKAGE_FAILED",
15806
15808
  INSTALL_INIT_TRIGGERED_UPDATE_FAILED: "INSTALL_INIT_TRIGGERED_UPDATE_FAILED",
15809
+ INSTALL_SKILLS_FAILED: "INSTALL_SKILLS_FAILED",
15807
15810
  INSTALL_SKILLS_REFRESH_FAILED: "INSTALL_SKILLS_REFRESH_FAILED",
15808
15811
  INSTALL_UNCLASSIFIED_FAILED: "INSTALL_UNCLASSIFIED_FAILED",
15809
15812
  UPDATE_INSTALLED_VERSION_DETECT_FAILED: "UPDATE_INSTALLED_VERSION_DETECT_FAILED",
@@ -16000,6 +16003,8 @@ var FAILURE_CODES = {
16000
16003
  REACT_PROFILER_START_FAILED: "REACT_PROFILER_START_FAILED",
16001
16004
  REACT_PROFILER_START_VERIFY_FAILED: "REACT_PROFILER_START_VERIFY_FAILED",
16002
16005
  REACT_PROFILER_SESSION_TORN_DOWN: "REACT_PROFILER_SESSION_TORN_DOWN",
16006
+ REACT_PROFILER_SESSION_TAKEN_OVER: "REACT_PROFILER_SESSION_TAKEN_OVER",
16007
+ REACT_PROFILER_STOP_IN_PROGRESS: "REACT_PROFILER_STOP_IN_PROGRESS",
16003
16008
  REACT_PROFILER_HOOK_ERROR: "REACT_PROFILER_HOOK_ERROR",
16004
16009
  REACT_PROFILER_ANALYZE_NO_DATA: "REACT_PROFILER_ANALYZE_NO_DATA",
16005
16010
  NATIVE_PROFILER_FACTORY_OPTIONS_MISSING: "NATIVE_PROFILER_FACTORY_OPTIONS_MISSING",
@@ -16078,6 +16083,32 @@ var FAILURE_CODES = {
16078
16083
  CHROMIUM_ELECTRON_SPAWN_FAILED: "CHROMIUM_ELECTRON_SPAWN_FAILED",
16079
16084
  CHROMIUM_ELECTRON_CDP_TIMEOUT: "CHROMIUM_ELECTRON_CDP_TIMEOUT",
16080
16085
  CHROMIUM_ELECTRON_EXITED_BEFORE_READY: "CHROMIUM_ELECTRON_EXITED_BEFORE_READY",
16086
+ /**
16087
+ * Native Mac apps (the `macos-apps` flag)
16088
+ * @see [macos-app.ts](../../tool-server/src/blueprints/macos-app.ts)
16089
+ */
16090
+ MACOS_APP_UNSUPPORTED_HOST: "MACOS_APP_UNSUPPORTED_HOST",
16091
+ MACOS_APP_PATH_INVALID: "MACOS_APP_PATH_INVALID",
16092
+ MACOS_APP_BUNDLE_INVALID: "MACOS_APP_BUNDLE_INVALID",
16093
+ MACOS_APP_NOT_FOUND: "MACOS_APP_NOT_FOUND",
16094
+ MACOS_APP_HARDENED_RUNTIME: "MACOS_APP_HARDENED_RUNTIME",
16095
+ MACOS_APP_LIBRARY_MISSING: "MACOS_APP_LIBRARY_MISSING",
16096
+ MACOS_APP_LIBRARY_STAGE_FAILED: "MACOS_APP_LIBRARY_STAGE_FAILED",
16097
+ MACOS_APP_ALREADY_RUNNING: "MACOS_APP_ALREADY_RUNNING",
16098
+ MACOS_APP_SPAWN_FAILED: "MACOS_APP_SPAWN_FAILED",
16099
+ MACOS_APP_EXITED_BEFORE_READY: "MACOS_APP_EXITED_BEFORE_READY",
16100
+ MACOS_APP_HANDSHAKE_TIMEOUT: "MACOS_APP_HANDSHAKE_TIMEOUT",
16101
+ MACOS_APP_HANDSHAKE_INVALID: "MACOS_APP_HANDSHAKE_INVALID",
16102
+ MACOS_APP_NOT_RUNNING: "MACOS_APP_NOT_RUNNING",
16103
+ MACOS_APP_NOT_CONNECTED: "MACOS_APP_NOT_CONNECTED",
16104
+ MACOS_APP_CONNECTION_LOST: "MACOS_APP_CONNECTION_LOST",
16105
+ MACOS_APP_CONNECTION_CLOSED: "MACOS_APP_CONNECTION_CLOSED",
16106
+ MACOS_APP_RPC_TIMEOUT: "MACOS_APP_RPC_TIMEOUT",
16107
+ MACOS_APP_RPC_ERROR: "MACOS_APP_RPC_ERROR",
16108
+ MACOS_APP_TERMINATE_FAILED: "MACOS_APP_TERMINATE_FAILED",
16109
+ MACOS_APP_BUNDLE_ID_MISMATCH: "MACOS_APP_BUNDLE_ID_MISMATCH",
16110
+ MACOS_APP_OPEN_URL_FAILED: "MACOS_APP_OPEN_URL_FAILED",
16111
+ MACOS_APP_FILE_ACCESS_FAILED: "MACOS_APP_FILE_ACCESS_FAILED",
16081
16112
  KEYBOARD_KEY_UNSUPPORTED: "KEYBOARD_KEY_UNSUPPORTED",
16082
16113
  KEYBOARD_CHARACTER_UNSUPPORTED: "KEYBOARD_CHARACTER_UNSUPPORTED",
16083
16114
  KEYBOARD_TEXT_AND_KEY_COMBINED: "KEYBOARD_TEXT_AND_KEY_COMBINED",
@@ -16194,7 +16225,8 @@ var PLATFORMS = [
16194
16225
  "vega",
16195
16226
  "harmony",
16196
16227
  "tvos",
16197
- "android-tv"
16228
+ "android-tv",
16229
+ "macos"
16198
16230
  ];
16199
16231
  var DEVICE_KINDS = [
16200
16232
  "simulator",
@@ -16346,6 +16378,9 @@ var ALLOWED = {
16346
16378
  warned_count: COUNT
16347
16379
  },
16348
16380
  "installation:skill_install": {
16381
+ source: oneOf(["pinned", "bundled"]),
16382
+ used_fallback: bool,
16383
+ fallback_reason: oneOf(["ref_missing", "unclassified"]),
16349
16384
  method: oneOf(["default", "interactive", "manual"]),
16350
16385
  is_online: bool,
16351
16386
  has_offline_cache: bool,
@@ -16523,9 +16558,9 @@ function isReplitAgent(env) {
16523
16558
  }
16524
16559
  var DEVIN_MARKER_PATH = "/opt/.devin";
16525
16560
  var JULES_MARKER_PATH = "/opt/environment_summary.sh";
16526
- function safeExists(fileExists, path29) {
16561
+ function safeExists(fileExists, path30) {
16527
16562
  try {
16528
- return fileExists(path29);
16563
+ return fileExists(path30);
16529
16564
  } catch {
16530
16565
  return false;
16531
16566
  }
@@ -16946,7 +16981,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
16946
16981
  var SESSION_ID = randomUUID4();
16947
16982
  function readCliVersion() {
16948
16983
  if (true) {
16949
- return "0.32.1-next.8";
16984
+ return "0.33.0";
16950
16985
  }
16951
16986
  return "0.0.0";
16952
16987
  }
@@ -19343,12 +19378,12 @@ function parseTree(text2, errors = [], options = ParseOptions.DEFAULT) {
19343
19378
  }
19344
19379
  return result;
19345
19380
  }
19346
- function findNodeAtLocation(root, path29) {
19381
+ function findNodeAtLocation(root, path30) {
19347
19382
  if (!root) {
19348
19383
  return void 0;
19349
19384
  }
19350
19385
  let node = root;
19351
- for (let segment of path29) {
19386
+ for (let segment of path30) {
19352
19387
  if (typeof segment === "string") {
19353
19388
  if (node.type !== "object" || !Array.isArray(node.children)) {
19354
19389
  return void 0;
@@ -19702,14 +19737,14 @@ function getNodeType(value) {
19702
19737
 
19703
19738
  // ../../node_modules/jsonc-parser/lib/esm/impl/edit.js
19704
19739
  function setProperty(text2, originalPath, value, options) {
19705
- const path29 = originalPath.slice();
19740
+ const path30 = originalPath.slice();
19706
19741
  const errors = [];
19707
19742
  const root = parseTree(text2, errors);
19708
19743
  let parent = void 0;
19709
19744
  let lastSegment = void 0;
19710
- while (path29.length > 0) {
19711
- lastSegment = path29.pop();
19712
- parent = findNodeAtLocation(root, path29);
19745
+ while (path30.length > 0) {
19746
+ lastSegment = path30.pop();
19747
+ parent = findNodeAtLocation(root, path30);
19713
19748
  if (parent === void 0 && value !== void 0) {
19714
19749
  if (typeof lastSegment === "string") {
19715
19750
  value = { [lastSegment]: value };
@@ -19895,8 +19930,8 @@ var ParseErrorCode;
19895
19930
  ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
19896
19931
  ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
19897
19932
  })(ParseErrorCode || (ParseErrorCode = {}));
19898
- function modify(text2, path29, value, options) {
19899
- return setProperty(text2, path29, value, options);
19933
+ function modify(text2, path30, value, options) {
19934
+ return setProperty(text2, path30, value, options);
19900
19935
  }
19901
19936
  function applyEdits(text2, edits) {
19902
19937
  let sortedEdits = edits.slice(0).sort((a2, b) => {
@@ -22327,6 +22362,12 @@ var INSTALL_INIT_TRIGGERED_UPDATE_FAILED = {
22327
22362
  failure_area: "installer",
22328
22363
  error_kind: "subprocess"
22329
22364
  };
22365
+ var INSTALL_SKILLS_FAILED = {
22366
+ error_code: FAILURE_CODES.INSTALL_SKILLS_FAILED,
22367
+ failure_stage: "installer_skills_install",
22368
+ failure_area: "installer",
22369
+ error_kind: "subprocess"
22370
+ };
22330
22371
  var INSTALL_UNCLASSIFIED_FAILED = {
22331
22372
  error_code: FAILURE_CODES.INSTALL_UNCLASSIFIED_FAILED,
22332
22373
  failure_stage: "installer_init_unclassified",
@@ -22520,6 +22561,30 @@ function refreshArgentSkills(projectRoot) {
22520
22561
  }
22521
22562
  return results;
22522
22563
  }
22564
+ function snapshotArgentSkills(projectRoot, scope, names) {
22565
+ const { skillTargets } = getManagedContentTargets(
22566
+ ALL_ADAPTERS,
22567
+ projectRoot,
22568
+ scope === "global" ? "global" : "local"
22569
+ );
22570
+ const found = /* @__PURE__ */ new Map();
22571
+ for (const { targetPath } of skillTargets) {
22572
+ let candidates = names;
22573
+ if (names.length === 0) {
22574
+ try {
22575
+ candidates = fs19.readdirSync(targetPath).filter((n3) => n3.startsWith(ARGENT_SKILL_PREFIX));
22576
+ } catch {
22577
+ continue;
22578
+ }
22579
+ }
22580
+ for (const name of candidates) {
22581
+ const stat6 = fs19.statSync(path21.join(targetPath, name, "SKILL.md"), { throwIfNoEntry: false });
22582
+ if (!stat6?.isFile()) continue;
22583
+ found.set(name, `${found.get(name) ?? ""}${stat6.ino}:${stat6.mtimeMs};`);
22584
+ }
22585
+ }
22586
+ return found;
22587
+ }
22523
22588
  function pruneLegacySkillDirs(projectRoot, scope, bundled = new Set(listBundledSkills())) {
22524
22589
  if (bundled.size === 0) return [];
22525
22590
  const legacy = LEGACY_ARGENT_SKILL_NAMES.filter((name) => !bundled.has(name));
@@ -23265,6 +23330,67 @@ async function configureAllowlist(args) {
23265
23330
  var import_picocolors10 = __toESM(require_picocolors(), 1);
23266
23331
  import { spawn as spawn3 } from "node:child_process";
23267
23332
  import * as os3 from "node:os";
23333
+ import * as path22 from "node:path";
23334
+ var REF_MISSING = /Remote branch .* not found in upstream|couldn't find remote ref|unknown revision/i;
23335
+ function meaningfulLine(err) {
23336
+ const lines = (err instanceof Error ? err.message : String(err)).split("\n").map((l2) => l2.replace(/^[│┌└■◇\s]+/, "").trim()).filter((l2) => l2 && !/^npm (warn|notice)/i.test(l2));
23337
+ return lines.find((l2) => l2.startsWith("fatal:")) ?? lines.find((l2) => /Error:|Failed to|not found|Could not/i.test(l2)) ?? lines[0] ?? "unknown error";
23338
+ }
23339
+ function bundledCopyFor(version) {
23340
+ const local = probeLocalInstall(resolveProjectRoot2(process.cwd()));
23341
+ if (local.packageDir && local.version === version) return path22.join(local.packageDir, "skills");
23342
+ const globalRoot = getGloballyInstalledPackageRoot();
23343
+ if (globalRoot && getGloballyInstalledVersion() === version) {
23344
+ return path22.join(globalRoot, "skills");
23345
+ }
23346
+ return SKILLS_DIR;
23347
+ }
23348
+ function printManualInstructions(source, bundledCopy, scope, customRoot, npxMissing = false) {
23349
+ const root = scope === "global" ? "~" : scope === "custom" ? customRoot : ".";
23350
+ const add = `skills add ${source}${scope === "global" ? " -g" : ""} --skill '*' -y`;
23351
+ const cd = scope === "custom" ? `cd ${customRoot} && ` : "";
23352
+ note(
23353
+ [
23354
+ `Skills are bundled at:`,
23355
+ ` ${import_picocolors10.default.cyan(bundledCopy)}`,
23356
+ ``,
23357
+ `To install manually, copy them to your editor's skills directory:`,
23358
+ ``,
23359
+ ` ${import_picocolors10.default.dim("# Claude Code")}`,
23360
+ ` mkdir -p ${root}/.claude/skills && cp -r ${bundledCopy}/* ${root}/.claude/skills/`,
23361
+ ``,
23362
+ ` ${import_picocolors10.default.dim("# Cursor")}`,
23363
+ ` mkdir -p ${root}/.cursor/skills && cp -r ${bundledCopy}/* ${root}/.cursor/skills/`,
23364
+ ``,
23365
+ ...npxMissing ? [` ${import_picocolors10.default.dim("# Or, with pnpm:")}`, ` ${cd}pnpm dlx ${add}`] : [` ${import_picocolors10.default.dim("# Or use npx skills directly:")}`, ` ${cd}npx ${add}`]
23366
+ ].join("\n"),
23367
+ "Manual Skills Installation"
23368
+ );
23369
+ }
23370
+ function skillsAreMissing(skills) {
23371
+ return skills.outcome === "failure" && skills.installedCount === 0;
23372
+ }
23373
+ function formatSkillsSummaryLine(skills) {
23374
+ const count = skills.installedCount;
23375
+ const label = import_picocolors10.default.yellow("Skills");
23376
+ if (skills.outcome === "failure" || skills.forcedManual) {
23377
+ const why = skills.forcedManual ? "offline, see the instructions above" : "see the error above";
23378
+ return count > 0 ? `${label} not updated (${why}), ${count} from an earlier install on disk` : `${label} NOT installed (${why})`;
23379
+ }
23380
+ if (skills.method === "manual") {
23381
+ const existing = count > 0 ? `, ${count} from an earlier install on disk` : "";
23382
+ return `${import_picocolors10.default.green("Skills")} instructions printed${existing}`;
23383
+ }
23384
+ if (skills.outcome === "skipped") {
23385
+ const existing = count > 0 ? `, ${count} from an earlier install on disk` : "";
23386
+ return `${label} none installed (none selected)${existing}`;
23387
+ }
23388
+ const written = skills.installedThisRun;
23389
+ if (skills.usedFallback) {
23390
+ return `${label} ${written} installed from the bundled copy (the pinned source failed)`;
23391
+ }
23392
+ return `${import_picocolors10.default.green("Skills")} ${written} installed`;
23393
+ }
23268
23394
  async function runSkillsStep(args) {
23269
23395
  const { nonInteractive, fromTar, version, scope, customRoot } = args;
23270
23396
  log.step(import_picocolors10.default.bold("Step 2: Skills Installation"));
@@ -23309,93 +23435,120 @@ async function runSkillsStep(args) {
23309
23435
  }
23310
23436
  const useGitHubSource = online && !fromTar && version !== "unknown";
23311
23437
  const skillsSource = useGitHubSource ? buildArgentSkillsSource(version) : SKILLS_DIR;
23438
+ const bundledCopy = useGitHubSource ? bundledCopyFor(version) : SKILLS_DIR;
23439
+ const skillsCwd = scope === "custom" ? customRoot : void 0;
23440
+ const skillsRoot = scope === "global" ? os3.homedir() : skillsCwd ?? process.cwd();
23441
+ const skillsScope = scope === "global" ? "global" : "project";
23442
+ const expected = listBundledSkills(bundledCopy);
23443
+ const snapshot = () => snapshotArgentSkills(skillsRoot, skillsScope, expected);
23444
+ const writtenSince = (before) => [...snapshot()].filter(([name, stamp]) => before.get(name) !== stamp).length;
23445
+ const initial = snapshot();
23312
23446
  let skillOutcome;
23447
+ let installedFrom = skillsSource;
23448
+ let fallbackReason = null;
23313
23449
  if (skillsMethod === "manual") {
23314
- note(
23315
- [
23316
- `Skills are bundled at:`,
23317
- ` ${import_picocolors10.default.cyan(SKILLS_DIR)}`,
23318
- ``,
23319
- `To install manually, copy them to your editor's skills directory:`,
23320
- ``,
23321
- ` ${import_picocolors10.default.dim("# Claude Code")}`,
23322
- ` cp -r ${SKILLS_DIR}/* ${scope === "global" ? "~/.claude/skills/" : `${scope === "custom" ? customRoot : "."}/.claude/skills/`}`,
23323
- ``,
23324
- ` ${import_picocolors10.default.dim("# Cursor")}`,
23325
- ` cp -r ${SKILLS_DIR}/* ${scope === "global" ? "~/.cursor/skills/" : `${scope === "custom" ? customRoot : "."}/.cursor/skills/`}`,
23326
- ``,
23327
- ` ${import_picocolors10.default.dim("# Or use npx skills directly:")}`,
23328
- ` npx skills add ${skillsSource}`
23329
- ].join("\n"),
23330
- "Manual Skills Installation"
23331
- );
23450
+ printManualInstructions(skillsSource, bundledCopy, scope, customRoot);
23332
23451
  skillOutcome = "skipped";
23333
23452
  } else {
23334
- const skillsArgs = ["skills", "add", skillsSource];
23335
- if (scope === "global") {
23336
- skillsArgs.push("-g");
23337
- }
23338
- if (skillsMethod === "default") {
23339
- skillsArgs.push("--skill", "*", "-y");
23340
- }
23341
- const baseArgs = offlineWithCache ? ["--no-install", ...skillsArgs] : skillsArgs;
23342
- const npxArgs = withNpmForce(baseArgs);
23343
- log.info(`Running: ${import_picocolors10.default.dim("npx")} ${import_picocolors10.default.cyan(baseArgs.join(" "))}`);
23453
+ const interactive = skillsMethod === "interactive";
23454
+ const buildSkillsArgs = (source2) => {
23455
+ const skillsArgs = ["skills", "add", source2];
23456
+ if (scope === "global") skillsArgs.push("-g");
23457
+ if (!interactive) skillsArgs.push("--skill", "*", "-y");
23458
+ return offlineWithCache ? ["--no-install", ...skillsArgs] : skillsArgs;
23459
+ };
23460
+ log.info(`Running: ${import_picocolors10.default.dim("npx")} ${import_picocolors10.default.cyan(buildSkillsArgs(skillsSource).join(" "))}`);
23344
23461
  const spinner2 = spinner();
23345
- if (skillsMethod === "default") {
23346
- spinner2.start("Installing skills...");
23347
- }
23462
+ if (!interactive) spinner2.start("Installing skills...");
23463
+ const attempt = async (source2, npmFlags = []) => {
23464
+ const before = snapshot();
23465
+ const npxArgs = withNpmForce([...npmFlags, ...buildSkillsArgs(source2)]);
23466
+ await runNpxSkills(npxArgs, interactive, skillsCwd);
23467
+ if (writtenSince(before) > 0) return "success";
23468
+ if (interactive) return "skipped";
23469
+ throw new Error("The skills CLI exited cleanly, but it installed no skills.");
23470
+ };
23471
+ const fail = (err, attempted, npxMissing = false) => {
23472
+ if (!interactive) spinner2.stop(import_picocolors10.default.red("Skills installation failed."));
23473
+ log.error(`Failed to install skills from ${attempted}: ${meaningfulLine(err)}`);
23474
+ printManualInstructions(bundledCopy, bundledCopy, scope, customRoot, npxMissing);
23475
+ return "failure";
23476
+ };
23348
23477
  try {
23349
- const skillsCwd = scope === "custom" ? customRoot : void 0;
23350
- await runNpxSkills(npxArgs, skillsMethod === "interactive", skillsCwd);
23351
- if (skillsMethod === "default") {
23352
- spinner2.stop("Skills installed.");
23353
- }
23354
- skillOutcome = "success";
23355
- const sourceIsBundled = skillsSource === SKILLS_DIR || version === getInstalledVersion();
23356
- if (skillsMethod === "default" && sourceIsBundled) {
23357
- const pruneRoot = scope === "global" ? os3.homedir() : skillsCwd ?? process.cwd();
23358
- const pruneScope = scope === "global" ? "global" : "project";
23359
- const tracked = listTrackedLegacySkills(pruneRoot, pruneScope);
23360
- const removed = /* @__PURE__ */ new Set();
23361
- if (tracked.length > 0) {
23362
- const removeArgs = ["skills", "remove", "-y", ...scope === "global" ? ["-g"] : []];
23478
+ skillOutcome = await attempt(skillsSource);
23479
+ if (!interactive) spinner2.stop("Skills installed.");
23480
+ } catch (err) {
23481
+ const npxMissing = err.code === "ENOENT";
23482
+ const interrupted = err instanceof ShellCommandError && err.signal !== null;
23483
+ const canRetry = skillsSource !== bundledCopy && !npxMissing && !interrupted && listBundledSkills(bundledCopy).length > 0;
23484
+ if (!canRetry) {
23485
+ skillOutcome = fail(err, skillsSource, npxMissing);
23486
+ } else {
23487
+ if (!interactive) spinner2.stop(import_picocolors10.default.yellow("Pinned skills source failed."));
23488
+ log.warn(`Could not install skills from ${skillsSource}: ${meaningfulLine(err)}`);
23489
+ fallbackReason = REF_MISSING.test(String(err)) ? "ref_missing" : "unclassified";
23490
+ const retry = interactive ? await confirm({ message: "Install from the copy bundled with this package instead?" }) : true;
23491
+ if (retry !== true) {
23492
+ skillOutcome = fail(err, skillsSource);
23493
+ } else {
23494
+ if (!interactive) spinner2.start("Installing the copy bundled with this package...");
23363
23495
  try {
23364
- await runNpxSkills(
23365
- withNpmForce([
23366
- ...offlineWithCache ? ["--no-install"] : [],
23367
- ...removeArgs,
23368
- ...tracked
23369
- ]),
23370
- false,
23371
- skillsCwd
23372
- );
23373
- for (const name of tracked) removed.add(name);
23374
- } catch {
23496
+ skillOutcome = await attempt(bundledCopy, ["--fetch-retries=0"]);
23497
+ if (!interactive) spinner2.stop("Skills installed from the bundled copy.");
23498
+ installedFrom = bundledCopy;
23499
+ } catch (fallbackErr) {
23500
+ skillOutcome = fail(fallbackErr, bundledCopy);
23375
23501
  }
23376
23502
  }
23377
- for (const name of pruneLegacySkillDirs(pruneRoot, pruneScope)) removed.add(name);
23378
- if (removed.size > 0) {
23379
- log.info(import_picocolors10.default.dim(`Removed legacy skills: ${[...removed].sort().join(", ")}`));
23503
+ }
23504
+ }
23505
+ if (!interactive && skillOutcome === "success" && (installedFrom === SKILLS_DIR || version === getInstalledVersion())) {
23506
+ const tracked = listTrackedLegacySkills(skillsRoot, skillsScope);
23507
+ const removed = /* @__PURE__ */ new Set();
23508
+ if (tracked.length > 0) {
23509
+ const removeArgs = ["skills", "remove", "-y", ...scope === "global" ? ["-g"] : []];
23510
+ try {
23511
+ await runNpxSkills(
23512
+ withNpmForce([
23513
+ ...offlineWithCache ? ["--no-install"] : [],
23514
+ ...removeArgs,
23515
+ ...tracked
23516
+ ]),
23517
+ false,
23518
+ skillsCwd
23519
+ );
23520
+ for (const name of tracked) removed.add(name);
23521
+ } catch {
23380
23522
  }
23381
23523
  }
23382
- } catch (err) {
23383
- if (skillsMethod === "default") {
23384
- spinner2.stop(import_picocolors10.default.red("Skills installation failed."));
23524
+ for (const name of pruneLegacySkillDirs(skillsRoot, skillsScope)) removed.add(name);
23525
+ if (removed.size > 0) {
23526
+ log.info(import_picocolors10.default.dim(`Removed legacy skills: ${[...removed].sort().join(", ")}`));
23385
23527
  }
23386
- log.error(`Failed to run npx skills: ${err}`);
23387
- log.info(`You can install skills manually:
23388
- npx ${skillsArgs.join(" ")}`);
23389
- skillOutcome = "failure";
23390
23528
  }
23391
23529
  }
23530
+ const usedFallback = fallbackReason !== null && skillOutcome === "success";
23531
+ const source = skillOutcome !== "success" ? null : useGitHubSource && installedFrom === skillsSource ? "pinned" : "bundled";
23392
23532
  track("installation:skill_install", {
23393
23533
  method: skillsMethod,
23394
23534
  is_online: online,
23395
23535
  has_offline_cache: offlineWithCache,
23396
- outcome: skillOutcome
23536
+ outcome: skillOutcome,
23537
+ // A release whose tag was never pushed makes every install fall back. That
23538
+ // is invisible once the fallback rescues it, so it has to be measurable.
23539
+ ...source ? { source } : {},
23540
+ used_fallback: usedFallback,
23541
+ ...fallbackReason ? { fallback_reason: fallbackReason } : {}
23397
23542
  });
23398
- return skillsMethod;
23543
+ return {
23544
+ method: skillsMethod,
23545
+ outcome: skillOutcome,
23546
+ source,
23547
+ usedFallback,
23548
+ installedCount: snapshot().size,
23549
+ installedThisRun: writtenSince(initial),
23550
+ forcedManual: !skillsCliReady
23551
+ };
23399
23552
  }
23400
23553
  function runNpxSkills(args, interactive, cwd) {
23401
23554
  return new Promise((resolve17, reject) => {
@@ -23416,12 +23569,14 @@ function runNpxSkills(args, interactive, cwd) {
23416
23569
  stderr += chunk.toString();
23417
23570
  });
23418
23571
  }
23419
- child.on("close", (code) => {
23572
+ child.on("close", (code, signal) => {
23420
23573
  if (code === 0) {
23421
23574
  resolve17();
23422
23575
  } else {
23423
23576
  const output = [stderr, stdout2].filter(Boolean).join("\n").trim();
23424
- reject(new Error(output || `npx skills exited with code ${code}`));
23577
+ reject(
23578
+ new ShellCommandError(output || `npx skills exited with code ${code}`, code, signal)
23579
+ );
23425
23580
  }
23426
23581
  });
23427
23582
  child.on("error", reject);
@@ -23586,7 +23741,7 @@ async function init2(args) {
23586
23741
  if (allowlist.enabled && allowlist.lines.length > 0) {
23587
23742
  note(allowlist.lines.join("\n"), "Tool Auto-Approval");
23588
23743
  }
23589
- const skillsMethod = await runSkillsStep({
23744
+ const skills = await runSkillsStep({
23590
23745
  nonInteractive: parsed.nonInteractive,
23591
23746
  fromTar: parsed.fromTar,
23592
23747
  version,
@@ -23620,25 +23775,40 @@ async function init2(args) {
23620
23775
  selectedAdapters: writtenAdapters,
23621
23776
  scope,
23622
23777
  allowlistEnabled: allowlist.enabled,
23623
- skillsMethod,
23778
+ skills,
23624
23779
  copiedRules: copyResults.length > 0,
23625
23780
  wroteProjectTelemetryOptOut
23626
23781
  });
23627
- note(
23628
- [
23629
- import_picocolors11.default.bold(import_picocolors11.default.green("Argent is ready!")),
23630
- "",
23631
- `${import_picocolors11.default.bold("Get started")} by asking your assistant:`,
23632
- "",
23633
- ` ${import_picocolors11.default.bold(import_picocolors11.default.cyan(`"What can Argent do?"`))}`,
23634
- "",
23635
- import_picocolors11.default.dim("It will walk you through all capabilities available.")
23636
- ].join("\n"),
23637
- import_picocolors11.default.bgGreen(import_picocolors11.default.black(" Get Started "))
23638
- );
23639
- outro("Done.");
23640
- tel.initSucceeded = true;
23782
+ const skillsMissing = skillsAreMissing(skills);
23783
+ if (skills.outcome === "success" || skills.method === "manual" && !skills.forcedManual) {
23784
+ note(
23785
+ [
23786
+ import_picocolors11.default.bold(import_picocolors11.default.green("Argent is ready!")),
23787
+ "",
23788
+ `${import_picocolors11.default.bold("Get started")} by asking your assistant:`,
23789
+ "",
23790
+ ` ${import_picocolors11.default.bold(import_picocolors11.default.cyan(`"What can Argent do?"`))}`,
23791
+ "",
23792
+ import_picocolors11.default.dim("It will walk you through all capabilities available.")
23793
+ ].join("\n"),
23794
+ import_picocolors11.default.bgGreen(import_picocolors11.default.black(" Get Started "))
23795
+ );
23796
+ } else if (skills.installedCount > 0) {
23797
+ log.warn(
23798
+ `${import_picocolors11.default.bold("Skills were not updated:")} ${skills.installedCount} skills from an earlier install stay in use. Run ${import_picocolors11.default.cyan("argent init")} again to update them.`
23799
+ );
23800
+ } else {
23801
+ log.warn(
23802
+ `${import_picocolors11.default.bold("Argent is not ready:")} the MCP server and rules are in place, but no skills are installed. Run ${import_picocolors11.default.cyan("argent init")} again to install them.`
23803
+ );
23804
+ }
23805
+ outro(skillsMissing ? "Done, without skills." : "Done.");
23806
+ tel.initSucceeded = !skillsMissing;
23641
23807
  if ("commit" in consent) consent.commit();
23808
+ if (skillsMissing) {
23809
+ await tel.finalize(INSTALL_SKILLS_FAILED);
23810
+ process.exit(1);
23811
+ }
23642
23812
  await tel.finalize();
23643
23813
  } catch (err) {
23644
23814
  if (err instanceof InitCancelled) {
@@ -23659,7 +23829,7 @@ function printSummary({
23659
23829
  selectedAdapters,
23660
23830
  scope,
23661
23831
  allowlistEnabled,
23662
- skillsMethod,
23832
+ skills,
23663
23833
  copiedRules,
23664
23834
  wroteProjectTelemetryOptOut
23665
23835
  }) {
@@ -23667,7 +23837,7 @@ function printSummary({
23667
23837
  `${import_picocolors11.default.green("Install mode")} ${installMode === "local" ? "local (devDependency)" : "global"}`,
23668
23838
  selectedAdapters.length > 0 ? `${import_picocolors11.default.green("MCP server")} configured for ${selectedAdapters.map((a2) => a2.name).join(", ")} (${scope})` : `${import_picocolors11.default.yellow("MCP server")} NOT configured \u2014 no editor config was written`,
23669
23839
  `${import_picocolors11.default.green("Auto-approve")} ${allowlistEnabled ? "enabled" : "skipped"}`,
23670
- `${import_picocolors11.default.green("Skills")} ${skillsMethod === "manual" ? "instructions printed" : "installed"}`,
23840
+ formatSkillsSummaryLine(skills),
23671
23841
  `${import_picocolors11.default.green("Rules")} ${copiedRules ? "copied" : "n/a"}`
23672
23842
  ];
23673
23843
  note(summaryLines.join("\n"), "Summary");
@@ -23712,7 +23882,7 @@ function printBanner() {
23712
23882
  // ../argent-installer/src/update.ts
23713
23883
  var import_picocolors12 = __toESM(require_picocolors(), 1);
23714
23884
  var import_semver5 = __toESM(require_semver2(), 1);
23715
- import * as path27 from "node:path";
23885
+ import * as path28 from "node:path";
23716
23886
 
23717
23887
  // ../argent-installer/src/install-targets.ts
23718
23888
  function parseTargetFlags(args) {
@@ -23778,16 +23948,16 @@ async function resolveInstallableUpdateTarget(pm, current) {
23778
23948
  // ../argent-tools-client/src/launcher.ts
23779
23949
  import * as net from "node:net";
23780
23950
  import * as fs20 from "node:fs";
23781
- import * as path22 from "node:path";
23951
+ import * as path23 from "node:path";
23782
23952
  import * as readline from "node:readline";
23783
23953
  import { homedir as homedir6 } from "node:os";
23784
23954
  import { spawn as spawn4, execFileSync as execFileSync7 } from "node:child_process";
23785
23955
  import { createHash as createHash3, randomBytes } from "node:crypto";
23786
23956
  import { mkdir, writeFile, readFile, readdir as readdir2, unlink, rename, chmod } from "node:fs/promises";
23787
- var STATE_DIR = path22.join(homedir6(), ".argent");
23788
- var STATE_FILE = path22.join(STATE_DIR, "tool-server.json");
23789
- var LOG_FILE = path22.join(STATE_DIR, "tool-server.log");
23790
- var LOCK_FILE = path22.join(STATE_DIR, "tool-server.lock");
23957
+ var STATE_DIR = path23.join(homedir6(), ".argent");
23958
+ var STATE_FILE = path23.join(STATE_DIR, "tool-server.json");
23959
+ var LOG_FILE = path23.join(STATE_DIR, "tool-server.log");
23960
+ var LOCK_FILE = path23.join(STATE_DIR, "tool-server.lock");
23791
23961
  function isProcessAlive(pid) {
23792
23962
  try {
23793
23963
  process.kill(pid, 0);
@@ -23798,7 +23968,7 @@ function isProcessAlive(pid) {
23798
23968
  }
23799
23969
  function stateFileForBundle(bundlePath) {
23800
23970
  const key = createHash3("sha256").update(bundlePath).digest("hex").slice(0, 12);
23801
- return path22.join(STATE_DIR, `tool-server-${key}.json`);
23971
+ return path23.join(STATE_DIR, `tool-server-${key}.json`);
23802
23972
  }
23803
23973
  async function readStateFile(file) {
23804
23974
  try {
@@ -23840,7 +24010,7 @@ async function readAllToolsServerStates() {
23840
24010
  const out = [];
23841
24011
  for (const name of names) {
23842
24012
  if (!STATE_FILE_RE.test(name)) continue;
23843
- const file = path22.join(STATE_DIR, name);
24013
+ const file = path23.join(STATE_DIR, name);
23844
24014
  const state2 = await readStateFile(file);
23845
24015
  if (state2) out.push({ file, state: state2 });
23846
24016
  }
@@ -23886,8 +24056,8 @@ async function killToolServer(bundlePath) {
23886
24056
  return alive;
23887
24057
  }
23888
24058
  function isPathWithin(child, parent) {
23889
- const rel = path22.relative(parent, child);
23890
- return rel !== "" && !rel.startsWith("..") && !path22.isAbsolute(rel);
24059
+ const rel = path23.relative(parent, child);
24060
+ return rel !== "" && !rel.startsWith("..") && !path23.isAbsolute(rel);
23891
24061
  }
23892
24062
  function tryRealpath(p) {
23893
24063
  try {
@@ -23897,10 +24067,10 @@ function tryRealpath(p) {
23897
24067
  }
23898
24068
  }
23899
24069
  async function killToolServerForInstallDir(packageDir) {
23900
- const parents = /* @__PURE__ */ new Set([path22.resolve(packageDir), tryRealpath(packageDir)]);
24070
+ const parents = /* @__PURE__ */ new Set([path23.resolve(packageDir), tryRealpath(packageDir)]);
23901
24071
  let killed = 0;
23902
24072
  for (const { file, state: state2 } of await readAllToolsServerStates()) {
23903
- const bundles = /* @__PURE__ */ new Set([path22.resolve(state2.bundlePath), tryRealpath(state2.bundlePath)]);
24073
+ const bundles = /* @__PURE__ */ new Set([path23.resolve(state2.bundlePath), tryRealpath(state2.bundlePath)]);
23904
24074
  const matches2 = [...bundles].some((b) => [...parents].some((p) => isPathWithin(b, p)));
23905
24075
  if (!matches2) continue;
23906
24076
  const fresh = await readStateFile(file);
@@ -23965,14 +24135,14 @@ function couldBeOurToolServer(pid, marker) {
23965
24135
  var import_yaml4 = __toESM(require_dist2(), 1);
23966
24136
  import { readFile as readFile5 } from "node:fs/promises";
23967
24137
  import { maxHeaderSize } from "node:http";
23968
- import * as path26 from "node:path";
24138
+ import * as path27 from "node:path";
23969
24139
 
23970
24140
  // ../argent-tools-client/src/link-config.ts
23971
- import * as path23 from "node:path";
24141
+ import * as path24 from "node:path";
23972
24142
  import { homedir as homedir7 } from "node:os";
23973
24143
  import { mkdir as mkdir2, writeFile as writeFile2, readFile as readFile2, unlink as unlink2, chmod as chmod2 } from "node:fs/promises";
23974
- var LINK_DIR = path23.join(homedir7(), ".argent");
23975
- var LINK_FILE = path23.join(LINK_DIR, "link.json");
24144
+ var LINK_DIR = path24.join(homedir7(), ".argent");
24145
+ var LINK_FILE = path24.join(LINK_DIR, "link.json");
23976
24146
 
23977
24147
  // ../argent-tools-client/src/file-inputs.ts
23978
24148
  import { createHash as createHash4, randomUUID as randomUUID6 } from "node:crypto";
@@ -23989,12 +24159,12 @@ import {
23989
24159
  writeFile as writeFile3
23990
24160
  } from "node:fs/promises";
23991
24161
  import { constants, tmpdir } from "node:os";
23992
- import * as path24 from "node:path";
24162
+ import * as path25 from "node:path";
23993
24163
 
23994
24164
  // ../archive/src/index.ts
23995
24165
  import { execFile } from "node:child_process";
23996
24166
  import { rm, readdir as readdir3 } from "node:fs/promises";
23997
- import { basename as basename4, dirname as dirname13, join as join23, posix as posix2, resolve as resolve13, sep as sep4 } from "node:path";
24167
+ import { basename as basename4, dirname as dirname13, join as join24, posix as posix2, resolve as resolve13, sep as sep4 } from "node:path";
23998
24168
  import { promisify } from "node:util";
23999
24169
  var execFileAsync = promisify(execFile);
24000
24170
 
@@ -24004,14 +24174,14 @@ var MAX_CONTENT_BYTES = 32 * 1024 * 1024;
24004
24174
  // ../argent-tools-client/src/flow-files.ts
24005
24175
  var import_yaml3 = __toESM(require_dist2(), 1);
24006
24176
  import { readdir as readdir4, readFile as readFile4, realpath as realpath3, stat as stat4 } from "node:fs/promises";
24007
- import * as path25 from "node:path";
24177
+ import * as path26 from "node:path";
24008
24178
  var INLINE_MEMBERS_BYTES = 256 * 1024;
24009
24179
 
24010
24180
  // ../argent-tools-client/src/artifacts.ts
24011
24181
  import { copyFile, mkdir as mkdir4, readFile as readFile6, realpath as realpath4, rm as rm3, stat as stat5, writeFile as writeFile4 } from "node:fs/promises";
24012
24182
  import { constants as fsConstants } from "node:fs";
24013
24183
  import { tmpdir as tmpdir2 } from "node:os";
24014
- import { basename as basename7, dirname as dirname17, extname as extname2, isAbsolute as isAbsolute8, join as join27, normalize as normalize2, resolve as resolve15, sep as sep6 } from "node:path";
24184
+ import { basename as basename7, dirname as dirname17, extname as extname2, isAbsolute as isAbsolute8, join as join28, normalize as normalize2, resolve as resolve15, sep as sep6 } from "node:path";
24015
24185
  import { createHash as createHash5 } from "node:crypto";
24016
24186
  var ALLOWED_SAVE_DIRS = /* @__PURE__ */ new Set([normalize2(".argent/recordings")]);
24017
24187
  var RECORDINGS_SAVE_DIR = normalize2(".argent/recordings");
@@ -24370,7 +24540,7 @@ async function update(args) {
24370
24540
  process.exit(1);
24371
24541
  }
24372
24542
  const rootOverride = getProjectRootOverride(args);
24373
- const projectRoot = rootOverride ? path27.resolve(rootOverride) : resolveProjectRoot2(process.cwd());
24543
+ const projectRoot = rootOverride ? path28.resolve(rootOverride) : resolveProjectRoot2(process.cwd());
24374
24544
  installMode = resolveInstallMode(projectRoot);
24375
24545
  const flags = parseTargetFlags(args);
24376
24546
  const localInstalled = installMode === "local" && probeLocalInstall(projectRoot).installed;
@@ -24566,7 +24736,7 @@ async function update(args) {
24566
24736
  var import_picocolors13 = __toESM(require_picocolors(), 1);
24567
24737
  var import_yaml5 = __toESM(require_dist2(), 1);
24568
24738
  import * as fs21 from "node:fs";
24569
- import * as path28 from "node:path";
24739
+ import * as path29 from "node:path";
24570
24740
  var UNINSTALL_TOOLSERVER_STOP_FAILED = {
24571
24741
  error_code: FAILURE_CODES.UNINSTALL_TOOLSERVER_STOP_FAILED,
24572
24742
  failure_stage: "installer_uninstall_toolserver_stop",
@@ -24601,8 +24771,8 @@ function collectBundledPaths(sourceDir) {
24601
24771
  const directories = [];
24602
24772
  function walk(currentDir, relativeDir = "") {
24603
24773
  for (const entry of fs21.readdirSync(currentDir, { withFileTypes: true })) {
24604
- const relativePath = relativeDir ? path28.join(relativeDir, entry.name) : entry.name;
24605
- const absolutePath = path28.join(currentDir, entry.name);
24774
+ const relativePath = relativeDir ? path29.join(relativeDir, entry.name) : entry.name;
24775
+ const absolutePath = path29.join(currentDir, entry.name);
24606
24776
  if (entry.isDirectory()) {
24607
24777
  walk(absolutePath, relativePath);
24608
24778
  directories.push(relativePath);
@@ -24621,7 +24791,7 @@ function removeBundledContent(sourceDir, targetDir) {
24621
24791
  const { files, directories } = collectBundledPaths(sourceDir);
24622
24792
  const removedPaths = [];
24623
24793
  for (const relativePath of files) {
24624
- const targetPath = path28.join(targetDir, relativePath);
24794
+ const targetPath = path29.join(targetDir, relativePath);
24625
24795
  try {
24626
24796
  if (!fs21.existsSync(targetPath)) continue;
24627
24797
  if (fs21.lstatSync(targetPath).isDirectory()) continue;
@@ -24631,10 +24801,10 @@ function removeBundledContent(sourceDir, targetDir) {
24631
24801
  }
24632
24802
  }
24633
24803
  directories.sort(
24634
- (a2, b) => b.split(path28.sep).length - a2.split(path28.sep).length || b.length - a2.length
24804
+ (a2, b) => b.split(path29.sep).length - a2.split(path29.sep).length || b.length - a2.length
24635
24805
  );
24636
24806
  for (const relativePath of directories) {
24637
- const targetPath = path28.join(targetDir, relativePath);
24807
+ const targetPath = path29.join(targetDir, relativePath);
24638
24808
  try {
24639
24809
  if (!fs21.existsSync(targetPath)) continue;
24640
24810
  if (!fs21.statSync(targetPath).isDirectory()) continue;
@@ -24654,7 +24824,7 @@ function removeBundledContent(sourceDir, targetDir) {
24654
24824
  } catch {
24655
24825
  }
24656
24826
  if (removedRoot) {
24657
- removeDirIfEmpty2(path28.dirname(targetDir));
24827
+ removeDirIfEmpty2(path29.dirname(targetDir));
24658
24828
  }
24659
24829
  return { removedPaths, removedRoot };
24660
24830
  }
@@ -24675,7 +24845,7 @@ function getBundledSkillNames(skillsDir) {
24675
24845
  const skillNames = [];
24676
24846
  for (const entry of fs21.readdirSync(skillsDir, { withFileTypes: true })) {
24677
24847
  if (!entry.isDirectory()) continue;
24678
- const skillFilePath = path28.join(skillsDir, entry.name, "SKILL.md");
24848
+ const skillFilePath = path29.join(skillsDir, entry.name, "SKILL.md");
24679
24849
  if (!fs21.existsSync(skillFilePath)) continue;
24680
24850
  skillNames.push(readBundledSkillName(skillFilePath, entry.name));
24681
24851
  }
@@ -24687,7 +24857,7 @@ function removeBundledSkillInstalls(skillNames, targetDir) {
24687
24857
  }
24688
24858
  const removedPaths = [];
24689
24859
  for (const skillName of skillNames) {
24690
- const targetPath = path28.join(targetDir, skillName);
24860
+ const targetPath = path29.join(targetDir, skillName);
24691
24861
  try {
24692
24862
  const stats = fs21.lstatSync(targetPath, { throwIfNoEntry: false });
24693
24863
  if (!stats) continue;
@@ -24702,7 +24872,7 @@ function removeBundledSkillInstalls(skillNames, targetDir) {
24702
24872
  }
24703
24873
  const removedRoot = removeDirIfEmpty2(targetDir);
24704
24874
  if (removedRoot) {
24705
- removeDirIfEmpty2(path28.dirname(targetDir));
24875
+ removeDirIfEmpty2(path29.dirname(targetDir));
24706
24876
  }
24707
24877
  return { removedPaths, removedRoot };
24708
24878
  }
@@ -24945,7 +25115,7 @@ async function uninstall(args) {
24945
25115
  ),
24946
25116
  { ask: false }
24947
25117
  );
24948
- for (const root of retired.removedRoots) removeDirIfEmpty2(path28.dirname(root));
25118
+ for (const root of retired.removedRoots) removeDirIfEmpty2(path29.dirname(root));
24949
25119
  const retiredLines = formatRetiredCleanup(retired);
24950
25120
  pruneResults.push(...retiredLines.removed.map((line) => `${import_picocolors13.default.green("+")} ${line}`));
24951
25121
  const retiredKept = retiredLines.kept.map((line) => ` ${line}`);