promptex-js 1.1.1 → 1.2.0
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/README.md +3 -3
- package/dist/cli/core-types.d.ts +8 -0
- package/dist/cli/main.d.ts +12 -2
- package/dist/cli/main.js +47 -21
- package/dist/cli/watch-pass.js +3 -1
- package/dist/cli/watch.js +2 -0
- package/dist/cli-contract.generated.d.ts +1 -1
- package/dist/cli-contract.generated.js +1 -1
- package/dist/config.d.ts +43 -0
- package/dist/config.js +18 -0
- package/dist/index.d.ts +1 -1
- package/dist/native.d.ts +11 -3
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -89,14 +89,14 @@ Common flags: `--out <install root>` (single-directory mode), `--platform <name>
|
|
|
89
89
|
## Machine-readable output
|
|
90
90
|
|
|
91
91
|
`--json` makes a command print one JSON document on stdout. Every document, and every
|
|
92
|
-
file the tool writes under `.promptex/`, carries `formatVersion` (currently `"1.
|
|
92
|
+
file the tool writes under `.promptex/`, carries `formatVersion` (currently `"1.2"`).
|
|
93
93
|
Within 1.x the version only gains keys, so read the keys you know and ignore the rest.
|
|
94
94
|
|
|
95
95
|
`promptex version --json` reports the package, the language and what this CLI
|
|
96
96
|
supports, so a caller can check a feature before using it:
|
|
97
97
|
|
|
98
98
|
```json
|
|
99
|
-
{"formatVersion":"1.
|
|
99
|
+
{"formatVersion":"1.2","package":{"name":"promptex-js","version":"1.0.1"},"language":"ts",
|
|
100
100
|
"capabilities":{"verbs":{"build":{"flags":["--install","--dry-run","…"]},"version":{"flags":[]}},
|
|
101
101
|
"globalFlags":["--json","--locale"]}}
|
|
102
102
|
```
|
|
@@ -105,7 +105,7 @@ A failing command with `--json` prints an error document on stdout and the same
|
|
|
105
105
|
message on one line of stderr:
|
|
106
106
|
|
|
107
107
|
```json
|
|
108
|
-
{"formatVersion":"1.
|
|
108
|
+
{"formatVersion":"1.2","error":{"code":"USAGE_UNKNOWN_FLAG","message":"Unknown flag: --foo","details":{"flag":"--foo","usage":"…"}}}
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
- `code` is stable. A `USAGE_` code means the call was wrong. A `RUN_` code means the
|
package/dist/cli/core-types.d.ts
CHANGED
|
@@ -64,6 +64,8 @@ export interface ResolvedUnitLike {
|
|
|
64
64
|
}[];
|
|
65
65
|
/** 該單元各目標宣告的平台原生設定(ADR-006);無宣告時缺席。 */
|
|
66
66
|
readonly settings?: unknown;
|
|
67
|
+
/** 該單元各目標宣告的平台 plugin(`{ 平台名: [宣告] }`,ADR-044);無宣告時缺席。 */
|
|
68
|
+
readonly plugins?: unknown;
|
|
67
69
|
}
|
|
68
70
|
export interface WatchTarget {
|
|
69
71
|
readonly promptDir: string;
|
|
@@ -76,6 +78,8 @@ export interface WatchTarget {
|
|
|
76
78
|
readonly targetPlan: unknown;
|
|
77
79
|
/** 該單元各目標宣告的平台原生設定(`{ 平台名: 設定 }`);無宣告時為 null。 */
|
|
78
80
|
readonly settings: unknown;
|
|
81
|
+
/** 該單元各目標宣告的平台 plugin(`{ 平台名: [宣告] }`);無宣告時為 null。 */
|
|
82
|
+
readonly plugins: unknown;
|
|
79
83
|
readonly opts: {
|
|
80
84
|
readonly select?: unknown;
|
|
81
85
|
readonly externals: readonly unknown[];
|
|
@@ -96,6 +100,8 @@ export interface WatchInstallSpec {
|
|
|
96
100
|
readonly installRoot: string;
|
|
97
101
|
readonly targetPlan: unknown;
|
|
98
102
|
readonly settings: unknown;
|
|
103
|
+
/** 平台 plugin 宣告(`{ 平台名: [宣告] }`,ADR-044);無宣告時為 null 或缺席。 */
|
|
104
|
+
readonly plugins?: unknown;
|
|
99
105
|
/** 每輪重跑的寫入模式(`build`/`install`/`export`,ADR-035);省略時為安裝。 */
|
|
100
106
|
readonly mode?: string;
|
|
101
107
|
/** 單元的範圍(AC-538)。 */
|
|
@@ -148,6 +154,8 @@ export interface CoreArgs {
|
|
|
148
154
|
readonly irPath: string;
|
|
149
155
|
readonly settingsPath?: string;
|
|
150
156
|
readonly externalsPath?: string;
|
|
157
|
+
/** 旁置的平台 plugin 宣告檔(ADR-044);無宣告時為空字串或缺席。 */
|
|
158
|
+
readonly pluginsPath?: string;
|
|
151
159
|
readonly root: string;
|
|
152
160
|
readonly platform: string;
|
|
153
161
|
readonly sourceRoot?: string;
|
package/dist/cli/main.d.ts
CHANGED
|
@@ -57,6 +57,14 @@ export declare const SWITCH_FIELDS: Readonly<Record<string, 'assumeYes' | 'json'
|
|
|
57
57
|
* 多個目標因此共用同一份輸入而不互相覆寫。
|
|
58
58
|
*/
|
|
59
59
|
export declare function writeSettingsFile(dir: string, settings: unknown): string;
|
|
60
|
+
/**
|
|
61
|
+
* 寫出本單元的旁置平台 plugin 宣告檔,回傳路徑(無宣告時回空字串、不寫檔)。
|
|
62
|
+
*
|
|
63
|
+
* 內容即核心算好的 `{ 平台名: [宣告] }`(見 `orchestrate::unit_plugins`),形態與
|
|
64
|
+
* 平台設定的旁置檔相同、但分開成另一份(ADR-044):平台設定逐字寫進平台的設定檔,
|
|
65
|
+
* 混進 plugin 宣告會被一起寫出去。
|
|
66
|
+
*/
|
|
67
|
+
export declare function writePluginsFile(dir: string, plugins: unknown): string;
|
|
60
68
|
/**
|
|
61
69
|
* 一個單元 × 一個目標的投影與落地,回傳結束碼(0 為成功)。
|
|
62
70
|
*
|
|
@@ -85,7 +93,7 @@ export declare function writeSettingsFile(dir: string, settings: unknown): strin
|
|
|
85
93
|
* 寫出的 `externalsPath`,其餘一律由核心的 `projection_entries` 算出本目標
|
|
86
94
|
* 實際用得到的落點子集。
|
|
87
95
|
*/
|
|
88
|
-
export declare function distributeTarget({ mode, scope, target, targetPlan, usedJson, externalsDir, irPath, settingsPath, externalsPath: fallbackExternalsPath, unitOutDir, unitName, installRoot, sourceRoot, select, }: {
|
|
96
|
+
export declare function distributeTarget({ mode, scope, target, targetPlan, usedJson, externalsDir, irPath, settingsPath, pluginsPath, externalsPath: fallbackExternalsPath, unitOutDir, unitName, installRoot, sourceRoot, select, }: {
|
|
89
97
|
mode: string;
|
|
90
98
|
/** 單元的範圍(AC-538);單一目錄模式與省略時為專案層。 */
|
|
91
99
|
scope?: string;
|
|
@@ -96,6 +104,8 @@ export declare function distributeTarget({ mode, scope, target, targetPlan, used
|
|
|
96
104
|
externalsDir: string;
|
|
97
105
|
irPath: string;
|
|
98
106
|
settingsPath: string;
|
|
107
|
+
/** 旁置的平台 plugin 宣告檔(ADR-044);無宣告時為空字串或缺席。 */
|
|
108
|
+
pluginsPath?: string;
|
|
99
109
|
externalsPath?: string;
|
|
100
110
|
unitOutDir: string;
|
|
101
111
|
unitName: string;
|
|
@@ -108,7 +118,7 @@ export declare function distributeTarget({ mode, scope, target, targetPlan, used
|
|
|
108
118
|
*
|
|
109
119
|
* 由 `src/cli/main.ts` 轉發呼叫。本檔被 import 而不呼叫本函式時(監看的求值
|
|
110
120
|
* 子行程),上方那批模組層狀態維持初始值、不執行任何命令列行為 ── 那正是子
|
|
111
|
-
* 行程要的:它只取用 `distributeTarget` 與 `
|
|
121
|
+
* 行程要的:它只取用 `distributeTarget`、`writeSettingsFile` 與 `writePluginsFile`。
|
|
112
122
|
*
|
|
113
123
|
* 賦值順序與此前的模組層敘述逐條相同:`configAction` 要早於 `parseCliArgs`
|
|
114
124
|
* (後者讀它判斷第二個位置參數是否合法),`config` 分派要早於動詞白名單檢查
|
package/dist/cli/main.js
CHANGED
|
@@ -868,11 +868,14 @@ function emitStructured(out, targetPlatform, queryMeta, contents) {
|
|
|
868
868
|
outcome: out,
|
|
869
869
|
}), LOCALE));
|
|
870
870
|
}
|
|
871
|
-
/** `invokeCore`/`coreOutcome`/`runExtendedTarget`
|
|
872
|
-
function readNativeInputs(irPath, settingsPath, externalsPath) {
|
|
871
|
+
/** `invokeCore`/`coreOutcome`/`runExtendedTarget` 共用的四份輸入讀法。 */
|
|
872
|
+
function readNativeInputs(irPath, settingsPath, externalsPath, pluginsPath) {
|
|
873
873
|
return {
|
|
874
874
|
irJson: readFileSync(irPath, 'utf8'),
|
|
875
875
|
settingsJson: readIfPresent(settingsPath),
|
|
876
|
+
// 平台 plugin 宣告(ADR-044):與平台設定分開成另一份旁置檔,因為平台設定逐字
|
|
877
|
+
// 寫進平台的設定檔,混進 plugin 宣告會被一起寫出去。
|
|
878
|
+
pluginsJson: readIfPresent(pluginsPath),
|
|
876
879
|
// 外部引用(AC-056 至 AC-060):build 與 install/dry-run/manifest 走同一張
|
|
877
880
|
// 落點表。build 不落地平台產物不代表它不需要落點資訊:省略的話引用外部目標
|
|
878
881
|
// 的節點會渲染成 `[名稱](id)` 占位形態而非算出的相對路徑,而寫進框架中繼
|
|
@@ -889,17 +892,17 @@ function readNativeInputs(irPath, settingsPath, externalsPath) {
|
|
|
889
892
|
* 呼叫核心的這一步因此必須與單獨執行 `build --install` 時完全相同,而非讀本檔
|
|
890
893
|
* 頂層的 `command`(該值此時是 `'watch'`,不是綁定認得的動詞)。
|
|
891
894
|
*/
|
|
892
|
-
function invokeCore({ irPath, settingsPath, externalsPath, root, platform, sourceRoot, unitName, mode = MODE, scope = 'project', queryMeta }) {
|
|
893
|
-
const result = coreOutcome({ irPath, settingsPath, externalsPath, root, platform, sourceRoot, unitName, mode, scope });
|
|
895
|
+
function invokeCore({ irPath, settingsPath, externalsPath, pluginsPath, root, platform, sourceRoot, unitName, mode = MODE, scope = 'project', queryMeta }) {
|
|
896
|
+
const result = coreOutcome({ irPath, settingsPath, externalsPath, pluginsPath, root, platform, sourceRoot, unitName, mode, scope });
|
|
894
897
|
if (!result.ok) {
|
|
895
898
|
failOps(result.message);
|
|
896
899
|
}
|
|
897
900
|
// 沒有擴充的目標,核心的投影樹即最終落地的那一棵,取它就是安裝結果本身。
|
|
898
901
|
let contents;
|
|
899
902
|
if (CONTENT_REQUESTED) {
|
|
900
|
-
const { irJson, settingsJson, externalsJson } = readNativeInputs(irPath, settingsPath, externalsPath);
|
|
903
|
+
const { irJson, settingsJson, externalsJson, pluginsJson } = readNativeInputs(irPath, settingsPath, externalsPath, pluginsPath);
|
|
901
904
|
try {
|
|
902
|
-
contents = JSON.parse(loadNativeCore().projectionTree(mode, root, irJson, platform, sourceRoot ?? '', settingsJson, externalsJson, unitName, LOCALE, scope));
|
|
905
|
+
contents = JSON.parse(loadNativeCore().projectionTree(mode, root, irJson, platform, sourceRoot ?? '', settingsJson, externalsJson, unitName, LOCALE, scope, pluginsJson));
|
|
903
906
|
}
|
|
904
907
|
catch (e) {
|
|
905
908
|
failOps(e instanceof Error ? e.message : String(e));
|
|
@@ -917,19 +920,19 @@ function invokeCore({ irPath, settingsPath, externalsPath, root, platform, sourc
|
|
|
917
920
|
* 兩者的結果形態不同(`BuildOutcome` 對 `DistributeOutcome`),由呼叫端依
|
|
918
921
|
* `mode` 分流(`present` 的無標籤形態比對)。
|
|
919
922
|
*/
|
|
920
|
-
function coreOutcome({ irPath, settingsPath, externalsPath, root, platform, sourceRoot, unitName: unit, mode = MODE, scope = 'project', }) {
|
|
923
|
+
function coreOutcome({ irPath, settingsPath, externalsPath, pluginsPath, root, platform, sourceRoot, unitName: unit, mode = MODE, scope = 'project', }) {
|
|
921
924
|
const native = loadNativeCore();
|
|
922
|
-
const { irJson, settingsJson, externalsJson } = readNativeInputs(irPath, settingsPath, externalsPath);
|
|
925
|
+
const { irJson, settingsJson, externalsJson, pluginsJson } = readNativeInputs(irPath, settingsPath, externalsPath, pluginsPath);
|
|
923
926
|
try {
|
|
924
927
|
if (mode === 'build') {
|
|
925
|
-
//
|
|
926
|
-
//
|
|
928
|
+
// 框架中繼住 `.promptex/{單元}/`(ADR-027),省略 `unit` 會讓每個單元都寫進
|
|
929
|
+
// 預設單元的目錄而互相覆蓋。
|
|
927
930
|
//
|
|
928
|
-
//
|
|
929
|
-
//
|
|
930
|
-
return { ok: true, outcome: JSON.parse(native.build(irJson, root, platform, settingsJson, externalsJson, unit, LOCALE, scope)) };
|
|
931
|
+
// `sourceRoot` 排在最後:本動詞不拷貝素材(ADR-028),它只用來核對平台
|
|
932
|
+
// plugin 的 `modules` 檔案存在(ADR-044)。
|
|
933
|
+
return { ok: true, outcome: JSON.parse(native.build(irJson, root, platform, settingsJson, externalsJson, unit, LOCALE, scope, pluginsJson, sourceRoot ?? '')) };
|
|
931
934
|
}
|
|
932
|
-
return { ok: true, outcome: JSON.parse(native.distribute(mode, irJson, root, platform, sourceRoot ?? '', settingsJson, unit, externalsJson, LOCALE, scope)) };
|
|
935
|
+
return { ok: true, outcome: JSON.parse(native.distribute(mode, irJson, root, platform, sourceRoot ?? '', settingsJson, unit, externalsJson, LOCALE, scope, pluginsJson)) };
|
|
933
936
|
}
|
|
934
937
|
catch (e) {
|
|
935
938
|
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
@@ -1123,10 +1126,10 @@ async function runExtendedTarget(target, mode, coreArgs, unitOutDir, unitName, q
|
|
|
1123
1126
|
const root = unitOutDir;
|
|
1124
1127
|
const unit = unitName;
|
|
1125
1128
|
const sourceRoot = coreArgs.sourceRoot;
|
|
1126
|
-
const { irJson, settingsJson, externalsJson } = readNativeInputs(coreArgs.irPath, coreArgs.settingsPath, coreArgs.externalsPath);
|
|
1129
|
+
const { irJson, settingsJson, externalsJson, pluginsJson } = readNativeInputs(coreArgs.irPath, coreArgs.settingsPath, coreArgs.externalsPath, coreArgs.pluginsPath);
|
|
1127
1130
|
let beforeJson;
|
|
1128
1131
|
try {
|
|
1129
|
-
beforeJson = native.projectionTree(mode, root, irJson, target.platform, sourceRoot ?? '', settingsJson, externalsJson, unit, LOCALE, coreArgs.scope ?? 'project');
|
|
1132
|
+
beforeJson = native.projectionTree(mode, root, irJson, target.platform, sourceRoot ?? '', settingsJson, externalsJson, unit, LOCALE, coreArgs.scope ?? 'project', pluginsJson);
|
|
1130
1133
|
}
|
|
1131
1134
|
catch (e) {
|
|
1132
1135
|
failOps(e instanceof Error ? e.message : String(e));
|
|
@@ -1475,6 +1478,21 @@ export function writeSettingsFile(dir, settings) {
|
|
|
1475
1478
|
dumpHandoff('PROMPTEX_DUMP_SETTINGS', text);
|
|
1476
1479
|
return path;
|
|
1477
1480
|
}
|
|
1481
|
+
/**
|
|
1482
|
+
* 寫出本單元的旁置平台 plugin 宣告檔,回傳路徑(無宣告時回空字串、不寫檔)。
|
|
1483
|
+
*
|
|
1484
|
+
* 內容即核心算好的 `{ 平台名: [宣告] }`(見 `orchestrate::unit_plugins`),形態與
|
|
1485
|
+
* 平台設定的旁置檔相同、但分開成另一份(ADR-044):平台設定逐字寫進平台的設定檔,
|
|
1486
|
+
* 混進 plugin 宣告會被一起寫出去。
|
|
1487
|
+
*/
|
|
1488
|
+
export function writePluginsFile(dir, plugins) {
|
|
1489
|
+
if (!plugins)
|
|
1490
|
+
return '';
|
|
1491
|
+
mkdirSync(dir, { recursive: true });
|
|
1492
|
+
const path = join(dir, 'plugins.json');
|
|
1493
|
+
writeFileSync(path, `${JSON.stringify(plugins, null, 2)}\n`);
|
|
1494
|
+
return path;
|
|
1495
|
+
}
|
|
1478
1496
|
/**
|
|
1479
1497
|
* 既有單一目錄模式:srcDir/root/platform/unit 均取 CLI 旗標,行為與配置
|
|
1480
1498
|
* 單元系統實作前逐字相同。
|
|
@@ -1509,9 +1527,10 @@ async function runSingleDir() {
|
|
|
1509
1527
|
const status = invokeCore({
|
|
1510
1528
|
irPath,
|
|
1511
1529
|
// 單一目錄模式沒有配置檔,也就沒有 target 可宣告平台原生設定
|
|
1512
|
-
// (ADR-006
|
|
1530
|
+
// (ADR-006「平台設定住目標」),平台 plugin 同理(ADR-044):這裡恆為空。
|
|
1513
1531
|
settingsPath: '',
|
|
1514
1532
|
externalsPath: '',
|
|
1533
|
+
pluginsPath: '',
|
|
1515
1534
|
root: singleRoot,
|
|
1516
1535
|
platform,
|
|
1517
1536
|
sourceRoot: srcDir,
|
|
@@ -1548,7 +1567,7 @@ async function runSingleDir() {
|
|
|
1548
1567
|
* 寫出的 `externalsPath`,其餘一律由核心的 `projection_entries` 算出本目標
|
|
1549
1568
|
* 實際用得到的落點子集。
|
|
1550
1569
|
*/
|
|
1551
|
-
export async function distributeTarget({ mode, scope = 'project', target, targetPlan, usedJson, externalsDir, irPath, settingsPath, externalsPath: fallbackExternalsPath = '', unitOutDir, unitName, installRoot, sourceRoot, select, }) {
|
|
1570
|
+
export async function distributeTarget({ mode, scope = 'project', target, targetPlan, usedJson, externalsDir, irPath, settingsPath, pluginsPath = '', externalsPath: fallbackExternalsPath = '', unitOutDir, unitName, installRoot, sourceRoot, select, }) {
|
|
1552
1571
|
present({ kind: 'unitHeader', unit: unitName, platform: target.platform, outDir: unitOutDir });
|
|
1553
1572
|
const queryMeta = { unit: unitName, installRoot };
|
|
1554
1573
|
if ('emit' in target && typeof target.emit === 'function') {
|
|
@@ -1559,7 +1578,7 @@ export async function distributeTarget({ mode, scope = 'project', target, target
|
|
|
1559
1578
|
const externalsPath = targetPlan
|
|
1560
1579
|
? writeExternalsFile(externalsDir, target.platform, JSON.parse(loadNativeCore().orchestrateProjectionEntries(targetJson, usedJson, LOCALE)))
|
|
1561
1580
|
: fallbackExternalsPath;
|
|
1562
|
-
const coreArgs = { irPath, settingsPath, externalsPath, platform: target.platform, sourceRoot, unitName, scope };
|
|
1581
|
+
const coreArgs = { irPath, settingsPath, externalsPath, pluginsPath, platform: target.platform, sourceRoot, unitName, scope };
|
|
1563
1582
|
// 平台適配的擴充(AC 無對應條款,依 promptex-prototype 原型行為實作):
|
|
1564
1583
|
// 各寫入模式一律走同一條路,起點與落地方式的差異由核心承擔(見
|
|
1565
1584
|
// `runExtendedTarget`)。
|
|
@@ -1659,6 +1678,8 @@ async function runConfigUnits(configPath) {
|
|
|
1659
1678
|
// 平台原生設定由核心從各目標的宣告合成(ADR-006「平台設定住目標」),本層
|
|
1660
1679
|
// 只把它原樣寫成投影要吃的旁置檔,不自行從配置物件取一次。
|
|
1661
1680
|
const settingsPath = writeSettingsFile(compileDir, resolved.settings);
|
|
1681
|
+
// 平台 plugin 宣告同樣由核心合成(ADR-044),寫成另一份旁置檔。
|
|
1682
|
+
const pluginsPath = writePluginsFile(compileDir, resolved.plugins);
|
|
1662
1683
|
const { irPath, diagnostics } = await compile(resolved.srcDir, compileDir, {
|
|
1663
1684
|
// 專案根即配置檔所在目錄(PDR-003),與下方呼叫核心時傳的 sourceRoot
|
|
1664
1685
|
// 同一個值:plugin 的快取目錄與 asset 素材的換算基準因此不會分家。
|
|
@@ -1700,6 +1721,7 @@ async function runConfigUnits(configPath) {
|
|
|
1700
1721
|
externalsDir: compileDir,
|
|
1701
1722
|
irPath,
|
|
1702
1723
|
settingsPath,
|
|
1724
|
+
pluginsPath,
|
|
1703
1725
|
unitOutDir: targetOutDir,
|
|
1704
1726
|
unitName,
|
|
1705
1727
|
installRoot: MODE === 'export' ? targetOutDir : resolved.installRoot,
|
|
@@ -1724,7 +1746,7 @@ async function runConfigUnits(configPath) {
|
|
|
1724
1746
|
*
|
|
1725
1747
|
* 由 `src/cli/main.ts` 轉發呼叫。本檔被 import 而不呼叫本函式時(監看的求值
|
|
1726
1748
|
* 子行程),上方那批模組層狀態維持初始值、不執行任何命令列行為 ── 那正是子
|
|
1727
|
-
* 行程要的:它只取用 `distributeTarget` 與 `
|
|
1749
|
+
* 行程要的:它只取用 `distributeTarget`、`writeSettingsFile` 與 `writePluginsFile`。
|
|
1728
1750
|
*
|
|
1729
1751
|
* 賦值順序與此前的模組層敘述逐條相同:`configAction` 要早於 `parseCliArgs`
|
|
1730
1752
|
* (後者讀它判斷第二個位置參數是否合法),`config` 分派要早於動詞白名單檢查
|
|
@@ -1827,6 +1849,8 @@ export async function main(argv) {
|
|
|
1827
1849
|
let watchTargetPlan = null;
|
|
1828
1850
|
// 單一目錄模式沒有配置檔、也就沒有 target 可宣告平台原生設定(ADR-006)。
|
|
1829
1851
|
let watchSettings = null;
|
|
1852
|
+
// 平台 plugin 同理只住目標(ADR-044)。
|
|
1853
|
+
let watchPlugins = null;
|
|
1830
1854
|
// 單元的範圍(AC-538):單一目錄模式固定專案層,配置單元模式取解析結果。
|
|
1831
1855
|
let watchScope = 'project';
|
|
1832
1856
|
if (existsSync(configPath)) {
|
|
@@ -1858,7 +1882,8 @@ export async function main(argv) {
|
|
|
1858
1882
|
}
|
|
1859
1883
|
;
|
|
1860
1884
|
({ promptDir: watchPromptDir, root: watchRoot, platform: watchPlatform, unitName: watchUnit,
|
|
1861
|
-
installRoot: watchInstallRoot, targetPlan: watchTargetPlan, settings: watchSettings,
|
|
1885
|
+
installRoot: watchInstallRoot, targetPlan: watchTargetPlan, settings: watchSettings, plugins: watchPlugins,
|
|
1886
|
+
opts: watchOpts } = target);
|
|
1862
1887
|
watchScope = resolution.units.find((u) => u.name === watchUnit)?.scope ?? 'project';
|
|
1863
1888
|
// 素材相對路徑的換算基準是專案根(配置檔所在目錄),與 runConfigUnits
|
|
1864
1889
|
// 呼叫核心時傳的 sourceRoot 同一個值:監看沿用安裝流程,不另立一套換算
|
|
@@ -1894,6 +1919,7 @@ export async function main(argv) {
|
|
|
1894
1919
|
installRoot: watchInstallRoot,
|
|
1895
1920
|
targetPlan: watchTargetPlan,
|
|
1896
1921
|
settings: watchSettings,
|
|
1922
|
+
plugins: watchPlugins,
|
|
1897
1923
|
mode: MODE,
|
|
1898
1924
|
scope: watchScope,
|
|
1899
1925
|
},
|
package/dist/cli/watch-pass.js
CHANGED
|
@@ -106,7 +106,7 @@ async function unitDef() {
|
|
|
106
106
|
* 作者改完檔案永遠等不到下一輪)。本輪安裝成功與否由行程的結束碼帶回。
|
|
107
107
|
*/
|
|
108
108
|
async function installTarget(unit, result, spec) {
|
|
109
|
-
const { distributeTarget, writeSettingsFile } = await import('./main.js');
|
|
109
|
+
const { distributeTarget, writePluginsFile, writeSettingsFile } = await import('./main.js');
|
|
110
110
|
const { engine } = await import('../index.js');
|
|
111
111
|
// 無配置檔時目標就是命令列指定的那個平台,沒有 emit 也沒有 extend;有配置
|
|
112
112
|
// 檔時取回作者宣告的那一筆(帶不經序列化的閉包)。
|
|
@@ -124,6 +124,8 @@ async function installTarget(unit, result, spec) {
|
|
|
124
124
|
// 平台設定由父行程從核心的單元解析結果帶過來(ADR-006「平台設定住目標」),
|
|
125
125
|
// 不由本輪求值產出:它是配置的宣告,重新求值不會改變它。
|
|
126
126
|
settingsPath: writeSettingsFile(workDir, spec.settings ?? null),
|
|
127
|
+
// 平台 plugin 宣告與平台設定同一條(ADR-044),分開成另一份旁置檔。
|
|
128
|
+
pluginsPath: writePluginsFile(workDir, spec.plugins ?? null),
|
|
127
129
|
externalsPath: result.externalsPath,
|
|
128
130
|
unitOutDir: spec.root,
|
|
129
131
|
unitName: spec.unitName,
|
package/dist/cli/watch.js
CHANGED
|
@@ -291,6 +291,8 @@ export function resolveWatchTarget(resolved, rawUnits = []) {
|
|
|
291
291
|
// 平台原生設定隨單元的解析結果一起帶過去(ADR-006「平台設定住目標」):
|
|
292
292
|
// 監看沿用安裝流程,設定的來源因此也與 安裝模式(`--install`)同一個。
|
|
293
293
|
settings: only.settings ?? null,
|
|
294
|
+
// 平台 plugin 宣告同理(ADR-044)。
|
|
295
|
+
plugins: only.plugins ?? null,
|
|
294
296
|
opts: {
|
|
295
297
|
select: rawUnits[target.unitIndex]?.select,
|
|
296
298
|
externals: target.evaluationExternals,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// crates/promptex-core/src/graph.rs 的 FORMAT_VERSION。要改內容就改來源,
|
|
5
5
|
// 再跑 `pnpm run gen:cli-contract` 重新生成;直接改本檔會被核對閘擋下。
|
|
6
6
|
/** 核心的格式版本(`crates/promptex-core/src/graph.rs` 的 `FORMAT_VERSION`),不載入原生綁定即可取得。 */
|
|
7
|
-
export const FORMAT_VERSION = '1.
|
|
7
|
+
export const FORMAT_VERSION = '1.2';
|
|
8
8
|
export const VERBS = [
|
|
9
9
|
{
|
|
10
10
|
name: 'build',
|
package/dist/config.d.ts
CHANGED
|
@@ -80,16 +80,49 @@ export interface Target {
|
|
|
80
80
|
readonly extend?: readonly AdapterExtension[];
|
|
81
81
|
/** 該平台的原生設定;鍵值逐字寫入該平台的設定檔。 */
|
|
82
82
|
readonly settings?: Record<string, unknown>;
|
|
83
|
+
/**
|
|
84
|
+
* 平台 plugin 的分組(ADR-044),只有內建 `claude()`/`codex()` 收這個選項;
|
|
85
|
+
* 第三方適配(`defineTarget`)不提供它,核心對第三方目標的宣告以 E219 阻斷。
|
|
86
|
+
*/
|
|
87
|
+
readonly plugins?: readonly PlatformPlugin[];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 目標上的一個平台 plugin(ADR-044):把一組節點打包成平台原生的 plugin。
|
|
91
|
+
*
|
|
92
|
+
* `select` 沿用單元的 `SelectSpec`,但只決定歸屬:它在單元的 `select` 已選出的
|
|
93
|
+
* 節點裡分組,選不到單元沒選的節點。沒被任何 plugin 選到的節點照常各自安裝;
|
|
94
|
+
* 一個節點在同一目標最多屬於一個 plugin。
|
|
95
|
+
*
|
|
96
|
+
* 這和單元的 `plugins`(解析期擴充,`Plugin`)是兩件事:這裡的產物是平台的 plugin
|
|
97
|
+
* 目錄,那裡是解析節點時執行的擴充。
|
|
98
|
+
*/
|
|
99
|
+
export interface PlatformPlugin {
|
|
100
|
+
/** plugin 名稱:小寫英數加 `-`,長度 1 至 64,不含 `--`,不用 Claude 保留名。 */
|
|
101
|
+
readonly name: string;
|
|
102
|
+
/** 版本字串,不核對格式;省略時不寫進 manifest。 */
|
|
103
|
+
readonly version?: string;
|
|
104
|
+
readonly description?: string;
|
|
105
|
+
readonly select: SelectSpec;
|
|
106
|
+
/** 原樣帶進 manifest 的其他欄位;不得覆寫框架產生的鍵(name、元件路徑等)。 */
|
|
107
|
+
readonly manifest?: Record<string, unknown>;
|
|
108
|
+
/** mod 的 hooks module 路徑,相對 plugin 根目錄,指向同一個 plugin 內 dir 節點的檔案(只屬於 Claude)。 */
|
|
109
|
+
readonly modules?: string;
|
|
83
110
|
}
|
|
111
|
+
/** codex 目標的平台 plugin:mod 只屬於 Claude,因此沒有 `modules`。 */
|
|
112
|
+
export type CodexPlatformPlugin = Omit<PlatformPlugin, 'modules'>;
|
|
84
113
|
/** claude target 建構器的選項。 */
|
|
85
114
|
export interface ClaudeTargetOptions {
|
|
86
115
|
readonly extend?: readonly AdapterExtension[];
|
|
87
116
|
readonly settings?: ClaudeSettings;
|
|
117
|
+
/** 打包成 Claude plugin 的節點分組(ADR-044)。 */
|
|
118
|
+
readonly plugins?: readonly PlatformPlugin[];
|
|
88
119
|
}
|
|
89
120
|
/** codex target 建構器的選項。 */
|
|
90
121
|
export interface CodexTargetOptions {
|
|
91
122
|
readonly extend?: readonly AdapterExtension[];
|
|
92
123
|
readonly settings?: CodexSettings;
|
|
124
|
+
/** 打包成 Codex plugin 的節點分組(ADR-044)。 */
|
|
125
|
+
readonly plugins?: readonly CodexPlatformPlugin[];
|
|
93
126
|
}
|
|
94
127
|
/** claude target 建構器:求值為 `{ platform: 'claude' }`(AC-086),可選帶 `extend` 擴充既有平台的產物形態、`settings` 宣告平台原生設定。 */
|
|
95
128
|
export declare const claude: (options?: ClaudeTargetOptions) => Target;
|
|
@@ -190,6 +223,16 @@ export interface TargetIR {
|
|
|
190
223
|
readonly settings?: Record<string, unknown>;
|
|
191
224
|
readonly configSchema?: unknown;
|
|
192
225
|
readonly configSchemaLocales?: Record<string, unknown>;
|
|
226
|
+
readonly plugins?: readonly PlatformPluginIR[];
|
|
227
|
+
}
|
|
228
|
+
/** 中介表示裡的一個平台 plugin:欄位順序與核心的 `PluginDecl` 相同,三語言逐字一致。 */
|
|
229
|
+
export interface PlatformPluginIR {
|
|
230
|
+
readonly name: string;
|
|
231
|
+
readonly version?: string;
|
|
232
|
+
readonly description?: string;
|
|
233
|
+
readonly select: SelectSpec;
|
|
234
|
+
readonly manifest?: Record<string, unknown>;
|
|
235
|
+
readonly modules?: string;
|
|
193
236
|
}
|
|
194
237
|
/** 中介表示裡的一個擴充:求值期的名字,加上它的參數宣告(ADR-013) */
|
|
195
238
|
export interface PluginIR {
|
package/dist/config.js
CHANGED
|
@@ -13,6 +13,7 @@ function builtinTarget(platform, options) {
|
|
|
13
13
|
platform,
|
|
14
14
|
...(options?.extend?.length ? { extend: options.extend } : {}),
|
|
15
15
|
...(options?.settings ? { settings: options.settings } : {}),
|
|
16
|
+
...(options?.plugins?.length ? { plugins: options.plugins } : {}),
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
/** claude target 建構器:求值為 `{ platform: 'claude' }`(AC-086),可選帶 `extend` 擴充既有平台的產物形態、`settings` 宣告平台原生設定。 */
|
|
@@ -35,6 +36,20 @@ export function isExternalConfigRef(spec) {
|
|
|
35
36
|
export function defineConfig(unit) {
|
|
36
37
|
return Array.isArray(unit) ? [...unit] : [unit];
|
|
37
38
|
}
|
|
39
|
+
/** 平台 plugin → 中介表示:鍵序固定、省略的欄位不帶,`select` 只留宣告了的兩個欄位。 */
|
|
40
|
+
function platformPluginToIR(p) {
|
|
41
|
+
return {
|
|
42
|
+
name: p.name,
|
|
43
|
+
...(p.version !== undefined ? { version: p.version } : {}),
|
|
44
|
+
...(p.description !== undefined ? { description: p.description } : {}),
|
|
45
|
+
select: {
|
|
46
|
+
...(p.select.tags !== undefined ? { tags: p.select.tags } : {}),
|
|
47
|
+
...(p.select.exclude !== undefined ? { exclude: p.select.exclude } : {}),
|
|
48
|
+
},
|
|
49
|
+
...(p.manifest !== undefined ? { manifest: p.manifest } : {}),
|
|
50
|
+
...(p.modules !== undefined ? { modules: p.modules } : {}),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
38
53
|
/**
|
|
39
54
|
* 命令列工具交給核心編排入口的配置形態(ADR-008 協作形態第 1 步)。
|
|
40
55
|
*
|
|
@@ -67,6 +82,9 @@ export function configToOrchestrationIR(units) {
|
|
|
67
82
|
...(t.settings ? { settings: t.settings } : {}),
|
|
68
83
|
...(t.configSchema !== undefined ? { configSchema: t.configSchema } : {}),
|
|
69
84
|
...(t.configSchemaLocales ? { configSchemaLocales: t.configSchemaLocales } : {}),
|
|
85
|
+
// 平台 plugin 是純資料(ADR-044),進中介表示交給核心分組;無宣告時不帶這一鍵,
|
|
86
|
+
// 未使用它的既有配置求值結果逐字不變。
|
|
87
|
+
...(t.plugins?.length ? { plugins: t.plugins.map(platformPluginToIR) } : {}),
|
|
70
88
|
})),
|
|
71
89
|
// 擴充帶名字與它的參數宣告(ADR-013):宣告由擴充自己 import 進來,隨中介表示
|
|
72
90
|
// 交給讀取端,讀取端因此不必知道它裝在哪裡。未宣告時該欄省略而非填 null:
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type { Content, ContentPiece, Ref, SelectSpec } from './registry.js';
|
|
|
3
3
|
export type { Ir, Kind, Node, Piece, Provenance, RefTarget } from './ir.js';
|
|
4
4
|
export type { MDNode } from './content.js';
|
|
5
5
|
export { engine, registerExternal } from './registry.js';
|
|
6
|
-
export { claude, codex, configToIR, configToOrchestrationIR, defineConfig, isExternalConfigRef, type AdapterExtension, type ClaudeSettings, type ClaudeTargetOptions, type CodexSettings, type CodexTargetOptions, type ConfigIr, type ConfigUnit, type ConfigUnitIR, type ExternalConfigRef, type ExternalEntry as ConfigExternalEntry, type ExternalSpec, type Target, } from './config.js';
|
|
6
|
+
export { claude, codex, configToIR, configToOrchestrationIR, defineConfig, isExternalConfigRef, type AdapterExtension, type ClaudeSettings, type ClaudeTargetOptions, type CodexSettings, type CodexPlatformPlugin, type CodexTargetOptions, type ConfigIr, type ConfigUnit, type ConfigUnitIR, type ExternalConfigRef, type ExternalEntry as ConfigExternalEntry, type ExternalSpec, type PlatformPlugin, type PlatformPluginIR, type Target, } from './config.js';
|
|
7
7
|
export type { ManifestNode, ManifestQuery } from './externals.js';
|
|
8
8
|
export { readConfig, REFUSAL_MESSAGES, declaredSchema, RefusalError, SCHEMA_FILE, writeConfig, type ConfigView, type Entry, type EntryField, type ImportStyle, type Op, type Refusal, type RefusalCode, type RewriteOutcome, type UnitView, } from './config-rewrite.js';
|
|
9
9
|
export type { LockEntry, Plugin, PluginEntry, PrepareContext, TransformContext, ValidateContext } from './plugin.js';
|
package/dist/native.d.ts
CHANGED
|
@@ -17,9 +17,15 @@
|
|
|
17
17
|
*/
|
|
18
18
|
export interface NativeCore {
|
|
19
19
|
/** 編譯:完整投影計算,只寫框架中繼、不落平台產物(ADR-028)。 */
|
|
20
|
-
build(irJson: string, root: string, platform: string, settingsJson: string | null | undefined, externalsJson: string | null | undefined, unit: string | null | undefined, locale: string, scope?: string | null
|
|
20
|
+
build(irJson: string, root: string, platform: string, settingsJson: string | null | undefined, externalsJson: string | null | undefined, unit: string | null | undefined, locale: string, scope?: string | null,
|
|
21
|
+
/** 旁置的平台 plugin 宣告(`{ 平台名: [宣告] }`,ADR-044)。 */
|
|
22
|
+
pluginsJson?: string | null,
|
|
23
|
+
/** 只用來核對平台 plugin 的 `modules` 檔案存在;本動詞不拷貝素材。 */
|
|
24
|
+
sourceRoot?: string | null): string;
|
|
21
25
|
/** 安裝/預覽/查詢:`mode` 決定副作用範圍。 */
|
|
22
|
-
distribute(mode: string, irJson: string, root: string, platform: string, sourceRoot: string, settingsJson: string | null | undefined, unit: string, externalsJson: string | null | undefined, locale: string, scope?: string | null
|
|
26
|
+
distribute(mode: string, irJson: string, root: string, platform: string, sourceRoot: string, settingsJson: string | null | undefined, unit: string, externalsJson: string | null | undefined, locale: string, scope?: string | null,
|
|
27
|
+
/** 旁置的平台 plugin 宣告(ADR-044)。 */
|
|
28
|
+
pluginsJson?: string | null): string;
|
|
23
29
|
/** 第三方適配的產物落地(AC-244):`emit` 回傳的檔案表交回核心。 */
|
|
24
30
|
thirdPartyDistribute(mode: string, filesJson: string, irJson: string, reportJson: string, root: string, unit: string, platform: string, locale: string): string;
|
|
25
31
|
/**
|
|
@@ -31,7 +37,9 @@ export interface NativeCore {
|
|
|
31
37
|
*/
|
|
32
38
|
projectionTree(mode: string, root: string, irJson: string, platform: string, sourceRoot: string, settingsJson: string | null | undefined, externalsJson: string | null | undefined, unit: string | null | undefined, locale: string,
|
|
33
39
|
/** 單元的範圍(`user`/`project`,AC-538);省略時視為專案層。 */
|
|
34
|
-
scope?: string | null
|
|
40
|
+
scope?: string | null,
|
|
41
|
+
/** 旁置的平台 plugin 宣告(ADR-044)。 */
|
|
42
|
+
pluginsJson?: string | null): string;
|
|
35
43
|
/** 平台擴充的落地:比對擴充前後的產物樹並寫入。 */
|
|
36
44
|
extensionApply(mode: string, root: string, unit: string, platform: string, beforeJson: string, afterJson: string, baselineJson: string, locale: string): string;
|
|
37
45
|
/** 人讀版面(ADR-030):版面住核心,三個生態印出同一份。 */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "promptex-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "TypeScript SDK、核心的預編譯二進位綁定與命令列工具,三者為同一次發布產出",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"author": "promptex-ai",
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
"vitest": "^4.1.11"
|
|
75
75
|
},
|
|
76
76
|
"optionalDependencies": {
|
|
77
|
-
"promptex-js-darwin-arm64": "1.
|
|
78
|
-
"promptex-js-darwin-x64": "1.
|
|
79
|
-
"promptex-js-linux-arm64-gnu": "1.
|
|
80
|
-
"promptex-js-linux-x64-gnu": "1.
|
|
81
|
-
"promptex-js-win32-arm64-msvc": "1.
|
|
82
|
-
"promptex-js-win32-x64-msvc": "1.
|
|
77
|
+
"promptex-js-darwin-arm64": "1.2.0",
|
|
78
|
+
"promptex-js-darwin-x64": "1.2.0",
|
|
79
|
+
"promptex-js-linux-arm64-gnu": "1.2.0",
|
|
80
|
+
"promptex-js-linux-x64-gnu": "1.2.0",
|
|
81
|
+
"promptex-js-win32-arm64-msvc": "1.2.0",
|
|
82
|
+
"promptex-js-win32-x64-msvc": "1.2.0"
|
|
83
83
|
}
|
|
84
84
|
}
|