x-ipe 1.0.20__py3-none-any.whl → 1.0.22__py3-none-any.whl

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.
x_ipe/cli/main.py CHANGED
@@ -175,8 +175,13 @@ def info(ctx: click.Context) -> None:
175
175
  is_flag=True,
176
176
  help="Skip copying skills from package.",
177
177
  )
178
+ @click.option(
179
+ "--no-mcp",
180
+ is_flag=True,
181
+ help="Skip MCP config merge prompt.",
182
+ )
178
183
  @click.pass_context
179
- def init(ctx: click.Context, force: bool, dry_run: bool, no_skills: bool) -> None:
184
+ def init(ctx: click.Context, force: bool, dry_run: bool, no_skills: bool, no_mcp: bool) -> None:
180
185
  """Initialize X-IPE in the current project.
181
186
 
182
187
  Creates the standard X-IPE folder structure:
@@ -199,7 +204,6 @@ def init(ctx: click.Context, force: bool, dry_run: bool, no_skills: bool) -> Non
199
204
 
200
205
  # Create folder structure
201
206
  scaffold.create_docs_structure()
202
- scaffold.create_runtime_folder()
203
207
 
204
208
  # Copy skills if requested
205
209
  if not no_skills:
@@ -208,6 +212,9 @@ def init(ctx: click.Context, force: bool, dry_run: bool, no_skills: bool) -> Non
208
212
  # Copy/merge copilot-instructions.md
209
213
  scaffold.copy_copilot_instructions()
210
214
 
215
+ # Copy MCP config (.github/copilot/mcp-config.json)
216
+ scaffold.copy_mcp_config()
217
+
211
218
  # Copy config files (copilot-prompt.json, tools.json, .env.example)
212
219
  scaffold.copy_config_files()
213
220
 
@@ -220,13 +227,9 @@ def init(ctx: click.Context, force: bool, dry_run: bool, no_skills: bool) -> Non
220
227
  # Create config file
221
228
  scaffold.create_config_file()
222
229
 
223
- # Update .gitignore if in git repo
224
- if (project_root / ".git").exists():
225
- scaffold.update_gitignore()
226
-
227
230
  # MCP config merge with user confirmation
228
231
  mcp_servers = scaffold.get_project_mcp_servers()
229
- if mcp_servers and not dry_run:
232
+ if mcp_servers and not dry_run and not no_mcp:
230
233
  click.echo("\n" + "-" * 40)
231
234
  click.echo("MCP Server Configuration")
232
235
  click.echo("-" * 40)
@@ -393,9 +396,14 @@ def serve(ctx: click.Context, host: Optional[str], port: Optional[int],
393
396
  default=None,
394
397
  help="Upgrade only the specified skill.",
395
398
  )
399
+ @click.option(
400
+ "--no-mcp",
401
+ is_flag=True,
402
+ help="Skip MCP config merge prompt.",
403
+ )
396
404
  @click.pass_context
397
405
  def upgrade(ctx: click.Context, force: bool, dry_run: bool,
398
- backup: bool, skill: Optional[str]) -> None:
406
+ backup: bool, skill: Optional[str], no_mcp: bool) -> None:
399
407
  """Upgrade skills from the X-IPE package.
400
408
 
401
409
  Syncs skills from the installed X-IPE package to the local
@@ -412,76 +420,80 @@ def upgrade(ctx: click.Context, force: bool, dry_run: bool,
412
420
 
413
421
  # Check for package skills
414
422
  package_skills = skills_manager.get_package_skills()
423
+ has_skills = bool(package_skills)
424
+
415
425
  if not package_skills:
416
426
  click.echo("No package skills available to sync.")
417
427
  click.echo("X-IPE may not be installed as a package, or skills are not bundled.")
418
- return
419
-
420
- click.echo(f"Package skills available: {len(package_skills)}")
421
-
422
- # Check local skills
423
- local_skills = skills_manager.get_local_skills()
424
- modified = skills_manager.detect_modifications()
428
+ else:
429
+ click.echo(f"Package skills available: {len(package_skills)}")
425
430
 
426
- if local_skills:
427
- click.echo(f"Local skills: {len(local_skills)}")
428
- if modified:
429
- click.echo(f"Modified skills: {len(modified)}")
430
-
431
- # Filter by specific skill if requested
432
- if skill:
433
- package_skills = [s for s in package_skills if s.name == skill]
434
- if not package_skills:
435
- click.echo(f"\nError: Skill '{skill}' not found in package.")
436
- raise click.Abort()
437
- click.echo(f"\nUpgrading skill: {skill}")
438
-
439
- # Check for modifications that would be overwritten
440
- skills_to_warn = []
441
- if not force:
442
- for pkg_skill in package_skills:
443
- local_skill = skills_manager.get_skill_info(pkg_skill.name)
444
- if local_skill and local_skill.source == "local" and local_skill.modified:
445
- skills_to_warn.append(local_skill)
446
-
447
- if skills_to_warn:
448
- click.echo(f"\nThe following skills have local modifications:")
449
- for s in skills_to_warn:
450
- click.echo(f" {s.name}")
431
+ # Only process skills if package skills are available
432
+ if has_skills:
433
+ # Check local skills
434
+ local_skills = skills_manager.get_local_skills()
435
+ modified = skills_manager.detect_modifications()
436
+
437
+ if local_skills:
438
+ click.echo(f"Local skills: {len(local_skills)}")
439
+ if modified:
440
+ click.echo(f"Modified skills: {len(modified)}")
441
+
442
+ # Filter by specific skill if requested
443
+ if skill:
444
+ package_skills = [s for s in package_skills if s.name == skill]
445
+ if not package_skills:
446
+ click.echo(f"\nError: Skill '{skill}' not found in package.")
447
+ raise click.Abort()
448
+ click.echo(f"\nUpgrading skill: {skill}")
449
+
450
+ # Check for modifications that would be overwritten
451
+ skills_to_warn = []
452
+ if not force:
453
+ for pkg_skill in package_skills:
454
+ local_skill = skills_manager.get_skill_info(pkg_skill.name)
455
+ if local_skill and local_skill.source == "local" and local_skill.modified:
456
+ skills_to_warn.append(local_skill)
457
+
458
+ if skills_to_warn:
459
+ click.echo(f"\nThe following skills have local modifications:")
460
+ for s in skills_to_warn:
461
+ click.echo(f" ⚠ {s.name}")
462
+
463
+ if not dry_run:
464
+ if not force:
465
+ if not click.confirm("\nOverwrite modified skills?"):
466
+ click.echo("Aborted.")
467
+ # Continue to MCP config section
451
468
 
452
469
  if not dry_run:
453
- if not force:
454
- if not click.confirm("\nOverwrite modified skills?"):
455
- click.echo("Aborted.")
456
- return
457
-
458
- if dry_run:
459
- click.echo("\nDry run - would sync:")
460
- for pkg_skill in package_skills:
461
- click.echo(f" → {pkg_skill.name}")
462
- click.echo("\nRun without --dry-run to apply changes.")
463
- return
464
-
465
- # Perform the sync
466
- synced = skills_manager.sync_from_package(
467
- skill_name=skill,
468
- backup=backup
469
- )
470
-
471
- if synced:
472
- click.echo(f"\n✓ Synced {len(synced)} skill(s):")
473
- for name in synced:
474
- click.echo(f" ✓ {name}")
475
- else:
476
- click.echo("\nNo skills were synced.")
477
-
478
- if backup and skills_to_warn:
479
- click.echo(f"\nBackups created in: {project_root / '.x-ipe' / 'backups'}")
470
+ # Perform the sync
471
+ synced = skills_manager.sync_from_package(
472
+ skill_name=skill,
473
+ backup=backup
474
+ )
475
+
476
+ if synced:
477
+ click.echo(f"\n✓ Synced {len(synced)} skill(s):")
478
+ for name in synced:
479
+ click.echo(f" {name}")
480
+ else:
481
+ click.echo("\nNo skills were synced.")
482
+
483
+ if backup and skills_to_warn:
484
+ click.echo(f"\nBackups created in: {project_root / '.x-ipe' / 'backups'}")
485
+ else:
486
+ click.echo("\nDry run - would sync:")
487
+ for pkg_skill in package_skills:
488
+ click.echo(f" → {pkg_skill.name}")
489
+
490
+ # Copy/update MCP config from package, then merge to global
491
+ scaffold = ScaffoldManager(project_root, dry_run=dry_run, force=force)
492
+ scaffold.copy_mcp_config()
480
493
 
481
494
  # MCP config merge with user confirmation
482
- scaffold = ScaffoldManager(project_root, dry_run=dry_run, force=force)
483
495
  mcp_servers = scaffold.get_project_mcp_servers()
484
- if mcp_servers and not dry_run:
496
+ if mcp_servers and not dry_run and not no_mcp:
485
497
  click.echo("\n" + "-" * 40)
486
498
  click.echo("MCP Server Configuration")
487
499
  click.echo("-" * 40)
x_ipe/core/scaffold.py CHANGED
@@ -12,17 +12,12 @@ class ScaffoldManager:
12
12
  DOCS_STRUCTURE = [
13
13
  "x-ipe-docs/requirements",
14
14
  "x-ipe-docs/planning",
15
- "x-ipe-docs/features",
16
15
  "x-ipe-docs/ideas",
17
16
  "x-ipe-docs/config",
18
17
  "x-ipe-docs/themes",
19
18
  ]
20
19
 
21
- GITIGNORE_ENTRIES = [
22
- "# X-IPE Runtime (managed by x-ipe)",
23
- ".x-ipe/",
24
- "",
25
- ]
20
+ GITIGNORE_ENTRIES: list = [] # No X-IPE specific gitignore entries needed
26
21
 
27
22
  def __init__(self, project_root: Path, dry_run: bool = False, force: bool = False):
28
23
  """Initialize ScaffoldManager.
@@ -145,6 +140,28 @@ class ScaffoldManager:
145
140
  shutil.copy2(source, target)
146
141
  self.created.append(target)
147
142
 
143
+ def copy_mcp_config(self) -> None:
144
+ """Copy mcp-config.json to .github/copilot/."""
145
+ source = self._get_resource_path("copilot")
146
+ if source is None or not source.exists():
147
+ return
148
+
149
+ source_file = source / "mcp-config.json"
150
+ if not source_file.exists():
151
+ return
152
+
153
+ target = self.project_root / ".github" / "copilot" / "mcp-config.json"
154
+
155
+ if target.exists():
156
+ if not self.force:
157
+ self.skipped.append(target)
158
+ return
159
+
160
+ if not self.dry_run:
161
+ target.parent.mkdir(parents=True, exist_ok=True)
162
+ shutil.copy2(source_file, target)
163
+ self.created.append(target)
164
+
148
165
  def get_project_mcp_servers(self) -> dict:
149
166
  """Get MCP servers from project's .github/copilot/mcp-config.json.
150
167
 
@@ -366,11 +383,12 @@ server:
366
383
  return
367
384
 
368
385
  # Append X-IPE entries
369
- if not content.endswith("\n"):
370
- content += "\n"
371
- content += "\n".join(self.GITIGNORE_ENTRIES)
372
- gitignore_path.write_text(content)
373
- self.created.append(gitignore_path)
386
+ if self.GITIGNORE_ENTRIES:
387
+ if not content.endswith("\n"):
388
+ content += "\n"
389
+ content += "\n".join(self.GITIGNORE_ENTRIES)
390
+ gitignore_path.write_text(content)
391
+ self.created.append(gitignore_path)
374
392
 
375
393
  def scaffold_all(self) -> Tuple[List[Path], List[Path]]:
376
394
  """Run all scaffolding operations.
@@ -379,14 +397,13 @@ server:
379
397
  Tuple of (created_paths, skipped_paths).
380
398
  """
381
399
  self.create_docs_structure()
382
- self.create_runtime_folder()
383
400
  self.copy_skills()
384
401
  self.copy_copilot_instructions()
402
+ self.copy_mcp_config()
385
403
  self.copy_config_files()
386
404
  self.copy_planning_templates()
387
405
  self.copy_themes()
388
406
  self.create_config_file()
389
- self.update_gitignore()
390
407
  self.merge_mcp_config()
391
408
  return self.get_summary()
392
409
 
@@ -0,0 +1,15 @@
1
+ {
2
+ "mcpServers": {
3
+ "chrome-devtools": {
4
+ "type": "local",
5
+ "command": "npx",
6
+ "tools": [
7
+ "*"
8
+ ],
9
+ "args": [
10
+ "-y",
11
+ "chrome-devtools-mcp@latest"
12
+ ]
13
+ }
14
+ }
15
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: x-ipe
3
- Version: 1.0.20
3
+ Version: 1.0.22
4
4
  Summary: X-IPE: AI-powered development framework
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -4,12 +4,12 @@ x_ipe/app.py,sha256=EkOYKxF-nKnRG2ev6tC-Fw5EHikWJyVxO7hfLAouJPE,5262
4
4
  x_ipe/app.py.bak,sha256=WRuPkrHkS77BAMFYV5uVS2Xl2-QDwQE0KdgTyJHxMpk,45732
5
5
  x_ipe/config.py,sha256=NYLhpfhxVMZETHW2SNej3sVoUutuPzTGrQTsJTuie80,1685
6
6
  x_ipe/cli/__init__.py,sha256=yAg0J4ULFDPnVbtFOORPAcWT_SwjW4CK9bNDd-c2xPg,80
7
- x_ipe/cli/main.py,sha256=sVX-T_w-sr-TtPpzdrYXlWWYOUKLy-sV_lE1mT8Cg5g,16160
7
+ x_ipe/cli/main.py,sha256=07MEkeGHsvUSKarqJ3dy4tsD0-ZNDgxj4VKGddkivdk,16792
8
8
  x_ipe/core/__init__.py,sha256=aB6UCmjC3QRrJfHPTV0uBqGHnnnQncX6rl4i6PKI5oo,556
9
9
  x_ipe/core/config.py,sha256=9JmWcVqBvfcqwkWnfx4WvmSi65JVnfhERE5w6pBZSRI,5590
10
10
  x_ipe/core/hashing.py,sha256=brF5W8fHZVxADkRqztoBg9yNkN8PpbLI7WWrsRY54Zg,3573
11
11
  x_ipe/core/paths.py,sha256=bTXouYy0-_k7A1mNaRg2MLWnfDuzZesPlsY9Rg6nMOo,2562
12
- x_ipe/core/scaffold.py,sha256=-Jw6jI6oMcwWJ5JMB2iENXxK2ywDhAsx-ADjrd6K2Lo,14337
12
+ x_ipe/core/scaffold.py,sha256=tc7QfRMSsZpDUndIpQ-1XBMY9zVfr9UZ4M_HMaPi6MY,15032
13
13
  x_ipe/core/skills.py,sha256=sZSk-eDLYxvpa9J1a7HIv3xuwrDLinvL7tLIcmTXixc,8535
14
14
  x_ipe/handlers/__init__.py,sha256=asR3VNYqVYbOowET6Nxn82S7hM52ySEuCmqAaKaZ78E,359
15
15
  x_ipe/handlers/terminal_handlers.py,sha256=1vc34FAdaBL2J_wi3BSlGKw6HmWADXf83O-ECTO8Ov0,4463
@@ -17,6 +17,7 @@ x_ipe/handlers/voice_handlers.py,sha256=Eo5qzQR4WIbG-Jm5zmQHro4kAb-1mbnUPIDnGcop
17
17
  x_ipe/resources/config/.env.example,sha256=uG9RiX2q9wd-RS-2kg8gqiYrZwNtYHjJINzrIIk3_1I,1192
18
18
  x_ipe/resources/config/copilot-prompt.json,sha256=R6aG7x63Kw_YHIZgs0QVNMA1w4DBY8ilTWBhSYTrAxo,709
19
19
  x_ipe/resources/config/tools.json,sha256=WilFs7YfsbPEhml10ksFcba61F1OU-iMqYocogqTefE,595
20
+ x_ipe/resources/copilot/mcp-config.json,sha256=cSjfY0a1ewqwnTMbTJNYk1UOZrPKCS43xKvOwP7DcjQ,216
20
21
  x_ipe/resources/planning/features.md,sha256=NhWPI3eeC7EN5yqWwR-7pKbLrbBJ5JVKDtWoiYOOiAY,981
21
22
  x_ipe/resources/planning/task-board.md,sha256=y_TZ7SZxCZCRUTs-g04BWewSb3CnX_lXY3UP7_5vkF4,2028
22
23
  x_ipe/resources/themes/theme-default/component-visualization.html,sha256=0Ykm6QxVsEyk4Xpt7uNggZnqD1UxAR0vN3qtLbb3OLk,27908
@@ -1243,8 +1244,8 @@ x_ipe/resources/skills/x-ipe-skill-creator/templates/references/examples.md,sha2
1243
1244
  x_ipe/resources/skills/xlsx/LICENSE.txt,sha256=efbY9bQnJS-jscEezb22v2ELlE91MLTeePdw84dBz6o,1467
1244
1245
  x_ipe/resources/skills/xlsx/SKILL.md,sha256=AgzNtZMiV7ZsY47BFX6iSNV_pSyMAfH2i1WbWXDH3zU,10632
1245
1246
  x_ipe/resources/skills/xlsx/recalc.py,sha256=qx7wyUU2uyO2xqPTJ2mwQB7DzIXnPCR9V03YTsc68V0,6408
1246
- x_ipe-1.0.20.dist-info/METADATA,sha256=3aKo1TZuRFH4JY1Ex8Fk-yRqNAXf5QCKnByjHevL5A4,637
1247
- x_ipe-1.0.20.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
1248
- x_ipe-1.0.20.dist-info/entry_points.txt,sha256=b787rsvZAIjLgjBzB87D_BE8yu6DCqBqv9zv4F6_j6M,41
1249
- x_ipe-1.0.20.dist-info/licenses/LICENSE,sha256=8lS-M88bBvSI9_8kauYvQRu03WEMnj1Q5KoxOFKFnhc,1062
1250
- x_ipe-1.0.20.dist-info/RECORD,,
1247
+ x_ipe-1.0.22.dist-info/METADATA,sha256=93yC-kRYsIc9w_xnXDFHPiQSGcEC-dclRpvCUqbe19o,637
1248
+ x_ipe-1.0.22.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
1249
+ x_ipe-1.0.22.dist-info/entry_points.txt,sha256=b787rsvZAIjLgjBzB87D_BE8yu6DCqBqv9zv4F6_j6M,41
1250
+ x_ipe-1.0.22.dist-info/licenses/LICENSE,sha256=8lS-M88bBvSI9_8kauYvQRu03WEMnj1Q5KoxOFKFnhc,1062
1251
+ x_ipe-1.0.22.dist-info/RECORD,,
File without changes