boboyr/TiecodePluginSkills

Guía completa para el desarrollo de plugins de Tiecode (IDE Tiecode/QiStudio). Cubre la API de plugins (com.rapid.api.* / studio-api.jar), puntos de extensión de program.json, empaquetado .rmx e implementación de varias funcionalidades como autocompletado de código (TextMate + LanguageEngine + LSP), árbol de archivos (PSObject/ExpansionCase/CreationOption/OpeningOption), configuraciones de ejecución (RunConfiguration/TaskRunConfiguration), selección de nuevos archivos, plantillas de proyecto (BaseTemplate), tareas de compilación (BaseTask/ToolchainService), toolchains, resaltado de sintaxis, menús, páginas de configuración, etc. Útil cuando se quiere desarrollar, modificar, aprender o solucionar problemas de plugins de Tiecode, plugins del IDE Tiecode, plugins .rmx, plugins Tiecode, o plugins de ingeniería en lenguajes como go/scala/kotlin/linux/aar.

¿Qué es TiecodePluginSkills?

Este conjunto de habilidades proporciona una guía exhaustiva y documentación completa para desarrollar plugins para el entorno de desarrollo integrado (IDE) Tiecode (también conocido como QiStudio). Está diseñado para desarrolladores que necesitan crear, modificar o depurar plugins que extienden las capacidades del IDE, ya sea añadiendo soporte para nuevos lenguajes de programación, herramientas de compilación, o funcionalidades personalizadas en la interfaz de usuario. La guía se basa en la ingeniería inversa del archivo studio-api-1.0-preview5.jar y el análisis de más de diez plugins reales, cubriendo desde los fundamentos de la arquitectura de plugins, como los puntos de extensión en el archivo program.json y el empaquetado en formato .rmx, hasta implementaciones detalladas para autocompletado de código, gestión del árbol de archivos, configuraciones de ejecución, plantillas de proyectos, y tareas de compilación. Incluye referencias oficiales y ejemplos de la comunidad, lo que la convierte en un recurso valioso tanto para principiantes como para desarrolladores avanzados que buscan dominar el ecosistema de plugins de Tiecode.

Compatible con~Claude Code~Codex CLI✓Cursor
npx skills add boboyr/TiecodePluginSkills

Installed? Explore more Productividad y colaboración skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Desarrollo de plugins para Tiecode

Documentación de desarrollo de plugins dirigida al «IDE Tiecode / QiStudio» (nombre del paquete host com.tiecode.develop). El nombre oficial formal de «Tiecode Studio» es QiStudio (plataforma de ingeniería abierta de nueva generación, la primera aplicación móvil que implementa el estándar OSGi, que extiende el entorno de desarrollo de ingeniería en forma de «microcomponentes/plugins»). Fuente del contenido: Ingeniería inversa de studio-api-1.0-preview5.jar (com.rapid.api.*) + reconstrucción del código fuente de más de una docena de plugins reales como go / scala / kotlin / linux / aar / libgdx / ejecución sin instalación.


Material oficial y repositorios (Importante)

Repositorios oficiales en Gitee

RepositorioDescripción
MobileIPE-Plugin-DevManualTutorial oficial de desarrollo de plugins (microcomponentes QiStudio). Incluye QiStudio核心体系介绍.md (Introducción al sistema central de QiStudio), Rapid框架介绍.md (Introducción al framework Rapid), plugin/扩展点介绍.md (Introducción a puntos de extensión), plugin/插件清单配置.md (Configuración del manifiesto del plugin), plugin/注册你的微组件——插件.md (Registra tu microcomponente: plugin).
TiecodeCompiler-PublicRepositorio de publicación de artefactos del compilador Tiecode (versión multiplataforma). Incluye docs/ (documentación de uso/sintaxis/empaquetado/integración de plataforma del compilador), headers/tiec/ (API C + archivos de cabecera de encapsulación C++), prebuilt/ (cli + bibliotecas dinámicas android/windows/linux/ohos/wasm), stdlibs/ (bibliotecas básicas Android/CXX/web).
QiStudio-PluginSamplesConjunto de proyectos de ejemplo oficiales de plugins (más de 19 ejemplos: inyección de dependencias, efectos dinámicos del editor/paréntesis arcoíris, registro de ventana flotante, administrador de proyectos Html, solicitudes de red, extensión de iconos, toolchain Javac9, resaltado de sintaxis, temas personalizados, ciclo de vida de Application, componentes de proyecto, varios tipos de menús, páginas de herramientas, páginas de configuración, etc.).

El nombre del archivo jar de la API oficial es qistudio-api-<versión>.jar (el studio-api-1.0-preview5.jar descompilado en esta skill es el SDK del lado host). Grupo de contacto QQ: 1016399857.

Implementaciones de referencia de la comunidad (GitHub)

Colección de código fuente de plugins reales asociada a esta skill (repositorio único con múltiples directorios, que contiene 8 plugins completos compilables):

https://github.com/boboyr/tiecode-plugin

DirectorioPluginCapacidad demostrada
go语言工程插件/Ingeniería de lenguaje Go (consola + SDL3)Doble plantilla + autocompletado LSP(gopls) + resaltado TextMate + toolchain + configuración de ejecución + nodos virtuales del árbol de archivos
结绳安卓工程aar构建插件/Construcción aar/jarReutilización de la cadena de compilación del host + salida en chino con NameGenerator
结绳免安装运行插件/Ejecutor sin instalaciónReutilización de tareas del host + carga de APK no instalado mediante plugin
libgdx游戏编辑器插件/Editor visual libgdxDiseñador + menú en área de código del editor + creación de escenas
scala安卓工程插件/Ingeniería Scala AndroidCadena de compilación sbt completa + plantilla «Proyecto de plugin Tiecode» + plugin de compilación/depuración
结绳Linux工程插件/Tiecode Linux-SDL3Toolchain GCC + SDL3 + cadena de tareas
外部kotlin文件注解插件/Anotación de archivos Kotlin externosAPI del compilador Tiecode: CompilerPlugin + AnnotationProcessor + autocompletado Kotlin
BasicLanguages-lang参考/Lenguajes base oficialesReferencia de resaltado de sintaxis para csml/json/markdown/xml/properties

0. Conceptos básicos y arquitectura general

Tiecode es un host IDE modular, los plugins se distribuyen como archivos .rmx. Un .rmx es esencialmente un APK: AndroidManifest.xml + classes.dex + META-INF/program.json. El host descubre las capacidades del plugin a través de las declaraciones de puntos de extensión en program.json, no a través de <application> o los cuatro componentes principales del manifest.

0.1 Tres paquetes clave

PaqueteFunción
com.rapid.api.*SDK del plugin (cuerpo principal de este documento). Ingeniería, lenguaje, tarea, estructura, página, UI, red, etc.
com.rapid.framework.*Capa de framework: VFS (Sistema de archivos virtual), claves Service/Data/Event, contenedor program/plugin
com.tiecode.compiler.*Compilador Tiecode (árbol sintáctico / tabla de símbolos / completer/processor de toolchain) — lado del host, los plugins generalmente solo usan su subpaquete toolchain

0.2 Puntos de extensión (el array extension en program.json)

Estructura completa de META-INF/program.json:

{
  "id": "com.goproject.plugin",
  "name": "go语言工程插件",
  "engine": "plugin",
  "description": "...",
  "versionCode": 4,
  "versionName": "1.3",
  "minSupport": 1,
  "vendor": { "name": "boboyr", "email": "", "url": "#" },
  "extension": [
    { "point": "application", "class": "com.goproject.plugin.MyApplication" },
    { "point": "project.manager", "class": "com.goproject.plugin.project.GoProjectManager" },
    { "point": "project.language", "class": "com.goproject.plugin.lang.GoLanguageFactory",
      "scope": { "unit": "project", "identifiers": "sample.go" } },
    { "point": "domain.menu", "class": "com.goproject.plugin.Gomodmenu" }
  ]
}

Explicación del campo minSupport (versión de host mínima requerida)

minSupport es un número entero que indica la versión mínima de Tiecode que requiere el plugin. Los valores varían según la versión:

Versión de TiecodeminSupportDescripción
Tiecode 4.61El plugin para 4.6 escribe "minSupport": 1
Tiecode 4.72El plugin para 4.7 escribe "minSupport": 2

Es decir: al desarrollar un plugin para 4.6, rellena minSupport con 1; al actualizar a 4.7 (o crear un plugin para 4.7), rellena con 2. Las reglas específicas de vinculación entre el valor y el número de versión del host se basan en la documentación oficial. Al desarrollarlo, simplemente completa según la versión de destino del host.

Conjunto completo de puntos de extensión confirmados (campo point):

Punto de extensiónClase a implementar/extenderFunciónPlugin de origen
applicationAndroidPluginPunto de entrada del plugin, onInit/activate/onUninstallgo/scala/aar/sin instalación
project.managerProjectManager (comúnmente CodeProjectManager)Registrar un tipo de proyectogo/scala/linux
project.languageLanguageFactoryRegistrar un lenguaje (resaltado + extensiones de archivo asociadas), puede tener scopego/scala
project.language.engineLanguageEngineRegistrar un motor de lenguaje (contenedor de proveedores de autocompletado/diagnóstico, etc.)Plugin de consola Tiecode
project.toolchainSubclase de Tool (ej. SunJdk8Compiler)Registrar una cadena de herramientas de compilaciónJavaCompiler8
project.componentComponentIntegrator/ComponentFactoryMontar componentes al abrir un proyecto (configuración de ejecución/ventana emergente inicial/hook)linux/kotlin/aar/sin instalación
project.file.creationOptionPSObjectCreationOptionElemento del menú «Nuevo archivo» en el árbol de archivoskotlin/libgdx
project.file.openWithEditorPSObjectOpeningOption«Abrir con» para archivoskotlin
project.event.fileUiProjectFileUiEventEventos de UI del árbol de archivos (asignar iconos, etc.)kotlin
domain.menuBaseDomainMenuAction/acción de menúElemento de menú de nivel superiorgo
domain.menu.editor.codeMenú del área de código del editorlibgdx
platform.settingsBuilderSettingsBuilderAñadir subpágina nueva en la página de configuraciónscala Android
project.file.creationOption———

Nota: scope.identifiers se usa para limitar un idioma/componente a un typeId de proyecto específico (ej. sample.go). La clase de algunos puntos de extensión puede ser None (marcador de posición).


1. Punto de entrada del plugin: punto de extensión application

import com.rapid.framework.program.android.app.AndroidPlugin;
import com.rapid.framework.program.android.DvmPluginDescriptor;
import com.rapid.api.Platform;
import com.rapid.api.framework.project.toolchain.ToolchainService;
import com.rapid.api.framework.project.ProjectServiceKeys;

public class MyApplication extends AndroidPlugin {
    @Override
    public void onInit(DvmPluginDescriptor descriptor) {
        // Registrar una cadena de herramientas de compilación personalizada (ejemplo: compilador Go)
        ToolchainService service = Platform.getService(ProjectServiceKeys.TOOLCHAIN);
        service.setTool(GoCompileApiKeys.Gocompile, new BaseGoCompiler());
    }
    @Override
    public void activate() {
        // Se ejecuta una vez cuando el plugin se activa (normalmente para colocar hooks, escuchas, ensamblar plugins de compilación)
    }
    @Override
    public void onUninstall() {
        // Limpiar al desinstalar: finalizar procesos secundarios iniciados por uno mismo (ej. gopls), desconectar LSP
    }
}

API clave (com.rapid.api.Platform) :

  • Platform.getService(Key<T>) — Obtener un servicio del host (ej. ProjectServiceKeys.TOOLCHAIN)
  • Platform.getProject() — Objeto del proyecto actualmente abierto
  • Platform.getApplicationContext() — Contexto del host

2. Tipo de proyecto: punto de extensión project.manager

Un plugin registra un «tipo de proyecto» (ej. go语言工程, 结绳安卓工程) a través de ProjectManager.

2.1 Esqueleto del gestor

public class GoProjectManager extends CodeProjectManager<GoProject> {
    public final static String TYPE = "go语言工程";       // Nombre para mostrar
    public final static String IDENTIFIER = "sample.go"; // typeId, esto se almacena en project.json

    public GoProjectManager() {
        super();
        this.fileManager = new GoFileManager();   // Opcional: gestor de archivos personalizado (asignar iconos, etc.)

        // ① Forma de abrir archivos (por extensión)
        fileManager.addPSObjectOpeningOption(DefaultOpeningOption.INSTANCE, ".go", ".mod");
        // ② Forma de expandir nodos del árbol de archivos (nodo virtual «Bibliotecas externas»)
        fileManager.addPSObjectExpansionCase(new ExternalLibrariesExpansionCase(), MARKER);
        // ③ Elemento del menú «Nuevo archivo»
        fileManager.addPSObjectCreationOption(new GoFileCreationOption());
        // ④ Motor de lenguaje y fábrica de lenguajes
        languageManager.registerEngine("go", GoLanguageEngine.getInstance());
        languageManager.registerLanguageFactory(new GoLanguageFactory());
        languageManager.registerOperatorProvider(GoLanguage.ID, new GoOperatorProvider());
        // ⑤ Plantilla de creación de proyecto
        addTemplate(new GoConsoleTemplate());
        addTemplate(new GoSdl3Template());
    }

    @Override public String getIdentifier() { return IDENTIFIER; }

    @Override public TypeDescription getTypeDescription() {
        Drawable d = ContextUtils.getDrawable(AndroidPlugins.getContext(this), R.drawable.golang);
        return new TypeDescription(TYPE, TypeDescription.APPLICATION, d);
    }

    @Override public GoProject newProject() { return new GoProject(); }

    @Override public boolean isProjectDir(File file) { return false; }
}

Métodos de la interfaz ProjectManager (de javap):

String getIdentifier();
TypeDescription getTypeDescription();      // Nombre + tipo + icono
List<Template<T>> getTemplates();
void addTemplate(Template<T>);
ProjectFileManager<T> getFileManager();
T newProject();
void load(T, LoadingPresentation);
boolean isProjectDir(File);                // Determinar si un directorio es de este tipo de proyecto
String backup(T); void delete(T);

Constantes de tipo para TypeDescription: APPLICATION / CONSOLE / LIBRARY.


3. Objeto de proyecto y ensamblaje de pipeline: CodeProject.prepare()

Un tipo de proyecto corresponde a una subclase de Project. El host llama a prepare() al abrir el proyecto; en ese momento, los archivos de plantilla ya se han escrito y se puede ensamblar la cadena de tareas, la configuración de ejecución y los componentes según el contenido del directorio.

public class GoProject extends CodeProject {
    @Override
    public void prepare() {
        if (GoProjectKind.isSdl3(getProjectDir())) {
            Task buildLibmain = new BuildLibmainTask();
            Task publishLib = new PublishLibTask();
            addTask(buildLibmain);
            addTask(publishLib);
            publishLib.dependsOn(buildLibmain);      // Dependencia de tareas
            addRunConfiguration(new GoSdl3RunConfiguration());
        } else {
            addTask(new CompilerGoTask());
            addTask(new RunGoTask());
            addRunConfiguration(new GoStartRunConfig());
            addRunConfiguration(new ElfRunConfig());
        }
    }
    @Override public ProjectVariant getVariant() { return ProjectVariant.DEBUG; }
}

Métodos clave de CodeProject (extiende BaseProject):

void prepare();
TaskContainer getTasks();  TaskExecutor getTaskExecutor();
void addTask(Task);  void setTasks(Iterable<Task>);
void addRunConfiguration(RunConfiguration);   // Exclusivo de CodeProject
ProjectVariant getVariant();  void setVariant(ProjectVariant);
Logger getLogger();  void setLogger(Logger);
String getName();
File getProjectDir();  File getChildFile(String);   // Resolver ruta relativa del proyecto a File
void recycle();

Valores de ProjectVariant: DEBUG / RELEASE / UNDEFINED.

Consejo (del plugin go): En prepare(), escribe archivos de marcador en el proyecto (ej. External Libraries) para añadir capacidades a proyectos antiguos existentes sin necesidad de recrearlos.


4. Plantilla de proyecto: BaseTemplate

La plantilla determina qué opciones están disponibles en el cuadro de diálogo «Nuevo proyecto» y qué archivos se escriben al crearlo.

public class GoConsoleTemplate extends BaseTemplate<GoProject> {
    @Override public String getName() { return "控制台工程"; } // Proyecto de Consola
    @Override public Drawable getPicture() { return null; }        // Imagen de vista previa de la plantilla, puede ser null
    @Override public String getDefaultProjectName() { return "我的go控制台工程"; } // Mi proyecto de consola Go
    @Override public Form getForm() { return new Form(); }         // Se pueden añadir elementos de entrada

    @Override public void create(GoProject project, Form form,
                                 Project.OnProjectCreateListener listener) {
        try {
            File file = project.getChildFile("src/main.go");
            String html = AssetUtils.readAsset(AndroidPlugins.getContext(this), "sample/main.go");
            html = html.replace("${project_name}", project.getName());
            FileUtils.writeFile(html, file);                        // Escribir en el directorio del proyecto
            FileUtils.writeFile("module main\ngo 1.26.0", project.getChildFile("src/go.mod"));
            listener.onSuccess();                                    // Callback de éxito
        } catch (IOException e) {
            listener.onFail("写出默认文件失败");                      // Callback de fallo: Error al escribir el archivo predeterminado
        }
    }
}

Métodos de la interfaz Template<T>:

String getName();
Drawable getPicture();
String getDefaultProjectName();
Form getForm();          // com.rapid.framework.data.form.Form, puede addInput(new FormInput(...))
void create(T, Form, OnProjectCreateListener);   // OnProjectCreateListener.onSuccess()/onFail(msg)

Recursos de la plantilla: Empaqueta los archivos de la plantilla dentro de app/src/main/assets/<nombre>, y usa AssetUtils.readAsset / AssetUtils.unZipAssetsFolder(context, zipName, destDir) para leerlos y descomprimirlos. (La plantilla del proyecto SDL3 descomprime gosdl3_template.zip directamente en el directorio del proyecto usando asset).


5. Tarea de compilación y toolchain: BaseTask + ToolchainService

5.1 Tarea BaseTask

public class CompilerGoTask extends BaseTask {
    @Override public void execute() throws TaskInterruptError {
        File output = new File(Platform.getProject().getProjectDir() + "/output");
        if (!output.exists()) output.mkdirs();
        GoCompile a = Platform.getService(ProjectServiceKeys.TOOLCHAIN)
                             .getTool(GoCompileApiKeys.Gocompile);
        if (!a.isInstalled(ctx)) { logger.info("安装工具链..."); a.install(ctx); } // Instalando toolchain...
        GoCompileParams p = new GoCompileParams();
        p.inputFiles = FileUtils.getGofile(srcDir);
        p.outputPath = output.getPath();
        p.options = new String[]{"build", "-o"};
        a.compile(p, new CompileOnExecutionCallback());
    }

    // Debe sobrescribirse: `BaseTask.prepare` por defecto lanza `UnsupportedOperationException`;
    // Además, los campos `logger`/`variant` deben asignarse aquí, de lo contrario `logger.info` en `execute()` causará NPE.
    @Override public void prepare(Project project, ProjectVariant variant, Logger logger) {
        this.logger = logger;
        this.variant = variant;
        Os.setenv("GOROOT", goRoot, false);   // Establecer variable de entorno (android.system.Os)
    }

    @Override public String getId() { return "compileWithGo"; }   // Para que la configuración de ejecución lo referencie con getTaskId()
    @Override public String getName() { return "编译到目标平台"; } // Compilar para plataforma destino
}

Interfaz Task (de javap):

String getId();  String getName();
void prepare(Project, ProjectVariant, Logger);      // Nota: por defecto lanza excepción, asegúrate de sobrescribirlo
void execute() throws TaskInterruptError;
TaskState getState();
void interrupt();
void dependsOn(Task...);  void dependsOn(List<Task>);
Task getDependencyTask(String);  Task getDependencyTaskByName(String);
String getIntermediatePath();  String getIntermediatePath(String);
String getOutputPath();  String getOutputPath(String);
File getGeneratedDir();

Error común (nota original del plugin go): Si logger no se asigna en la tarea, usar logger.info en execute() causará un NPE y fallará directamente, la instalación de la herramienta nunca se ejecutará.

5.2 Toolchain Tool + Installable

public interface Tool { /* Tiene claves integradas como ANDROID_SDK/AAPT/AAPT2/D8/R8/DX/PROGUARD/
                         MANIFEST_MERGER/APK_SIGNER/JAVA_SDK/JAVA_COMPILER, etc. */ }
public interface Installable {
    boolean isInstalled(Context);
    void install(Context) throws IOException;
}
  • Las toolchains personalizadas se registran en application.onInit() usando ToolchainService.setTool(customKey, impl).
  • Las claves de las toolchains de Android integradas están todas en la interfaz Tool (se puede usar directamente Platform.getService(TOOLCHAIN).getTool(Tool.AAPT2)).
  • Reutilizar la cadena de compilación del host (método del plugin aar / plugin sin instalación): no empaquetar tu propio compilador, sino usar getDependencyTaskByName("compileWithTiecodec") para obtener la tarea del host y establecer dependencias, o reutilizar directamente getTaskId().

6. Configuración de ejecución: RunConfiguration / TaskRunConfiguration

Añade elementos ejecutables al menú «Ejecutar» del proyecto. El más común es TaskRunConfiguration: especifica un id de tarea, y cuando la tarea se ejecuta con éxito, se llama al callback onResult.

public class GoStartRunConfig extends TaskRunConfiguration {
    public Project getProject() { return Platform.getProject(); }
    public String getTaskId() { return "RunWithGo"; }          // Id de la tarea asociada
    public ProjectVariant getVariant() { return Proje

...

Nota: El contenido se ha truncado para la traducción, pero esta skill cubre completamente todos los aspectos del desarrollo de plugins de Tiecode, incluyendo el manejo del árbol de archivos, motores de lenguaje, componentes de proyecto, eventos y más.

Skills relacionados