@labacacia/nps-sdk 1.0.0-alpha.1

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.
Files changed (311) hide show
  1. package/CONTRIBUTING.md +33 -0
  2. package/LICENSE +170 -0
  3. package/NOTICE +7 -0
  4. package/README.md +153 -0
  5. package/dist/codec-CmHeovTV.d.cts +120 -0
  6. package/dist/codec-CmHeovTV.d.ts +120 -0
  7. package/dist/core/anchor-cache.d.ts +42 -0
  8. package/dist/core/anchor-cache.d.ts.map +1 -0
  9. package/dist/core/anchor-cache.js +104 -0
  10. package/dist/core/anchor-cache.js.map +1 -0
  11. package/dist/core/cache.d.ts +14 -0
  12. package/dist/core/cache.d.ts.map +1 -0
  13. package/dist/core/cache.js +80 -0
  14. package/dist/core/cache.js.map +1 -0
  15. package/dist/core/canonical-json.d.ts +12 -0
  16. package/dist/core/canonical-json.d.ts.map +1 -0
  17. package/dist/core/canonical-json.js +44 -0
  18. package/dist/core/canonical-json.js.map +1 -0
  19. package/dist/core/codec.d.ts +32 -0
  20. package/dist/core/codec.d.ts.map +1 -0
  21. package/dist/core/codec.js +119 -0
  22. package/dist/core/codec.js.map +1 -0
  23. package/dist/core/codecs/index.d.ts +4 -0
  24. package/dist/core/codecs/index.d.ts.map +1 -0
  25. package/dist/core/codecs/index.js +6 -0
  26. package/dist/core/codecs/index.js.map +1 -0
  27. package/dist/core/codecs/ncp-codec.d.ts +39 -0
  28. package/dist/core/codecs/ncp-codec.d.ts.map +1 -0
  29. package/dist/core/codecs/ncp-codec.js +93 -0
  30. package/dist/core/codecs/ncp-codec.js.map +1 -0
  31. package/dist/core/codecs/tier1-json-codec.d.ts +10 -0
  32. package/dist/core/codecs/tier1-json-codec.d.ts.map +1 -0
  33. package/dist/core/codecs/tier1-json-codec.js +28 -0
  34. package/dist/core/codecs/tier1-json-codec.js.map +1 -0
  35. package/dist/core/codecs/tier2-msgpack-codec.d.ts +10 -0
  36. package/dist/core/codecs/tier2-msgpack-codec.d.ts.map +1 -0
  37. package/dist/core/codecs/tier2-msgpack-codec.js +26 -0
  38. package/dist/core/codecs/tier2-msgpack-codec.js.map +1 -0
  39. package/dist/core/crypto-provider.d.ts +31 -0
  40. package/dist/core/crypto-provider.d.ts.map +1 -0
  41. package/dist/core/crypto-provider.js +10 -0
  42. package/dist/core/crypto-provider.js.map +1 -0
  43. package/dist/core/exceptions.d.ts +27 -0
  44. package/dist/core/exceptions.d.ts.map +1 -0
  45. package/dist/core/exceptions.js +52 -0
  46. package/dist/core/exceptions.js.map +1 -0
  47. package/dist/core/frame-header.d.ts +87 -0
  48. package/dist/core/frame-header.d.ts.map +1 -0
  49. package/dist/core/frame-header.js +185 -0
  50. package/dist/core/frame-header.js.map +1 -0
  51. package/dist/core/frame-registry.d.ts +35 -0
  52. package/dist/core/frame-registry.d.ts.map +1 -0
  53. package/dist/core/frame-registry.js +63 -0
  54. package/dist/core/frame-registry.js.map +1 -0
  55. package/dist/core/frames.d.ts +80 -0
  56. package/dist/core/frames.d.ts.map +1 -0
  57. package/dist/core/frames.js +153 -0
  58. package/dist/core/frames.js.map +1 -0
  59. package/dist/core/index.cjs +371 -0
  60. package/dist/core/index.cjs.map +1 -0
  61. package/dist/core/index.d.cts +41 -0
  62. package/dist/core/index.d.ts +9 -0
  63. package/dist/core/index.d.ts.map +1 -0
  64. package/dist/core/index.js +10 -0
  65. package/dist/core/index.js.map +1 -0
  66. package/dist/core/registry.d.ts +11 -0
  67. package/dist/core/registry.d.ts.map +1 -0
  68. package/dist/core/registry.js +17 -0
  69. package/dist/core/registry.js.map +1 -0
  70. package/dist/core/status-codes.d.ts +28 -0
  71. package/dist/core/status-codes.d.ts.map +1 -0
  72. package/dist/core/status-codes.js +38 -0
  73. package/dist/core/status-codes.js.map +1 -0
  74. package/dist/frames-B3qLdl_g.d.cts +77 -0
  75. package/dist/frames-Ff7-ZPUl.d.ts +77 -0
  76. package/dist/index.cjs +1556 -0
  77. package/dist/index.cjs.map +1 -0
  78. package/dist/index.d.cts +21 -0
  79. package/dist/index.d.ts +2 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +10 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/ncp/frames/anchor-frame.d.ts +29 -0
  84. package/dist/ncp/frames/anchor-frame.d.ts.map +1 -0
  85. package/dist/ncp/frames/anchor-frame.js +54 -0
  86. package/dist/ncp/frames/anchor-frame.js.map +1 -0
  87. package/dist/ncp/frames/caps-frame.d.ts +29 -0
  88. package/dist/ncp/frames/caps-frame.d.ts.map +1 -0
  89. package/dist/ncp/frames/caps-frame.js +29 -0
  90. package/dist/ncp/frames/caps-frame.js.map +1 -0
  91. package/dist/ncp/frames/diff-frame.d.ts +32 -0
  92. package/dist/ncp/frames/diff-frame.d.ts.map +1 -0
  93. package/dist/ncp/frames/diff-frame.js +37 -0
  94. package/dist/ncp/frames/diff-frame.js.map +1 -0
  95. package/dist/ncp/frames/error-frame.d.ts +16 -0
  96. package/dist/ncp/frames/error-frame.d.ts.map +1 -0
  97. package/dist/ncp/frames/error-frame.js +13 -0
  98. package/dist/ncp/frames/error-frame.js.map +1 -0
  99. package/dist/ncp/frames/hello-frame.d.ts +21 -0
  100. package/dist/ncp/frames/hello-frame.d.ts.map +1 -0
  101. package/dist/ncp/frames/hello-frame.js +25 -0
  102. package/dist/ncp/frames/hello-frame.js.map +1 -0
  103. package/dist/ncp/frames/stream-frame.d.ts +16 -0
  104. package/dist/ncp/frames/stream-frame.d.ts.map +1 -0
  105. package/dist/ncp/frames/stream-frame.js +18 -0
  106. package/dist/ncp/frames/stream-frame.js.map +1 -0
  107. package/dist/ncp/frames.d.ts +76 -0
  108. package/dist/ncp/frames.d.ts.map +1 -0
  109. package/dist/ncp/frames.js +147 -0
  110. package/dist/ncp/frames.js.map +1 -0
  111. package/dist/ncp/handshake.d.ts +30 -0
  112. package/dist/ncp/handshake.d.ts.map +1 -0
  113. package/dist/ncp/handshake.js +80 -0
  114. package/dist/ncp/handshake.js.map +1 -0
  115. package/dist/ncp/index.cjs +188 -0
  116. package/dist/ncp/index.cjs.map +1 -0
  117. package/dist/ncp/index.d.cts +6 -0
  118. package/dist/ncp/index.d.ts +11 -0
  119. package/dist/ncp/index.d.ts.map +1 -0
  120. package/dist/ncp/index.js +13 -0
  121. package/dist/ncp/index.js.map +1 -0
  122. package/dist/ncp/ncp-error-codes.d.ts +22 -0
  123. package/dist/ncp/ncp-error-codes.d.ts.map +1 -0
  124. package/dist/ncp/ncp-error-codes.js +32 -0
  125. package/dist/ncp/ncp-error-codes.js.map +1 -0
  126. package/dist/ncp/ncp-patch-format.d.ts +7 -0
  127. package/dist/ncp/ncp-patch-format.d.ts.map +1 -0
  128. package/dist/ncp/ncp-patch-format.js +13 -0
  129. package/dist/ncp/ncp-patch-format.js.map +1 -0
  130. package/dist/ncp/registry.d.ts +3 -0
  131. package/dist/ncp/registry.d.ts.map +1 -0
  132. package/dist/ncp/registry.js +12 -0
  133. package/dist/ncp/registry.js.map +1 -0
  134. package/dist/ncp/stream-manager.d.ts +57 -0
  135. package/dist/ncp/stream-manager.d.ts.map +1 -0
  136. package/dist/ncp/stream-manager.js +163 -0
  137. package/dist/ncp/stream-manager.js.map +1 -0
  138. package/dist/ndp/frames.d.ts +56 -0
  139. package/dist/ndp/frames.d.ts.map +1 -0
  140. package/dist/ndp/frames.js +87 -0
  141. package/dist/ndp/frames.js.map +1 -0
  142. package/dist/ndp/index.cjs +252 -0
  143. package/dist/ndp/index.cjs.map +1 -0
  144. package/dist/ndp/index.d.cts +86 -0
  145. package/dist/ndp/index.d.ts +5 -0
  146. package/dist/ndp/index.d.ts.map +1 -0
  147. package/dist/ndp/index.js +7 -0
  148. package/dist/ndp/index.js.map +1 -0
  149. package/dist/ndp/ndp-registry.d.ts +11 -0
  150. package/dist/ndp/ndp-registry.d.ts.map +1 -0
  151. package/dist/ndp/ndp-registry.js +79 -0
  152. package/dist/ndp/ndp-registry.js.map +1 -0
  153. package/dist/ndp/registry.d.ts +3 -0
  154. package/dist/ndp/registry.d.ts.map +1 -0
  155. package/dist/ndp/registry.js +10 -0
  156. package/dist/ndp/registry.js.map +1 -0
  157. package/dist/ndp/validator.d.ts +18 -0
  158. package/dist/ndp/validator.d.ts.map +1 -0
  159. package/dist/ndp/validator.js +48 -0
  160. package/dist/ndp/validator.js.map +1 -0
  161. package/dist/nip/frames.d.ts +44 -0
  162. package/dist/nip/frames.d.ts.map +1 -0
  163. package/dist/nip/frames.js +81 -0
  164. package/dist/nip/frames.js.map +1 -0
  165. package/dist/nip/identity.d.ts +18 -0
  166. package/dist/nip/identity.d.ts.map +1 -0
  167. package/dist/nip/identity.js +94 -0
  168. package/dist/nip/identity.js.map +1 -0
  169. package/dist/nip/index.cjs +214 -0
  170. package/dist/nip/index.cjs.map +1 -0
  171. package/dist/nip/index.d.cts +65 -0
  172. package/dist/nip/index.d.ts +4 -0
  173. package/dist/nip/index.d.ts.map +1 -0
  174. package/dist/nip/index.js +6 -0
  175. package/dist/nip/index.js.map +1 -0
  176. package/dist/nip/registry.d.ts +3 -0
  177. package/dist/nip/registry.d.ts.map +1 -0
  178. package/dist/nip/registry.js +10 -0
  179. package/dist/nip/registry.js.map +1 -0
  180. package/dist/nop/client.d.ts +34 -0
  181. package/dist/nop/client.d.ts.map +1 -0
  182. package/dist/nop/client.js +90 -0
  183. package/dist/nop/client.js.map +1 -0
  184. package/dist/nop/frames.d.ts +65 -0
  185. package/dist/nop/frames.d.ts.map +1 -0
  186. package/dist/nop/frames.js +148 -0
  187. package/dist/nop/frames.js.map +1 -0
  188. package/dist/nop/index.cjs +762 -0
  189. package/dist/nop/index.cjs.map +1 -0
  190. package/dist/nop/index.d.cts +155 -0
  191. package/dist/nop/index.d.ts +5 -0
  192. package/dist/nop/index.d.ts.map +1 -0
  193. package/dist/nop/index.js +7 -0
  194. package/dist/nop/index.js.map +1 -0
  195. package/dist/nop/models.d.ts +58 -0
  196. package/dist/nop/models.d.ts.map +1 -0
  197. package/dist/nop/models.js +50 -0
  198. package/dist/nop/models.js.map +1 -0
  199. package/dist/nop/nop-types.d.ts +136 -0
  200. package/dist/nop/nop-types.d.ts.map +1 -0
  201. package/dist/nop/nop-types.js +44 -0
  202. package/dist/nop/nop-types.js.map +1 -0
  203. package/dist/nop/registry.d.ts +3 -0
  204. package/dist/nop/registry.d.ts.map +1 -0
  205. package/dist/nop/registry.js +11 -0
  206. package/dist/nop/registry.js.map +1 -0
  207. package/dist/nwp/client.d.ts +22 -0
  208. package/dist/nwp/client.d.ts.map +1 -0
  209. package/dist/nwp/client.js +101 -0
  210. package/dist/nwp/client.js.map +1 -0
  211. package/dist/nwp/frames.d.ts +46 -0
  212. package/dist/nwp/frames.d.ts.map +1 -0
  213. package/dist/nwp/frames.js +81 -0
  214. package/dist/nwp/frames.js.map +1 -0
  215. package/dist/nwp/index.cjs +658 -0
  216. package/dist/nwp/index.cjs.map +1 -0
  217. package/dist/nwp/index.d.cts +65 -0
  218. package/dist/nwp/index.d.ts +4 -0
  219. package/dist/nwp/index.d.ts.map +1 -0
  220. package/dist/nwp/index.js +6 -0
  221. package/dist/nwp/index.js.map +1 -0
  222. package/dist/nwp/registry.d.ts +3 -0
  223. package/dist/nwp/registry.d.ts.map +1 -0
  224. package/dist/nwp/registry.js +9 -0
  225. package/dist/nwp/registry.js.map +1 -0
  226. package/dist/setup.d.ts +10 -0
  227. package/dist/setup.d.ts.map +1 -0
  228. package/dist/setup.js +29 -0
  229. package/dist/setup.js.map +1 -0
  230. package/nip-ca-server/Dockerfile +27 -0
  231. package/nip-ca-server/README.md +45 -0
  232. package/nip-ca-server/db/001_init.sql +25 -0
  233. package/nip-ca-server/docker-compose.yml +29 -0
  234. package/nip-ca-server/package.json +23 -0
  235. package/nip-ca-server/src/ca.ts +155 -0
  236. package/nip-ca-server/src/db.ts +104 -0
  237. package/nip-ca-server/src/index.ts +157 -0
  238. package/nip-ca-server/tsconfig.json +13 -0
  239. package/package.json +47 -0
  240. package/src/core/anchor-cache.ts +129 -0
  241. package/src/core/cache.ts +93 -0
  242. package/src/core/canonical-json.ts +50 -0
  243. package/src/core/codec.ts +158 -0
  244. package/src/core/codecs/index.ts +5 -0
  245. package/src/core/codecs/ncp-codec.ts +170 -0
  246. package/src/core/codecs/tier1-json-codec.ts +33 -0
  247. package/src/core/codecs/tier2-msgpack-codec.ts +30 -0
  248. package/src/core/crypto-provider.ts +47 -0
  249. package/src/core/exceptions.ts +57 -0
  250. package/src/core/frame-header.ts +282 -0
  251. package/src/core/frame-registry.ts +91 -0
  252. package/src/core/frames.ts +183 -0
  253. package/src/core/index.ts +10 -0
  254. package/src/core/registry.ts +28 -0
  255. package/src/core/status-codes.ts +46 -0
  256. package/src/index.ts +10 -0
  257. package/src/ncp/frames/anchor-frame.ts +87 -0
  258. package/src/ncp/frames/caps-frame.ts +59 -0
  259. package/src/ncp/frames/diff-frame.ts +69 -0
  260. package/src/ncp/frames/error-frame.ts +26 -0
  261. package/src/ncp/frames/hello-frame.ts +50 -0
  262. package/src/ncp/frames/stream-frame.ts +35 -0
  263. package/src/ncp/frames.ts +199 -0
  264. package/src/ncp/handshake.ts +95 -0
  265. package/src/ncp/index.ts +12 -0
  266. package/src/ncp/ncp-error-codes.ts +34 -0
  267. package/src/ncp/ncp-patch-format.ts +16 -0
  268. package/src/ncp/registry.ts +14 -0
  269. package/src/ncp/stream-manager.ts +212 -0
  270. package/src/ndp/frames.ts +124 -0
  271. package/src/ndp/index.ts +7 -0
  272. package/src/ndp/ndp-registry.ts +82 -0
  273. package/src/ndp/registry.ts +12 -0
  274. package/src/ndp/validator.ts +64 -0
  275. package/src/nip/frames.ts +106 -0
  276. package/src/nip/identity.ts +113 -0
  277. package/src/nip/index.ts +6 -0
  278. package/src/nip/registry.ts +12 -0
  279. package/src/nop/client.ts +103 -0
  280. package/src/nop/frames.ts +181 -0
  281. package/src/nop/index.ts +7 -0
  282. package/src/nop/models.ts +79 -0
  283. package/src/nop/nop-types.ts +208 -0
  284. package/src/nop/registry.ts +13 -0
  285. package/src/nwp/client.ts +114 -0
  286. package/src/nwp/frames.ts +116 -0
  287. package/src/nwp/index.ts +6 -0
  288. package/src/nwp/registry.ts +11 -0
  289. package/src/setup.ts +32 -0
  290. package/tests/core/anchor-cache.test.ts +242 -0
  291. package/tests/core/codec.test.ts +205 -0
  292. package/tests/core/frame-registry.test.ts +46 -0
  293. package/tests/core.test.ts +327 -0
  294. package/tests/ncp/diff-binary-bitset.test.ts +107 -0
  295. package/tests/ncp/e2e-enc-reject.test.ts +93 -0
  296. package/tests/ncp/err-error-frame.test.ts +152 -0
  297. package/tests/ncp/frames.test.ts +359 -0
  298. package/tests/ncp/framing.test.ts +233 -0
  299. package/tests/ncp/hello-frame.test.ts +122 -0
  300. package/tests/ncp/inline-anchor.test.ts +88 -0
  301. package/tests/ncp/security.test.ts +184 -0
  302. package/tests/ncp/stream-window.test.ts +167 -0
  303. package/tests/ncp/stream.test.ts +242 -0
  304. package/tests/ncp/version-negotiation.test.ts +123 -0
  305. package/tests/ndp.test.ts +271 -0
  306. package/tests/nip.test.ts +184 -0
  307. package/tests/nop.test.ts +344 -0
  308. package/tests/nwp.test.ts +237 -0
  309. package/tsconfig.json +20 -0
  310. package/tsup.config.ts +20 -0
  311. package/vitest.config.ts +10 -0
@@ -0,0 +1,208 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (c) 2026 LabAcacia / INNO LOTUS PTY LTD
3
+ //
4
+ // NOP Task Protocol — TypeScript Type Definitions
5
+ // NPS-5 Neural Orchestration Protocol, MVP subset
6
+ //
7
+ // NCP carries the envelope. NOP fills the payload.
8
+ // IntentFrame dispatches. ResultFrame reports back.
9
+
10
+ // -----------------------------------------------------------------------------
11
+ // NCP Envelope Types (NPS-1)
12
+ // -----------------------------------------------------------------------------
13
+
14
+ /** NCP protocol version marker */
15
+ type NcpVersion = 1;
16
+
17
+ /** Alternative approach considered but not taken */
18
+ export interface Alternative {
19
+ value: string;
20
+ probability: number;
21
+ }
22
+
23
+ // -----------------------------------------------------------------------------
24
+ // NOP Payload Types — Intent (Dispatch)
25
+ // -----------------------------------------------------------------------------
26
+
27
+ /** NOP protocol version marker */
28
+ type NopVersion = 1;
29
+
30
+ /** Task priority levels */
31
+ export type Priority = "urgent" | "normal" | "low";
32
+
33
+ /** Task category — what kind of work this is */
34
+ export type TaskCategory = "code" | "research" | "docs" | "test" | "refactor" | "ops";
35
+
36
+ /** Task mailbox paths — where files live during lifecycle */
37
+ export interface Mailbox {
38
+ /** Base path for the task mailbox */
39
+ base: string;
40
+ /** Active directory name. Default: "active" */
41
+ active?: string;
42
+ /** Done directory name. Default: "done" */
43
+ done?: string;
44
+ }
45
+
46
+ /** Context the worker needs to do its job */
47
+ export interface TaskContext {
48
+ /** File paths relevant to the task */
49
+ files?: string[];
50
+ /** Key facts the worker needs to know */
51
+ knowledge?: string[];
52
+ /** Git branch to work on */
53
+ branch?: string;
54
+ }
55
+
56
+ /** Boundaries the worker must operate within */
57
+ export interface TaskConstraints {
58
+ /** Model to use: "sonnet", "haiku", "opus" */
59
+ model?: string;
60
+ /** Max seconds for task execution */
61
+ time_limit?: number;
62
+ /** Directories/files the worker may touch */
63
+ scope?: string[];
64
+ /** Whether changes need operator approval gate */
65
+ proceed_gate?: boolean;
66
+ }
67
+
68
+ /** NOP payload for task dispatch (MVP subset of TaskFrame 0x40) */
69
+ export interface NopIntentPayload {
70
+ _nop: NopVersion;
71
+ /** Unique task ID: task-{source}-{YYYYMMDD}-{HHMMSS} */
72
+ id: string;
73
+ /** Who dispatched — NPS NID format: urn:nps:agent:{domain}:{name} */
74
+ from: string;
75
+ /** Target worker NID. Omit = any available worker picks up */
76
+ to?: string;
77
+ /** ISO 8601 timestamp when task was dispatched */
78
+ created_at: string;
79
+ /** Task priority. Default: "normal" */
80
+ priority?: Priority;
81
+ /** What kind of work this task involves */
82
+ category?: TaskCategory;
83
+ /** Where task files live during lifecycle */
84
+ mailbox: Mailbox;
85
+ /** Context for the worker */
86
+ context?: TaskContext;
87
+ /** Execution boundaries (NPS-5 §3.2 scope carving) */
88
+ constraints?: TaskConstraints;
89
+ }
90
+
91
+ // -----------------------------------------------------------------------------
92
+ // NOP Payload Types — Result (Report Back)
93
+ // -----------------------------------------------------------------------------
94
+
95
+ /** Terminal task states (NPS-5 §4 state machine) */
96
+ export type TaskStatus = "completed" | "failed" | "timeout" | "blocked";
97
+
98
+ /** NOP payload for task result (AlignStream equivalent — NPS-5 §3.4) */
99
+ export interface NopResultPayload {
100
+ _nop: NopVersion;
101
+ /** Same task ID from the intent */
102
+ id: string;
103
+ /** Terminal state */
104
+ status: TaskStatus;
105
+ /** Which worker executed — NPS NID format */
106
+ from: string;
107
+ /** ISO 8601 timestamp when worker claimed the task */
108
+ picked_up_at: string;
109
+ /** ISO 8601 timestamp when worker finished */
110
+ completed_at: string;
111
+ /** Files that were modified */
112
+ files_changed?: string[];
113
+ /** Git commit hashes + messages */
114
+ commits?: string[];
115
+ /** New tasks discovered during execution */
116
+ follow_up?: string[];
117
+ /** Seconds the task took */
118
+ duration?: number;
119
+ /** Error message if failed/timeout */
120
+ error?: string | null;
121
+ }
122
+
123
+ // -----------------------------------------------------------------------------
124
+ // Full NCP+NOP Messages
125
+ // -----------------------------------------------------------------------------
126
+
127
+ /** Complete intent message: NCP envelope + NOP payload */
128
+ export interface IntentMessage {
129
+ _ncp: NcpVersion;
130
+ type: "intent";
131
+ /** Short verb phrase: "fix-bug", "write-test", "research", "refactor" */
132
+ intent: string;
133
+ /** Orchestrator's confidence this is the right task/worker. 0-1 */
134
+ confidence: number;
135
+ /** NOP task payload */
136
+ payload: NopIntentPayload;
137
+ }
138
+
139
+ /** Complete result message: NCP envelope + NOP payload */
140
+ export interface ResultMessage {
141
+ _ncp: NcpVersion;
142
+ type: "result";
143
+ /** Human-readable summary of what was done */
144
+ value: string;
145
+ /** Worker's confidence in the result quality. 0-1 */
146
+ probability: number;
147
+ /** Other approaches considered but not taken */
148
+ alternatives: Alternative[];
149
+ /** NOP result payload */
150
+ payload: NopResultPayload;
151
+ }
152
+
153
+ /** Any NOP message */
154
+ export type NopMessage = IntentMessage | ResultMessage;
155
+
156
+ // -----------------------------------------------------------------------------
157
+ // Task Lifecycle (NPS-5 §4)
158
+ // -----------------------------------------------------------------------------
159
+
160
+ /** All possible task states */
161
+ export type TaskState =
162
+ | "pending" // inbox/ — waiting for pickup
163
+ | "active" // active/ — worker executing
164
+ | "completed" // done/ — success
165
+ | "failed" // done/ — error
166
+ | "timeout" // done/ — exceeded time_limit
167
+ | "blocked" // blocked/ — needs external input
168
+ | "cancelled"; // done/ — orchestrator cancelled
169
+
170
+ /** Valid state transitions */
171
+ export const VALID_TRANSITIONS: Record<string, TaskState[]> = {
172
+ pending: ["active", "cancelled"],
173
+ active: ["completed", "failed", "timeout", "blocked"],
174
+ blocked: ["active", "cancelled"],
175
+ completed: [],
176
+ failed: [],
177
+ timeout: [],
178
+ cancelled: [],
179
+ };
180
+
181
+ // -----------------------------------------------------------------------------
182
+ // File Naming Conventions
183
+ // -----------------------------------------------------------------------------
184
+
185
+ /** Directory where a task file lives based on its state */
186
+ export const STATE_DIRECTORY: Record<TaskState, string> = {
187
+ pending: "inbox",
188
+ active: "active",
189
+ completed: "done",
190
+ failed: "done",
191
+ timeout: "done",
192
+ blocked: "blocked",
193
+ cancelled: "done",
194
+ };
195
+
196
+ /** File extensions by message type */
197
+ export const FILE_EXTENSIONS = {
198
+ intent: ".intent.json",
199
+ result: ".result.json",
200
+ } as const;
201
+
202
+ /** Default mailbox directory names */
203
+ export const MAILBOX_DEFAULTS = {
204
+ active: "active",
205
+ done: "done",
206
+ inbox: "inbox",
207
+ blocked: "blocked",
208
+ } as const;
@@ -0,0 +1,13 @@
1
+ // Copyright 2026 INNO LOTUS PTY LTD
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { FrameRegistry } from "../core/registry.js";
5
+ import { FrameType } from "../core/frames.js";
6
+ import { AlignStreamFrame, DelegateFrame, SyncFrame, TaskFrame } from "./frames.js";
7
+
8
+ export function registerNopFrames(registry: FrameRegistry): void {
9
+ registry.register(FrameType.TASK, TaskFrame);
10
+ registry.register(FrameType.DELEGATE, DelegateFrame);
11
+ registry.register(FrameType.SYNC, SyncFrame);
12
+ registry.register(FrameType.ALIGN_STREAM, AlignStreamFrame);
13
+ }
@@ -0,0 +1,114 @@
1
+ // Copyright 2026 INNO LOTUS PTY LTD
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * NwpClient — async HTTP-mode client for NPS Neural Web Protocol nodes (NPS-2).
6
+ */
7
+
8
+ import { NpsFrameCodec } from "../core/codec.js";
9
+ import { EncodingTier } from "../core/frames.js";
10
+ import { FrameRegistry } from "../core/registry.js";
11
+ import { registerNcpFrames } from "../ncp/registry.js";
12
+ import { CapsFrame } from "../ncp/frames.js";
13
+ import type { StreamFrame } from "../ncp/frames.js";
14
+ import { registerNwpFrames } from "./registry.js";
15
+ import { ActionFrame, asyncActionResponseFromDict } from "./frames.js";
16
+ import type { AnchorFrame } from "../ncp/frames.js";
17
+ import type { QueryFrame, AsyncActionResponse } from "./frames.js";
18
+
19
+ const CONTENT_TYPE = "application/x-nps-frame";
20
+
21
+ export class NwpClient {
22
+ private readonly _baseUrl: string;
23
+ private readonly _codec: NpsFrameCodec;
24
+ private readonly _tier: EncodingTier;
25
+
26
+ constructor(
27
+ baseUrl: string,
28
+ options: { defaultTier?: EncodingTier; maxPayload?: number; registry?: FrameRegistry } = {},
29
+ ) {
30
+ this._baseUrl = baseUrl.replace(/\/$/, "");
31
+ this._tier = options.defaultTier ?? EncodingTier.MSGPACK;
32
+
33
+ const registry = options.registry ?? (() => {
34
+ const r = new FrameRegistry();
35
+ registerNcpFrames(r);
36
+ registerNwpFrames(r);
37
+ return r;
38
+ })();
39
+ const codecOpts = options.maxPayload !== undefined ? { maxPayload: options.maxPayload } : {};
40
+ this._codec = new NpsFrameCodec(registry, codecOpts);
41
+ }
42
+
43
+ async sendAnchor(frame: AnchorFrame): Promise<void> {
44
+ const wire = this._codec.encode(frame, { overrideTier: this._tier });
45
+ const res = await fetch(`${this._baseUrl}/anchor`, {
46
+ method: "POST",
47
+ body: wire,
48
+ headers: { "Content-Type": CONTENT_TYPE, "Accept": CONTENT_TYPE },
49
+ });
50
+ if (!res.ok) throw new Error(`NWP /anchor failed: HTTP ${res.status}`);
51
+ }
52
+
53
+ async query(frame: QueryFrame): Promise<CapsFrame> {
54
+ const wire = this._codec.encode(frame, { overrideTier: this._tier });
55
+ const res = await fetch(`${this._baseUrl}/query`, {
56
+ method: "POST",
57
+ body: wire,
58
+ headers: { "Content-Type": CONTENT_TYPE, "Accept": CONTENT_TYPE },
59
+ });
60
+ if (!res.ok) throw new Error(`NWP /query failed: HTTP ${res.status}`);
61
+
62
+ const buf = new Uint8Array(await res.arrayBuffer());
63
+ const result = this._codec.decode(buf);
64
+ if (!(result instanceof CapsFrame)) {
65
+ throw new TypeError(`Expected CapsFrame from /query, got ${result.constructor.name}.`);
66
+ }
67
+ return result;
68
+ }
69
+
70
+ async *stream(frame: QueryFrame): AsyncGenerator<StreamFrame> {
71
+ const wire = this._codec.encode(frame, { overrideTier: this._tier });
72
+ const res = await fetch(`${this._baseUrl}/stream`, {
73
+ method: "POST",
74
+ body: wire,
75
+ headers: { "Content-Type": CONTENT_TYPE, "Accept": CONTENT_TYPE },
76
+ });
77
+ if (!res.ok) throw new Error(`NWP /stream failed: HTTP ${res.status}`);
78
+ if (res.body === null) return;
79
+
80
+ const { StreamFrame: SF } = await import("../ncp/frames.js");
81
+
82
+ for await (const chunk of res.body) {
83
+ const bytes = chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk as ArrayBuffer);
84
+ if (bytes.length === 0) continue;
85
+ const result = this._codec.decode(bytes);
86
+ if (!(result instanceof SF)) {
87
+ throw new TypeError(`Expected StreamFrame from /stream, got ${result.constructor.name}.`);
88
+ }
89
+ yield result;
90
+ if (result.isLast) break;
91
+ }
92
+ }
93
+
94
+ async invoke(frame: ActionFrame): Promise<unknown> {
95
+ const wire = this._codec.encode(frame, { overrideTier: this._tier });
96
+ const res = await fetch(`${this._baseUrl}/invoke`, {
97
+ method: "POST",
98
+ body: wire,
99
+ headers: { "Content-Type": CONTENT_TYPE, "Accept": CONTENT_TYPE },
100
+ });
101
+ if (!res.ok) throw new Error(`NWP /invoke failed: HTTP ${res.status}`);
102
+
103
+ if (frame.async_) {
104
+ return asyncActionResponseFromDict(await res.json() as Record<string, unknown>) as AsyncActionResponse;
105
+ }
106
+
107
+ const contentType = res.headers.get("content-type") ?? "";
108
+ if (contentType.includes(CONTENT_TYPE)) {
109
+ const buf = new Uint8Array(await res.arrayBuffer());
110
+ return this._codec.decode(buf);
111
+ }
112
+ return res.json();
113
+ }
114
+ }
@@ -0,0 +1,116 @@
1
+ // Copyright 2026 INNO LOTUS PTY LTD
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { EncodingTier, FrameType } from "../core/frames.js";
5
+ import type { NpsFrame } from "../core/codec.js";
6
+
7
+ // ── Filter DSL ────────────────────────────────────────────────────────────────
8
+
9
+ export interface QueryOrderClause {
10
+ field: string;
11
+ dir: "asc" | "desc";
12
+ }
13
+
14
+ export interface VectorSearchOptions {
15
+ vector: readonly number[];
16
+ topK?: number;
17
+ minScore?: number;
18
+ vectorField?: string;
19
+ }
20
+
21
+ // ── QueryFrame ────────────────────────────────────────────────────────────────
22
+
23
+ export class QueryFrame implements NpsFrame {
24
+ readonly frameType = FrameType.QUERY;
25
+ readonly preferredTier = EncodingTier.MSGPACK;
26
+
27
+ constructor(
28
+ public readonly anchorRef?: string,
29
+ public readonly filter?: Record<string, unknown>,
30
+ public readonly limit?: number,
31
+ public readonly offset?: number,
32
+ public readonly orderBy?: readonly QueryOrderClause[],
33
+ public readonly fields?: readonly string[],
34
+ public readonly vectorSearch?: VectorSearchOptions,
35
+ public readonly depth?: number,
36
+ ) {}
37
+
38
+ toDict(): Record<string, unknown> {
39
+ return {
40
+ anchor_ref: this.anchorRef ?? null,
41
+ filter: this.filter ?? null,
42
+ limit: this.limit ?? null,
43
+ offset: this.offset ?? null,
44
+ order_by: this.orderBy ?? null,
45
+ fields: this.fields ?? null,
46
+ vector_search: this.vectorSearch ?? null,
47
+ depth: this.depth ?? null,
48
+ };
49
+ }
50
+
51
+ static fromDict(data: Record<string, unknown>): QueryFrame {
52
+ return new QueryFrame(
53
+ (data["anchor_ref"] as string | null) ?? undefined,
54
+ (data["filter"] as Record<string, unknown> | null) ?? undefined,
55
+ (data["limit"] as number | null) ?? undefined,
56
+ (data["offset"] as number | null) ?? undefined,
57
+ (data["order_by"] as QueryOrderClause[] | null) ?? undefined,
58
+ (data["fields"] as string[] | null) ?? undefined,
59
+ (data["vector_search"] as VectorSearchOptions | null) ?? undefined,
60
+ (data["depth"] as number | null) ?? undefined,
61
+ );
62
+ }
63
+ }
64
+
65
+ // ── ActionFrame ───────────────────────────────────────────────────────────────
66
+
67
+ export class ActionFrame implements NpsFrame {
68
+ readonly frameType = FrameType.ACTION;
69
+ readonly preferredTier = EncodingTier.MSGPACK;
70
+
71
+ constructor(
72
+ public readonly actionId: string,
73
+ public readonly params?: Record<string, unknown>,
74
+ public readonly async_?: boolean,
75
+ public readonly idempotencyKey?: string,
76
+ public readonly timeoutMs?: number,
77
+ ) {}
78
+
79
+ toDict(): Record<string, unknown> {
80
+ return {
81
+ action_id: this.actionId,
82
+ params: this.params ?? null,
83
+ async: this.async_ ?? false,
84
+ idempotency_key: this.idempotencyKey ?? null,
85
+ timeout_ms: this.timeoutMs ?? null,
86
+ };
87
+ }
88
+
89
+ static fromDict(data: Record<string, unknown>): ActionFrame {
90
+ return new ActionFrame(
91
+ data["action_id"] as string,
92
+ (data["params"] as Record<string, unknown> | null) ?? undefined,
93
+ (data["async"] as boolean | null) ?? undefined,
94
+ (data["idempotency_key"] as string | null) ?? undefined,
95
+ (data["timeout_ms"] as number | null) ?? undefined,
96
+ );
97
+ }
98
+ }
99
+
100
+ // ── AsyncActionResponse ───────────────────────────────────────────────────────
101
+
102
+ export interface AsyncActionResponse {
103
+ taskId: string;
104
+ status: string;
105
+ pollUrl?: string | undefined;
106
+ }
107
+
108
+ export function asyncActionResponseFromDict(data: Record<string, unknown>): AsyncActionResponse {
109
+ const r: AsyncActionResponse = {
110
+ taskId: data["task_id"] as string,
111
+ status: data["status"] as string,
112
+ };
113
+ const pollUrl = data["poll_url"] as string | null | undefined;
114
+ if (pollUrl != null) r.pollUrl = pollUrl;
115
+ return r;
116
+ }
@@ -0,0 +1,6 @@
1
+ // Copyright 2026 INNO LOTUS PTY LTD
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from "./frames.js";
5
+ export * from "./registry.js";
6
+ export * from "./client.js";
@@ -0,0 +1,11 @@
1
+ // Copyright 2026 INNO LOTUS PTY LTD
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { FrameRegistry } from "../core/registry.js";
5
+ import { FrameType } from "../core/frames.js";
6
+ import { ActionFrame, QueryFrame } from "./frames.js";
7
+
8
+ export function registerNwpFrames(registry: FrameRegistry): void {
9
+ registry.register(FrameType.QUERY, QueryFrame);
10
+ registry.register(FrameType.ACTION, ActionFrame);
11
+ }
package/src/setup.ts ADDED
@@ -0,0 +1,32 @@
1
+ // Copyright 2026 INNO LOTUS PTY LTD
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * Registry factory helpers — lives outside core/ to avoid circular imports.
6
+ * Use createDefaultRegistry() for NCP-only, createFullRegistry() for all protocols.
7
+ */
8
+
9
+ import { FrameRegistry } from "./core/registry.js";
10
+ import { registerNcpFrames } from "./ncp/registry.js";
11
+ import { registerNwpFrames } from "./nwp/registry.js";
12
+ import { registerNipFrames } from "./nip/registry.js";
13
+ import { registerNdpFrames } from "./ndp/registry.js";
14
+ import { registerNopFrames } from "./nop/registry.js";
15
+
16
+ /** NCP frames only (ANCHOR, DIFF, STREAM, CAPS, ERROR). */
17
+ export function createDefaultRegistry(): FrameRegistry {
18
+ const r = new FrameRegistry();
19
+ registerNcpFrames(r);
20
+ return r;
21
+ }
22
+
23
+ /** All 5 protocols (NCP + NWP + NIP + NDP + NOP). */
24
+ export function createFullRegistry(): FrameRegistry {
25
+ const r = new FrameRegistry();
26
+ registerNcpFrames(r);
27
+ registerNwpFrames(r);
28
+ registerNipFrames(r);
29
+ registerNdpFrames(r);
30
+ registerNopFrames(r);
31
+ return r;
32
+ }