openxiangda 1.0.267 → 1.0.268
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.
- package/LICENSE +21 -0
- package/README.md +1 -1
- package/lib/cli.js +30 -13
- package/lib/generation-update.js +42 -0
- package/lib/skills.js +8 -16
- package/openxiangda-skills/SKILL.md +5 -3
- package/openxiangda-skills/references/openxiangda-api.md +1 -1
- package/openxiangda-skills/references/resource-manifest-cheatsheet.md +1 -1
- package/openxiangda-skills/references/workspace-state.md +2 -2
- package/package.json +52 -2
- package/templates/openxiangda-react-spa/app-workspace.config.ts +1 -1
- package/templates/sy-lowcode-app-workspace/AGENTS.md +1 -1
- package/templates/sy-lowcode-app-workspace/app-workspace.config.ts +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenXiangda contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ packages, unified AI skill, templates, and documentation. It must not use the
|
|
|
20
20
|
|
|
21
21
|
Normal OpenXiangda app development uses platform-user login tokens through `/openxiangda-api/v1`; it does not use AK/SK. External backend and third-party integrations use the separate `openxiangda-open-api` skill, `/dingtalk-api/v1.0`, and a platform-managed AK/SK credential.
|
|
22
22
|
|
|
23
|
-
Private platform routing is fixed: backend APIs are under `/service`, platform management is under `/platform`, and app runtime access is under `/view`. Passing a root domain such as `https://
|
|
23
|
+
Private platform routing is fixed: backend APIs are under `/service`, platform management is under `/platform`, and app runtime access is under `/view`. Passing a root domain such as `https://platform.example.com/` to the CLI is supported; OpenXiangda stores the API base as `https://platform.example.com/service`.
|
|
24
24
|
|
|
25
25
|
## OpenXiangda 1.x Delivery V2 (maintenance)
|
|
26
26
|
|
package/lib/cli.js
CHANGED
|
@@ -114,6 +114,7 @@ const {
|
|
|
114
114
|
summarizeBindingDifferences,
|
|
115
115
|
} = require('./resource-binding-contract');
|
|
116
116
|
const { getSkillStatusReport, installSkills } = require('./skills');
|
|
117
|
+
const { resolveUpdateTarget, buildGenerationUpdateCommand } = require('./generation-update');
|
|
117
118
|
const {
|
|
118
119
|
assertOrClaimWorktreeOwner,
|
|
119
120
|
claimWorktreeOwner,
|
|
@@ -532,9 +533,10 @@ async function update(args) {
|
|
|
532
533
|
return;
|
|
533
534
|
}
|
|
534
535
|
const registry = normalizeNpmRegistry(flags.registry || OFFICIAL_NPM_REGISTRY);
|
|
536
|
+
const selection = resolveUpdateTarget({ target: flags.target });
|
|
535
537
|
|
|
536
538
|
if (requestedSubcommand === 'check') {
|
|
537
|
-
const result = checkOpenXiangdaUpdate(registry);
|
|
539
|
+
const result = checkOpenXiangdaUpdate(registry, selection);
|
|
538
540
|
if (flags.json) return writeJson(result);
|
|
539
541
|
printUpdateCheck(result);
|
|
540
542
|
return;
|
|
@@ -545,6 +547,7 @@ async function update(args) {
|
|
|
545
547
|
json: Boolean(flags.json),
|
|
546
548
|
skipSkills: Boolean(flags['no-skills']),
|
|
547
549
|
timeoutSeconds: flags['timeout-seconds'],
|
|
550
|
+
...selection,
|
|
548
551
|
});
|
|
549
552
|
if (flags.json) return writeJson(result);
|
|
550
553
|
print('OpenXiangda 已更新。');
|
|
@@ -562,8 +565,8 @@ function normalizeNpmRegistry(value) {
|
|
|
562
565
|
return registry.replace(/\/+$/, '') || OFFICIAL_NPM_REGISTRY;
|
|
563
566
|
}
|
|
564
567
|
|
|
565
|
-
function checkOpenXiangdaUpdate(registry) {
|
|
566
|
-
const latestVersion = fetchLatestOpenXiangdaVersion(registry);
|
|
568
|
+
function checkOpenXiangdaUpdate(registry, selection = resolveUpdateTarget()) {
|
|
569
|
+
const latestVersion = fetchLatestOpenXiangdaVersion(registry, selection.channel);
|
|
567
570
|
const versionComparison = compareVersions(latestVersion, CURRENT_VERSION);
|
|
568
571
|
const updateAvailable = versionComparison > 0;
|
|
569
572
|
return {
|
|
@@ -577,8 +580,10 @@ function checkOpenXiangdaUpdate(registry) {
|
|
|
577
580
|
: versionComparison < 0
|
|
578
581
|
? 'local_newer_than_registry'
|
|
579
582
|
: 'latest',
|
|
580
|
-
|
|
581
|
-
|
|
583
|
+
target: selection.target,
|
|
584
|
+
channel: selection.channel,
|
|
585
|
+
installCommand: `openxiangda update install --target ${selection.target}`,
|
|
586
|
+
skillInstallCommand: 'openxiangda skill install',
|
|
582
587
|
compatibilityCheckCommand: 'openxiangda commands --json',
|
|
583
588
|
checkedAt: new Date().toISOString(),
|
|
584
589
|
notes: [
|
|
@@ -588,10 +593,10 @@ function checkOpenXiangdaUpdate(registry) {
|
|
|
588
593
|
};
|
|
589
594
|
}
|
|
590
595
|
|
|
591
|
-
function fetchLatestOpenXiangdaVersion(registry) {
|
|
596
|
+
function fetchLatestOpenXiangdaVersion(registry, channel = 'v1') {
|
|
592
597
|
const result = spawnSync(
|
|
593
598
|
'npm',
|
|
594
|
-
['view', `${NPM_PACKAGE_NAME}
|
|
599
|
+
['view', `${NPM_PACKAGE_NAME}@${channel}`, 'version', `--registry=${registry}`, '--json'],
|
|
595
600
|
{
|
|
596
601
|
encoding: 'utf8',
|
|
597
602
|
timeout: 30000,
|
|
@@ -630,17 +635,22 @@ function normalizeUpdateInstallTimeoutSeconds(value) {
|
|
|
630
635
|
|
|
631
636
|
function buildOpenXiangdaUpdateInstallPlan(registryInput, options = {}) {
|
|
632
637
|
const registry = normalizeNpmRegistry(registryInput);
|
|
638
|
+
const selection = resolveUpdateTarget(options);
|
|
639
|
+
const version = options.version || fetchLatestOpenXiangdaVersion(registry, selection.channel);
|
|
640
|
+
const execution = buildGenerationUpdateCommand(selection, version);
|
|
633
641
|
const timeoutSeconds = normalizeUpdateInstallTimeoutSeconds(
|
|
634
642
|
options.timeoutSeconds
|
|
635
643
|
);
|
|
636
644
|
return {
|
|
637
645
|
registry,
|
|
638
646
|
timeoutSeconds,
|
|
647
|
+
...selection,
|
|
648
|
+
command: execution.command,
|
|
649
|
+
version,
|
|
639
650
|
args: [
|
|
640
|
-
|
|
641
|
-
'-g',
|
|
642
|
-
`${NPM_PACKAGE_NAME}@latest`,
|
|
651
|
+
...execution.args,
|
|
643
652
|
`--registry=${registry}`,
|
|
653
|
+
...(execution.command === 'npm' ? [
|
|
644
654
|
'--prefer-offline',
|
|
645
655
|
'--legacy-peer-deps',
|
|
646
656
|
'--no-audit',
|
|
@@ -650,6 +660,7 @@ function buildOpenXiangdaUpdateInstallPlan(registryInput, options = {}) {
|
|
|
650
660
|
'--fetch-timeout=60000',
|
|
651
661
|
'--fetch-retry-mintimeout=1000',
|
|
652
662
|
'--fetch-retry-maxtimeout=10000',
|
|
663
|
+
] : []),
|
|
653
664
|
],
|
|
654
665
|
};
|
|
655
666
|
}
|
|
@@ -662,6 +673,7 @@ async function runCommandWithHeartbeat(command, args, options = {}) {
|
|
|
662
673
|
let child;
|
|
663
674
|
try {
|
|
664
675
|
child = spawn(command, args, {
|
|
676
|
+
cwd: options.cwd || process.cwd(),
|
|
665
677
|
encoding: 'utf8',
|
|
666
678
|
stdio: quiet ? ['ignore', 'pipe', 'pipe'] : 'inherit',
|
|
667
679
|
env: options.env || process.env,
|
|
@@ -731,7 +743,8 @@ async function installOpenXiangdaUpdate(registry, options = {}) {
|
|
|
731
743
|
if (!quiet) {
|
|
732
744
|
print(`执行: npm ${npmArgs.join(' ')}`);
|
|
733
745
|
}
|
|
734
|
-
const installResult = await runCommandWithHeartbeat(
|
|
746
|
+
const installResult = await runCommandWithHeartbeat(plan.command, npmArgs, {
|
|
747
|
+
cwd: plan.cwd,
|
|
735
748
|
quiet,
|
|
736
749
|
timeoutMs: plan.timeoutSeconds * 1000,
|
|
737
750
|
env: { ...process.env, npm_config_registry: plan.registry },
|
|
@@ -763,11 +776,15 @@ async function installOpenXiangdaUpdate(registry, options = {}) {
|
|
|
763
776
|
},
|
|
764
777
|
};
|
|
765
778
|
|
|
766
|
-
if (!options.skipSkills) {
|
|
779
|
+
if (!options.skipSkills && plan.target === 'workspace') {
|
|
767
780
|
if (!quiet) {
|
|
768
781
|
print('刷新 OpenXiangda skills: openxiangda skill install --force');
|
|
769
782
|
}
|
|
770
|
-
const
|
|
783
|
+
const localManifest = path.join(plan.cwd, 'node_modules/openxiangda/package.json');
|
|
784
|
+
const localPackage = JSON.parse(fs.readFileSync(localManifest, 'utf8'));
|
|
785
|
+
const localBin = path.resolve(path.dirname(localManifest), typeof localPackage.bin === 'string' ? localPackage.bin : localPackage.bin.openxiangda);
|
|
786
|
+
const skillResult = spawnSync(process.execPath, [localBin, 'skill', 'install'], {
|
|
787
|
+
cwd: plan.cwd,
|
|
771
788
|
encoding: 'utf8',
|
|
772
789
|
stdio: quiet ? 'pipe' : 'inherit',
|
|
773
790
|
timeout: 60000,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function resolveUpdateTarget(options = {}) {
|
|
5
|
+
let root = path.resolve(options.cwd || process.cwd());
|
|
6
|
+
let workspace = null;
|
|
7
|
+
while (true) {
|
|
8
|
+
const v1 = fs.existsSync(path.join(root, 'app-workspace.config.ts')) || fs.existsSync(path.join(root, '.openxiangda/state.json'));
|
|
9
|
+
const v2 = fs.existsSync(path.join(root, 'openxiangda.config.ts')) || fs.existsSync(path.join(root, 'openxiangda-app.config.ts'));
|
|
10
|
+
if (v1 && v2) throw new Error('WORKSPACE_GENERATION_CONFLICT: 同一目录存在 V1/V2 工作区标记');
|
|
11
|
+
if (v2) throw new Error('WORKSPACE_ENGINE_GENERATION_MISMATCH: V1 CLI 不能升级 V2 项目;请使用统一入口');
|
|
12
|
+
if (v1) { workspace = root; break; }
|
|
13
|
+
const parent = path.dirname(root);
|
|
14
|
+
if (parent === root) break;
|
|
15
|
+
root = parent;
|
|
16
|
+
}
|
|
17
|
+
const target = options.target || (workspace ? 'workspace' : 'launcher');
|
|
18
|
+
if (!['workspace', 'launcher'].includes(target)) throw new Error('DISTRIBUTION_UPDATE_TARGET_INVALID: 使用 workspace 或 launcher');
|
|
19
|
+
if (target === 'workspace' && !workspace) throw new Error('DISTRIBUTION_WORKSPACE_REQUIRED: 未找到 V1 工作区');
|
|
20
|
+
return { target, channel: target === 'workspace' ? 'legacy-v1' : 'latest', cwd: workspace || process.cwd() };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function buildGenerationUpdateCommand(selection, version) {
|
|
24
|
+
if (!/^[12]\.\d+\.\d+$/.test(version)) throw new Error('DISTRIBUTION_UPDATE_VERSION_INVALID: 升级目标必须是已发布的稳定版本');
|
|
25
|
+
if (selection.target === 'launcher') {
|
|
26
|
+
if (!version.startsWith('2.')) throw new Error('DISTRIBUTION_UPDATE_GENERATION_MISMATCH: 全局入口需要 V2');
|
|
27
|
+
if (Number(process.versions.node.split('.')[0]) < 24) throw new Error('DISTRIBUTION_NODE_VERSION_REQUIRED: 全局统一入口需要 Node.js 24;当前 V1 项目环境不会自动改变');
|
|
28
|
+
return { command: 'npm', args: ['install', '-g', `openxiangda@${version}`] };
|
|
29
|
+
}
|
|
30
|
+
if (!version.startsWith('1.')) throw new Error('DISTRIBUTION_UPDATE_GENERATION_MISMATCH: V1 项目只允许安装 V1');
|
|
31
|
+
const file = path.join(selection.cwd, 'package.json');
|
|
32
|
+
if (!fs.existsSync(file)) throw new Error('DISTRIBUTION_PACKAGE_MANIFEST_REQUIRED: 工作区缺少 package.json');
|
|
33
|
+
const manifest = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
34
|
+
const pnpm = fs.existsSync(path.join(selection.cwd, 'pnpm-lock.yaml')) || manifest.packageManager?.startsWith('pnpm@');
|
|
35
|
+
if (pnpm && fs.existsSync(path.join(selection.cwd, 'package-lock.json'))) throw new Error('DISTRIBUTION_PACKAGE_MANAGER_CONFLICT: 多个包管理器锁文件');
|
|
36
|
+
if (fs.existsSync(path.join(selection.cwd, 'yarn.lock'))) throw new Error('DISTRIBUTION_PACKAGE_MANAGER_UNSUPPORTED: 请通过项目 Yarn 命令显式安装 openxiangda@legacy-v1');
|
|
37
|
+
return { command: pnpm ? 'pnpm' : 'npm', args: pnpm
|
|
38
|
+
? ['add', ...(manifest.dependencies?.openxiangda ? [] : ['--save-dev']), '--save-exact', `openxiangda@${version}`, ...(fs.existsSync(path.join(selection.cwd, 'pnpm-workspace.yaml')) ? ['--workspace-root'] : [])]
|
|
39
|
+
: ['install', manifest.dependencies?.openxiangda ? '--save-prod' : '--save-dev', '--save-exact', `openxiangda@${version}`] };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = { resolveUpdateTarget, buildGenerationUpdateCommand };
|
package/lib/skills.js
CHANGED
|
@@ -11,9 +11,9 @@ const MANAGER = 'openxiangda';
|
|
|
11
11
|
|
|
12
12
|
const SKILL_SPECS = [
|
|
13
13
|
{
|
|
14
|
-
name: 'openxiangda',
|
|
15
|
-
displayName: 'OpenXiangda',
|
|
16
|
-
shortDescription: '
|
|
14
|
+
name: 'openxiangda-v1',
|
|
15
|
+
displayName: 'OpenXiangda V1',
|
|
16
|
+
shortDescription: 'OpenXiangda V1 维护入口,仅用于 V1 工作区。',
|
|
17
17
|
sourceRelativePath: 'openxiangda-skills',
|
|
18
18
|
type: 'root',
|
|
19
19
|
},
|
|
@@ -84,16 +84,8 @@ const SKILL_SPECS = [
|
|
|
84
84
|
},
|
|
85
85
|
];
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
{ name: 'openxiangda-v2-architecture', sourceRelativePath: 'v2/skills/openxiangda-v2-architecture' },
|
|
90
|
-
{ name: 'openxiangda-v2-frontend', sourceRelativePath: 'v2/skills/openxiangda-v2-frontend' },
|
|
91
|
-
{ name: 'openxiangda-v2-backend', sourceRelativePath: 'v2/skills/openxiangda-v2-backend' },
|
|
92
|
-
{ name: 'openxiangda-v2-data-authz', sourceRelativePath: 'v2/skills/openxiangda-v2-data-authz' },
|
|
93
|
-
{ name: 'openxiangda-v2-workflow-events', sourceRelativePath: 'v2/skills/openxiangda-v2-workflow-events' },
|
|
94
|
-
{ name: 'openxiangda-v2-delivery', sourceRelativePath: 'v2/skills/openxiangda-v2-delivery' },
|
|
95
|
-
{ name: 'openxiangda-v1-maintenance', sourceRelativePath: 'v2/skills/openxiangda-v1-maintenance' },
|
|
96
|
-
];
|
|
87
|
+
// V1 does not own V2 or the unified routing skill, including historical installs.
|
|
88
|
+
const RETIRED_SKILL_SPECS = [];
|
|
97
89
|
|
|
98
90
|
function getDefaultCodexSkillsDir(env = process.env) {
|
|
99
91
|
const codexHome = env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
@@ -232,7 +224,7 @@ function getSkillStatusReport(options = {}) {
|
|
|
232
224
|
const env = options.env || process.env;
|
|
233
225
|
|
|
234
226
|
// 获取目标目录列表
|
|
235
|
-
const skillsDirs = getDualSkillsDirs(agent, env);
|
|
227
|
+
const skillsDirs = options.dest ? [path.resolve(options.dest)] : getDualSkillsDirs(agent, env);
|
|
236
228
|
|
|
237
229
|
const results = [];
|
|
238
230
|
for (const skillsDir of skillsDirs) {
|
|
@@ -265,7 +257,7 @@ function installSkills(options = {}) {
|
|
|
265
257
|
const force = Boolean(options.force);
|
|
266
258
|
|
|
267
259
|
// 获取目标目录列表
|
|
268
|
-
const skillsDirs = getDualSkillsDirs(agent, options.env);
|
|
260
|
+
const skillsDirs = options.dest ? [path.resolve(options.dest)] : getDualSkillsDirs(agent, options.env);
|
|
269
261
|
|
|
270
262
|
const results = [];
|
|
271
263
|
for (const skillsDir of skillsDirs) {
|
|
@@ -410,7 +402,7 @@ function writeAgentMetadata(spec, skillDir) {
|
|
|
410
402
|
const defaultPrompt =
|
|
411
403
|
spec.defaultPrompt ||
|
|
412
404
|
(spec.name === 'openxiangda'
|
|
413
|
-
? '使用 $openxiangda
|
|
405
|
+
? '使用 $openxiangda-v1 处理 V1 工作区的登录、发布和诊断任务。'
|
|
414
406
|
: `使用 $${spec.name} 处理对应的 OpenXiangda 低代码平台任务。`);
|
|
415
407
|
const content = [
|
|
416
408
|
'interface:',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: openxiangda
|
|
3
|
-
description: "
|
|
2
|
+
name: openxiangda-v1
|
|
3
|
+
description: "Maintain existing OpenXiangda V1 workspaces: forms, pages, resources, workflows, permissions, publishing and diagnosis. New applications default to V2; assess V2 adoption for V1 projects still in testing when capability coverage and migration cost permit."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<!-- OpenXiangda-Policy-Version: 7 -->
|
|
@@ -13,10 +13,12 @@ This file is a router and safety card. Read only the one or two subskills select
|
|
|
13
13
|
|
|
14
14
|
## Select the runtime generation first
|
|
15
15
|
|
|
16
|
-
If the workspace contains `openxiangda.config.ts
|
|
16
|
+
If the nearest workspace contains `openxiangda.config.ts` or `openxiangda-app.config.ts`, it is a platform-2.0 application; a Nest server is optional. Stop this 1.x resource flow and use the independently released `$openxiangda-v2` skill. The 2.0 CLI operates on one immutable application package and does not use SDD or per-resource publishing.
|
|
17
17
|
|
|
18
18
|
If the workspace contains `app-workspace.config.ts`, forms/pages/resource manifests, or an existing 1.x state directory, continue with this router. Never migrate a stable 1.x application merely because platform 2.0 is available.
|
|
19
19
|
|
|
20
|
+
For an existing V1 project, proactively check whether V2 covers its required capabilities, whether it is still in testing, and whether migration cost is manageable. When those conditions hold, recommend V2 first and explain the benefit, rebuild scope and verification cost. Use the unified entry's `openxiangda migrate assess --to v2` for source pointers; confirm the project design, data/workflow mapping, acceptance and rollback before implementing migration. Keep unknown conditions explicit and continue current maintenance with the matching engine until migration is authorized.
|
|
21
|
+
|
|
20
22
|
## 1.x Delivery V2 is the normal 1.x release path
|
|
21
23
|
|
|
22
24
|
When `app-workspace.config.ts` declares `deliveryVersion: 2`, all later V1 SDD,
|
|
@@ -930,7 +930,7 @@ Body:
|
|
|
930
930
|
"allowedExtensions": ["txt", "pdf", "png"],
|
|
931
931
|
"cors": {
|
|
932
932
|
"managed": true,
|
|
933
|
-
"allowedOrigins": ["https://
|
|
933
|
+
"allowedOrigins": ["https://platform.example.com"],
|
|
934
934
|
"allowedMethods": ["PUT", "GET", "HEAD"],
|
|
935
935
|
"allowedHeaders": ["content-type", "x-oss-*"],
|
|
936
936
|
"exposeHeaders": ["ETag", "x-oss-request-id"],
|
|
@@ -173,7 +173,7 @@ await auth.phoneCodeLogin({ phone, code, challengeId: sent.challengeId });
|
|
|
173
173
|
"allowedExtensions": ["txt", "pdf", "png"],
|
|
174
174
|
"cors": {
|
|
175
175
|
"managed": true,
|
|
176
|
-
"allowedOrigins": ["https://
|
|
176
|
+
"allowedOrigins": ["https://platform.example.com"],
|
|
177
177
|
"allowedMethods": ["PUT", "GET", "HEAD"],
|
|
178
178
|
"allowedHeaders": ["content-type", "x-oss-*"],
|
|
179
179
|
"exposeHeaders": ["ETag", "x-oss-request-id"],
|
|
@@ -64,7 +64,7 @@ Environment-managed workspaces add a logical application and target-specific bin
|
|
|
64
64
|
"currentTarget": "preproduction",
|
|
65
65
|
"targets": {
|
|
66
66
|
"preproduction": {
|
|
67
|
-
"profile": "
|
|
67
|
+
"profile": "instrument-example",
|
|
68
68
|
"environmentId": "PRE_ENV_UUID",
|
|
69
69
|
"kind": "preproduction",
|
|
70
70
|
"appType": "APP_PRE",
|
|
@@ -82,7 +82,7 @@ Environment-managed workspaces add a logical application and target-specific bin
|
|
|
82
82
|
"resources": {}
|
|
83
83
|
},
|
|
84
84
|
"production": {
|
|
85
|
-
"profile": "
|
|
85
|
+
"profile": "instrument-example",
|
|
86
86
|
"environmentId": "PROD_ENV_UUID",
|
|
87
87
|
"kind": "production",
|
|
88
88
|
"appType": "APP_PROD",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openxiangda",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.268",
|
|
4
4
|
"description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
@@ -215,8 +215,58 @@
|
|
|
215
215
|
"node": ">=18"
|
|
216
216
|
},
|
|
217
217
|
"publishConfig": {
|
|
218
|
+
"tag": "legacy-v1",
|
|
218
219
|
"access": "public",
|
|
219
220
|
"registry": "https://registry.npmjs.org/"
|
|
220
221
|
},
|
|
221
|
-
"license": "MIT"
|
|
222
|
+
"license": "MIT",
|
|
223
|
+
"repository": {
|
|
224
|
+
"type": "git",
|
|
225
|
+
"url": "git+https://github.com/1377385356/openxiangda-v1.git"
|
|
226
|
+
},
|
|
227
|
+
"homepage": "https://github.com/1377385356/openxiangda-v1",
|
|
228
|
+
"bugs": {
|
|
229
|
+
"url": "https://github.com/1377385356/openxiangda-v1/issues"
|
|
230
|
+
},
|
|
231
|
+
"openxiangdaRelease": {
|
|
232
|
+
"schemaVersion": "openxiangda.release-notes/v1",
|
|
233
|
+
"version": "1.0.268",
|
|
234
|
+
"title": "OpenXiangda V1 维护版 1.0.268",
|
|
235
|
+
"status": "reviewed",
|
|
236
|
+
"summary": "旧项目继续使用 V1 引擎,项目升级保持在 V1 维护渠道;同时兼容新的全局统一入口与独立的 V2 Skill。",
|
|
237
|
+
"newFeatures": [
|
|
238
|
+
"V1 工具源码从经审查的公开基线发布到独立 GitHub 仓库,并提供对应版本说明。"
|
|
239
|
+
],
|
|
240
|
+
"fixes": [
|
|
241
|
+
"在 V1 项目内执行 update 默认更新项目依赖,使用 v1 维护渠道并固定具体版本。",
|
|
242
|
+
"全局入口更新单独使用 --target launcher,检查 Node.js 24 要求并安装统一 V2 入口。",
|
|
243
|
+
"V1 主 Skill 使用 openxiangda-v1 名称,安装时保留统一入口和 V2 技能。",
|
|
244
|
+
"V1 发布仅允许 legacy-v1 渠道,防止维护版覆盖 V2 的 latest。"
|
|
245
|
+
],
|
|
246
|
+
"affectedUsers": [
|
|
247
|
+
"维护既有 V1 项目的开发者",
|
|
248
|
+
"已经安装全局统一入口的 V1 用户"
|
|
249
|
+
],
|
|
250
|
+
"compatibility": {
|
|
251
|
+
"node": ">=18;全局 V2 统一入口需要 >=24",
|
|
252
|
+
"workspaceGenerations": [
|
|
253
|
+
"v1"
|
|
254
|
+
],
|
|
255
|
+
"workspacePolicy": "沿用现有 app-workspace.config.ts、平台绑定、登录态、业务数据及流程。",
|
|
256
|
+
"platformPolicy": "本次维护不改变平台协议或部署状态。"
|
|
257
|
+
},
|
|
258
|
+
"upgradeSteps": [
|
|
259
|
+
"项目依赖通过 v1 维护渠道升级,例如 npm install --save-dev --save-exact openxiangda@1.0.268;按项目实际包管理器和依赖类型调整。",
|
|
260
|
+
"安装全局 V2 统一入口后,进入旧项目运行 openxiangda version --json 核对 V1 引擎来源。",
|
|
261
|
+
"刷新对应项目的 V1 Skill,检查依赖与锁文件差异,并执行原有项目测试。",
|
|
262
|
+
"V2 能力满足、项目仍在测试阶段且迁移成本可控时,优先建议 V1 项目采用 V2;先完成项目评估、设计确认和迁移验收。"
|
|
263
|
+
],
|
|
264
|
+
"knownLimitations": [
|
|
265
|
+
"本版本不会自动把 V1 应用迁移到 V2;跨代迁移需要独立设计、映射、演练和批准。",
|
|
266
|
+
"既有 1.0.267 及更早版本的全局更新命令可能安装 latest;新统一入口仍按旧项目标记调用 V1 引擎。"
|
|
267
|
+
],
|
|
268
|
+
"issues": [],
|
|
269
|
+
"sha256": "7aaa99d31b91f725b785259031daaeaf3841cb18a95f6155e43009f1f601e6c9",
|
|
270
|
+
"url": "https://github.com/1377385356/openxiangda-v1/releases/tag/v1.0.268"
|
|
271
|
+
}
|
|
222
272
|
}
|
|
@@ -8,7 +8,7 @@ export default defineAppWorkspaceConfig({
|
|
|
8
8
|
platformUrl:
|
|
9
9
|
process.env.APP_PLATFORM_URL ||
|
|
10
10
|
process.env.OPENXIANGDA_BASE_URL ||
|
|
11
|
-
"https://
|
|
11
|
+
"https://platform.example.com/service",
|
|
12
12
|
servicePrefix: process.env.APP_SERVICE_PREFIX || "/service",
|
|
13
13
|
appKey: process.env.APP_KEY || "",
|
|
14
14
|
appSecret: process.env.APP_SECRET || "",
|
|
@@ -139,7 +139,7 @@ sy-lowcode-app-workspace/
|
|
|
139
139
|
|
|
140
140
|
## 还想看更细的
|
|
141
141
|
|
|
142
|
-
- 全局 skill:`~/.qoder/skills/openxiangda/SKILL.md`(
|
|
142
|
+
- 全局 V1 skill:`~/.qoder/skills/openxiangda-v1/SKILL.md`(V1 决策卡)+ 9 个子 skill;`openxiangda` 由统一分发入口管理。
|
|
143
143
|
- 资源 / 连接器 manifest:`docs/openxiangda-resources-and-connectors.md`(来自 openxiangda 仓库)。
|
|
144
144
|
- 平台数据模型:`references/platform-data-model.md`(option `{label, value}`、附件、成员字段等持久化形态)。
|
|
145
145
|
- 排错清单:`references/troubleshooting.md`。
|
|
@@ -4,7 +4,7 @@ export default defineAppWorkspaceConfig({
|
|
|
4
4
|
deliveryVersion: 2,
|
|
5
5
|
appType: process.env.APP_TYPE || process.env.OPENXIANGDA_APP_TYPE || "APP_XXXXXXXXXXXXXXXX",
|
|
6
6
|
appName: process.env.APP_NAME || "低代码应用",
|
|
7
|
-
platformUrl: process.env.APP_PLATFORM_URL || process.env.OPENXIANGDA_BASE_URL || "http://
|
|
7
|
+
platformUrl: process.env.APP_PLATFORM_URL || process.env.OPENXIANGDA_BASE_URL || "http://platform.example.com/service",
|
|
8
8
|
servicePrefix: process.env.APP_SERVICE_PREFIX || "/service",
|
|
9
9
|
appKey: process.env.APP_KEY || "",
|
|
10
10
|
appSecret: process.env.APP_SECRET || "",
|