@autodevjapan/godd-mcp-alpha 2.15.0 → 2.16.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 -60
- package/assets/native/godd-native-aarch64-apple-darwin +0 -0
- package/assets/native/godd-native-aarch64-apple-darwin.sha256 +1 -1
- package/assets/native/godd-native-x86_64-apple-darwin +0 -0
- package/assets/native/godd-native-x86_64-apple-darwin.sha256 +1 -1
- package/assets/native/godd-native-x86_64-pc-windows-msvc.exe +0 -0
- package/assets/native/godd-native-x86_64-pc-windows-msvc.exe.sha256 +1 -1
- package/assets/native/godd-native-x86_64-unknown-linux-musl +0 -0
- package/assets/native/godd-native-x86_64-unknown-linux-musl.sha256 +1 -1
- package/dist/compile-cache-runtime.cjs +4 -0
- package/dist/compile-cache-runtime.d.ts +154 -0
- package/dist/godd.cjs +272 -239
- package/docs/adapter-contracts.md +182 -0
- package/native-assets.json +14 -12
- package/package.json +21 -10
- package/scripts/native-assets.js +7 -5
package/README.md
CHANGED
|
@@ -44,26 +44,7 @@ The server validates your license online at every startup — there is no offlin
|
|
|
44
44
|
|
|
45
45
|
The full tool list, CLI reference, and troubleshooting live on the **[documentation site](https://www.getgodd.dev/en/docs)**.
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
For adapter implementers only — this subpath exposes no production media-processing route.
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
import {
|
|
53
|
-
forwardMediaIntervalTransformation,
|
|
54
|
-
loadMediaIntervalCalibrationSnapshot,
|
|
55
|
-
validateMediaIntervalAdapterContract,
|
|
56
|
-
} from "@autodevjapan/godd-mcp-alpha/media-interval-adapter-contract";
|
|
57
|
-
|
|
58
|
-
const contract = validateMediaIntervalAdapterContract(adapterPayload);
|
|
59
|
-
const transformation = forwardMediaIntervalTransformation(contract);
|
|
60
|
-
const calibration = loadMediaIntervalCalibrationSnapshot();
|
|
61
|
-
if (calibration.status === "INCONCLUSIVE") {
|
|
62
|
-
throw new Error("Media interval calibration could not be verified");
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Node validates and forwards the envelope only. Interval arithmetic, canonical union coverage, coverage decisions, and source-buffer application remain Rust-owned and must not be duplicated in the adapter payload. An unsupported schema, unknown nested field, insufficient sample count, invalid metadata, or digest mismatch returns `INCONCLUSIVE` with no numeric fallback — stop instead of inventing a default tolerance.
|
|
47
|
+
Writing an adapter? All three subpath contracts (media interval / audio length / compile cache) ship with the package at `docs/adapter-contracts.md`.
|
|
67
48
|
|
|
68
49
|
### License
|
|
69
50
|
|
|
@@ -103,26 +84,7 @@ Node.js 22+ ・ MCP クライアント(Cursor / Claude Code / Codex / Kimi CLI
|
|
|
103
84
|
|
|
104
85
|
ツール一覧・CLI リファレンス・トラブルシューティングは **[ドキュメントサイト](https://www.getgodd.dev/docs)** にまとまっています。
|
|
105
86
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
アダプター実装者向けの契約です(本 subpath は本番の media 処理経路を公開しません)。
|
|
109
|
-
|
|
110
|
-
```ts
|
|
111
|
-
import {
|
|
112
|
-
forwardMediaIntervalTransformation,
|
|
113
|
-
loadMediaIntervalCalibrationSnapshot,
|
|
114
|
-
validateMediaIntervalAdapterContract,
|
|
115
|
-
} from "@autodevjapan/godd-mcp-alpha/media-interval-adapter-contract";
|
|
116
|
-
|
|
117
|
-
const contract = validateMediaIntervalAdapterContract(adapterPayload);
|
|
118
|
-
const transformation = forwardMediaIntervalTransformation(contract);
|
|
119
|
-
const calibration = loadMediaIntervalCalibrationSnapshot();
|
|
120
|
-
if (calibration.status === "INCONCLUSIVE") {
|
|
121
|
-
throw new Error("Media interval calibration could not be verified");
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Node は envelope の検証と転送のみを行います。区間算術、canonical union coverage、coverage判定、source bufferへの適用はRustだけが所有し、アダプター payload 側で再実装してはいけません。未対応スキーマ・未知のネストフィールド・サンプル数不足・不正なメタデータ・digest 不一致は `INCONCLUSIVE` を返し、数値のフォールバックは行いません。既定の許容値を捏造せず、処理を停止してください。
|
|
87
|
+
アダプターを実装する場合、3 つの subpath 契約(media interval / audio length / compile cache)はパッケージ同梱の `docs/adapter-contracts.md` にあります。
|
|
126
88
|
|
|
127
89
|
### ライセンス
|
|
128
90
|
|
|
@@ -162,26 +124,7 @@ Node.js 22+ · MCP-клиент (Cursor / Claude Code / Codex / Kimi CLI / Antig
|
|
|
162
124
|
|
|
163
125
|
Полный список инструментов, справочник CLI и устранение неполадок — на **[сайте документации](https://www.getgodd.dev/ru/docs)**.
|
|
164
126
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
Только для разработчиков адаптеров — этот subpath не открывает production-маршрут обработки медиа.
|
|
168
|
-
|
|
169
|
-
```ts
|
|
170
|
-
import {
|
|
171
|
-
forwardMediaIntervalTransformation,
|
|
172
|
-
loadMediaIntervalCalibrationSnapshot,
|
|
173
|
-
validateMediaIntervalAdapterContract,
|
|
174
|
-
} from "@autodevjapan/godd-mcp-alpha/media-interval-adapter-contract";
|
|
175
|
-
|
|
176
|
-
const contract = validateMediaIntervalAdapterContract(adapterPayload);
|
|
177
|
-
const transformation = forwardMediaIntervalTransformation(contract);
|
|
178
|
-
const calibration = loadMediaIntervalCalibrationSnapshot();
|
|
179
|
-
if (calibration.status === "INCONCLUSIVE") {
|
|
180
|
-
throw new Error("Media interval calibration could not be verified");
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Node только проверяет и передаёт envelope. Расчёт интервалов, canonical union coverage, решение по coverage и применение к source buffer остаются исключительно в Rust и не должны дублироваться в payload адаптера. Неподдерживаемая схема, неизвестное вложенное поле, недостаточное число выборок, некорректные метаданные или несовпадение digest возвращают `INCONCLUSIVE` без числового запасного значения — остановитесь, а не придумывайте допуск по умолчанию.
|
|
127
|
+
Пишете адаптер? Все три контракта subpath (media interval / audio length / compile cache) поставляются вместе с пакетом: `docs/adapter-contracts.md`.
|
|
185
128
|
|
|
186
129
|
### Лицензия
|
|
187
130
|
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
31e2f38fd12481a373fa29470e12870991f56f0e934bf6e8af897d90fec2e21a
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3546b2504c1f8f7897e1ca0693d2da3ca3cddc97ecfdb47f7964a41d4511e7b0
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
a5aca66a29cda82852d756a46e9707caa449cc9b285c9a974fb800e2c2b31870
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
73a803147de665ca9e89715da1a1491f112f4d6f3fd3f31ce2aca5abad67a40a
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";var I=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var G=Object.prototype.hasOwnProperty;var V=(o,e)=>{for(var i in e)I(o,i,{get:e[i],enumerable:!0})},B=(o,e,i,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of H(e))!G.call(o,n)&&n!==i&&I(o,n,{get:()=>e[n],enumerable:!(t=F(e,n))||t.enumerable});return o};var j=o=>B(I({},"__esModule",{value:!0}),o);var ee={};V(ee,{CompileCacheRejectedError:()=>p,CompileCacheRuntime:()=>L,CompileCacheRuntimeError:()=>c,createNdjsonCompileCacheEvaluator:()=>k,spawnCompileCacheEvaluator:()=>Z});module.exports=j(ee);var U=require("node:child_process");var b=require("node:crypto"),K=/^sha256:[0-9a-f]{64}$/u,J=1024,W=Object.freeze({owner:"nextjs-server",clock:"monotonic-milliseconds",trigger:"timer-and-after-lifecycle-event"});function d(o,e,i,t=0){return Object.freeze({action:o,disposition:e,max_retries:t,on_retry_exhausted:t===1?"REJECT":null,reason:i})}var h=Object.freeze({CACHE_HIT:d("USE_CACHED_MODULE","CONTINUE",null),CACHE_MISS_COMPILED:d("PUBLISH_COMPILED_MODULE","CONTINUE",null),SINGLE_FLIGHT_JOINED:d("WAIT_FOR_SINGLE_FLIGHT","CONTINUE",null),TOO_LARGE_FOR_CACHE:d("COMPILE_WITHOUT_CACHE","CONTINUE","ENTRY_LIMIT_EXCEEDED"),BUDGET_OVERFLOW:d("REJECT_CACHE_OPERATION","REJECT","ARITHMETIC_OVERFLOW"),BUDGET_UNRECLAIMABLE:d("RETRY_AFTER_RECONCILE","RETRY","RECLAIMABLE_ENTRIES_INSUFFICIENT",1),BUDGET_EVICTED_LRU:d("DROP_OPAQUE_HANDLE","CONTINUE","LRU_PRESSURE_EVICTION"),SUPERSEDED_BY_NEW_SOURCE:d("DROP_OPAQUE_HANDLE","CONTINUE","SOURCE_GENERATION_SUPERSEDED"),DECK_TOMBSTONED:d("DROP_OPAQUE_HANDLE","CONTINUE","DECK_LIFECYCLE_ENDED"),STALE_GENERATION_REJECTED:d("DISCARD_COMPILED_MODULE","CONTINUE","GENERATION_FENCE_CHANGED"),PREVIEW_LEASE_EXPIRED:d("DROP_OPAQUE_HANDLE","CONTINUE","PREVIEW_LEASE_ENDED"),AGE_EXPIRED:d("DROP_OPAQUE_HANDLE","CONTINUE","MAXIMUM_AGE_EXCEEDED"),IDLE_EXPIRED:d("DROP_OPAQUE_HANDLE","CONTINUE","MAXIMUM_IDLE_EXCEEDED"),RESERVATION_EXPIRED:d("DISCARD_COMPILED_MODULE","CONTINUE","RESERVATION_DEADLINE_EXCEEDED"),COMPILE_FAILED_ROLLED_BACK:d("RELEASE_FAILED_COMPILE","CONTINUE","COMPILE_DID_NOT_COMPLETE"),RECONCILE_CLOCK_REGRESSION:d("REJECT_CACHE_OPERATION","REJECT","RECONCILE_CLOCK_REGRESSED")});function y(o,e){if(o===null||typeof o!="object"||Array.isArray(o))throw new TypeError(`${e} must be an object`);return o}function R(o,e,i){let t=Object.keys(o).sort(),n=[...e].sort();if(t.length!==n.length||t.some((a,r)=>a!==n[r]))throw new TypeError(`${i} has an invalid field set`)}function u(o){return typeof o=="number"&&Number.isSafeInteger(o)&&o>=0}function T(o){return u(o)&&o>0}function g(o){return typeof o=="string"&&K.test(o)}function N(o){return o==="unversioned"||g(o)}function A(o){return typeof o=="string"&&o.length>0&&Buffer.byteLength(o,"utf8")<=J&&!new RegExp("\\p{Cc}","u").test(o)}function X(o){let e=y(o,"compile cache manifest");if(R(e,["workspace_id","deck_id","deck_generation","slide_filename","canonical_source_digest","mdx_policy_generation","compiler_generation","runtime_abi"],"compile cache manifest"),!A(e.workspace_id)||!A(e.deck_id)||!A(e.slide_filename)||!T(e.deck_generation)||!g(e.canonical_source_digest)||!N(e.mdx_policy_generation)||!g(e.compiler_generation)||e.runtime_abi!=="amaroad")throw new TypeError("compile cache manifest is invalid");return e}function q(o){let e=y(o,"compile cache register request");if(R(e,["schema_version","operation","manifest","source_bytes","declared_max_compiled_bytes","now_ms"],"compile cache register request"),X(e.manifest),e.schema_version!==1||e.operation!=="register"||!u(e.source_bytes)||!T(e.declared_max_compiled_bytes)||!u(e.now_ms))throw new TypeError("compile cache register request is invalid");return e}function P(o){let e=y(o,"compile cache project input");R(e,["schema_version","manifest","canonical_source","declared_max_compiled_bytes","now_ms"],"compile cache project input");let i=y(e.manifest,"compile cache project manifest");if(R(i,["workspace_id","deck_id","deck_generation","slide_filename","mdx_policy_generation","compiler_generation","runtime_abi"],"compile cache project manifest"),typeof e.canonical_source!="string")throw new TypeError("compile cache canonical source is invalid");let t=Buffer.byteLength(e.canonical_source,"utf8"),n={schema_version:1,operation:"register",manifest:{...i,canonical_source_digest:`sha256:${(0,b.createHash)("sha256").update(e.canonical_source,"utf8").digest("hex")}`},source_bytes:t,declared_max_compiled_bytes:e.declared_max_compiled_bytes,now_ms:e.now_ms};return q(n)}function M(o){let e=y(o,"compile cache time budget");if(R(e,["age_ms","idle_ms","reservation_ttl_ms"],"compile cache time budget"),!T(e.age_ms)||!T(e.idle_ms)||!T(e.reservation_ttl_ms))throw new TypeError("compile cache time budget is invalid");return Object.freeze({...W,interval_ms:Math.min(e.age_ms,e.idle_ms,e.reservation_ttl_ms)})}function Y(o){if(typeof o!="string"||!Object.hasOwn(h,o))throw new TypeError("compile cache receipt outcome is unsupported");let e=o;return[e,h[e]]}function Q(o){let e=y(o,"compile cache receipt");R(e,["schema_version","canonical_source_digest","deck_generation","mdx_policy_generation","compiler_generation","key_bytes","source_bytes","compiled_bytes","compiled_bytes_measured","outcome","reason"],"compile cache receipt");let[,i]=Y(e.outcome);if(e.schema_version!==1||!g(e.canonical_source_digest)||!u(e.deck_generation)||!N(e.mdx_policy_generation)||!g(e.compiler_generation)||!u(e.key_bytes)||!u(e.source_bytes)||!u(e.compiled_bytes)||typeof e.compiled_bytes_measured!="boolean")throw new TypeError("compile cache receipt is invalid");if(e.reason!==i.reason)throw new TypeError("compile cache receipt reason does not match outcome");return e}function v(o){let e=Q(o);return Object.freeze({action:h[e.outcome].action,disposition:h[e.outcome].disposition,max_retries:h[e.outcome].max_retries,on_retry_exhausted:h[e.outcome].on_retry_exhausted,outcome:e.outcome})}var c=class extends Error{code;constructor(e){super(e),this.name="CompileCacheRuntimeError",this.code=e}},p=class extends Error{outcome;action;disposition;retriesExhausted;constructor(e,i,t,n){super(e),this.name="CompileCacheRejectedError",this.outcome=e,this.action=i,this.disposition=t,this.retriesExhausted=n}},O=class{outcome;action;constructor(e,i){this.outcome=e,this.action=i}},x="";function z(o){return[o.workspace_id,o.deck_id,String(o.deck_generation),o.slide_filename,o.canonical_source_digest,o.mdx_policy_generation,o.compiler_generation,o.runtime_abi].join(x)}function S(o){return[o.canonical_source_digest,String(o.deck_generation),o.mdx_policy_generation,o.compiler_generation].join(x)}var L=class{#c;#y;#s;#m;#_;#n=new Map;#r=new Map;#i=new Map;#E;#t=null;#l=!1;#C=0;#u=null;#d=!1;constructor(e){this.#c=e.evaluator,this.#y=e.budget,this.#s=e.compile,this.#m=e.now,this.#_=e.onReconcileError??(()=>{}),this.#E=M({age_ms:e.budget.age_ms,idle_ms:e.budget.idle_ms,reservation_ttl_ms:e.budget.reservation_ttl_ms})}get reconcilePolicy(){return this.#E}get retainedModuleCount(){return this.#n.size}get reconcileTimerStarted(){return this.#t!==null}startReconcileTimer(){if(this.#t!==null)throw new c("RECONCILE_TIMER_ALREADY_OWNED");this.#t=setInterval(()=>{this.#l||(this.#l=!0,this.reconcile().catch(e=>{this.#_(e)}).finally(()=>{this.#l=!1}))},this.#E.interval_ms),this.#t.unref?.()}stopReconcileTimer(){if(this.#t===null)throw new c("RECONCILE_TIMER_NOT_OWNED");clearInterval(this.#t),this.#t=null,this.#l=!1}async close(){this.#t!==null&&this.stopReconcileTimer(),this.#d=!0,this.#n.clear(),this.#r.clear(),this.#i.clear(),await this.#c.close()}async compile(e){await this.#h();let i=await this.#R(e,!1);if(!(i instanceof O))return i;await this.reconcile();let t=await this.#R(e,!0);if(t instanceof O)throw new p(t.outcome,t.action,"RETRY",!0);return t}async reconcile(){await this.#h();let e=await this.#a({schema_version:1,command:"reconcile",now_ms:this.#m()}),i=e.action==="REJECTED",t=this.#o(e.receipts,i);if(i)throw t===null?new c("EVALUATOR_PROTOCOL"):new p(t.outcome,t.action,t.disposition,!1);return e.receipts}async onDeckRemoved(e,i){await this.#p({schema_version:1,command:"tombstone_deck",workspace_id:e,deck_id:i})}async onPreviewLeaseExpired(e,i){await this.#p({schema_version:1,command:"expire_preview_lease",workspace_id:e,deck_id:i})}async onGenerationUpdated(e){await this.#p({schema_version:1,command:"fence_generations",...e})}async#p(e){await this.#h();let i=await this.#a(e);this.#o(i.receipts,!1),await this.reconcile()}async#R(e,i){let t=P({schema_version:1,manifest:e.manifest,canonical_source:e.canonical_source,declared_max_compiled_bytes:e.declared_max_compiled_bytes,now_ms:this.#m()}),{operation:n,...a}=t,r=await this.#a({command:n,...a}),s=z(t.manifest),l=S(t.manifest);switch(r.action){case"HIT":return this.#T(e,r,s,l,i);case"JOINED":return this.#g(r,s,i);case"COMPILE_REQUESTED":return this.#w(e,r,s,l,i);case"REJECTED":return this.#I(e,r,i);default:try{this.#o(r.receipts,!1)}finally{await this.#e(r.lease)}throw new c("EVALUATOR_PROTOCOL")}}async#T(e,i,t,n,a){try{let r=this.#O(i,"USE_CACHED_MODULE"),s=this.#n.get(t),l=!0;if(s===void 0){let C=this.#C,E=await this.#s(e);s=E.module,l=!1;let f=i.receipts[i.receipts.length-1];if(E.compiled_bytes!==f.compiled_bytes||this.#C!==C)return{module:s,outcome:r.outcome,action:r.action,served_from_cache:!1,retained:!1,retried:a};this.#f(t,n,s)}return{module:s,outcome:r.outcome,action:r.action,served_from_cache:l,retained:!0,retried:a}}finally{await this.#e(i.lease)}}async#g(e,i,t){try{let n=this.#O(e,"WAIT_FOR_SINGLE_FLIGHT"),a=this.#i.get(i);if(a===void 0)throw new c("SINGLE_FLIGHT_MISSING");let r=await a;return{module:r.module,outcome:n.outcome,action:n.action,served_from_cache:!0,retained:r.retained,retried:t}}finally{await this.#e(e.lease)}}async#w(e,i,t,n,a){try{this.#o(i.receipts,!1)}catch(m){throw await this.#e(i.lease),m}if(i.compile_owner!==!0||i.lease===null)throw await this.#e(i.lease),new c("EVALUATOR_PROTOCOL");let r=i.lease,s,l,C=new Promise((m,w)=>{s=m,l=w});C.catch(()=>{}),this.#i.set(t,C);let E;try{E=await this.#s(e)}catch(m){l?.(m);try{let w=await this.#a({schema_version:1,command:"rollback",lease:r});this.#o(w.receipts,!1)}catch{}throw this.#i.delete(t),m}let f;try{f=await this.#a({schema_version:1,command:"commit",lease:r,compiled_bytes:E.compiled_bytes})}catch(m){throw l?.(m),await this.#e(r),this.#i.delete(t),m}let _;try{_=this.#o(f.receipts,!0)}catch(m){throw l?.(m),this.#i.delete(t),await this.#e(r),m}if(this.#i.delete(t),f.action==="NOOP"||_===null){let m=new c("COMMIT_NOT_ACCEPTED");throw l?.(m),await this.#e(r),m}if(_.action==="PUBLISH_COMPILED_MODULE")return this.#f(t,n,E.module),s?.({module:E.module,retained:!0}),await this.#e(r),{module:E.module,outcome:_.outcome,action:_.action,served_from_cache:!1,retained:!0,retried:a};if(_.action==="COMPILE_WITHOUT_CACHE")return s?.({module:E.module,retained:!1}),await this.#e(r),{module:E.module,outcome:_.outcome,action:_.action,served_from_cache:!1,retained:!1,retried:a};let D=new p(_.outcome,_.action,_.disposition,!1);if(l?.(D),await this.#e(r),_.disposition==="RETRY")return new O(_.outcome,_.action);throw D}async#I(e,i,t){let n=this.#o(i.receipts,!0);if(n===null)throw new c("EVALUATOR_PROTOCOL");if(n.disposition==="RETRY")return new O(n.outcome,n.action);if(n.action==="COMPILE_WITHOUT_CACHE")return{module:(await this.#s(e)).module,outcome:n.outcome,action:n.action,served_from_cache:!1,retained:!1,retried:t};throw new p(n.outcome,n.action,n.disposition,!1)}#o(e,i){let t=null;for(let n=0;n<e.length;n+=1){let a=v(e[n]);n===e.length-1&&(t=a),e[n].compiled_bytes_measured&&(a.action==="DROP_OPAQUE_HANDLE"||a.action==="DISCARD_COMPILED_MODULE"||a.action==="RELEASE_FAILED_COMPILE")&&(this.#C+=1,this.#A(S(e[n])))}return i?t:null}#O(e,i){let t=this.#o(e.receipts,!0);if(t===null||t.action!==i)throw new c("EVALUATOR_PROTOCOL");return t}#f(e,i,t){this.#n.set(e,t);let n=this.#r.get(i);if(n===void 0){this.#r.set(i,new Set([e]));return}n.add(e)}#A(e){let i=this.#r.get(e);if(i!==void 0){for(let t of i)this.#n.delete(t);this.#r.delete(e)}}async#e(e){if(e!==null)try{let i=await this.#a({schema_version:1,command:"release",lease:e});this.#o(i.receipts,!1)}catch(i){this.#_(i)}}async#h(){if(this.#d)throw new c("EVALUATOR_CLOSED");this.#u??=(async()=>{if((await this.#c.send({schema_version:1,command:"configure",budget:this.#y})).action!=="CONFIGURED")throw new c("EVALUATOR_PROTOCOL")})().catch(e=>{throw this.#u=null,e}),await this.#u}async#a(e){if(this.#d)throw new c("EVALUATOR_CLOSED");try{return await this.#c.send(e)}catch(i){throw i instanceof c&&i.code==="EVALUATOR_CLOSED"&&(this.#d=!0,this.#n.clear(),this.#r.clear(),this.#i.clear()),i}}};function $(o){if(o===null||typeof o!="object"||Array.isArray(o))throw new c("EVALUATOR_PROTOCOL");let e=o;if(e.schema_version!==1||typeof e.action!="string")throw new c("EVALUATOR_PROTOCOL");if(!Array.isArray(e.receipts))throw new c("EVALUATOR_PROTOCOL");if(e.lease!==null&&(!Number.isSafeInteger(e.lease)||e.lease<1))throw new c("EVALUATOR_PROTOCOL");return o}function k(o){let e=[],i="",t=null;o.readable.setEncoding?.("utf8"),o.readable.on("data",a=>{i+=typeof a=="string"?a:a.toString("utf8");let r=i.indexOf(`
|
|
2
|
+
`);for(;r>=0;){let s=i.slice(0,r).replace(/\r$/u,"");if(i=i.slice(r+1),r=i.indexOf(`
|
|
3
|
+
`),s.length===0)continue;let l=e.shift();if(l===void 0){t=new c("EVALUATOR_PROTOCOL");continue}try{l.resolve($(JSON.parse(s)))}catch(C){l.reject(C)}}});let n=a=>{t=a;for(let r of e.splice(0,e.length))r.reject(a)};return o.readable.on("end",()=>{n(new c("EVALUATOR_CLOSED"))}),o.readable.on("close",()=>{n(new c("EVALUATOR_CLOSED"))}),o.readable.on("error",()=>{n(new c("EVALUATOR_PROTOCOL"))}),{async send(a){if(t!==null)throw t;return new Promise((r,s)=>{let l={resolve:r,reject:s};e.push(l);try{o.writable.write(`${JSON.stringify(a)}
|
|
4
|
+
`)}catch(C){let E=e.indexOf(l);E>=0&&e.splice(E,1),s(C)}})},async close(){n(new c("EVALUATOR_CLOSED")),await o.close()}}}function Z(o){let e=(0,U.spawn)(o.command,[...o.args??["compile-cache","session"]],{stdio:["pipe","pipe","ignore"]});if(e.stdin===null||e.stdout===null)throw new c("EVALUATOR_PROTOCOL");let i=()=>{e.stdout?.destroy()};return e.on("error",i),e.stdin.on("error",i),k({writable:e.stdin,readable:e.stdout,close:()=>{e.stdin?.end(),e.kill()}})}0&&(module.exports={CompileCacheRejectedError,CompileCacheRuntime,CompileCacheRuntimeError,createNdjsonCompileCacheEvaluator,spawnCompileCacheEvaluator});
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The caller that Stage 3 declared but never wired up.
|
|
3
|
+
*
|
|
4
|
+
* `compile-cache-adapter-contract.ts` fixed the 16-outcome policy table and the
|
|
5
|
+
* reconcile driving contract, and `native/src/compile_cache.rs` evaluates them —
|
|
6
|
+
* but nothing called either one, so `age_ms` / `idle_ms` / `reservation_ttl_ms`
|
|
7
|
+
* could not fire and no compiled module was ever actually released. This module
|
|
8
|
+
* is that missing caller: it owns the reconcile timer, branches on every
|
|
9
|
+
* `action` / `disposition` the contract returns, and keeps the compiled modules
|
|
10
|
+
* whose lifetime the receipts govern.
|
|
11
|
+
*
|
|
12
|
+
* The MDX compiler stays outside. `amaroad-mdx-slide-workflow-design.md` Phase 3
|
|
13
|
+
* keeps the Next.js runtime host-owned, so the host injects `compile` and this
|
|
14
|
+
* runtime decides only whether its result may be reused, published, or dropped.
|
|
15
|
+
*/
|
|
16
|
+
import { deriveCompileCacheReconcilePolicy, type CompileCacheCallerAction, type CompileCacheDisposition, type CompileCacheKeyManifest, type CompileCacheOutcome, type CompileCacheReceipt } from "./compile-cache-adapter-contract.js";
|
|
17
|
+
/** Every budget scope `CompileCache::new` validates, mirrored field for field. */
|
|
18
|
+
export interface CompileCacheBudget {
|
|
19
|
+
readonly entry_count: number;
|
|
20
|
+
readonly global_bytes: number;
|
|
21
|
+
readonly deck_bytes: number;
|
|
22
|
+
readonly entry_source_bytes: number;
|
|
23
|
+
readonly entry_compiled_bytes: number;
|
|
24
|
+
readonly inflight_entries: number;
|
|
25
|
+
readonly inflight_bytes: number;
|
|
26
|
+
readonly age_ms: number;
|
|
27
|
+
readonly idle_ms: number;
|
|
28
|
+
readonly reservation_ttl_ms: number;
|
|
29
|
+
}
|
|
30
|
+
export type CompileCacheEvaluatorAction = "CONFIGURED" | "COMPILE_REQUESTED" | "HIT" | "JOINED" | "COMMITTED" | "RELEASED" | "REJECTED" | "MARKED" | "NOOP";
|
|
31
|
+
export interface CompileCacheEvaluatorResponse {
|
|
32
|
+
readonly schema_version: 1;
|
|
33
|
+
readonly action: CompileCacheEvaluatorAction;
|
|
34
|
+
readonly lease: number | null;
|
|
35
|
+
readonly compile_owner: boolean | null;
|
|
36
|
+
readonly receipts: readonly CompileCacheReceipt[];
|
|
37
|
+
}
|
|
38
|
+
/** Transport to the Rust evaluator. One in-flight command at a time, FIFO. */
|
|
39
|
+
export interface CompileCacheEvaluator {
|
|
40
|
+
send(command: Readonly<Record<string, unknown>>): Promise<CompileCacheEvaluatorResponse>;
|
|
41
|
+
close(): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
export type CompileCacheRuntimeErrorCode = "EVALUATOR_PROTOCOL" | "EVALUATOR_CLOSED" | "RECONCILE_TIMER_ALREADY_OWNED" | "RECONCILE_TIMER_NOT_OWNED" | "SINGLE_FLIGHT_MISSING" | "COMMIT_NOT_ACCEPTED";
|
|
44
|
+
export declare class CompileCacheRuntimeError extends Error {
|
|
45
|
+
readonly code: CompileCacheRuntimeErrorCode;
|
|
46
|
+
constructor(code: CompileCacheRuntimeErrorCode);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A cache operation the contract refuses to continue past. Carries the outcome
|
|
50
|
+
* so the host can log a fixed token; it never carries caller input.
|
|
51
|
+
*/
|
|
52
|
+
export declare class CompileCacheRejectedError extends Error {
|
|
53
|
+
readonly outcome: CompileCacheOutcome;
|
|
54
|
+
readonly action: CompileCacheCallerAction;
|
|
55
|
+
readonly disposition: CompileCacheDisposition;
|
|
56
|
+
readonly retriesExhausted: boolean;
|
|
57
|
+
constructor(outcome: CompileCacheOutcome, action: CompileCacheCallerAction, disposition: CompileCacheDisposition, retriesExhausted: boolean);
|
|
58
|
+
}
|
|
59
|
+
export interface CompileCacheCompileRequest {
|
|
60
|
+
readonly manifest: Omit<CompileCacheKeyManifest, "canonical_source_digest">;
|
|
61
|
+
readonly canonical_source: string;
|
|
62
|
+
readonly declared_max_compiled_bytes: number;
|
|
63
|
+
}
|
|
64
|
+
export interface CompileCacheCompiledModule<TModule> {
|
|
65
|
+
readonly module: TModule;
|
|
66
|
+
readonly compiled_bytes: number;
|
|
67
|
+
}
|
|
68
|
+
export type CompileCacheCompiler<TModule> = (request: CompileCacheCompileRequest) => Promise<CompileCacheCompiledModule<TModule>>;
|
|
69
|
+
export interface CompileCacheResult<TModule> {
|
|
70
|
+
readonly module: TModule;
|
|
71
|
+
readonly outcome: CompileCacheOutcome;
|
|
72
|
+
readonly action: CompileCacheCallerAction;
|
|
73
|
+
/** True when the module came back without invoking the compiler. */
|
|
74
|
+
readonly served_from_cache: boolean;
|
|
75
|
+
/** True when the module is deliberately not retained (`TOO_LARGE_FOR_CACHE`). */
|
|
76
|
+
readonly retained: boolean;
|
|
77
|
+
/** True when a `RETRY_AFTER_RECONCILE` disposition forced a second attempt. */
|
|
78
|
+
readonly retried: boolean;
|
|
79
|
+
}
|
|
80
|
+
export interface CompileCacheRuntimeOptions<TModule> {
|
|
81
|
+
readonly evaluator: CompileCacheEvaluator;
|
|
82
|
+
readonly budget: CompileCacheBudget;
|
|
83
|
+
readonly compile: CompileCacheCompiler<TModule>;
|
|
84
|
+
/** Monotonic millisecond clock. The Rust side rejects any regression. */
|
|
85
|
+
readonly now: () => number;
|
|
86
|
+
/**
|
|
87
|
+
* Failures with no caller to raise to — a timer-driven sweep, or a lease
|
|
88
|
+
* release running on an error path — surface here instead of becoming
|
|
89
|
+
* unhandled rejections or replacing the error the caller is already seeing.
|
|
90
|
+
*/
|
|
91
|
+
readonly onReconcileError?: (error: unknown) => void;
|
|
92
|
+
}
|
|
93
|
+
export declare class CompileCacheRuntime<TModule> {
|
|
94
|
+
#private;
|
|
95
|
+
constructor(options: CompileCacheRuntimeOptions<TModule>);
|
|
96
|
+
/** Owner, clock and interval the Next.js server must honour. */
|
|
97
|
+
get reconcilePolicy(): ReturnType<typeof deriveCompileCacheReconcilePolicy>;
|
|
98
|
+
/** Compiled modules this runtime still holds. Drops as reconcile reclaims. */
|
|
99
|
+
get retainedModuleCount(): number;
|
|
100
|
+
get reconcileTimerStarted(): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Starts the single timer the contract names the Next.js server as owner of.
|
|
103
|
+
* A second owner would double-sweep and race the first, so this throws
|
|
104
|
+
* instead of quietly installing another interval.
|
|
105
|
+
*/
|
|
106
|
+
startReconcileTimer(): void;
|
|
107
|
+
stopReconcileTimer(): void;
|
|
108
|
+
close(): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* The wired compile path: consult the cache, compile only when the evaluator
|
|
111
|
+
* says to, and publish only what it accepts.
|
|
112
|
+
*/
|
|
113
|
+
compile(request: CompileCacheCompileRequest): Promise<CompileCacheResult<TModule>>;
|
|
114
|
+
/**
|
|
115
|
+
* The only enforcement point for `age` / `idle` / reservation deadlines.
|
|
116
|
+
* Receipts it returns are what actually frees the retained modules.
|
|
117
|
+
*/
|
|
118
|
+
reconcile(): Promise<readonly CompileCacheReceipt[]>;
|
|
119
|
+
/** Deck delete and rename both end the deck's lifecycle. */
|
|
120
|
+
onDeckRemoved(workspace_id: string, deck_id: string): Promise<void>;
|
|
121
|
+
onPreviewLeaseExpired(workspace_id: string, deck_id: string): Promise<void>;
|
|
122
|
+
/** Deck / policy / compiler generation change: fence everything older. */
|
|
123
|
+
onGenerationUpdated(update: {
|
|
124
|
+
readonly workspace_id: string;
|
|
125
|
+
readonly deck_id: string;
|
|
126
|
+
readonly deck_generation: number;
|
|
127
|
+
readonly mdx_policy_generation: string;
|
|
128
|
+
readonly compiler_generation: string;
|
|
129
|
+
}): Promise<void>;
|
|
130
|
+
}
|
|
131
|
+
interface NdjsonStreams {
|
|
132
|
+
readonly writable: {
|
|
133
|
+
write(chunk: string): unknown;
|
|
134
|
+
};
|
|
135
|
+
readonly readable: {
|
|
136
|
+
on(event: "data", listener: (chunk: Buffer | string) => void): unknown;
|
|
137
|
+
on(event: "end" | "close" | "error", listener: (error?: unknown) => void): unknown;
|
|
138
|
+
setEncoding?(encoding: string): unknown;
|
|
139
|
+
};
|
|
140
|
+
readonly close: () => void | Promise<void>;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* NDJSON codec over an already-connected pair of streams. Responses are matched
|
|
144
|
+
* to commands by arrival order, which is exactly how the Rust session replies.
|
|
145
|
+
*/
|
|
146
|
+
export declare function createNdjsonCompileCacheEvaluator(streams: NdjsonStreams): CompileCacheEvaluator;
|
|
147
|
+
export interface SpawnCompileCacheEvaluatorOptions {
|
|
148
|
+
/** Path to the `godd-native` binary the host already resolves for MCP. */
|
|
149
|
+
readonly command: string;
|
|
150
|
+
readonly args?: readonly string[];
|
|
151
|
+
}
|
|
152
|
+
/** Starts `godd-native compile-cache session` and speaks NDJSON to it. */
|
|
153
|
+
export declare function spawnCompileCacheEvaluator(options: SpawnCompileCacheEvaluatorOptions): CompileCacheEvaluator;
|
|
154
|
+
export {};
|