cc-codeconductor 0.2.10 → 0.3.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 (61) hide show
  1. package/dist/index.js +499 -266
  2. package/package.json +1 -1
  3. package/presets/agy/AGENTS.md +11 -0
  4. package/presets/claude/CLAUDE.md +34 -0
  5. package/presets/claude/skills/android/SKILL.md +119 -0
  6. package/presets/claude/skills/laravel-specialist/SKILL.md +264 -0
  7. package/presets/claude/skills/laravel-specialist/references/eloquent.md +351 -0
  8. package/presets/claude/skills/laravel-specialist/references/livewire.md +512 -0
  9. package/presets/claude/skills/laravel-specialist/references/queues.md +423 -0
  10. package/presets/claude/skills/laravel-specialist/references/routing.md +362 -0
  11. package/presets/claude/skills/laravel-specialist/references/testing.md +522 -0
  12. package/presets/claude/skills/php-pro/SKILL.md +208 -0
  13. package/presets/claude/skills/php-pro/references/async-patterns.md +412 -0
  14. package/presets/claude/skills/php-pro/references/laravel-patterns.md +377 -0
  15. package/presets/claude/skills/php-pro/references/modern-php-features.md +323 -0
  16. package/presets/claude/skills/php-pro/references/symfony-patterns.md +466 -0
  17. package/presets/claude/skills/php-pro/references/testing-quality.md +466 -0
  18. package/presets/codex/AGENTS.md +19 -0
  19. package/presets/codex/skills/android/SKILL.md +119 -0
  20. package/presets/codex/skills/laravel-specialist/SKILL.md +264 -0
  21. package/presets/codex/skills/laravel-specialist/references/eloquent.md +351 -0
  22. package/presets/codex/skills/laravel-specialist/references/livewire.md +512 -0
  23. package/presets/codex/skills/laravel-specialist/references/queues.md +423 -0
  24. package/presets/codex/skills/laravel-specialist/references/routing.md +362 -0
  25. package/presets/codex/skills/laravel-specialist/references/testing.md +522 -0
  26. package/presets/codex/skills/php-pro/SKILL.md +208 -0
  27. package/presets/codex/skills/php-pro/references/async-patterns.md +412 -0
  28. package/presets/codex/skills/php-pro/references/laravel-patterns.md +377 -0
  29. package/presets/codex/skills/php-pro/references/modern-php-features.md +323 -0
  30. package/presets/codex/skills/php-pro/references/symfony-patterns.md +466 -0
  31. package/presets/codex/skills/php-pro/references/testing-quality.md +466 -0
  32. package/presets/opencode/agents/orchestrator.md +121 -1
  33. package/presets/opencode/agents/reviewer.md +31 -0
  34. package/presets/opencode/prompts/v0.3.0/architect.md +221 -0
  35. package/presets/opencode/prompts/v0.3.0/docs.md +189 -0
  36. package/presets/opencode/prompts/v0.3.0/implementer.md +162 -0
  37. package/presets/opencode/prompts/v0.3.0/orchestrator.md +360 -0
  38. package/presets/opencode/prompts/v0.3.0/repo-explorer.md +110 -0
  39. package/presets/opencode/prompts/v0.3.0/reviewer.md +225 -0
  40. package/presets/opencode/prompts/v0.3.0/task-coach.md +155 -0
  41. package/presets/opencode/prompts/v0.3.0/tester.md +251 -0
  42. package/presets/opencode/skills/android/SKILL.md +119 -0
  43. package/presets/opencode/skills/laravel-specialist/SKILL.md +264 -0
  44. package/presets/opencode/skills/laravel-specialist/references/eloquent.md +351 -0
  45. package/presets/opencode/skills/laravel-specialist/references/livewire.md +512 -0
  46. package/presets/opencode/skills/laravel-specialist/references/queues.md +423 -0
  47. package/presets/opencode/skills/laravel-specialist/references/routing.md +362 -0
  48. package/presets/opencode/skills/laravel-specialist/references/testing.md +522 -0
  49. package/presets/opencode/skills/php-pro/SKILL.md +208 -0
  50. package/presets/opencode/skills/php-pro/references/async-patterns.md +412 -0
  51. package/presets/opencode/skills/php-pro/references/laravel-patterns.md +377 -0
  52. package/presets/opencode/skills/php-pro/references/modern-php-features.md +323 -0
  53. package/presets/opencode/skills/php-pro/references/symfony-patterns.md +466 -0
  54. package/presets/opencode/skills/php-pro/references/testing-quality.md +466 -0
  55. package/src/presets/manifests/agy.yml +3 -2
  56. package/src/presets/manifests/claude.yml +3 -2
  57. package/src/presets/manifests/codex.yml +3 -2
  58. package/src/presets/manifests/cursor.yml +3 -2
  59. package/src/presets/manifests/gemini.yml +3 -2
  60. package/src/presets/manifests/opencode.yml +3 -2
  61. package/src/presets/models/opencode.yml +6 -6
package/dist/index.js CHANGED
@@ -77,24 +77,24 @@ var require_identity = __commonJS((exports) => {
77
77
  var SCALAR = Symbol.for("yaml.scalar");
78
78
  var SEQ = Symbol.for("yaml.seq");
79
79
  var NODE_TYPE = Symbol.for("yaml.node.type");
80
- var isAlias = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === ALIAS;
81
- var isDocument = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === DOC;
82
- var isMap = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === MAP;
83
- var isPair = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === PAIR;
84
- var isScalar = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === SCALAR;
85
- var isSeq = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === SEQ;
86
- function isCollection(node) {
87
- if (node && typeof node === "object")
88
- switch (node[NODE_TYPE]) {
80
+ var isAlias = (node2) => !!node2 && typeof node2 === "object" && node2[NODE_TYPE] === ALIAS;
81
+ var isDocument = (node2) => !!node2 && typeof node2 === "object" && node2[NODE_TYPE] === DOC;
82
+ var isMap = (node2) => !!node2 && typeof node2 === "object" && node2[NODE_TYPE] === MAP;
83
+ var isPair = (node2) => !!node2 && typeof node2 === "object" && node2[NODE_TYPE] === PAIR;
84
+ var isScalar = (node2) => !!node2 && typeof node2 === "object" && node2[NODE_TYPE] === SCALAR;
85
+ var isSeq = (node2) => !!node2 && typeof node2 === "object" && node2[NODE_TYPE] === SEQ;
86
+ function isCollection(node2) {
87
+ if (node2 && typeof node2 === "object")
88
+ switch (node2[NODE_TYPE]) {
89
89
  case MAP:
90
90
  case SEQ:
91
91
  return true;
92
92
  }
93
93
  return false;
94
94
  }
95
- function isNode(node) {
96
- if (node && typeof node === "object")
97
- switch (node[NODE_TYPE]) {
95
+ function isNode(node2) {
96
+ if (node2 && typeof node2 === "object")
97
+ switch (node2[NODE_TYPE]) {
98
98
  case ALIAS:
99
99
  case MAP:
100
100
  case SCALAR:
@@ -103,7 +103,7 @@ var require_identity = __commonJS((exports) => {
103
103
  }
104
104
  return false;
105
105
  }
106
- var hasAnchor = (node) => (isScalar(node) || isCollection(node)) && !!node.anchor;
106
+ var hasAnchor = (node2) => (isScalar(node2) || isCollection(node2)) && !!node2.anchor;
107
107
  exports.ALIAS = ALIAS;
108
108
  exports.DOC = DOC;
109
109
  exports.MAP = MAP;
@@ -128,98 +128,98 @@ var require_visit = __commonJS((exports) => {
128
128
  var BREAK = Symbol("break visit");
129
129
  var SKIP = Symbol("skip children");
130
130
  var REMOVE = Symbol("remove node");
131
- function visit(node, visitor) {
131
+ function visit(node2, visitor) {
132
132
  const visitor_ = initVisitor(visitor);
133
- if (identity.isDocument(node)) {
134
- const cd = visit_(null, node.contents, visitor_, Object.freeze([node]));
133
+ if (identity.isDocument(node2)) {
134
+ const cd = visit_(null, node2.contents, visitor_, Object.freeze([node2]));
135
135
  if (cd === REMOVE)
136
- node.contents = null;
136
+ node2.contents = null;
137
137
  } else
138
- visit_(null, node, visitor_, Object.freeze([]));
138
+ visit_(null, node2, visitor_, Object.freeze([]));
139
139
  }
140
140
  visit.BREAK = BREAK;
141
141
  visit.SKIP = SKIP;
142
142
  visit.REMOVE = REMOVE;
143
- function visit_(key, node, visitor, path) {
144
- const ctrl = callVisitor(key, node, visitor, path);
143
+ function visit_(key, node2, visitor, path) {
144
+ const ctrl = callVisitor(key, node2, visitor, path);
145
145
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
146
146
  replaceNode(key, path, ctrl);
147
147
  return visit_(key, ctrl, visitor, path);
148
148
  }
149
149
  if (typeof ctrl !== "symbol") {
150
- if (identity.isCollection(node)) {
151
- path = Object.freeze(path.concat(node));
152
- for (let i = 0;i < node.items.length; ++i) {
153
- const ci = visit_(i, node.items[i], visitor, path);
150
+ if (identity.isCollection(node2)) {
151
+ path = Object.freeze(path.concat(node2));
152
+ for (let i = 0;i < node2.items.length; ++i) {
153
+ const ci = visit_(i, node2.items[i], visitor, path);
154
154
  if (typeof ci === "number")
155
155
  i = ci - 1;
156
156
  else if (ci === BREAK)
157
157
  return BREAK;
158
158
  else if (ci === REMOVE) {
159
- node.items.splice(i, 1);
159
+ node2.items.splice(i, 1);
160
160
  i -= 1;
161
161
  }
162
162
  }
163
- } else if (identity.isPair(node)) {
164
- path = Object.freeze(path.concat(node));
165
- const ck = visit_("key", node.key, visitor, path);
163
+ } else if (identity.isPair(node2)) {
164
+ path = Object.freeze(path.concat(node2));
165
+ const ck = visit_("key", node2.key, visitor, path);
166
166
  if (ck === BREAK)
167
167
  return BREAK;
168
168
  else if (ck === REMOVE)
169
- node.key = null;
170
- const cv = visit_("value", node.value, visitor, path);
169
+ node2.key = null;
170
+ const cv = visit_("value", node2.value, visitor, path);
171
171
  if (cv === BREAK)
172
172
  return BREAK;
173
173
  else if (cv === REMOVE)
174
- node.value = null;
174
+ node2.value = null;
175
175
  }
176
176
  }
177
177
  return ctrl;
178
178
  }
179
- async function visitAsync(node, visitor) {
179
+ async function visitAsync(node2, visitor) {
180
180
  const visitor_ = initVisitor(visitor);
181
- if (identity.isDocument(node)) {
182
- const cd = await visitAsync_(null, node.contents, visitor_, Object.freeze([node]));
181
+ if (identity.isDocument(node2)) {
182
+ const cd = await visitAsync_(null, node2.contents, visitor_, Object.freeze([node2]));
183
183
  if (cd === REMOVE)
184
- node.contents = null;
184
+ node2.contents = null;
185
185
  } else
186
- await visitAsync_(null, node, visitor_, Object.freeze([]));
186
+ await visitAsync_(null, node2, visitor_, Object.freeze([]));
187
187
  }
188
188
  visitAsync.BREAK = BREAK;
189
189
  visitAsync.SKIP = SKIP;
190
190
  visitAsync.REMOVE = REMOVE;
191
- async function visitAsync_(key, node, visitor, path) {
192
- const ctrl = await callVisitor(key, node, visitor, path);
191
+ async function visitAsync_(key, node2, visitor, path) {
192
+ const ctrl = await callVisitor(key, node2, visitor, path);
193
193
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
194
194
  replaceNode(key, path, ctrl);
195
195
  return visitAsync_(key, ctrl, visitor, path);
196
196
  }
197
197
  if (typeof ctrl !== "symbol") {
198
- if (identity.isCollection(node)) {
199
- path = Object.freeze(path.concat(node));
200
- for (let i = 0;i < node.items.length; ++i) {
201
- const ci = await visitAsync_(i, node.items[i], visitor, path);
198
+ if (identity.isCollection(node2)) {
199
+ path = Object.freeze(path.concat(node2));
200
+ for (let i = 0;i < node2.items.length; ++i) {
201
+ const ci = await visitAsync_(i, node2.items[i], visitor, path);
202
202
  if (typeof ci === "number")
203
203
  i = ci - 1;
204
204
  else if (ci === BREAK)
205
205
  return BREAK;
206
206
  else if (ci === REMOVE) {
207
- node.items.splice(i, 1);
207
+ node2.items.splice(i, 1);
208
208
  i -= 1;
209
209
  }
210
210
  }
211
- } else if (identity.isPair(node)) {
212
- path = Object.freeze(path.concat(node));
213
- const ck = await visitAsync_("key", node.key, visitor, path);
211
+ } else if (identity.isPair(node2)) {
212
+ path = Object.freeze(path.concat(node2));
213
+ const ck = await visitAsync_("key", node2.key, visitor, path);
214
214
  if (ck === BREAK)
215
215
  return BREAK;
216
216
  else if (ck === REMOVE)
217
- node.key = null;
218
- const cv = await visitAsync_("value", node.value, visitor, path);
217
+ node2.key = null;
218
+ const cv = await visitAsync_("value", node2.value, visitor, path);
219
219
  if (cv === BREAK)
220
220
  return BREAK;
221
221
  else if (cv === REMOVE)
222
- node.value = null;
222
+ node2.value = null;
223
223
  }
224
224
  }
225
225
  return ctrl;
@@ -242,32 +242,32 @@ var require_visit = __commonJS((exports) => {
242
242
  }
243
243
  return visitor;
244
244
  }
245
- function callVisitor(key, node, visitor, path) {
245
+ function callVisitor(key, node2, visitor, path) {
246
246
  if (typeof visitor === "function")
247
- return visitor(key, node, path);
248
- if (identity.isMap(node))
249
- return visitor.Map?.(key, node, path);
250
- if (identity.isSeq(node))
251
- return visitor.Seq?.(key, node, path);
252
- if (identity.isPair(node))
253
- return visitor.Pair?.(key, node, path);
254
- if (identity.isScalar(node))
255
- return visitor.Scalar?.(key, node, path);
256
- if (identity.isAlias(node))
257
- return visitor.Alias?.(key, node, path);
247
+ return visitor(key, node2, path);
248
+ if (identity.isMap(node2))
249
+ return visitor.Map?.(key, node2, path);
250
+ if (identity.isSeq(node2))
251
+ return visitor.Seq?.(key, node2, path);
252
+ if (identity.isPair(node2))
253
+ return visitor.Pair?.(key, node2, path);
254
+ if (identity.isScalar(node2))
255
+ return visitor.Scalar?.(key, node2, path);
256
+ if (identity.isAlias(node2))
257
+ return visitor.Alias?.(key, node2, path);
258
258
  return;
259
259
  }
260
- function replaceNode(key, path, node) {
260
+ function replaceNode(key, path, node2) {
261
261
  const parent = path[path.length - 1];
262
262
  if (identity.isCollection(parent)) {
263
- parent.items[key] = node;
263
+ parent.items[key] = node2;
264
264
  } else if (identity.isPair(parent)) {
265
265
  if (key === "key")
266
- parent.key = node;
266
+ parent.key = node2;
267
267
  else
268
- parent.value = node;
268
+ parent.value = node2;
269
269
  } else if (identity.isDocument(parent)) {
270
- parent.contents = node;
270
+ parent.contents = node2;
271
271
  } else {
272
272
  const pt = identity.isAlias(parent) ? "alias" : "scalar";
273
273
  throw new Error(`Cannot replace node with ${pt} parent`);
@@ -407,9 +407,9 @@ var require_directives = __commonJS((exports) => {
407
407
  let tagNames;
408
408
  if (doc && tagEntries.length > 0 && identity.isNode(doc.contents)) {
409
409
  const tags = {};
410
- visit.visit(doc.contents, (_key, node) => {
411
- if (identity.isNode(node) && node.tag)
412
- tags[node.tag] = true;
410
+ visit.visit(doc.contents, (_key, node2) => {
411
+ if (identity.isNode(node2) && node2.tag)
412
+ tags[node2.tag] = true;
413
413
  });
414
414
  tagNames = Object.keys(tags);
415
415
  } else
@@ -444,9 +444,9 @@ var require_anchors = __commonJS((exports) => {
444
444
  function anchorNames(root) {
445
445
  const anchors = new Set;
446
446
  visit.visit(root, {
447
- Value(_key, node) {
448
- if (node.anchor)
449
- anchors.add(node.anchor);
447
+ Value(_key, node2) {
448
+ if (node2.anchor)
449
+ anchors.add(node2.anchor);
450
450
  }
451
451
  });
452
452
  return anchors;
@@ -629,20 +629,20 @@ var require_Alias = __commonJS((exports) => {
629
629
  } else {
630
630
  nodes = [];
631
631
  visit.visit(doc, {
632
- Node: (_key, node) => {
633
- if (identity.isAlias(node) || identity.hasAnchor(node))
634
- nodes.push(node);
632
+ Node: (_key, node2) => {
633
+ if (identity.isAlias(node2) || identity.hasAnchor(node2))
634
+ nodes.push(node2);
635
635
  }
636
636
  });
637
637
  if (ctx)
638
638
  ctx.aliasResolveCache = nodes;
639
639
  }
640
640
  let found = undefined;
641
- for (const node of nodes) {
642
- if (node === this)
641
+ for (const node2 of nodes) {
642
+ if (node2 === this)
643
643
  break;
644
- if (node.anchor === this.source)
645
- found = node;
644
+ if (node2.anchor === this.source)
645
+ found = node2;
646
646
  }
647
647
  return found;
648
648
  }
@@ -689,22 +689,22 @@ var require_Alias = __commonJS((exports) => {
689
689
  return src;
690
690
  }
691
691
  }
692
- function getAliasCount(doc, node, anchors2) {
693
- if (identity.isAlias(node)) {
694
- const source = node.resolve(doc);
692
+ function getAliasCount(doc, node2, anchors2) {
693
+ if (identity.isAlias(node2)) {
694
+ const source = node2.resolve(doc);
695
695
  const anchor = anchors2 && source && anchors2.get(source);
696
696
  return anchor ? anchor.count * anchor.aliasCount : 0;
697
- } else if (identity.isCollection(node)) {
697
+ } else if (identity.isCollection(node2)) {
698
698
  let count = 0;
699
- for (const item of node.items) {
699
+ for (const item of node2.items) {
700
700
  const c = getAliasCount(doc, item, anchors2);
701
701
  if (c > count)
702
702
  count = c;
703
703
  }
704
704
  return count;
705
- } else if (identity.isPair(node)) {
706
- const kc = getAliasCount(doc, node.key, anchors2);
707
- const vc = getAliasCount(doc, node.value, anchors2);
705
+ } else if (identity.isPair(node2)) {
706
+ const kc = getAliasCount(doc, node2.key, anchors2);
707
+ const vc = getAliasCount(doc, node2.value, anchors2);
708
708
  return Math.max(kc, vc);
709
709
  }
710
710
  return 1;
@@ -789,10 +789,10 @@ var require_createNode = __commonJS((exports) => {
789
789
  value = value.toJSON();
790
790
  }
791
791
  if (!value || typeof value !== "object") {
792
- const node2 = new Scalar.Scalar(value);
792
+ const node3 = new Scalar.Scalar(value);
793
793
  if (ref)
794
- ref.node = node2;
795
- return node2;
794
+ ref.node = node3;
795
+ return node3;
796
796
  }
797
797
  tagObj = value instanceof Map ? schema[identity.MAP] : (Symbol.iterator in Object(value)) ? schema[identity.SEQ] : schema[identity.MAP];
798
798
  }
@@ -800,14 +800,14 @@ var require_createNode = __commonJS((exports) => {
800
800
  onTagObj(tagObj);
801
801
  delete ctx.onTagObj;
802
802
  }
803
- const node = tagObj?.createNode ? tagObj.createNode(ctx.schema, value, ctx) : typeof tagObj?.nodeClass?.from === "function" ? tagObj.nodeClass.from(ctx.schema, value, ctx) : new Scalar.Scalar(value);
803
+ const node2 = tagObj?.createNode ? tagObj.createNode(ctx.schema, value, ctx) : typeof tagObj?.nodeClass?.from === "function" ? tagObj.nodeClass.from(ctx.schema, value, ctx) : new Scalar.Scalar(value);
804
804
  if (tagName)
805
- node.tag = tagName;
805
+ node2.tag = tagName;
806
806
  else if (!tagObj.default)
807
- node.tag = tagObj.tag;
807
+ node2.tag = tagObj.tag;
808
808
  if (ref)
809
- ref.node = node;
810
- return node;
809
+ ref.node = node2;
810
+ return node2;
811
811
  }
812
812
  exports.createNode = createNode;
813
813
  });
@@ -865,10 +865,10 @@ var require_Collection = __commonJS((exports) => {
865
865
  this.add(value);
866
866
  else {
867
867
  const [key, ...rest] = path;
868
- const node = this.get(key, true);
869
- if (identity.isCollection(node))
870
- node.addIn(rest, value);
871
- else if (node === undefined && this.schema)
868
+ const node2 = this.get(key, true);
869
+ if (identity.isCollection(node2))
870
+ node2.addIn(rest, value);
871
+ else if (node2 === undefined && this.schema)
872
872
  this.set(key, collectionFromPath(this.schema, rest, value));
873
873
  else
874
874
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
@@ -878,25 +878,25 @@ var require_Collection = __commonJS((exports) => {
878
878
  const [key, ...rest] = path;
879
879
  if (rest.length === 0)
880
880
  return this.delete(key);
881
- const node = this.get(key, true);
882
- if (identity.isCollection(node))
883
- return node.deleteIn(rest);
881
+ const node2 = this.get(key, true);
882
+ if (identity.isCollection(node2))
883
+ return node2.deleteIn(rest);
884
884
  else
885
885
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
886
886
  }
887
887
  getIn(path, keepScalar) {
888
888
  const [key, ...rest] = path;
889
- const node = this.get(key, true);
889
+ const node2 = this.get(key, true);
890
890
  if (rest.length === 0)
891
- return !keepScalar && identity.isScalar(node) ? node.value : node;
891
+ return !keepScalar && identity.isScalar(node2) ? node2.value : node2;
892
892
  else
893
- return identity.isCollection(node) ? node.getIn(rest, keepScalar) : undefined;
893
+ return identity.isCollection(node2) ? node2.getIn(rest, keepScalar) : undefined;
894
894
  }
895
895
  hasAllNullValues(allowScalar) {
896
- return this.items.every((node) => {
897
- if (!identity.isPair(node))
896
+ return this.items.every((node2) => {
897
+ if (!identity.isPair(node2))
898
898
  return false;
899
- const n = node.value;
899
+ const n = node2.value;
900
900
  return n == null || allowScalar && identity.isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag;
901
901
  });
902
902
  }
@@ -904,18 +904,18 @@ var require_Collection = __commonJS((exports) => {
904
904
  const [key, ...rest] = path;
905
905
  if (rest.length === 0)
906
906
  return this.has(key);
907
- const node = this.get(key, true);
908
- return identity.isCollection(node) ? node.hasIn(rest) : false;
907
+ const node2 = this.get(key, true);
908
+ return identity.isCollection(node2) ? node2.hasIn(rest) : false;
909
909
  }
910
910
  setIn(path, value) {
911
911
  const [key, ...rest] = path;
912
912
  if (rest.length === 0) {
913
913
  this.set(key, value);
914
914
  } else {
915
- const node = this.get(key, true);
916
- if (identity.isCollection(node))
917
- node.setIn(rest, value);
918
- else if (node === undefined && this.schema)
915
+ const node2 = this.get(key, true);
916
+ if (identity.isCollection(node2))
917
+ node2.setIn(rest, value);
918
+ else if (node2 === undefined && this.schema)
919
919
  this.set(key, collectionFromPath(this.schema, rest, value));
920
920
  else
921
921
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
@@ -1454,16 +1454,16 @@ var require_stringify = __commonJS((exports) => {
1454
1454
  }
1455
1455
  return tagObj;
1456
1456
  }
1457
- function stringifyProps(node, tagObj, { anchors: anchors$1, doc }) {
1457
+ function stringifyProps(node2, tagObj, { anchors: anchors$1, doc }) {
1458
1458
  if (!doc.directives)
1459
1459
  return "";
1460
1460
  const props = [];
1461
- const anchor = (identity.isScalar(node) || identity.isCollection(node)) && node.anchor;
1461
+ const anchor = (identity.isScalar(node2) || identity.isCollection(node2)) && node2.anchor;
1462
1462
  if (anchor && anchors.anchorIsValid(anchor)) {
1463
1463
  anchors$1.add(anchor);
1464
1464
  props.push(`&${anchor}`);
1465
1465
  }
1466
- const tag = node.tag ?? (tagObj.default ? null : tagObj.tag);
1466
+ const tag = node2.tag ?? (tagObj.default ? null : tagObj.tag);
1467
1467
  if (tag)
1468
1468
  props.push(doc.directives.tagString(tag));
1469
1469
  return props.join(" ");
@@ -1485,15 +1485,15 @@ var require_stringify = __commonJS((exports) => {
1485
1485
  }
1486
1486
  }
1487
1487
  let tagObj = undefined;
1488
- const node = identity.isNode(item) ? item : ctx.doc.createNode(item, { onTagObj: (o) => tagObj = o });
1489
- tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node));
1490
- const props = stringifyProps(node, tagObj, ctx);
1488
+ const node2 = identity.isNode(item) ? item : ctx.doc.createNode(item, { onTagObj: (o) => tagObj = o });
1489
+ tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node2));
1490
+ const props = stringifyProps(node2, tagObj, ctx);
1491
1491
  if (props.length > 0)
1492
1492
  ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;
1493
- const str = typeof tagObj.stringify === "function" ? tagObj.stringify(node, ctx, onComment, onChompKeep) : identity.isScalar(node) ? stringifyString.stringifyString(node, ctx, onComment, onChompKeep) : node.toString(ctx, onComment, onChompKeep);
1493
+ const str = typeof tagObj.stringify === "function" ? tagObj.stringify(node2, ctx, onComment, onChompKeep) : identity.isScalar(node2) ? stringifyString.stringifyString(node2, ctx, onComment, onChompKeep) : node2.toString(ctx, onComment, onChompKeep);
1494
1494
  if (!props)
1495
1495
  return str;
1496
- return identity.isScalar(node) || str[0] === "{" || str[0] === "[" ? `${props} ${str}` : `${props}
1496
+ return identity.isScalar(node2) || str[0] === "{" || str[0] === "[" ? `${props} ${str}` : `${props}
1497
1497
  ${ctx.indent}${str}`;
1498
1498
  }
1499
1499
  exports.createStringifyContext = createStringifyContext;
@@ -1754,8 +1754,8 @@ var require_addPairToJSMap = __commonJS((exports) => {
1754
1754
  if (identity.isNode(key) && ctx?.doc) {
1755
1755
  const strCtx = stringify.createStringifyContext(ctx.doc, {});
1756
1756
  strCtx.anchors = new Set;
1757
- for (const node of ctx.anchors.keys())
1758
- strCtx.anchors.add(node.anchor);
1757
+ for (const node2 of ctx.anchors.keys())
1758
+ strCtx.anchors.add(node2.anchor);
1759
1759
  strCtx.inFlow = true;
1760
1760
  strCtx.inStringifyKey = true;
1761
1761
  const strKey = key.toString(strCtx);
@@ -2051,8 +2051,8 @@ var require_YAMLMap = __commonJS((exports) => {
2051
2051
  }
2052
2052
  get(key, keepScalar) {
2053
2053
  const it = findPair(this.items, key);
2054
- const node = it?.value;
2055
- return (!keepScalar && identity.isScalar(node) ? node.value : node) ?? undefined;
2054
+ const node2 = it?.value;
2055
+ return (!keepScalar && identity.isScalar(node2) ? node2.value : node2) ?? undefined;
2056
2056
  }
2057
2057
  has(key) {
2058
2058
  return !!findPair(this.items, key);
@@ -2316,9 +2316,9 @@ var require_float = __commonJS((exports) => {
2316
2316
  format: "EXP",
2317
2317
  test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,
2318
2318
  resolve: (str) => parseFloat(str),
2319
- stringify(node) {
2320
- const num = Number(node.value);
2321
- return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
2319
+ stringify(node2) {
2320
+ const num = Number(node2.value);
2321
+ return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node2);
2322
2322
  }
2323
2323
  };
2324
2324
  var float = {
@@ -2327,11 +2327,11 @@ var require_float = __commonJS((exports) => {
2327
2327
  tag: "tag:yaml.org,2002:float",
2328
2328
  test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,
2329
2329
  resolve(str) {
2330
- const node = new Scalar.Scalar(parseFloat(str));
2330
+ const node2 = new Scalar.Scalar(parseFloat(str));
2331
2331
  const dot = str.indexOf(".");
2332
2332
  if (dot !== -1 && str[str.length - 1] === "0")
2333
- node.minFractionDigits = str.length - dot - 1;
2334
- return node;
2333
+ node2.minFractionDigits = str.length - dot - 1;
2334
+ return node2;
2335
2335
  },
2336
2336
  stringify: stringifyNumber.stringifyNumber
2337
2337
  };
@@ -2345,11 +2345,11 @@ var require_int = __commonJS((exports) => {
2345
2345
  var stringifyNumber = require_stringifyNumber();
2346
2346
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
2347
2347
  var intResolve = (str, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix);
2348
- function intStringify(node, radix, prefix) {
2349
- const { value } = node;
2348
+ function intStringify(node2, radix, prefix) {
2349
+ const { value } = node2;
2350
2350
  if (intIdentify(value) && value >= 0)
2351
2351
  return prefix + value.toString(radix);
2352
- return stringifyNumber.stringifyNumber(node);
2352
+ return stringifyNumber.stringifyNumber(node2);
2353
2353
  }
2354
2354
  var intOct = {
2355
2355
  identify: (value) => intIdentify(value) && value >= 0,
@@ -2358,7 +2358,7 @@ var require_int = __commonJS((exports) => {
2358
2358
  format: "OCT",
2359
2359
  test: /^0o[0-7]+$/,
2360
2360
  resolve: (str, _onError, opt) => intResolve(str, 2, 8, opt),
2361
- stringify: (node) => intStringify(node, 8, "0o")
2361
+ stringify: (node2) => intStringify(node2, 8, "0o")
2362
2362
  };
2363
2363
  var int = {
2364
2364
  identify: intIdentify,
@@ -2375,7 +2375,7 @@ var require_int = __commonJS((exports) => {
2375
2375
  format: "HEX",
2376
2376
  test: /^0x[0-9a-fA-F]+$/,
2377
2377
  resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
2378
- stringify: (node) => intStringify(node, 16, "0x")
2378
+ stringify: (node2) => intStringify(node2, 16, "0x")
2379
2379
  };
2380
2380
  exports.int = int;
2381
2381
  exports.intHex = intHex;
@@ -2721,9 +2721,9 @@ var require_float2 = __commonJS((exports) => {
2721
2721
  format: "EXP",
2722
2722
  test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,
2723
2723
  resolve: (str) => parseFloat(str.replace(/_/g, "")),
2724
- stringify(node) {
2725
- const num = Number(node.value);
2726
- return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
2724
+ stringify(node2) {
2725
+ const num = Number(node2.value);
2726
+ return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node2);
2727
2727
  }
2728
2728
  };
2729
2729
  var float = {
@@ -2732,14 +2732,14 @@ var require_float2 = __commonJS((exports) => {
2732
2732
  tag: "tag:yaml.org,2002:float",
2733
2733
  test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,
2734
2734
  resolve(str) {
2735
- const node = new Scalar.Scalar(parseFloat(str.replace(/_/g, "")));
2735
+ const node2 = new Scalar.Scalar(parseFloat(str.replace(/_/g, "")));
2736
2736
  const dot = str.indexOf(".");
2737
2737
  if (dot !== -1) {
2738
2738
  const f = str.substring(dot + 1).replace(/_/g, "");
2739
2739
  if (f[f.length - 1] === "0")
2740
- node.minFractionDigits = f.length;
2740
+ node2.minFractionDigits = f.length;
2741
2741
  }
2742
- return node;
2742
+ return node2;
2743
2743
  },
2744
2744
  stringify: stringifyNumber.stringifyNumber
2745
2745
  };
@@ -2775,13 +2775,13 @@ var require_int2 = __commonJS((exports) => {
2775
2775
  const n = parseInt(str, radix);
2776
2776
  return sign === "-" ? -1 * n : n;
2777
2777
  }
2778
- function intStringify(node, radix, prefix) {
2779
- const { value } = node;
2778
+ function intStringify(node2, radix, prefix) {
2779
+ const { value } = node2;
2780
2780
  if (intIdentify(value)) {
2781
2781
  const str = value.toString(radix);
2782
2782
  return value < 0 ? "-" + prefix + str.substr(1) : prefix + str;
2783
2783
  }
2784
- return stringifyNumber.stringifyNumber(node);
2784
+ return stringifyNumber.stringifyNumber(node2);
2785
2785
  }
2786
2786
  var intBin = {
2787
2787
  identify: intIdentify,
@@ -2790,7 +2790,7 @@ var require_int2 = __commonJS((exports) => {
2790
2790
  format: "BIN",
2791
2791
  test: /^[-+]?0b[0-1_]+$/,
2792
2792
  resolve: (str, _onError, opt) => intResolve(str, 2, 2, opt),
2793
- stringify: (node) => intStringify(node, 2, "0b")
2793
+ stringify: (node2) => intStringify(node2, 2, "0b")
2794
2794
  };
2795
2795
  var intOct = {
2796
2796
  identify: intIdentify,
@@ -2799,7 +2799,7 @@ var require_int2 = __commonJS((exports) => {
2799
2799
  format: "OCT",
2800
2800
  test: /^[-+]?0[0-7_]+$/,
2801
2801
  resolve: (str, _onError, opt) => intResolve(str, 1, 8, opt),
2802
- stringify: (node) => intStringify(node, 8, "0")
2802
+ stringify: (node2) => intStringify(node2, 8, "0")
2803
2803
  };
2804
2804
  var int = {
2805
2805
  identify: intIdentify,
@@ -2816,7 +2816,7 @@ var require_int2 = __commonJS((exports) => {
2816
2816
  format: "HEX",
2817
2817
  test: /^[-+]?0x[0-9a-fA-F_]+$/,
2818
2818
  resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
2819
- stringify: (node) => intStringify(node, 16, "0x")
2819
+ stringify: (node2) => intStringify(node2, 16, "0x")
2820
2820
  };
2821
2821
  exports.int = int;
2822
2822
  exports.intBin = intBin;
@@ -2917,13 +2917,13 @@ var require_timestamp = __commonJS((exports) => {
2917
2917
  const res = parts.replace(/_/g, "").split(":").reduce((res2, p) => res2 * num(60) + num(p), num(0));
2918
2918
  return sign === "-" ? num(-1) * res : res;
2919
2919
  }
2920
- function stringifySexagesimal(node) {
2921
- let { value } = node;
2920
+ function stringifySexagesimal(node2) {
2921
+ let { value } = node2;
2922
2922
  let num = (n) => n;
2923
2923
  if (typeof value === "bigint")
2924
2924
  num = (n) => BigInt(n);
2925
2925
  else if (isNaN(value) || !isFinite(value))
2926
- return stringifyNumber.stringifyNumber(node);
2926
+ return stringifyNumber.stringifyNumber(node2);
2927
2927
  let sign = "";
2928
2928
  if (value < 0) {
2929
2929
  sign = "-";
@@ -3305,12 +3305,12 @@ var require_Document = __commonJS((exports) => {
3305
3305
  if (assertCollection(this.contents))
3306
3306
  this.contents.addIn(path, value);
3307
3307
  }
3308
- createAlias(node, name) {
3309
- if (!node.anchor) {
3308
+ createAlias(node2, name) {
3309
+ if (!node2.anchor) {
3310
3310
  const prev = anchors.anchorNames(this);
3311
- node.anchor = !name || prev.has(name) ? anchors.findNewAnchor(name || "a", prev) : name;
3311
+ node2.anchor = !name || prev.has(name) ? anchors.findNewAnchor(name || "a", prev) : name;
3312
3312
  }
3313
- return new Alias.Alias(node.anchor);
3313
+ return new Alias.Alias(node2.anchor);
3314
3314
  }
3315
3315
  createNode(value, replacer, options) {
3316
3316
  let _replacer = undefined;
@@ -3338,11 +3338,11 @@ var require_Document = __commonJS((exports) => {
3338
3338
  schema: this.schema,
3339
3339
  sourceObjects
3340
3340
  };
3341
- const node = createNode.createNode(value, tag, ctx);
3342
- if (flow && identity.isCollection(node))
3343
- node.flow = true;
3341
+ const node2 = createNode.createNode(value, tag, ctx);
3342
+ if (flow && identity.isCollection(node2))
3343
+ node2.flow = true;
3344
3344
  setAnchors();
3345
- return node;
3345
+ return node2;
3346
3346
  }
3347
3347
  createPair(key, value, options = {}) {
3348
3348
  const k = this.createNode(key, null, options);
@@ -3872,11 +3872,11 @@ var require_resolve_block_seq = __commonJS((exports) => {
3872
3872
  continue;
3873
3873
  }
3874
3874
  }
3875
- const node = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, start, null, props, onError);
3875
+ const node2 = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, start, null, props, onError);
3876
3876
  if (ctx.schema.compat)
3877
3877
  utilFlowIndentCheck.flowIndentCheck(bs.indent, value, onError);
3878
- offset = node.range[2];
3879
- seq.items.push(node);
3878
+ offset = node2.range[2];
3879
+ seq.items.push(node2);
3880
3880
  }
3881
3881
  seq.range = [bs.offset, offset, commentEnd ?? offset];
3882
3882
  return seq;
@@ -4167,12 +4167,12 @@ var require_compose_collection = __commonJS((exports) => {
4167
4167
  }
4168
4168
  const coll = resolveCollection(CN, ctx, token, onError, tagName, tag);
4169
4169
  const res = tag.resolve?.(coll, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg), ctx.options) ?? coll;
4170
- const node = identity.isNode(res) ? res : new Scalar.Scalar(res);
4171
- node.range = coll.range;
4172
- node.tag = tagName;
4170
+ const node2 = identity.isNode(res) ? res : new Scalar.Scalar(res);
4171
+ node2.range = coll.range;
4172
+ node2.tag = tagName;
4173
4173
  if (tag?.format)
4174
- node.format = tag.format;
4175
- return node;
4174
+ node2.format = tag.format;
4175
+ return node2;
4176
4176
  }
4177
4177
  exports.composeCollection = composeCollection;
4178
4178
  });
@@ -4704,11 +4704,11 @@ var require_compose_node = __commonJS((exports) => {
4704
4704
  function composeNode(ctx, token, props, onError) {
4705
4705
  const atKey = ctx.atKey;
4706
4706
  const { spaceBefore, comment, anchor, tag } = props;
4707
- let node;
4707
+ let node2;
4708
4708
  let isSrcToken = true;
4709
4709
  switch (token.type) {
4710
4710
  case "alias":
4711
- node = composeAlias(ctx, token, onError);
4711
+ node2 = composeAlias(ctx, token, onError);
4712
4712
  if (anchor || tag)
4713
4713
  onError(token, "ALIAS_PROPS", "An alias node must not specify any properties");
4714
4714
  break;
@@ -4716,17 +4716,17 @@ var require_compose_node = __commonJS((exports) => {
4716
4716
  case "single-quoted-scalar":
4717
4717
  case "double-quoted-scalar":
4718
4718
  case "block-scalar":
4719
- node = composeScalar.composeScalar(ctx, token, tag, onError);
4719
+ node2 = composeScalar.composeScalar(ctx, token, tag, onError);
4720
4720
  if (anchor)
4721
- node.anchor = anchor.source.substring(1);
4721
+ node2.anchor = anchor.source.substring(1);
4722
4722
  break;
4723
4723
  case "block-map":
4724
4724
  case "block-seq":
4725
4725
  case "flow-collection":
4726
4726
  try {
4727
- node = composeCollection.composeCollection(CN, ctx, token, props, onError);
4727
+ node2 = composeCollection.composeCollection(CN, ctx, token, props, onError);
4728
4728
  if (anchor)
4729
- node.anchor = anchor.source.substring(1);
4729
+ node2.anchor = anchor.source.substring(1);
4730
4730
  } catch (error) {
4731
4731
  const message = error instanceof Error ? error.message : String(error);
4732
4732
  onError(token, "RESOURCE_EXHAUSTION", message);
@@ -4738,24 +4738,24 @@ var require_compose_node = __commonJS((exports) => {
4738
4738
  isSrcToken = false;
4739
4739
  }
4740
4740
  }
4741
- node ?? (node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));
4742
- if (anchor && node.anchor === "")
4741
+ node2 ?? (node2 = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));
4742
+ if (anchor && node2.anchor === "")
4743
4743
  onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
4744
- if (atKey && ctx.options.stringKeys && (!identity.isScalar(node) || typeof node.value !== "string" || node.tag && node.tag !== "tag:yaml.org,2002:str")) {
4744
+ if (atKey && ctx.options.stringKeys && (!identity.isScalar(node2) || typeof node2.value !== "string" || node2.tag && node2.tag !== "tag:yaml.org,2002:str")) {
4745
4745
  const msg = "With stringKeys, all keys must be strings";
4746
4746
  onError(tag ?? token, "NON_STRING_KEY", msg);
4747
4747
  }
4748
4748
  if (spaceBefore)
4749
- node.spaceBefore = true;
4749
+ node2.spaceBefore = true;
4750
4750
  if (comment) {
4751
4751
  if (token.type === "scalar" && token.source === "")
4752
- node.comment = comment;
4752
+ node2.comment = comment;
4753
4753
  else
4754
- node.commentBefore = comment;
4754
+ node2.commentBefore = comment;
4755
4755
  }
4756
4756
  if (ctx.options.keepSourceTokens && isSrcToken)
4757
- node.srcToken = token;
4758
- return node;
4757
+ node2.srcToken = token;
4758
+ return node2;
4759
4759
  }
4760
4760
  function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anchor, tag, end }, onError) {
4761
4761
  const token = {
@@ -4764,19 +4764,19 @@ var require_compose_node = __commonJS((exports) => {
4764
4764
  indent: -1,
4765
4765
  source: ""
4766
4766
  };
4767
- const node = composeScalar.composeScalar(ctx, token, tag, onError);
4767
+ const node2 = composeScalar.composeScalar(ctx, token, tag, onError);
4768
4768
  if (anchor) {
4769
- node.anchor = anchor.source.substring(1);
4770
- if (node.anchor === "")
4769
+ node2.anchor = anchor.source.substring(1);
4770
+ if (node2.anchor === "")
4771
4771
  onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
4772
4772
  }
4773
4773
  if (spaceBefore)
4774
- node.spaceBefore = true;
4774
+ node2.spaceBefore = true;
4775
4775
  if (comment) {
4776
- node.comment = comment;
4777
- node.range[2] = end;
4776
+ node2.comment = comment;
4777
+ node2.range[2] = end;
4778
4778
  }
4779
- return node;
4779
+ return node2;
4780
4780
  }
4781
4781
  function composeAlias({ options }, { offset, source, end }, onError) {
4782
4782
  const alias = new Alias.Alias(source.substring(1));
@@ -7044,7 +7044,7 @@ function getExitCode(error) {
7044
7044
  // package.json
7045
7045
  var package_default = {
7046
7046
  name: "cc-codeconductor",
7047
- version: "0.2.10",
7047
+ version: "0.3.0",
7048
7048
  description: "A multi-agent orchestration framework for AI-assisted software engineering workflows.",
7049
7049
  keywords: [
7050
7050
  "ai",
@@ -7098,6 +7098,230 @@ var package_default = {
7098
7098
  }
7099
7099
  };
7100
7100
 
7101
+ // src/core/detection/detectors/node.ts
7102
+ async function detectNode(rootDir) {
7103
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7104
+ const signals = [];
7105
+ if (await fileExists2(rootDir, "package.json")) {
7106
+ signals.push("package.json");
7107
+ }
7108
+ if (await fileExists2(rootDir, "node_modules")) {
7109
+ signals.push("node_modules/");
7110
+ }
7111
+ return signals;
7112
+ }
7113
+ async function detectBun(rootDir) {
7114
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7115
+ const signals = [];
7116
+ if (await fileExists2(rootDir, "bun.lockb")) {
7117
+ signals.push("bun.lockb");
7118
+ }
7119
+ if (await fileExists2(rootDir, "bun.lock")) {
7120
+ signals.push("bun.lock");
7121
+ }
7122
+ return signals;
7123
+ }
7124
+ // src/core/detection/detectors/backend.ts
7125
+ async function detectSpring(rootDir) {
7126
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7127
+ const signals = [];
7128
+ if (await fileExists2(rootDir, "build.gradle") || await fileExists2(rootDir, "build.gradle.kts")) {
7129
+ signals.push("build.gradle");
7130
+ }
7131
+ if (await fileExists2(rootDir, "pom.xml")) {
7132
+ signals.push("pom.xml");
7133
+ }
7134
+ return signals;
7135
+ }
7136
+ async function detectDjango(rootDir) {
7137
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7138
+ const signals = [];
7139
+ if (await fileExists2(rootDir, "manage.py")) {
7140
+ signals.push("manage.py");
7141
+ }
7142
+ if (await fileExists2(rootDir, "requirements.txt")) {
7143
+ signals.push("requirements.txt");
7144
+ }
7145
+ return signals;
7146
+ }
7147
+ async function detectFastApi(rootDir) {
7148
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7149
+ const { join } = await import("node:path");
7150
+ const { readFile } = await import("node:fs/promises");
7151
+ const signals = [];
7152
+ if (await fileExists2(rootDir, "requirements.txt")) {
7153
+ try {
7154
+ const content = await readFile(join(rootDir, "requirements.txt"), "utf-8");
7155
+ if (content.includes("fastapi")) {
7156
+ signals.push("fastapi-requirements");
7157
+ }
7158
+ } catch {}
7159
+ }
7160
+ if (await fileExists2(rootDir, "pyproject.toml")) {
7161
+ try {
7162
+ const content = await readFile(join(rootDir, "pyproject.toml"), "utf-8");
7163
+ if (content.includes("fastapi")) {
7164
+ signals.push("fastapi-pyproject");
7165
+ }
7166
+ } catch {}
7167
+ }
7168
+ for (const filename of ["main.py", "app.py", "app/main.py", "app/app.py"]) {
7169
+ if (await fileExists2(rootDir, filename)) {
7170
+ try {
7171
+ const content = await readFile(join(rootDir, filename), "utf-8");
7172
+ if (content.includes("FastAPI") && content.includes("fastapi")) {
7173
+ signals.push(`${filename}-fastapi`);
7174
+ }
7175
+ } catch {}
7176
+ }
7177
+ }
7178
+ return signals;
7179
+ }
7180
+ async function detectPhp(rootDir) {
7181
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7182
+ const signals = [];
7183
+ if (await fileExists2(rootDir, "composer.json")) {
7184
+ signals.push("composer.json");
7185
+ }
7186
+ if (await fileExists2(rootDir, "artisan")) {
7187
+ signals.push("artisan");
7188
+ }
7189
+ try {
7190
+ const { readdir } = await import("node:fs/promises");
7191
+ const entries = await readdir(rootDir, { withFileTypes: true });
7192
+ const hasPhpFiles = entries.some((entry) => entry.isFile() && entry.name.endsWith(".php"));
7193
+ if (hasPhpFiles) {
7194
+ signals.push("*.php");
7195
+ }
7196
+ } catch {}
7197
+ return signals;
7198
+ }
7199
+ async function detectGenericBackend(rootDir) {
7200
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7201
+ const { readdir } = await import("node:fs/promises");
7202
+ const signals = [];
7203
+ if (await fileExists2(rootDir, "go.mod")) {
7204
+ signals.push("go.mod");
7205
+ }
7206
+ if (await fileExists2(rootDir, "Cargo.toml")) {
7207
+ signals.push("Cargo.toml");
7208
+ }
7209
+ if (await fileExists2(rootDir, "Gemfile")) {
7210
+ signals.push("Gemfile");
7211
+ }
7212
+ try {
7213
+ const entries = await readdir(rootDir, { withFileTypes: true });
7214
+ const hasCsProj = entries.some((entry) => entry.isFile() && entry.name.endsWith(".csproj"));
7215
+ if (hasCsProj) {
7216
+ signals.push("*.csproj");
7217
+ }
7218
+ } catch {}
7219
+ return signals;
7220
+ }
7221
+ // src/core/detection/detectors/frontend.ts
7222
+ async function detectAstro(rootDir) {
7223
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7224
+ const signals = [];
7225
+ if (await fileExists2(rootDir, "astro.config.mjs") || await fileExists2(rootDir, "astro.config.ts")) {
7226
+ signals.push("astro.config");
7227
+ }
7228
+ return signals;
7229
+ }
7230
+ async function detectNext(rootDir) {
7231
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7232
+ const { join } = await import("node:path");
7233
+ const { readFile } = await import("node:fs/promises");
7234
+ const signals = [];
7235
+ if (await fileExists2(rootDir, "next.config.js") || await fileExists2(rootDir, "next.config.mjs") || await fileExists2(rootDir, "next.config.ts")) {
7236
+ signals.push("next.config");
7237
+ }
7238
+ if (await fileExists2(rootDir, "package.json")) {
7239
+ try {
7240
+ const content = await readFile(join(rootDir, "package.json"), "utf-8");
7241
+ const pkg = JSON.parse(content);
7242
+ if (pkg.dependencies?.next || pkg.devDependencies?.next) {
7243
+ signals.push("package.json-next");
7244
+ }
7245
+ } catch {}
7246
+ }
7247
+ return signals;
7248
+ }
7249
+ async function detectGenericFrontend(rootDir) {
7250
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7251
+ const { join } = await import("node:path");
7252
+ const { readFile } = await import("node:fs/promises");
7253
+ const signals = [];
7254
+ if (await fileExists2(rootDir, "index.html")) {
7255
+ signals.push("index.html");
7256
+ }
7257
+ if (await fileExists2(rootDir, "vite.config.js") || await fileExists2(rootDir, "vite.config.ts")) {
7258
+ signals.push("vite.config");
7259
+ }
7260
+ if (await fileExists2(rootDir, "webpack.config.js")) {
7261
+ signals.push("webpack.config.js");
7262
+ }
7263
+ if (await fileExists2(rootDir, "package.json")) {
7264
+ try {
7265
+ const content = await readFile(join(rootDir, "package.json"), "utf-8");
7266
+ const pkg = JSON.parse(content);
7267
+ const frontendDeps = ["react", "vue", "svelte", "solid-js", "angular", "@angular/core"];
7268
+ const hasFrontendDep = frontendDeps.some((dep) => pkg.dependencies?.[dep] || pkg.devDependencies?.[dep]);
7269
+ if (hasFrontendDep) {
7270
+ signals.push("package.json-frontend");
7271
+ }
7272
+ } catch {}
7273
+ }
7274
+ return signals;
7275
+ }
7276
+ // src/core/detection/detectors/monorepo.ts
7277
+ async function detectMonorepo(rootDir) {
7278
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7279
+ const { join } = await import("node:path");
7280
+ const { readFile } = await import("node:fs/promises");
7281
+ const signals = [];
7282
+ if (await fileExists2(rootDir, "pnpm-workspace.yaml")) {
7283
+ signals.push("pnpm-workspace.yaml");
7284
+ }
7285
+ if (await fileExists2(rootDir, "lerna.json")) {
7286
+ signals.push("lerna.json");
7287
+ }
7288
+ if (await fileExists2(rootDir, "go.work")) {
7289
+ signals.push("go.work");
7290
+ }
7291
+ if (await fileExists2(rootDir, "package.json")) {
7292
+ try {
7293
+ const content = await readFile(join(rootDir, "package.json"), "utf-8");
7294
+ const pkg = JSON.parse(content);
7295
+ if (pkg.workspaces) {
7296
+ signals.push("package.json-workspaces");
7297
+ }
7298
+ } catch {}
7299
+ }
7300
+ if (await fileExists2(rootDir, "Cargo.toml")) {
7301
+ try {
7302
+ const content = await readFile(join(rootDir, "Cargo.toml"), "utf-8");
7303
+ if (content.includes("[workspace]")) {
7304
+ signals.push("Cargo.toml-workspace");
7305
+ }
7306
+ } catch {}
7307
+ }
7308
+ return signals;
7309
+ }
7310
+ // src/core/detection/detectors/android.ts
7311
+ async function detectAndroid(rootDir) {
7312
+ const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7313
+ const signals = [];
7314
+ if (await fileExists2(rootDir, "AndroidManifest.xml") || await fileExists2(rootDir, "app/src/main/AndroidManifest.xml")) {
7315
+ signals.push("AndroidManifest.xml");
7316
+ }
7317
+ if (await fileExists2(rootDir, "settings.gradle") || await fileExists2(rootDir, "settings.gradle.kts")) {
7318
+ signals.push("settings.gradle");
7319
+ }
7320
+ if (await fileExists2(rootDir, "gradlew")) {
7321
+ signals.push("gradlew");
7322
+ }
7323
+ return signals;
7324
+ }
7101
7325
  // src/core/detection/project-detector.ts
7102
7326
  async function detectProject(rootDir) {
7103
7327
  const signals = [];
@@ -7138,12 +7362,68 @@ async function detectProject(rootDir) {
7138
7362
  languages.push("php");
7139
7363
  runtimes.push("php");
7140
7364
  packageManagers.push("composer");
7365
+ if (phpSignals.includes("artisan")) {
7366
+ frameworks.push("laravel");
7367
+ }
7141
7368
  }
7142
7369
  const astroSignals = await detectAstro(rootDir);
7143
7370
  if (astroSignals.length > 0) {
7144
7371
  signals.push(...astroSignals);
7145
7372
  frameworks.push("astro");
7146
7373
  }
7374
+ const nextSignals = await detectNext(rootDir);
7375
+ if (nextSignals.length > 0) {
7376
+ signals.push(...nextSignals);
7377
+ languages.push("javascript", "typescript");
7378
+ runtimes.push("node");
7379
+ frameworks.push("nextjs");
7380
+ }
7381
+ const fastapiSignals = await detectFastApi(rootDir);
7382
+ if (fastapiSignals.length > 0) {
7383
+ signals.push(...fastapiSignals);
7384
+ languages.push("python");
7385
+ runtimes.push("python");
7386
+ frameworks.push("fastapi");
7387
+ }
7388
+ const monorepoSignals = await detectMonorepo(rootDir);
7389
+ if (monorepoSignals.length > 0) {
7390
+ signals.push(...monorepoSignals);
7391
+ }
7392
+ const androidSignals = await detectAndroid(rootDir);
7393
+ if (androidSignals.includes("AndroidManifest.xml")) {
7394
+ signals.push(...androidSignals);
7395
+ languages.push("kotlin", "java");
7396
+ runtimes.push("android");
7397
+ frameworks.push("android");
7398
+ }
7399
+ const genericBackendSignals = await detectGenericBackend(rootDir);
7400
+ if (genericBackendSignals.length > 0 && !frameworks.includes("django") && !frameworks.includes("fastapi") && !frameworks.includes("spring")) {
7401
+ signals.push(...genericBackendSignals);
7402
+ frameworks.push("backend");
7403
+ if (genericBackendSignals.includes("go.mod")) {
7404
+ languages.push("go");
7405
+ runtimes.push("go");
7406
+ }
7407
+ if (genericBackendSignals.includes("Cargo.toml")) {
7408
+ languages.push("rust");
7409
+ runtimes.push("rust");
7410
+ }
7411
+ if (genericBackendSignals.includes("Gemfile")) {
7412
+ languages.push("ruby");
7413
+ runtimes.push("ruby");
7414
+ }
7415
+ if (genericBackendSignals.includes("*.csproj")) {
7416
+ languages.push("csharp");
7417
+ runtimes.push("dotnet");
7418
+ }
7419
+ }
7420
+ const genericFrontendSignals = await detectGenericFrontend(rootDir);
7421
+ if (genericFrontendSignals.length > 0 && !frameworks.includes("astro") && !frameworks.includes("nextjs")) {
7422
+ signals.push(...genericFrontendSignals);
7423
+ frameworks.push("frontend");
7424
+ languages.push("javascript", "typescript");
7425
+ runtimes.push("node");
7426
+ }
7147
7427
  const uniqueSignals = [...new Set(signals)];
7148
7428
  return {
7149
7429
  rootDir,
@@ -7173,74 +7453,6 @@ function calculateConfidence(profile) {
7173
7453
  }
7174
7454
  return "low";
7175
7455
  }
7176
- async function detectNode(rootDir) {
7177
- const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7178
- const signals = [];
7179
- if (await fileExists2(rootDir, "package.json")) {
7180
- signals.push("package.json");
7181
- }
7182
- if (await fileExists2(rootDir, "node_modules")) {
7183
- signals.push("node_modules/");
7184
- }
7185
- return signals;
7186
- }
7187
- async function detectBun(rootDir) {
7188
- const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7189
- const signals = [];
7190
- if (await fileExists2(rootDir, "bun.lockb")) {
7191
- signals.push("bun.lockb");
7192
- }
7193
- if (await fileExists2(rootDir, "bun.lock")) {
7194
- signals.push("bun.lock");
7195
- }
7196
- return signals;
7197
- }
7198
- async function detectSpring(rootDir) {
7199
- const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7200
- const signals = [];
7201
- if (await fileExists2(rootDir, "build.gradle") || await fileExists2(rootDir, "build.gradle.kts")) {
7202
- signals.push("build.gradle");
7203
- }
7204
- if (await fileExists2(rootDir, "pom.xml")) {
7205
- signals.push("pom.xml");
7206
- }
7207
- return signals;
7208
- }
7209
- async function detectDjango(rootDir) {
7210
- const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7211
- const signals = [];
7212
- if (await fileExists2(rootDir, "manage.py")) {
7213
- signals.push("manage.py");
7214
- }
7215
- if (await fileExists2(rootDir, "requirements.txt")) {
7216
- signals.push("requirements.txt");
7217
- }
7218
- return signals;
7219
- }
7220
- async function detectAstro(rootDir) {
7221
- const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7222
- const signals = [];
7223
- if (await fileExists2(rootDir, "astro.config.mjs") || await fileExists2(rootDir, "astro.config.ts")) {
7224
- signals.push("astro.config");
7225
- }
7226
- return signals;
7227
- }
7228
- async function detectPhp(rootDir) {
7229
- const { fileExists: fileExists2 } = await Promise.resolve().then(() => (init_safety(), exports_safety));
7230
- const signals = [];
7231
- if (await fileExists2(rootDir, "composer.json")) {
7232
- signals.push("composer.json");
7233
- }
7234
- try {
7235
- const { readdir } = await import("node:fs/promises");
7236
- const entries = await readdir(rootDir, { withFileTypes: true });
7237
- const hasPhpFiles = entries.some((entry) => entry.isFile() && entry.name.endsWith(".php"));
7238
- if (hasPhpFiles) {
7239
- signals.push("*.php");
7240
- }
7241
- } catch {}
7242
- return signals;
7243
- }
7244
7456
 
7245
7457
  // src/commands/detect.command.ts
7246
7458
  async function detectCommand(options) {
@@ -11699,10 +11911,17 @@ async function writeConfig(projectRoot, config = {}, force = false) {
11699
11911
  }
11700
11912
 
11701
11913
  // src/core/presets/preset-resolver.ts
11702
- var CURRENT_PRESET_VERSION = "v0.2.0";
11914
+ var CURRENT_PRESET_VERSION = "v0.3.0";
11703
11915
  function resolvePreset(target, profile) {
11704
11916
  const stack = resolveStack(profile);
11705
- const architecture = profile.signals.length > 0 ? "single-project" : "unknown";
11917
+ const isMonorepo = profile.signals.some((s) => [
11918
+ "pnpm-workspace.yaml",
11919
+ "lerna.json",
11920
+ "go.work",
11921
+ "package.json-workspaces",
11922
+ "Cargo.toml-workspace"
11923
+ ].includes(s));
11924
+ const architecture = isMonorepo ? "monorepo" : profile.signals.length > 0 ? "single-project" : "unknown";
11706
11925
  const warnings = [];
11707
11926
  if (profile.confidence === "low") {
11708
11927
  warnings.push("Detection confidence is low; review the selected preset before applying it.");
@@ -11732,6 +11951,20 @@ function resolveStack(profile) {
11732
11951
  return "django";
11733
11952
  if (profile.frameworks.includes("astro"))
11734
11953
  return "astro";
11954
+ if (profile.frameworks.includes("nextjs"))
11955
+ return "nextjs";
11956
+ if (profile.frameworks.includes("fastapi"))
11957
+ return "fastapi";
11958
+ if (profile.frameworks.includes("backend"))
11959
+ return "backend";
11960
+ if (profile.frameworks.includes("frontend"))
11961
+ return "frontend";
11962
+ if (profile.frameworks.includes("android"))
11963
+ return "android";
11964
+ if (profile.frameworks.includes("laravel"))
11965
+ return "laravel";
11966
+ if (profile.runtimes.includes("php"))
11967
+ return "php";
11735
11968
  if (profile.runtimes.includes("bun"))
11736
11969
  return "bun";
11737
11970
  if (profile.runtimes.includes("node"))
@@ -11741,17 +11974,17 @@ function resolveStack(profile) {
11741
11974
  function resolveAssets(target) {
11742
11975
  switch (target) {
11743
11976
  case "opencode":
11744
- return ["opencode.jsonc", "agents", "commands", "prompts/v0.2.0", "skills"];
11977
+ return ["opencode.jsonc", "agents", "commands", "prompts/v0.3.0", "skills"];
11745
11978
  case "claude":
11746
- return ["CLAUDE.md", "settings.json", "commands", "skills", "agents", "prompts/v0.2.0"];
11979
+ return ["CLAUDE.md", "settings.json", "commands", "skills", "agents", "prompts/v0.3.0"];
11747
11980
  case "codex":
11748
- return ["AGENTS.md", "skills", "prompts/v0.2.0"];
11981
+ return ["AGENTS.md", "skills", "prompts/v0.3.0"];
11749
11982
  case "gemini":
11750
- return ["agents", "prompts/v0.2.0"];
11983
+ return ["agents", "prompts/v0.3.0"];
11751
11984
  case "cursor":
11752
- return ["agents", "prompts/v0.2.0"];
11985
+ return ["agents", "prompts/v0.3.0"];
11753
11986
  case "agy":
11754
- return ["AGENTS.md", "rules", "workflows", "skills", "prompts/v0.2.0"];
11987
+ return ["AGENTS.md", "rules", "workflows", "skills", "prompts/v0.3.0"];
11755
11988
  }
11756
11989
  }
11757
11990