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 +81 -69
- x_ipe/core/scaffold.py +30 -13
- x_ipe/resources/copilot/mcp-config.json +15 -0
- {x_ipe-1.0.20.dist-info → x_ipe-1.0.22.dist-info}/METADATA +1 -1
- {x_ipe-1.0.20.dist-info → x_ipe-1.0.22.dist-info}/RECORD +8 -7
- {x_ipe-1.0.20.dist-info → x_ipe-1.0.22.dist-info}/WHEEL +0 -0
- {x_ipe-1.0.20.dist-info → x_ipe-1.0.22.dist-info}/entry_points.txt +0 -0
- {x_ipe-1.0.20.dist-info → x_ipe-1.0.22.dist-info}/licenses/LICENSE +0 -0
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
|
-
|
|
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
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
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
|
|
|
@@ -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=
|
|
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
|
|
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.
|
|
1247
|
-
x_ipe-1.0.
|
|
1248
|
-
x_ipe-1.0.
|
|
1249
|
-
x_ipe-1.0.
|
|
1250
|
-
x_ipe-1.0.
|
|
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
|
|
File without changes
|
|
File without changes
|