IncludeCPP 4.0.0__py3-none-any.whl → 4.2.2__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.
@@ -9,8 +9,12 @@ import re
9
9
  import urllib.request
10
10
  import urllib.error
11
11
  from pathlib import Path
12
+ from colorama import init as colorama_init, Fore, Style
12
13
  from .config_parser import CppProjectConfig
13
14
 
15
+ # Initialize colorama for Windows ANSI color support
16
+ colorama_init()
17
+
14
18
 
15
19
  def _is_experimental_enabled() -> bool:
16
20
  """Check if experimental features (cppy, ai) are enabled."""
@@ -148,113 +152,276 @@ def _render_readme_with_colors(readme_text):
148
152
  click.echo(" " + stripped)
149
153
 
150
154
 
151
- def _show_changelog():
152
- """Extract and display changelog from README."""
155
+ def _get_changelog_path():
156
+ """Get path to CHANGELOG.md file."""
157
+ # Try package location first
158
+ package_dir = Path(__file__).parent.parent
159
+ changelog_path = package_dir / 'CHANGELOG.md'
160
+ if changelog_path.exists():
161
+ return changelog_path
162
+ # Fallback to current directory
163
+ cwd_path = Path.cwd() / 'CHANGELOG.md'
164
+ if cwd_path.exists():
165
+ return cwd_path
166
+ return None
167
+
168
+
169
+ def _parse_changelog_entries(content: str) -> list:
170
+ """Parse changelog into list of version entries.
171
+
172
+ Returns list of tuples: (version_header, content_lines)
173
+ """
174
+ entries = []
175
+ lines = content.split('\n')
176
+ current_version = None
177
+ current_lines = []
178
+
179
+ for line in lines:
180
+ # Match version headers like "## v4.2.0 (2025-01-08)"
181
+ if line.startswith('## '):
182
+ # Save previous entry
183
+ if current_version:
184
+ entries.append((current_version, current_lines))
185
+ current_version = line[3:].strip()
186
+ current_lines = []
187
+ elif current_version:
188
+ current_lines.append(line)
189
+
190
+ # Save last entry
191
+ if current_version:
192
+ entries.append((current_version, current_lines))
193
+
194
+ return entries
195
+
196
+
197
+ def _show_changelog(count: int = 2, show_all: bool = False):
198
+ """Display changelog from local CHANGELOG.md file.
199
+
200
+ Args:
201
+ count: Number of version entries to show (default 2)
202
+ show_all: If True, show all entries
203
+ """
153
204
  _safe_echo("=" * 70)
154
205
  _safe_echo("IncludeCPP Changelog", fg='cyan', bold=True)
155
206
  _safe_echo("=" * 70)
156
207
  _safe_echo("")
157
208
 
158
- try:
159
- _safe_echo(" Fetching changelog from PyPI...", nl=False)
160
- req = urllib.request.Request(
161
- "https://pypi.org/pypi/IncludeCPP/json",
162
- headers={"User-Agent": "IncludeCPP-CLI"}
163
- )
164
- with urllib.request.urlopen(req, timeout=15) as response:
165
- raw_data = response.read().decode('utf-8')
166
-
167
- data = json.loads(raw_data)
168
- description = data.get('info', {}).get('description', '')
169
- version = data.get('info', {}).get('version', 'unknown')
170
- _safe_echo(" OK", fg='green')
209
+ changelog_path = _get_changelog_path()
210
+ if not changelog_path:
211
+ _safe_echo("CHANGELOG.md not found.", fg='yellow')
171
212
  _safe_echo("")
213
+ _safe_echo("=" * 70)
214
+ return
215
+
216
+ try:
217
+ content = changelog_path.read_text(encoding='utf-8')
218
+ entries = _parse_changelog_entries(content)
172
219
 
173
- if description:
174
- _safe_echo(f"Current Version: {version}", fg='green', bold=True)
220
+ if not entries:
221
+ _safe_echo("No changelog entries found.", fg='yellow')
175
222
  _safe_echo("")
223
+ _safe_echo("=" * 70)
224
+ return
176
225
 
177
- lines = description.split('\n')
178
- in_changelog = False
179
- changelog_lines = []
226
+ # Determine how many to show
227
+ if show_all:
228
+ entries_to_show = entries
229
+ else:
230
+ entries_to_show = entries[:count]
231
+
232
+ _safe_echo(f"Showing {len(entries_to_show)} of {len(entries)} releases", fg='bright_black')
233
+ _safe_echo("")
234
+
235
+ for version, lines in entries_to_show:
236
+ _safe_echo(version, fg='yellow', bold=True)
180
237
 
181
238
  for line in lines:
182
- if line.strip().startswith('# Changelog'):
183
- in_changelog = True
239
+ stripped = line.strip()
240
+ if not stripped:
184
241
  continue
185
- if in_changelog:
186
- if line.startswith('# ') and not line.startswith('## '):
187
- break
188
- changelog_lines.append(line)
189
-
190
- if changelog_lines:
191
- for line in changelog_lines:
192
- stripped = line.strip()
193
- if stripped.startswith('## '):
194
- _safe_echo(stripped[3:], fg='yellow', bold=True)
195
- elif stripped.startswith('- '):
196
- _safe_echo(" " + stripped)
197
- elif stripped:
198
- _safe_echo(" " + stripped)
242
+ elif stripped.startswith('### '):
243
+ _safe_echo(" " + stripped[4:], fg='cyan', bold=True)
244
+ elif stripped.startswith('- '):
245
+ _safe_echo(" " + stripped)
246
+ elif stripped.startswith('---'):
247
+ _safe_echo("")
248
+ else:
249
+ _safe_echo(" " + stripped)
250
+
251
+ _safe_echo("")
252
+
253
+ if not show_all and len(entries) > count:
254
+ _safe_echo(f"Use --changelog --all to see all {len(entries)} releases", fg='bright_black')
255
+ _safe_echo(f"Or --changelog --{len(entries)} to see specific count", fg='bright_black')
256
+
257
+ except Exception as e:
258
+ _safe_echo(f"Error reading changelog: {e}", fg='red', err=True)
259
+
260
+ _safe_echo("")
261
+ _safe_echo("=" * 70)
262
+
263
+
264
+ def _get_doc_path():
265
+ """Get path to DOCUMENTATION.md file."""
266
+ package_dir = Path(__file__).parent.parent
267
+ doc_path = package_dir / 'DOCUMENTATION.md'
268
+ if doc_path.exists():
269
+ return doc_path
270
+ # Fallback to current directory
271
+ cwd_path = Path.cwd() / 'DOCUMENTATION.md'
272
+ if cwd_path.exists():
273
+ return cwd_path
274
+ return None
275
+
276
+
277
+ def _show_doc(search_term: str = None):
278
+ """Display documentation from local DOCUMENTATION.md file.
279
+
280
+ Args:
281
+ search_term: Optional search term to filter content
282
+ """
283
+ _safe_echo("=" * 70)
284
+ _safe_echo("IncludeCPP Documentation", fg='cyan', bold=True)
285
+ _safe_echo("=" * 70)
286
+ _safe_echo("")
287
+
288
+ doc_path = _get_doc_path()
289
+ if not doc_path:
290
+ _safe_echo("DOCUMENTATION.md not found.", fg='yellow')
291
+ _safe_echo("")
292
+ _safe_echo("=" * 70)
293
+ return
294
+
295
+ try:
296
+ content = doc_path.read_text(encoding='utf-8')
297
+
298
+ if search_term:
299
+ # Search mode - find matching sections
300
+ _safe_echo(f"Searching for: '{search_term}'", fg='green', bold=True)
301
+ _safe_echo("")
302
+
303
+ # Split into sections (## headers)
304
+ sections = re.split(r'(?=^## )', content, flags=re.MULTILINE)
305
+
306
+ # Find matching sections
307
+ matches = []
308
+ for section in sections:
309
+ if search_term.lower() in section.lower():
310
+ # Get section title
311
+ title_match = re.match(r'^## (.+)$', section, re.MULTILINE)
312
+ if title_match:
313
+ matches.append((title_match.group(1), section))
314
+
315
+ if matches:
316
+ _safe_echo(f"Found {len(matches)} matching section(s):", fg='green')
317
+ _safe_echo("")
318
+
319
+ for title, section_content in matches[:5]: # Limit to 5
320
+ _safe_echo(f"## {title}", fg='yellow', bold=True)
321
+
322
+ # Highlight search term
323
+ lines = section_content.split('\n')
324
+ for line in lines[:30]: # Limit lines per section
325
+ stripped = line.strip()
326
+ if not stripped or stripped.startswith('## '):
327
+ continue
328
+
329
+ # Highlight matches
330
+ if search_term.lower() in stripped.lower():
331
+ # Simple highlight - wrap matches
332
+ highlighted = re.sub(
333
+ f'({re.escape(search_term)})',
334
+ lambda m: click.style(m.group(1), fg='green', bold=True),
335
+ stripped,
336
+ flags=re.IGNORECASE
337
+ )
338
+ _safe_echo(" " + highlighted)
339
+ else:
340
+ _safe_echo(" " + stripped)
341
+
342
+ _safe_echo("")
343
+ _safe_echo("-" * 40)
344
+ _safe_echo("")
345
+
346
+ if len(matches) > 5:
347
+ _safe_echo(f"... and {len(matches) - 5} more sections", fg='bright_black')
199
348
  else:
200
- _safe_echo("No changelog found in README.", fg='yellow')
349
+ _safe_echo(f"No matches found for '{search_term}'", fg='yellow')
350
+ _safe_echo("")
351
+ _safe_echo("Try searching for:")
352
+ _safe_echo(" - Commands: init, rebuild, plugin, auto")
353
+ _safe_echo(" - Features: CSSL, AI, CPPY, classes, functions")
354
+ _safe_echo(" - Syntax: $, @, <==, define, class")
201
355
  else:
202
- _safe_echo("No documentation available.", fg='yellow')
356
+ # Full documentation display
357
+ _safe_echo("+" + "=" * 68 + "+", fg='red', bold=True)
358
+ _safe_echo("| IMPORTANT: All C++ code MUST be in 'namespace includecpp { }' |", fg='red', bold=True)
359
+ _safe_echo("+" + "=" * 68 + "+", fg='red', bold=True)
360
+ _safe_echo("")
361
+ _render_readme_with_colors(content)
203
362
 
204
363
  except Exception as e:
205
- _safe_echo(" FAILED", fg='red')
206
- _safe_echo("")
207
- _safe_echo("Could not fetch changelog: " + str(e), fg='red', err=True)
364
+ _safe_echo(f"Error reading documentation: {e}", fg='red', err=True)
208
365
 
209
366
  _safe_echo("")
210
367
  _safe_echo("=" * 70)
211
368
 
212
369
 
213
370
  @click.group(invoke_without_command=True)
214
- @click.option('--doc', 'show_doc', is_flag=True, help='Show documentation (README) with color highlighting')
215
- @click.option('--changelog', 'show_changelog', is_flag=True, help='Show changelog for the latest version')
371
+ @click.option('--doc', 'doc_search', is_flag=False, flag_value='__SHOW_ALL__', default=None, help='Show documentation. Use --doc "term" to search.')
372
+ @click.option('--changelog', 'show_changelog', is_flag=True, help='Show changelog (last 2 releases by default)')
373
+ @click.option('--all', 'changelog_all', is_flag=True, help='Show all changelog entries (use with --changelog)')
374
+ @click.option('--1', 'changelog_1', is_flag=True, hidden=True)
375
+ @click.option('--2', 'changelog_2', is_flag=True, hidden=True)
376
+ @click.option('--3', 'changelog_3', is_flag=True, hidden=True)
377
+ @click.option('--4', 'changelog_4', is_flag=True, hidden=True)
378
+ @click.option('--5', 'changelog_5', is_flag=True, hidden=True)
379
+ @click.option('--6', 'changelog_6', is_flag=True, hidden=True)
380
+ @click.option('--7', 'changelog_7', is_flag=True, hidden=True)
381
+ @click.option('--8', 'changelog_8', is_flag=True, hidden=True)
382
+ @click.option('--9', 'changelog_9', is_flag=True, hidden=True)
383
+ @click.option('--10', 'changelog_10', is_flag=True, hidden=True)
216
384
  @click.pass_context
217
- def cli(ctx, show_doc, show_changelog):
218
- """IncludeCPP - C++ Performance in Python, Zero Hassle"""
219
- if show_changelog:
220
- _show_changelog()
221
- ctx.exit(0)
222
- if show_doc:
223
- click.echo("=" * 70)
224
- click.secho("IncludeCPP Documentation", fg='cyan', bold=True)
225
- click.echo("=" * 70)
226
- click.echo()
227
-
228
- try:
229
- click.echo(" Fetching documentation from PyPI...", nl=False)
230
- req = urllib.request.Request(
231
- "https://pypi.org/pypi/IncludeCPP/json",
232
- headers={"User-Agent": "IncludeCPP-CLI"}
233
- )
234
- with urllib.request.urlopen(req, timeout=15) as response:
235
- raw_data = response.read().decode('utf-8')
385
+ def cli(ctx, doc_search, show_changelog, changelog_all, changelog_1, changelog_2, changelog_3,
386
+ changelog_4, changelog_5, changelog_6, changelog_7, changelog_8, changelog_9, changelog_10):
387
+ """IncludeCPP - C++ Performance in Python, Zero Hassle
236
388
 
237
- data = json.loads(raw_data)
238
- description = data.get('info', {}).get('description', '')
239
- click.secho(" OK", fg='green')
240
- click.echo()
241
-
242
- if description:
243
- click.secho("+" + "=" * 68 + "+", fg='red', bold=True)
244
- click.secho("| IMPORTANT: All C++ code MUST be in 'namespace includecpp { }' |", fg='red', bold=True)
245
- click.secho("| This is REQUIRED for IncludeCPP to work! |", fg='red', bold=True)
246
- click.secho("+" + "=" * 68 + "+", fg='red', bold=True)
247
- click.echo()
248
- _render_readme_with_colors(description)
249
- else:
250
- click.secho("No documentation available.", fg='yellow')
389
+ \b
390
+ Documentation:
391
+ includecpp --doc Show full documentation
392
+ includecpp --doc "CSSL" Search documentation for "CSSL"
393
+ includecpp --doc "rebuild" Search documentation for "rebuild"
251
394
 
252
- except Exception as e:
253
- click.secho(" FAILED", fg='red')
254
- click.echo()
255
- click.secho("Could not fetch documentation: " + str(e), fg='red', err=True)
395
+ \b
396
+ Changelog:
397
+ includecpp --changelog Show last 2 releases
398
+ includecpp --changelog --all Show all releases
399
+ includecpp --changelog --5 Show last 5 releases
400
+ """
401
+ # Handle changelog
402
+ if show_changelog:
403
+ # Determine count from --N flags
404
+ count = 2 # default
405
+ if changelog_all:
406
+ _show_changelog(show_all=True)
407
+ else:
408
+ if changelog_1: count = 1
409
+ elif changelog_2: count = 2
410
+ elif changelog_3: count = 3
411
+ elif changelog_4: count = 4
412
+ elif changelog_5: count = 5
413
+ elif changelog_6: count = 6
414
+ elif changelog_7: count = 7
415
+ elif changelog_8: count = 8
416
+ elif changelog_9: count = 9
417
+ elif changelog_10: count = 10
418
+ _show_changelog(count=count)
419
+ ctx.exit(0)
256
420
 
257
- click.echo("=" * 70)
421
+ # Handle documentation - --doc or --doc "search"
422
+ if doc_search is not None:
423
+ search_term = None if doc_search == '__SHOW_ALL__' else doc_search
424
+ _show_doc(search_term)
258
425
  ctx.exit(0)
259
426
 
260
427
  # If no subcommand is given, show help
@@ -5195,7 +5362,7 @@ def ai_ask(question, module_name, files, all_modules, exclude, think_mode, think
5195
5362
  verbose.phase('init', 'Setting up context')
5196
5363
  verbose.detail('Question', question[:50] + '...' if len(question) > 50 else question)
5197
5364
  verbose.detail('Mode', mode)
5198
- verbose.detail('Model', ai_mgr.config.get('model', 'gpt-5'))
5365
+ verbose.detail('Model', ai_mgr.config.get('model', 'gpt-4o'))
5199
5366
 
5200
5367
  project_root = Path.cwd()
5201
5368
  plugins_dir = project_root / "plugins"
@@ -5216,7 +5383,7 @@ def ai_ask(question, module_name, files, all_modules, exclude, think_mode, think
5216
5383
  files=len(source_files) + len(plugin_files),
5217
5384
  lines=total_lines,
5218
5385
  tokens=total_lines * 4, # Approximate
5219
- model=ai_mgr.config.get('model', 'gpt-5')
5386
+ model=ai_mgr.config.get('model', 'gpt-4o')
5220
5387
  )
5221
5388
 
5222
5389
  if use_websearch:
@@ -6452,7 +6619,7 @@ def _convert_with_ai(content: str, module_name: str, source_file,
6452
6619
  )
6453
6620
 
6454
6621
  if not success:
6455
- ai_verbose.warning("AI conversion failed, using standard converter")
6622
+ ai_verbose.warning(f"AI conversion failed: {response}")
6456
6623
  ai_verbose.phase('fallback', 'Falling back to standard conversion')
6457
6624
  ai_verbose.end(success=True, message="Fallback successful")
6458
6625
  if to_cpp:
@@ -7320,7 +7487,6 @@ def exec_repl(lang, path, import_all):
7320
7487
  code_lines = imports + [''] + lines if imports else lines
7321
7488
 
7322
7489
  click.echo()
7323
- click.secho("--- Output ---", fg='green')
7324
7490
 
7325
7491
  if is_python:
7326
7492
  # Execute Python code
@@ -7443,9 +7609,6 @@ def exec_repl(lang, path, import_all):
7443
7609
  except Exception:
7444
7610
  pass
7445
7611
 
7446
- click.echo()
7447
- click.secho("--------------", fg='green')
7448
-
7449
7612
 
7450
7613
  # ============================================================================
7451
7614
  # CSSL - Hidden Command Group
@@ -7526,19 +7689,12 @@ def _cssl_execute(path, code):
7526
7689
  source = '\n'.join(lines)
7527
7690
 
7528
7691
  # Execute
7529
- click.secho("--- Output ---", fg='green')
7530
7692
  try:
7531
7693
  result = cssl_lang.run(source)
7532
-
7533
- # Output is already printed to stdout during execution via runtime.output()
7534
- # Don't print "Result:" automatically - users should use printl() for output
7535
- # This prevents unwanted output for function calls like: Function();
7536
- pass
7537
-
7538
7694
  except Exception as e:
7539
- click.secho(f"CSSL Error: {e}", fg='red')
7540
-
7541
- click.secho("--------------", fg='green')
7695
+ error_msg = str(e)
7696
+ # Clean display - single CSSL Error: prefix with colorama
7697
+ click.echo(f"{Fore.RED}CSSL Error: {error_msg}{Style.RESET_ALL}")
7542
7698
 
7543
7699
 
7544
7700
  @cssl.command(name='makemodule')
@@ -7926,6 +8082,457 @@ def cssl_vscode():
7926
8082
  click.secho(f"Installation failed: {e}", fg='red')
7927
8083
 
7928
8084
 
8085
+ @cssl.command(name='sdk')
8086
+ @click.argument('lang', required=False, default=None)
8087
+ @click.option('--doc', is_flag=True, help='Show SDK documentation')
8088
+ def cssl_sdk(lang, doc):
8089
+ """Generate SDK files for cross-language instance sharing.
8090
+
8091
+ \b
8092
+ Usage:
8093
+ includecpp cssl sdk cpp # Create C++ SDK in ./sdk/cpp/
8094
+ includecpp cssl sdk java # Create Java SDK in ./sdk/java/
8095
+ includecpp cssl sdk csharp # Create C# SDK in ./sdk/csharp/
8096
+ includecpp cssl sdk js # Create JavaScript SDK in ./sdk/javascript/
8097
+ includecpp cssl sdk all # Create all SDKs
8098
+ includecpp cssl sdk --doc # Show SDK documentation
8099
+
8100
+ \b
8101
+ Languages:
8102
+ cpp, c++ C++ header-only SDK
8103
+ java Java SDK (com.includecpp.CSSL)
8104
+ csharp, c# C# SDK (IncludeCPP.CSSL)
8105
+ js, javascript JavaScript/Node.js SDK
8106
+ all All languages
8107
+
8108
+ \b
8109
+ Cross-Language Instance Sharing:
8110
+ Share instances from any language and access them in CSSL using
8111
+ the lang$InstanceName syntax:
8112
+
8113
+ C++: CSSL::share("Engine", &engine); -> cpp$Engine
8114
+ Java: CSSL.share("Service", svc); -> java$Service
8115
+ C#: CSSL.Share("Handler", hdl); -> csharp$Handler
8116
+ JS: CSSL.share('Processor', proc); -> js$Processor
8117
+ """
8118
+ from pathlib import Path as PathLib
8119
+ import shutil
8120
+
8121
+ # Show documentation if --doc flag is set
8122
+ if doc or lang == 'doc':
8123
+ _show_sdk_documentation()
8124
+ return
8125
+
8126
+ if lang is None:
8127
+ # Show help
8128
+ click.secho("CSSL Multi-Language SDK Generator", fg='cyan', bold=True)
8129
+ click.echo()
8130
+ click.echo("Usage:")
8131
+ click.echo(" includecpp cssl sdk <lang> Create SDK for language")
8132
+ click.echo(" includecpp cssl sdk --doc Show documentation")
8133
+ click.echo()
8134
+ click.echo("Languages:")
8135
+ click.echo(" cpp, c++ C++ header-only SDK")
8136
+ click.echo(" java Java SDK")
8137
+ click.echo(" csharp, c# C# SDK")
8138
+ click.echo(" js, javascript JavaScript SDK")
8139
+ click.echo(" all All SDKs")
8140
+ return
8141
+
8142
+ # Normalize language name
8143
+ lang_map = {
8144
+ 'cpp': 'cpp', 'c++': 'cpp',
8145
+ 'java': 'java',
8146
+ 'csharp': 'csharp', 'c#': 'csharp', 'cs': 'csharp',
8147
+ 'js': 'javascript', 'javascript': 'javascript',
8148
+ 'all': 'all'
8149
+ }
8150
+
8151
+ normalized = lang_map.get(lang.lower())
8152
+ if normalized is None:
8153
+ click.secho(f"Unknown language: {lang}", fg='red')
8154
+ click.echo("Supported: cpp, java, csharp, js, all")
8155
+ return
8156
+
8157
+ # Find source SDK directory in package
8158
+ package_dir = PathLib(__file__).parent.parent
8159
+ source_sdk_dir = package_dir / 'sdk'
8160
+
8161
+ # Target SDK directory
8162
+ target_sdk_dir = PathLib.cwd() / 'sdk'
8163
+
8164
+ langs_to_create = ['cpp', 'java', 'csharp', 'javascript'] if normalized == 'all' else [normalized]
8165
+
8166
+ click.secho("Creating CSSL SDK files...", fg='cyan', bold=True)
8167
+ click.echo()
8168
+
8169
+ for lang_name in langs_to_create:
8170
+ _create_sdk_for_language(target_sdk_dir, lang_name)
8171
+
8172
+ click.echo()
8173
+ click.secho("SDK created successfully!", fg='green', bold=True)
8174
+ click.echo()
8175
+ click.echo("Next steps:")
8176
+ click.echo(" 1. Copy SDK file(s) to your project")
8177
+ click.echo(" 2. Import and use CSSL.share() in your code")
8178
+ click.echo(" 3. Access instances in CSSL via lang$InstanceName")
8179
+ click.echo()
8180
+ click.echo("Documentation: includecpp cssl sdk --doc")
8181
+
8182
+
8183
+ def _create_sdk_for_language(target_dir, lang_name):
8184
+ """Create SDK files for a specific language."""
8185
+ from pathlib import Path as PathLib
8186
+
8187
+ # SDK content for each language
8188
+ sdk_content = {
8189
+ 'cpp': _get_cpp_sdk_content(),
8190
+ 'java': _get_java_sdk_content(),
8191
+ 'csharp': _get_csharp_sdk_content(),
8192
+ 'javascript': _get_js_sdk_content(),
8193
+ }
8194
+
8195
+ sdk_paths = {
8196
+ 'cpp': ('cpp', 'includecpp.h'),
8197
+ 'java': ('java/src/com/includecpp', 'CSSL.java'),
8198
+ 'csharp': ('csharp', 'IncludeCPP.cs'),
8199
+ 'javascript': ('javascript', 'includecpp.js'),
8200
+ }
8201
+
8202
+ subdir, filename = sdk_paths[lang_name]
8203
+ target_subdir = target_dir / subdir
8204
+ target_subdir.mkdir(parents=True, exist_ok=True)
8205
+
8206
+ target_file = target_subdir / filename
8207
+ target_file.write_text(sdk_content[lang_name], encoding='utf-8')
8208
+
8209
+ lang_display = {'cpp': 'C++', 'java': 'Java', 'csharp': 'C#', 'javascript': 'JavaScript'}
8210
+ click.echo(f" {lang_display[lang_name]}: {target_file}")
8211
+
8212
+
8213
+ def _get_cpp_sdk_content():
8214
+ return '''/**
8215
+ * IncludeCPP CSSL SDK for C++ (v4.2.0)
8216
+ * Cross-language instance sharing between C++ and CSSL.
8217
+ *
8218
+ * USAGE:
8219
+ * #include "includecpp.h"
8220
+ *
8221
+ * class Engine { public: int power = 100; };
8222
+ *
8223
+ * int main() {
8224
+ * Engine engine;
8225
+ * CSSL::share("Engine", &engine);
8226
+ * // In CSSL: cpp = libinclude("c++"); engine = cpp$Engine;
8227
+ * return 0;
8228
+ * }
8229
+ */
8230
+ #pragma once
8231
+ #include <string>
8232
+ #include <any>
8233
+ #include <unordered_map>
8234
+ #include <vector>
8235
+ #include <mutex>
8236
+
8237
+ namespace includecpp { namespace cssl {
8238
+ class Registry {
8239
+ public:
8240
+ static Registry& instance() { static Registry r; return r; }
8241
+ void share(const std::string& n, std::any v) { std::lock_guard<std::mutex> l(_m); _i[n] = v; }
8242
+ template<typename T> void share(const std::string& n, T* p) { std::lock_guard<std::mutex> l(_m); _i[n] = static_cast<void*>(p); }
8243
+ std::any get(const std::string& n) { std::lock_guard<std::mutex> l(_m); auto it = _i.find(n); return it != _i.end() ? it->second : std::any{}; }
8244
+ template<typename T> T* get(const std::string& n) { std::lock_guard<std::mutex> l(_m); auto it = _i.find(n); if (it != _i.end()) try { return static_cast<T*>(std::any_cast<void*>(it->second)); } catch (...) {} return nullptr; }
8245
+ bool has(const std::string& n) { std::lock_guard<std::mutex> l(_m); return _i.count(n) > 0; }
8246
+ bool remove(const std::string& n) { std::lock_guard<std::mutex> l(_m); return _i.erase(n) > 0; }
8247
+ std::vector<std::string> list() { std::lock_guard<std::mutex> l(_m); std::vector<std::string> r; for (auto& p : _i) r.push_back(p.first); return r; }
8248
+ void clear() { std::lock_guard<std::mutex> l(_m); _i.clear(); }
8249
+ private:
8250
+ Registry() = default;
8251
+ std::unordered_map<std::string, std::any> _i;
8252
+ std::mutex _m;
8253
+ };
8254
+ }}
8255
+
8256
+ namespace CSSL {
8257
+ template<typename T> inline void share(const std::string& n, T* i) { includecpp::cssl::Registry::instance().share(n, i); }
8258
+ inline void share(const std::string& n, std::any v) { includecpp::cssl::Registry::instance().share(n, v); }
8259
+ template<typename T> inline T* get(const std::string& n) { return includecpp::cssl::Registry::instance().get<T>(n); }
8260
+ inline bool has(const std::string& n) { return includecpp::cssl::Registry::instance().has(n); }
8261
+ inline bool remove(const std::string& n) { return includecpp::cssl::Registry::instance().remove(n); }
8262
+ inline std::vector<std::string> list() { return includecpp::cssl::Registry::instance().list(); }
8263
+ inline void clear() { includecpp::cssl::Registry::instance().clear(); }
8264
+ }
8265
+
8266
+ #define CSSL_SHARE(name, instance) CSSL::share(#name, instance)
8267
+ #define CSSL_GET(type, name) CSSL::get<type>(#name)
8268
+ '''
8269
+
8270
+
8271
+ def _get_java_sdk_content():
8272
+ return '''/**
8273
+ * IncludeCPP CSSL SDK for Java (v4.2.0)
8274
+ * Cross-language instance sharing between Java and CSSL.
8275
+ *
8276
+ * USAGE:
8277
+ * import com.includecpp.CSSL;
8278
+ *
8279
+ * MyService service = new MyService();
8280
+ * CSSL.share("MyService", service);
8281
+ * // In CSSL: java = libinclude("java"); svc = java$MyService;
8282
+ */
8283
+ package com.includecpp;
8284
+
8285
+ import java.util.concurrent.ConcurrentHashMap;
8286
+ import java.util.List;
8287
+ import java.util.ArrayList;
8288
+
8289
+ public class CSSL {
8290
+ private static final ConcurrentHashMap<String, Object> instances = new ConcurrentHashMap<>();
8291
+
8292
+ public static void share(String name, Object instance) { instances.put(name, instance); }
8293
+ @SuppressWarnings("unchecked")
8294
+ public static <T> T get(String name) { return (T) instances.get(name); }
8295
+ public static <T> T get(String name, Class<T> type) { Object o = instances.get(name); return type.isInstance(o) ? type.cast(o) : null; }
8296
+ public static boolean has(String name) { return instances.containsKey(name); }
8297
+ public static boolean remove(String name) { return instances.remove(name) != null; }
8298
+ public static List<String> list() { return new ArrayList<>(instances.keySet()); }
8299
+ public static void clear() { instances.clear(); }
8300
+ public static int size() { return instances.size(); }
8301
+ }
8302
+ '''
8303
+
8304
+
8305
+ def _get_csharp_sdk_content():
8306
+ return '''/**
8307
+ * IncludeCPP CSSL SDK for C# (v4.2.0)
8308
+ * Cross-language instance sharing between C# and CSSL.
8309
+ *
8310
+ * USAGE:
8311
+ * using IncludeCPP;
8312
+ *
8313
+ * var service = new MyService();
8314
+ * CSSL.Share("MyService", service);
8315
+ * // In CSSL: cs = libinclude("c#"); svc = cs$MyService;
8316
+ */
8317
+ using System.Collections.Concurrent;
8318
+ using System.Collections.Generic;
8319
+ using System.Linq;
8320
+
8321
+ namespace IncludeCPP
8322
+ {
8323
+ public static class CSSL
8324
+ {
8325
+ private static readonly ConcurrentDictionary<string, object> _instances = new();
8326
+
8327
+ public static void Share(string name, object instance) => _instances[name] = instance;
8328
+ public static T Get<T>(string name) where T : class => _instances.TryGetValue(name, out var o) ? o as T : null;
8329
+ public static object Get(string name) => _instances.TryGetValue(name, out var o) ? o : null;
8330
+ public static bool Has(string name) => _instances.ContainsKey(name);
8331
+ public static bool Remove(string name) => _instances.TryRemove(name, out _);
8332
+ public static IReadOnlyList<string> List() => _instances.Keys.ToList().AsReadOnly();
8333
+ public static void Clear() => _instances.Clear();
8334
+ public static int Count => _instances.Count;
8335
+ }
8336
+ }
8337
+ '''
8338
+
8339
+
8340
+ def _get_js_sdk_content():
8341
+ return '''/**
8342
+ * IncludeCPP CSSL SDK for JavaScript (v4.2.0)
8343
+ * Cross-language instance sharing between JavaScript and CSSL.
8344
+ *
8345
+ * USAGE:
8346
+ * const { CSSL } = require('includecpp-cssl');
8347
+ * // or: import { CSSL } from 'includecpp-cssl';
8348
+ *
8349
+ * class DataProcessor { process(data) { return data.toUpperCase(); } }
8350
+ * CSSL.share('DataProcessor', new DataProcessor());
8351
+ * // In CSSL: js = libinclude("javascript"); proc = js$DataProcessor;
8352
+ */
8353
+ const instances = new Map();
8354
+
8355
+ const CSSL = {
8356
+ share(name, instance) { instances.set(name, instance); },
8357
+ get(name) { return instances.get(name); },
8358
+ has(name) { return instances.has(name); },
8359
+ remove(name) { return instances.delete(name); },
8360
+ list() { return Array.from(instances.keys()); },
8361
+ clear() { instances.clear(); },
8362
+ get size() { return instances.size; }
8363
+ };
8364
+
8365
+ if (typeof module !== 'undefined') { module.exports = { CSSL }; module.exports.default = CSSL; }
8366
+ if (typeof window !== 'undefined') { window.CSSL = CSSL; }
8367
+ export { CSSL };
8368
+ export default CSSL;
8369
+ '''
8370
+
8371
+
8372
+ def _show_sdk_documentation():
8373
+ """Show detailed SDK documentation."""
8374
+ click.secho("=" * 70, fg='cyan')
8375
+ click.secho(" CSSL Multi-Language SDK Documentation (v4.2.0)", fg='cyan', bold=True)
8376
+ click.secho("=" * 70, fg='cyan')
8377
+ click.echo()
8378
+
8379
+ click.secho("OVERVIEW", fg='yellow', bold=True)
8380
+ click.echo(" The CSSL SDK enables cross-language instance sharing between")
8381
+ click.echo(" C++, Java, C#, JavaScript and CSSL scripts.")
8382
+ click.echo()
8383
+ click.echo(" Share an instance from any language, then access it in CSSL")
8384
+ click.echo(" using the lang$InstanceName syntax.")
8385
+ click.echo()
8386
+
8387
+ click.secho("HOW IT WORKS", fg='yellow', bold=True)
8388
+ click.echo(" 1. In your language, call CSSL.share(name, instance)")
8389
+ click.echo(" 2. In CSSL, load language support with libinclude()")
8390
+ click.echo(" 3. Access instance via lang$InstanceName")
8391
+ click.echo()
8392
+
8393
+ click.secho("C++ USAGE", fg='green', bold=True)
8394
+ click.echo('''
8395
+ #include "includecpp.h"
8396
+
8397
+ class Engine {
8398
+ public:
8399
+ int power = 500;
8400
+ void start() { /* ... */ }
8401
+ };
8402
+
8403
+ int main() {
8404
+ Engine engine;
8405
+ CSSL::share("Engine", &engine);
8406
+
8407
+ // Alternative macro syntax:
8408
+ // CSSL_SHARE(Engine, &engine);
8409
+
8410
+ return 0;
8411
+ }
8412
+
8413
+ // In CSSL:
8414
+ // cpp = libinclude("c++");
8415
+ // engine = cpp$Engine;
8416
+ // printl(engine.power); // 500
8417
+ ''')
8418
+
8419
+ click.secho("JAVA USAGE", fg='green', bold=True)
8420
+ click.echo('''
8421
+ import com.includecpp.CSSL;
8422
+
8423
+ public class Main {
8424
+ public static void main(String[] args) {
8425
+ MyService service = new MyService();
8426
+ CSSL.share("MyService", service);
8427
+
8428
+ // Check if exists
8429
+ if (CSSL.has("MyService")) {
8430
+ MyService s = CSSL.get("MyService", MyService.class);
8431
+ }
8432
+ }
8433
+ }
8434
+
8435
+ // In CSSL:
8436
+ // java = libinclude("java");
8437
+ // service = java$MyService;
8438
+ // service.doSomething();
8439
+ ''')
8440
+
8441
+ click.secho("C# USAGE", fg='green', bold=True)
8442
+ click.echo('''
8443
+ using IncludeCPP;
8444
+
8445
+ class Program {
8446
+ static void Main() {
8447
+ var handler = new DataHandler();
8448
+ CSSL.Share("DataHandler", handler);
8449
+
8450
+ // List all shared
8451
+ foreach (var name in CSSL.List()) {
8452
+ Console.WriteLine(name);
8453
+ }
8454
+ }
8455
+ }
8456
+
8457
+ // In CSSL:
8458
+ // cs = libinclude("c#");
8459
+ // handler = cs$DataHandler;
8460
+ // handler.Process(data);
8461
+ ''')
8462
+
8463
+ click.secho("JAVASCRIPT USAGE", fg='green', bold=True)
8464
+ click.echo('''
8465
+ const { CSSL } = require('includecpp-cssl');
8466
+ // or: import { CSSL } from 'includecpp-cssl';
8467
+
8468
+ class DataProcessor {
8469
+ process(data) {
8470
+ return data.toUpperCase();
8471
+ }
8472
+ }
8473
+
8474
+ CSSL.share('DataProcessor', new DataProcessor());
8475
+ console.log(CSSL.list()); // ['DataProcessor']
8476
+
8477
+ // In CSSL:
8478
+ // js = libinclude("javascript");
8479
+ // processor = js$DataProcessor;
8480
+ // result = processor.process("hello");
8481
+ ''')
8482
+
8483
+ click.secho("CSSL SIDE (Complete Example)", fg='green', bold=True)
8484
+ click.echo('''
8485
+ // Load language support
8486
+ cpp = libinclude("c++");
8487
+ java = libinclude("java");
8488
+ cs = libinclude("c#");
8489
+ js = libinclude("javascript");
8490
+
8491
+ // Access shared instances
8492
+ engine = cpp$Engine;
8493
+ service = java$MyService;
8494
+ handler = cs$DataHandler;
8495
+ processor = js$DataProcessor;
8496
+
8497
+ // Use them
8498
+ printl("Engine power: " + engine.power);
8499
+ service.doSomething();
8500
+ handler.Process(data);
8501
+ result = processor.process("hello");
8502
+
8503
+ // Cross-language inheritance
8504
+ class TurboEngine : extends cpp$Engine {
8505
+ int boost;
8506
+
8507
+ constr TurboEngine(int b) {
8508
+ this->boost = b;
8509
+ }
8510
+ }
8511
+ ''')
8512
+
8513
+ click.secho("API REFERENCE", fg='yellow', bold=True)
8514
+ click.echo('''
8515
+ Method Description
8516
+ --------------- ------------------------------------------
8517
+ share(name, obj) Share an instance by name
8518
+ get(name) Get a shared instance
8519
+ has(name) Check if instance exists
8520
+ remove(name) Remove a shared instance
8521
+ list() Get all instance names
8522
+ clear() Clear all instances
8523
+ size/Count Number of shared instances
8524
+ ''')
8525
+
8526
+ click.secho("GENERATE SDK FILES", fg='yellow', bold=True)
8527
+ click.echo('''
8528
+ includecpp cssl sdk cpp # C++ SDK
8529
+ includecpp cssl sdk java # Java SDK
8530
+ includecpp cssl sdk csharp # C# SDK
8531
+ includecpp cssl sdk js # JavaScript SDK
8532
+ includecpp cssl sdk all # All SDKs
8533
+ ''')
8534
+
8535
+
7929
8536
  # Register hidden cssl command group
7930
8537
  cli.add_command(cssl)
7931
8538