@cleocode/core 2026.4.27 → 2026.4.29
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/dist/adrs/sync.d.ts.map +1 -1
- package/dist/adrs/types.d.ts +1 -0
- package/dist/adrs/types.d.ts.map +1 -1
- package/dist/index.js +198 -105
- package/dist/index.js.map +3 -3
- package/dist/mvi-helpers.d.ts.map +1 -1
- package/dist/reconciliation/link-store.d.ts +4 -0
- package/dist/reconciliation/link-store.d.ts.map +1 -1
- package/dist/security/input-sanitization.d.ts.map +1 -1
- package/dist/sticky/list.d.ts.map +1 -1
- package/dist/sticky/types.d.ts +2 -0
- package/dist/sticky/types.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/adrs/sync.ts +58 -5
- package/src/adrs/types.ts +1 -0
- package/src/mvi-helpers.ts +0 -1
- package/src/nexus/transfer.ts +54 -44
- package/src/reconciliation/link-store.ts +61 -1
- package/src/security/input-sanitization.ts +8 -2
- package/src/sticky/list.ts +18 -2
- package/src/sticky/types.ts +2 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mvi-helpers.d.ts","sourceRoot":"","sources":["../src/mvi-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAM3D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAI/D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"mvi-helpers.d.ts","sourceRoot":"","sources":["../src/mvi-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAM3D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAI/D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAIrE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CAKjD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAIjE"}
|
|
@@ -19,6 +19,10 @@ export declare function getLinkByExternalId(providerId: string, externalId: stri
|
|
|
19
19
|
export declare function getLinksByTaskId(taskId: string, cwd?: string): Promise<ExternalTaskLink[]>;
|
|
20
20
|
/**
|
|
21
21
|
* Create a new external task link.
|
|
22
|
+
*
|
|
23
|
+
* Ensures the external_task_links table exists before inserting, providing
|
|
24
|
+
* graceful degradation for older project databases that predate the
|
|
25
|
+
* wave0-schema-hardening migration.
|
|
22
26
|
*/
|
|
23
27
|
export declare function createLink(params: {
|
|
24
28
|
taskId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-store.d.ts","sourceRoot":"","sources":["../../src/reconciliation/link-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"link-store.d.ts","sourceRoot":"","sources":["../../src/reconciliation/link-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAY5D;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAO7B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAYlC;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAOhG;AA0DD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE;IACN,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACvC,aAAa,CAAC,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,EACD,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,CAAC,CAiC3B;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,EACD,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM7F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-sanitization.d.ts","sourceRoot":"","sources":["../../src/security/input-sanitization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAYH;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAG7B,IAAI,EAAE,MAAM;IACZ,KAAK,CAAC,EAAE,MAAM;gBAFrB,OAAO,EAAE,MAAM,EACR,IAAI,GAAE,MAA+B,EACrC,KAAK,CAAC,EAAE,MAAM,YAAA;CAKxB;AAiBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAoBrD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CA2CtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAmC,GAC7C,MAAM,CAcR;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAgBxF;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,wGAShB,CAAC;AAEX,eAAO,MAAM,cAAc,8BAA+B,CAAC;AAE3D,eAAO,MAAM,uBAAuB,0DAAoB,CAAC;AAEzD,eAAO,MAAM,8BAA8B,sFAA2B,CAAC;AAEvE,eAAO,MAAM,kBAAkB,2HAAoD,CAAC;AAEpF,eAAO,MAAM,gBAAgB,gDAAkB,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAI/D,CAAC;AAEF;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,OAAO,CAA2C;gBAE9C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;IAOrD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;IA8BnC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMzB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;IASrC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAQzB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAInD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;CAGtD;AAsBD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CASjF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC3C,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"input-sanitization.d.ts","sourceRoot":"","sources":["../../src/security/input-sanitization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAYH;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAG7B,IAAI,EAAE,MAAM;IACZ,KAAK,CAAC,EAAE,MAAM;gBAFrB,OAAO,EAAE,MAAM,EACR,IAAI,GAAE,MAA+B,EACrC,KAAK,CAAC,EAAE,MAAM,YAAA;CAKxB;AAiBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAoBrD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CA2CtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAmC,GAC7C,MAAM,CAcR;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAgBxF;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,wGAShB,CAAC;AAEX,eAAO,MAAM,cAAc,8BAA+B,CAAC;AAE3D,eAAO,MAAM,uBAAuB,0DAAoB,CAAC;AAEzD,eAAO,MAAM,8BAA8B,sFAA2B,CAAC;AAEvE,eAAO,MAAM,kBAAkB,2HAAoD,CAAC;AAEpF,eAAO,MAAM,gBAAgB,gDAAkB,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAI/D,CAAC;AAEF;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,OAAO,CAA2C;gBAE9C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;IAOrD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;IA8BnC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMzB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;IASrC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAQzB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAInD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;CAGtD;AAsBD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CASjF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC3C,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAwGrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/sticky/list.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAoBjE;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,EAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/sticky/list.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAoBjE;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,EAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,EAAE,CAAC,CA2BvB"}
|
package/dist/sticky/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sticky/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE7E;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,cAAc,GAAG,WAAW,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,oCAAoC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,qBAAqB;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,qCAAqC;IACrC,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,mBAAmB;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,mBAAmB,CAAC;IAChC,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sticky/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE7E;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,cAAc,GAAG,WAAW,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,oCAAoC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,qBAAqB;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,qCAAqC;IACrC,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,mBAAmB;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,mBAAmB,CAAC;IAChC,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleocode/core",
|
|
3
|
-
"version": "2026.4.
|
|
3
|
+
"version": "2026.4.29",
|
|
4
4
|
"description": "CLEO core business logic kernel — tasks, sessions, memory, orchestration, lifecycle, with bundled SQLite store",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
"write-file-atomic": "^7.0.1",
|
|
37
37
|
"yaml": "^2.8.3",
|
|
38
38
|
"zod": "^4.3.6",
|
|
39
|
-
"@cleocode/adapters": "2026.4.
|
|
40
|
-
"@cleocode/agents": "2026.4.
|
|
41
|
-
"@cleocode/caamp": "2026.4.
|
|
42
|
-
"@cleocode/
|
|
43
|
-
"@cleocode/
|
|
44
|
-
"@cleocode/skills": "2026.4.
|
|
39
|
+
"@cleocode/adapters": "2026.4.29",
|
|
40
|
+
"@cleocode/agents": "2026.4.29",
|
|
41
|
+
"@cleocode/caamp": "2026.4.29",
|
|
42
|
+
"@cleocode/lafs": "2026.4.29",
|
|
43
|
+
"@cleocode/contracts": "2026.4.29",
|
|
44
|
+
"@cleocode/skills": "2026.4.29"
|
|
45
45
|
},
|
|
46
46
|
"optionalDependencies": {
|
|
47
47
|
"tree-sitter-c": "^0.24.1",
|
package/src/adrs/sync.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
16
16
|
import { join } from 'node:path';
|
|
17
|
-
import { adrTaskLinks, architectureDecisions } from '../store/tasks-schema.js';
|
|
17
|
+
import { adrTaskLinks, architectureDecisions, tasks } from '../store/tasks-schema.js';
|
|
18
18
|
import { parseAdrFile } from './parse.js';
|
|
19
19
|
import type { AdrSyncResult } from './types.js';
|
|
20
20
|
|
|
@@ -68,7 +68,7 @@ function collectAdrFiles(dir: string): Array<{ file: string; relPath: string }>
|
|
|
68
68
|
*/
|
|
69
69
|
export async function syncAdrsToDb(projectRoot: string): Promise<AdrSyncResult> {
|
|
70
70
|
const adrsDir = join(projectRoot, '.cleo', 'adrs');
|
|
71
|
-
const result: AdrSyncResult = { inserted: 0, updated: 0, skipped: 0, errors: [] };
|
|
71
|
+
const result: AdrSyncResult = { inserted: 0, updated: 0, skipped: 0, errors: [], warnings: [] };
|
|
72
72
|
|
|
73
73
|
if (!existsSync(adrsDir)) {
|
|
74
74
|
return result;
|
|
@@ -93,9 +93,50 @@ export async function syncAdrsToDb(projectRoot: string): Promise<AdrSyncResult>
|
|
|
93
93
|
const dbRelPath = `.cleo/adrs/${relPath}`;
|
|
94
94
|
const content = readFileSync(filePath, 'utf-8');
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
let supersedesId = fm.Supersedes ? extractAdrIdFromRef(fm.Supersedes) : null;
|
|
97
|
+
let supersededById = fm['Superseded By'] ? extractAdrIdFromRef(fm['Superseded By']) : null;
|
|
98
|
+
let amendsId = fm.Amends ? extractAdrIdFromRef(fm.Amends) : null;
|
|
99
|
+
|
|
100
|
+
// Validate FK references exist before insert/update to avoid constraint violations
|
|
101
|
+
if (supersedesId) {
|
|
102
|
+
const exists = await db
|
|
103
|
+
.select({ id: architectureDecisions.id })
|
|
104
|
+
.from(architectureDecisions)
|
|
105
|
+
.where(eq(architectureDecisions.id, supersedesId))
|
|
106
|
+
.all();
|
|
107
|
+
if (exists.length === 0) {
|
|
108
|
+
result.warnings.push(
|
|
109
|
+
`${record.id}: supersedes target ${supersedesId} not found in DB, setting to null`,
|
|
110
|
+
);
|
|
111
|
+
supersedesId = null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (supersededById) {
|
|
115
|
+
const exists = await db
|
|
116
|
+
.select({ id: architectureDecisions.id })
|
|
117
|
+
.from(architectureDecisions)
|
|
118
|
+
.where(eq(architectureDecisions.id, supersededById))
|
|
119
|
+
.all();
|
|
120
|
+
if (exists.length === 0) {
|
|
121
|
+
result.warnings.push(
|
|
122
|
+
`${record.id}: supersededBy target ${supersededById} not found in DB, setting to null`,
|
|
123
|
+
);
|
|
124
|
+
supersededById = null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (amendsId) {
|
|
128
|
+
const exists = await db
|
|
129
|
+
.select({ id: architectureDecisions.id })
|
|
130
|
+
.from(architectureDecisions)
|
|
131
|
+
.where(eq(architectureDecisions.id, amendsId))
|
|
132
|
+
.all();
|
|
133
|
+
if (exists.length === 0) {
|
|
134
|
+
result.warnings.push(
|
|
135
|
+
`${record.id}: amends target ${amendsId} not found in DB, setting to null`,
|
|
136
|
+
);
|
|
137
|
+
amendsId = null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
99
140
|
|
|
100
141
|
const rowBase = {
|
|
101
142
|
id: record.id,
|
|
@@ -136,6 +177,18 @@ export async function syncAdrsToDb(projectRoot: string): Promise<AdrSyncResult>
|
|
|
136
177
|
await db.delete(adrTaskLinks).where(eq(adrTaskLinks.adrId, record.id));
|
|
137
178
|
if (fm['Related Tasks']) {
|
|
138
179
|
for (const taskId of parseTaskIds(fm['Related Tasks'])) {
|
|
180
|
+
// Validate task exists before inserting link to avoid FK constraint violation
|
|
181
|
+
const taskExists = await db
|
|
182
|
+
.select({ id: tasks.id })
|
|
183
|
+
.from(tasks)
|
|
184
|
+
.where(eq(tasks.id, taskId))
|
|
185
|
+
.all();
|
|
186
|
+
if (taskExists.length === 0) {
|
|
187
|
+
result.warnings.push(
|
|
188
|
+
`${record.id}: related task ${taskId} not found in DB, skipping link`,
|
|
189
|
+
);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
139
192
|
await db.insert(adrTaskLinks).values({ adrId: record.id, taskId, linkType: 'related' });
|
|
140
193
|
}
|
|
141
194
|
}
|
package/src/adrs/types.ts
CHANGED
package/src/mvi-helpers.ts
CHANGED
|
@@ -52,7 +52,6 @@ export function taskListItemNext(taskId: string): NextDirectives {
|
|
|
52
52
|
export function sessionListItemNext(sessionId: string): NextDirectives {
|
|
53
53
|
return {
|
|
54
54
|
show: `cleo session show ${sessionId}`,
|
|
55
|
-
serialize: `cleo session serialize ${sessionId}`,
|
|
56
55
|
};
|
|
57
56
|
}
|
|
58
57
|
|
package/src/nexus/transfer.ts
CHANGED
|
@@ -169,54 +169,64 @@ async function executeTransferInternal(params: TransferParams): Promise<Transfer
|
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
// Step 6: Create bidirectional external_task_links
|
|
172
|
-
// Only create links for tasks that were actually imported (verify they exist in target)
|
|
172
|
+
// Only create links for tasks that were actually imported (verify they exist in target).
|
|
173
|
+
// Wrapped in try-catch: link creation is non-critical — the transfer itself has already
|
|
174
|
+
// succeeded by this point. If the target DB predates the wave0-schema-hardening migration
|
|
175
|
+
// and table creation fails, we log a warning and continue rather than aborting the transfer.
|
|
173
176
|
let linksCreated = 0;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
177
|
+
try {
|
|
178
|
+
const targetAccessor = await getAccessor(targetProject.path);
|
|
179
|
+
const { tasks: targetTasks } = await targetAccessor.queryTasks({});
|
|
180
|
+
const targetTaskIds = new Set(targetTasks.map((t) => t.id));
|
|
181
|
+
|
|
182
|
+
for (const entry of entries) {
|
|
183
|
+
if (importResult.idRemap[entry.sourceId] && targetTaskIds.has(entry.targetId)) {
|
|
184
|
+
// Link in target: points back to source
|
|
185
|
+
await createLink(
|
|
186
|
+
{
|
|
187
|
+
taskId: entry.targetId,
|
|
188
|
+
providerId: `nexus:${sourceProject.name}`,
|
|
189
|
+
externalId: entry.sourceId,
|
|
190
|
+
externalTitle: entry.title,
|
|
191
|
+
linkType: 'transferred',
|
|
192
|
+
syncDirection: 'inbound',
|
|
193
|
+
metadata: {
|
|
194
|
+
transferMode: mode,
|
|
195
|
+
transferScope: scope,
|
|
196
|
+
sourceProject: sourceProject.name,
|
|
197
|
+
transferredAt: new Date().toISOString(),
|
|
198
|
+
},
|
|
194
199
|
},
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
200
|
+
targetProject.path,
|
|
201
|
+
);
|
|
202
|
+
linksCreated++;
|
|
203
|
+
|
|
204
|
+
// Link in source: points to target
|
|
205
|
+
await createLink(
|
|
206
|
+
{
|
|
207
|
+
taskId: entry.sourceId,
|
|
208
|
+
providerId: `nexus:${targetProject.name}`,
|
|
209
|
+
externalId: entry.targetId,
|
|
210
|
+
externalTitle: entry.title,
|
|
211
|
+
linkType: 'transferred',
|
|
212
|
+
syncDirection: 'outbound',
|
|
213
|
+
metadata: {
|
|
214
|
+
transferMode: mode,
|
|
215
|
+
transferScope: scope,
|
|
216
|
+
targetProject: targetProject.name,
|
|
217
|
+
transferredAt: new Date().toISOString(),
|
|
218
|
+
},
|
|
214
219
|
},
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
220
|
+
sourceProject.path,
|
|
221
|
+
);
|
|
222
|
+
linksCreated++;
|
|
223
|
+
}
|
|
219
224
|
}
|
|
225
|
+
} catch (err) {
|
|
226
|
+
log.warn(
|
|
227
|
+
{ err, linksCreated },
|
|
228
|
+
'Failed to create external_task_links during transfer — tasks were transferred successfully but provenance links could not be written',
|
|
229
|
+
);
|
|
220
230
|
}
|
|
221
231
|
result.linksCreated = linksCreated;
|
|
222
232
|
|
|
@@ -7,10 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
import { randomUUID } from 'node:crypto';
|
|
9
9
|
import type { ExternalTaskLink } from '@cleocode/contracts';
|
|
10
|
-
import { and, eq } from 'drizzle-orm';
|
|
10
|
+
import { and, eq, sql } from 'drizzle-orm';
|
|
11
|
+
import { getLogger } from '../logger.js';
|
|
11
12
|
import { getDb } from '../store/sqlite.js';
|
|
12
13
|
import { externalTaskLinks } from '../store/tasks-schema.js';
|
|
13
14
|
|
|
15
|
+
const log = getLogger('link-store');
|
|
16
|
+
|
|
14
17
|
// ---------------------------------------------------------------------------
|
|
15
18
|
// Read operations
|
|
16
19
|
// ---------------------------------------------------------------------------
|
|
@@ -63,12 +66,68 @@ export async function getLinksByTaskId(taskId: string, cwd?: string): Promise<Ex
|
|
|
63
66
|
return rows.map(rowToLink);
|
|
64
67
|
}
|
|
65
68
|
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Table safety
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Ensure the external_task_links table exists in the given database.
|
|
75
|
+
*
|
|
76
|
+
* Older project databases (created before the wave0-schema-hardening migration)
|
|
77
|
+
* may lack this table. Rather than aborting operations like nexus transfer,
|
|
78
|
+
* we create the table on demand using CREATE TABLE IF NOT EXISTS.
|
|
79
|
+
*
|
|
80
|
+
* This is idempotent — safe to call on every write operation.
|
|
81
|
+
*/
|
|
82
|
+
async function ensureExternalTaskLinksTable(cwd?: string): Promise<void> {
|
|
83
|
+
const db = await getDb(cwd);
|
|
84
|
+
try {
|
|
85
|
+
db.run(
|
|
86
|
+
sql.raw(`
|
|
87
|
+
CREATE TABLE IF NOT EXISTS external_task_links (
|
|
88
|
+
id text PRIMARY KEY NOT NULL,
|
|
89
|
+
task_id text NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
|
90
|
+
provider_id text NOT NULL,
|
|
91
|
+
external_id text NOT NULL,
|
|
92
|
+
external_url text,
|
|
93
|
+
external_title text,
|
|
94
|
+
link_type text NOT NULL,
|
|
95
|
+
sync_direction text NOT NULL DEFAULT 'inbound',
|
|
96
|
+
metadata_json text DEFAULT '{}',
|
|
97
|
+
linked_at text NOT NULL DEFAULT (datetime('now')),
|
|
98
|
+
last_sync_at text
|
|
99
|
+
)
|
|
100
|
+
`),
|
|
101
|
+
);
|
|
102
|
+
db.run(
|
|
103
|
+
sql.raw(
|
|
104
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS uq_ext_links_task_provider_external ON external_task_links(task_id, provider_id, external_id)`,
|
|
105
|
+
),
|
|
106
|
+
);
|
|
107
|
+
db.run(
|
|
108
|
+
sql.raw(`CREATE INDEX IF NOT EXISTS idx_ext_links_task_id ON external_task_links(task_id)`),
|
|
109
|
+
);
|
|
110
|
+
db.run(
|
|
111
|
+
sql.raw(
|
|
112
|
+
`CREATE INDEX IF NOT EXISTS idx_ext_links_provider_id ON external_task_links(provider_id)`,
|
|
113
|
+
),
|
|
114
|
+
);
|
|
115
|
+
} catch (err) {
|
|
116
|
+
log.warn({ err }, 'Failed to ensure external_task_links table exists');
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
66
121
|
// ---------------------------------------------------------------------------
|
|
67
122
|
// Write operations
|
|
68
123
|
// ---------------------------------------------------------------------------
|
|
69
124
|
|
|
70
125
|
/**
|
|
71
126
|
* Create a new external task link.
|
|
127
|
+
*
|
|
128
|
+
* Ensures the external_task_links table exists before inserting, providing
|
|
129
|
+
* graceful degradation for older project databases that predate the
|
|
130
|
+
* wave0-schema-hardening migration.
|
|
72
131
|
*/
|
|
73
132
|
export async function createLink(
|
|
74
133
|
params: {
|
|
@@ -83,6 +142,7 @@ export async function createLink(
|
|
|
83
142
|
},
|
|
84
143
|
cwd?: string,
|
|
85
144
|
): Promise<ExternalTaskLink> {
|
|
145
|
+
await ensureExternalTaskLinksTable(cwd);
|
|
86
146
|
const db = await getDb(cwd);
|
|
87
147
|
const now = new Date().toISOString();
|
|
88
148
|
const id = randomUUID();
|
|
@@ -379,8 +379,14 @@ export function sanitizeParams(
|
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
if (typeof value === 'string' && (key === 'path' || key === 'file') && projectRoot) {
|
|
382
|
-
|
|
383
|
-
|
|
382
|
+
// Skip path sanitization for operations that intentionally accept external paths
|
|
383
|
+
const allowExternalPath =
|
|
384
|
+
context?.domain === 'nexus' &&
|
|
385
|
+
(context?.operation === 'register' || context?.operation === 'reconcile');
|
|
386
|
+
if (!allowExternalPath) {
|
|
387
|
+
sanitized[key] = sanitizePath(value, projectRoot);
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
384
390
|
}
|
|
385
391
|
|
|
386
392
|
if (
|
package/src/sticky/list.ts
CHANGED
|
@@ -42,12 +42,28 @@ export async function listStickies(
|
|
|
42
42
|
): Promise<StickyNote[]> {
|
|
43
43
|
const accessor = await getBrainAccessor(projectRoot);
|
|
44
44
|
|
|
45
|
+
// Tags are stored as JSON in a text column, so we filter in-memory after
|
|
46
|
+
// the SQL query. Request extra rows (no limit) when tag filtering is active
|
|
47
|
+
// so we don't inadvertently clip the result set before filtering.
|
|
48
|
+
const hasTagFilter = params.tags && params.tags.length > 0;
|
|
49
|
+
|
|
45
50
|
const rows = await accessor.findStickyNotes({
|
|
46
51
|
status: params.status,
|
|
47
52
|
color: params.color,
|
|
48
53
|
priority: params.priority,
|
|
49
|
-
limit: params.limit,
|
|
54
|
+
limit: hasTagFilter ? undefined : params.limit,
|
|
50
55
|
});
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
let notes = rows.map(rowToStickyNote);
|
|
58
|
+
|
|
59
|
+
// In-memory tag filter: keep notes that contain ALL requested tags.
|
|
60
|
+
if (hasTagFilter) {
|
|
61
|
+
const requiredTags = params.tags!;
|
|
62
|
+
notes = notes.filter((note) => requiredTags.every((t) => note.tags.includes(t)));
|
|
63
|
+
if (params.limit && notes.length > params.limit) {
|
|
64
|
+
notes = notes.slice(0, params.limit);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return notes;
|
|
53
69
|
}
|
package/src/sticky/types.ts
CHANGED