@hellolynk-ai/codex-plugin 0.0.0-stage → 0.2.99

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 (123) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/LICENSE +92 -0
  3. package/README.md +86 -2
  4. package/bin/hellolynk-client-setup.mjs +2748 -0
  5. package/bin/hellolynk-mcp-config-shape.mjs +23 -0
  6. package/hellolynk-client-pack-manifest.json +619 -0
  7. package/hellolynk-client-pack-pin.json +4 -0
  8. package/package.json +58 -4
  9. package/plugins/hellolynk-codex/.app.json +3 -0
  10. package/plugins/hellolynk-codex/.codex-plugin/plugin.json +38 -0
  11. package/plugins/hellolynk-codex/.mcp.json +19 -0
  12. package/plugins/hellolynk-codex/assets/hellolynk-mark.png +0 -0
  13. package/plugins/hellolynk-codex/package.json +11 -0
  14. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-client-account.mjs +180 -0
  15. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-client-core.mjs +770 -0
  16. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-client-profile.mjs +191 -0
  17. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-host-auth.mjs +347 -0
  18. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-host-protected-store.mjs +2721 -0
  19. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-local-process-lock.mjs +157 -0
  20. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-neutral-host-installation-store.mjs +765 -0
  21. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-platform-credential-store.mjs +773 -0
  22. package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-runtime-safety.cjs +471 -0
  23. package/plugins/hellolynk-codex/runtime/bootstrap/platform/windows/hellolynk-host-protected-store.ps1 +2866 -0
  24. package/plugins/hellolynk-codex/runtime/connect-activate.mjs +837 -0
  25. package/plugins/hellolynk-codex/runtime/core/hellolynk-agent-configurator.mjs +701 -0
  26. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-account.mjs +180 -0
  27. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-core.mjs +770 -0
  28. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-profile.mjs +191 -0
  29. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-update-entry.mjs +31 -0
  30. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-update-runtime.mjs +600 -0
  31. package/plugins/hellolynk-codex/runtime/core/hellolynk-client-update.mjs +453 -0
  32. package/plugins/hellolynk-codex/runtime/core/hellolynk-contact-request-e2ee.mjs +867 -0
  33. package/plugins/hellolynk-codex/runtime/core/hellolynk-device-enrollment.mjs +435 -0
  34. package/plugins/hellolynk-codex/runtime/core/hellolynk-direct-text-e2ee-client.mjs +1964 -0
  35. package/plugins/hellolynk-codex/runtime/core/hellolynk-direct-text-e2ee.mjs +1207 -0
  36. package/plugins/hellolynk-codex/runtime/core/hellolynk-host-auth.mjs +347 -0
  37. package/plugins/hellolynk-codex/runtime/core/hellolynk-host-protected-store.mjs +2721 -0
  38. package/plugins/hellolynk-codex/runtime/core/hellolynk-host-transport-client.mjs +946 -0
  39. package/plugins/hellolynk-codex/runtime/core/hellolynk-host.mjs +2374 -0
  40. package/plugins/hellolynk-codex/runtime/core/hellolynk-human-confirmation-ledger.mjs +256 -0
  41. package/plugins/hellolynk-codex/runtime/core/hellolynk-human-relationship-controller.mjs +1234 -0
  42. package/plugins/hellolynk-codex/runtime/core/hellolynk-inbox-read-state.mjs +11 -0
  43. package/plugins/hellolynk-codex/runtime/core/hellolynk-indexed-message-store.mjs +1558 -0
  44. package/plugins/hellolynk-codex/runtime/core/hellolynk-instance-conversation.mjs +185 -0
  45. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-contact-requests.mjs +1733 -0
  46. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-contacts.mjs +1228 -0
  47. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-data-migration.mjs +766 -0
  48. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-data-protection.mjs +747 -0
  49. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-identity-trust.mjs +274 -0
  50. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-messaging.mjs +3043 -0
  51. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-peer-transport.mjs +103 -0
  52. package/plugins/hellolynk-codex/runtime/core/hellolynk-local-process-lock.mjs +157 -0
  53. package/plugins/hellolynk-codex/runtime/core/hellolynk-model-inbox.mjs +230 -0
  54. package/plugins/hellolynk-codex/runtime/core/hellolynk-model-notices.cjs +60 -0
  55. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-addressing-tools.cjs +231 -0
  56. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-conversations.mjs +280 -0
  57. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-human-confirmation-broker.mjs +1036 -0
  58. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-inbox-runtime.mjs +553 -0
  59. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-notice.mjs +50 -0
  60. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-reply-routes.mjs +96 -0
  61. package/plugins/hellolynk-codex/runtime/core/hellolynk-native-worker-lease.mjs +84 -0
  62. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-assembly.mjs +955 -0
  63. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-installation-store.mjs +765 -0
  64. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-launcher.mjs +665 -0
  65. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-process.mjs +4374 -0
  66. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-store-adapters.mjs +548 -0
  67. package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-workbench-read-model.mjs +1365 -0
  68. package/plugins/hellolynk-codex/runtime/core/hellolynk-platform-credential-store.mjs +773 -0
  69. package/plugins/hellolynk-codex/runtime/core/hellolynk-relay-client-cli.mjs +232 -0
  70. package/plugins/hellolynk-codex/runtime/core/hellolynk-release-retention.mjs +160 -0
  71. package/plugins/hellolynk-codex/runtime/core/hellolynk-runtime-safety.cjs +471 -0
  72. package/plugins/hellolynk-codex/runtime/core/hellolynk-workbench-action-grants.mjs +457 -0
  73. package/plugins/hellolynk-codex/runtime/core/hellolynk-workbench-connection.mjs +234 -0
  74. package/plugins/hellolynk-codex/runtime/neutral-host-bootstrap.mjs +64 -0
  75. package/plugins/hellolynk-codex/runtime/neutral-host-release-entry.mjs +70 -0
  76. package/plugins/hellolynk-codex/runtime/neutral-host-release-loader.mjs +156 -0
  77. package/plugins/hellolynk-codex/runtime/neutral-host-release-manifest.json +358 -0
  78. package/plugins/hellolynk-codex/runtime/neutral-host-release-pin.json +4 -0
  79. package/plugins/hellolynk-codex/runtime/platform/windows/configure-agent.ps1 +281 -0
  80. package/plugins/hellolynk-codex/runtime/platform/windows/credential-store.ps1 +844 -0
  81. package/plugins/hellolynk-codex/runtime/platform/windows/hellolynk-host-protected-store.ps1 +2866 -0
  82. package/plugins/hellolynk-codex/runtime/platform/windows/hellolynk-human-confirmation-ledger.ps1 +155 -0
  83. package/plugins/hellolynk-codex/runtime/platform/windows/hellolynk-local-data-key.ps1 +300 -0
  84. package/plugins/hellolynk-codex/runtime/platform/windows/hellolynk-native-human-confirmation-broker.ps1 +216 -0
  85. package/plugins/hellolynk-codex/runtime/workbench/candidate-bootstrap.mjs +54 -0
  86. package/plugins/hellolynk-codex/runtime/workbench/contract.mjs +1314 -0
  87. package/plugins/hellolynk-codex/runtime/workbench/hellolynk-workbench-build.json +215 -0
  88. package/plugins/hellolynk-codex/runtime/workbench/host-capabilities.mjs +80 -0
  89. package/plugins/hellolynk-codex/runtime/workbench/i18n.mjs +1127 -0
  90. package/plugins/hellolynk-codex/runtime/workbench/loopback-surface.mjs +740 -0
  91. package/plugins/hellolynk-codex/runtime/workbench/mcp-app-bundle.mjs +97 -0
  92. package/plugins/hellolynk-codex/runtime/workbench/service.mjs +485 -0
  93. package/plugins/hellolynk-codex/runtime/workbench/state.mjs +421 -0
  94. package/plugins/hellolynk-codex/runtime/workbench/transports.mjs +171 -0
  95. package/plugins/hellolynk-codex/runtime/workbench/ui/app.mjs +6120 -0
  96. package/plugins/hellolynk-codex/runtime/workbench/ui/connection-form.mjs +155 -0
  97. package/plugins/hellolynk-codex/runtime/workbench/ui/hellolynk-mark.png +0 -0
  98. package/plugins/hellolynk-codex/runtime/workbench/ui/http-transport.mjs +247 -0
  99. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/arrow-left.svg +3 -0
  100. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/close.svg +3 -0
  101. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/contacts.svg +3 -0
  102. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/inbox.svg +3 -0
  103. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/refresh.svg +3 -0
  104. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/search.svg +3 -0
  105. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/security.svg +3 -0
  106. package/plugins/hellolynk-codex/runtime/workbench/ui/icons/settings.svg +3 -0
  107. package/plugins/hellolynk-codex/runtime/workbench/ui/index.html +139 -0
  108. package/plugins/hellolynk-codex/runtime/workbench/ui/loopback-entry.mjs +26 -0
  109. package/plugins/hellolynk-codex/runtime/workbench/ui/mcp-app-client.mjs +151 -0
  110. package/plugins/hellolynk-codex/runtime/workbench/ui/mcp-app-entry.mjs +452 -0
  111. package/plugins/hellolynk-codex/runtime/workbench/ui/styles.css +686 -0
  112. package/plugins/hellolynk-codex/server/codex-neutral-production.mjs +520 -0
  113. package/plugins/hellolynk-codex/server/mcp-proxy.mjs +306 -0
  114. package/plugins/hellolynk-codex/server/mcp-server.mjs +1193 -0
  115. package/plugins/hellolynk-codex/server/native-conversation-directory.mjs +33 -0
  116. package/plugins/hellolynk-codex/server/native-reply-routes.mjs +32 -0
  117. package/plugins/hellolynk-codex/server/native-task-client.mjs +382 -0
  118. package/plugins/hellolynk-codex/server/native-task-runtime.mjs +8 -0
  119. package/plugins/hellolynk-codex/server/neutral-host-adapter.mjs +649 -0
  120. package/plugins/hellolynk-codex/server/workbench-runtime.mjs +180 -0
  121. package/plugins/hellolynk-codex/skills/hellolynk-open/SKILL.md +11 -0
  122. package/plugins/hellolynk-codex/skills/hellolynk-open/agents/openai.yaml +4 -0
  123. package/tools/hellolynk-activate-neutral-host-clients.mjs +837 -0
@@ -0,0 +1,185 @@
1
+ import crypto from "node:crypto";
2
+ import runtimeSafety from "./hellolynk-runtime-safety.cjs";
3
+
4
+ const BINDING_FIELDS = Object.freeze([
5
+ "schemaVersion", "region", "localPrincipalId", "localDelegateId", "peerPrincipalId", "peerDelegateId",
6
+ ]);
7
+ const ID_FIELDS = BINDING_FIELDS.slice(2);
8
+ const METADATA_FIELDS = Object.freeze([
9
+ "senderPrincipalId", "senderDelegateId", "senderHelloLynkId",
10
+ "recipientPrincipalId", "recipientDelegateId", "recipientHelloLynkId",
11
+ ]);
12
+ const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{2,199}$/;
13
+
14
+ function invalid(code = "instance_conversation_binding_invalid") {
15
+ const error = new Error(code);
16
+ error.code = code;
17
+ return error;
18
+ }
19
+
20
+ function contextRegion(value) {
21
+ if (value == null) return null;
22
+ if (value === "international") return "intl";
23
+ if (value !== "intl" && value !== "cn") throw invalid();
24
+ return value;
25
+ }
26
+
27
+ function stableIdRegion(value) {
28
+ const identity = runtimeSafety.classifyHelloLynkStableId(value);
29
+ if (!identity) throw invalid("instance_conversation_metadata_invalid");
30
+ return identity.region;
31
+ }
32
+
33
+ export function normalizeInstanceConversationBinding(value, options = {}) {
34
+ if (value == null) return null;
35
+ if (typeof value !== "object" || Array.isArray(value)
36
+ || Object.keys(value).length !== BINDING_FIELDS.length
37
+ || BINDING_FIELDS.some((field) => !Object.hasOwn(value, field))
38
+ || value.schemaVersion !== 1 || !["intl", "cn"].includes(value.region)
39
+ || ID_FIELDS.some((field) => typeof value[field] !== "string" || !SAFE_ID.test(value[field]))) {
40
+ throw invalid();
41
+ }
42
+ const region = contextRegion(options.region);
43
+ if ((region != null && region !== value.region)
44
+ || (options.principalId != null && options.principalId !== value.localPrincipalId)) {
45
+ throw invalid("instance_conversation_owner_mismatch");
46
+ }
47
+ return Object.freeze(Object.fromEntries(BINDING_FIELDS.map((field) => [field, value[field]])));
48
+ }
49
+
50
+ // The caller supplies metadata only after opening and verifying v2 ciphertext,
51
+ // or from its own previously sealed, durably saved outgoing envelope.
52
+ export function deriveInstanceConversationBinding(metadata, options = {}) {
53
+ if (!metadata || typeof metadata !== "object" || metadata.e2eeVersion !== 2
54
+ || !["incoming", "outgoing"].includes(options.direction)
55
+ || METADATA_FIELDS.some((field) => typeof metadata[field] !== "string" || !SAFE_ID.test(metadata[field]))) {
56
+ throw invalid("instance_conversation_metadata_invalid");
57
+ }
58
+ const region = stableIdRegion(metadata.senderHelloLynkId);
59
+ if (region !== stableIdRegion(metadata.recipientHelloLynkId)) {
60
+ throw invalid("instance_conversation_region_mismatch");
61
+ }
62
+ const local = options.direction === "incoming" ? "recipient" : "sender";
63
+ const peer = options.direction === "incoming" ? "sender" : "recipient";
64
+ return normalizeInstanceConversationBinding({
65
+ schemaVersion: 1,
66
+ region,
67
+ localPrincipalId: metadata[`${local}PrincipalId`],
68
+ localDelegateId: metadata[`${local}DelegateId`],
69
+ peerPrincipalId: metadata[`${peer}PrincipalId`],
70
+ peerDelegateId: metadata[`${peer}DelegateId`],
71
+ }, options);
72
+ }
73
+
74
+ function assertMessageMatchesBinding(message, binding) {
75
+ const incoming = message.direction === "incoming";
76
+ const senderPrincipalId = incoming ? binding.peerPrincipalId : binding.localPrincipalId;
77
+ const senderDelegateId = incoming ? binding.peerDelegateId : binding.localDelegateId;
78
+ const recipientPrincipalId = incoming ? binding.localPrincipalId : binding.peerPrincipalId;
79
+ const recipientDelegateId = incoming ? binding.localDelegateId : binding.peerDelegateId;
80
+ const expectations = {
81
+ senderPrincipalId, senderDelegateId, recipientPrincipalId, recipientDelegateId,
82
+ peerPrincipalId: binding.peerPrincipalId,
83
+ };
84
+ for (const [field, expected] of Object.entries(expectations)) {
85
+ if (message[field] != null && message[field] !== expected) {
86
+ throw invalid("instance_conversation_message_mismatch");
87
+ }
88
+ }
89
+ for (const field of ["peerHelloLynkId", "senderHelloLynkId", "recipientHelloLynkId"]) {
90
+ if (message[field] != null && stableIdRegion(message[field]) !== binding.region) {
91
+ throw invalid("instance_conversation_region_mismatch");
92
+ }
93
+ }
94
+ }
95
+
96
+ export function getMessageConversationBinding(message, options = {}) {
97
+ if (!message || !["incoming", "outgoing"].includes(message.direction)) throw invalid();
98
+ const persisted = normalizeInstanceConversationBinding(message.conversationBinding, options);
99
+ if (persisted) assertMessageMatchesBinding(message, persisted);
100
+ if (message.direction === "incoming") return persisted;
101
+ const intent = getOutgoingConversationIntent(message, options);
102
+ if (persisted && intent && instanceConversationKey(persisted) !== instanceConversationKey(intent)) {
103
+ throw invalid("instance_conversation_message_mismatch");
104
+ }
105
+
106
+ const envelope = message.e2ee?.envelope;
107
+ const metadata = envelope?.protected;
108
+ // Incomplete historical records stay readable as legacy. Current endpoint
109
+ // selection and contact labels are never evidence of their missing recipient.
110
+ if (envelope?.schemaVersion !== 2 || !metadata
111
+ || METADATA_FIELDS.some((field) => metadata[field] == null)) return persisted;
112
+ if (message.e2ee.envelopeDigest == null) {
113
+ if (persisted) throw invalid("instance_conversation_metadata_invalid");
114
+ return null;
115
+ }
116
+ if (message.e2ee.version != null && String(message.e2ee.version) !== "2"
117
+ || message.e2ee.envelopeDigest !== crypto.createHash("sha256").update(JSON.stringify(envelope), "utf8").digest("hex")) {
118
+ throw invalid("instance_conversation_metadata_invalid");
119
+ }
120
+ const derived = deriveInstanceConversationBinding({ ...metadata, e2eeVersion: 2 }, {
121
+ ...options, direction: "outgoing",
122
+ });
123
+ assertMessageMatchesBinding(message, derived);
124
+ if (message.e2ee.recipientDelegateId != null
125
+ && message.e2ee.recipientDelegateId !== metadata.recipientDelegateId) {
126
+ throw invalid("instance_conversation_message_mismatch");
127
+ }
128
+ if (message.peerHelloLynkId != null && message.peerHelloLynkId !== metadata.recipientHelloLynkId) {
129
+ throw invalid("instance_conversation_message_mismatch");
130
+ }
131
+ for (const field of ["senderHelloLynkId", "recipientHelloLynkId"]) {
132
+ if (message[field] != null && message[field] !== metadata[field]) {
133
+ throw invalid("instance_conversation_message_mismatch");
134
+ }
135
+ }
136
+ if (persisted && instanceConversationKey(persisted) !== instanceConversationKey(derived)) {
137
+ throw invalid("instance_conversation_message_mismatch");
138
+ }
139
+ if (intent && instanceConversationKey(intent) !== instanceConversationKey(derived)) {
140
+ throw invalid("instance_conversation_message_mismatch");
141
+ }
142
+ return persisted || derived;
143
+ }
144
+
145
+ // An explicit outgoing target is useful before encryption, but is never used
146
+ // as verified evidence for an incoming message or to recover historical IDs.
147
+ export function getOutgoingConversationIntent(message, options = {}) {
148
+ if (!message || message.direction !== "outgoing") return null;
149
+ const intent = normalizeInstanceConversationBinding(message.conversationIntent, options);
150
+ if (intent) {
151
+ if (message.senderPrincipalId !== intent.localPrincipalId
152
+ || message.senderDelegateId !== intent.localDelegateId
153
+ || stableIdRegion(message.peerHelloLynkId) !== intent.region) {
154
+ throw invalid("instance_conversation_message_mismatch");
155
+ }
156
+ assertMessageMatchesBinding(message, intent);
157
+ }
158
+ return intent;
159
+ }
160
+
161
+ export function createOutgoingConversationIntent(input = {}) {
162
+ if (input.region == null && input.recipientPrincipalId == null) return null;
163
+ const intent = normalizeInstanceConversationBinding({
164
+ schemaVersion: 1,
165
+ region: contextRegion(input.region),
166
+ localPrincipalId: input.senderPrincipalId,
167
+ localDelegateId: input.senderDelegateId,
168
+ peerPrincipalId: input.recipientPrincipalId,
169
+ peerDelegateId: input.recipientDelegateId,
170
+ });
171
+ return getOutgoingConversationIntent({
172
+ direction: "outgoing", conversationIntent: intent,
173
+ senderPrincipalId: input.senderPrincipalId, senderDelegateId: input.senderDelegateId,
174
+ peerHelloLynkId: input.recipientHelloLynkId,
175
+ });
176
+ }
177
+
178
+ export function instanceConversationKey(value) {
179
+ const binding = normalizeInstanceConversationBinding(value);
180
+ if (!binding) throw invalid();
181
+ const tuple = [binding.region, ...ID_FIELDS.map((field) => binding[field])];
182
+ return `thread_${crypto.createHash("sha256")
183
+ .update("hellolynk-instance-conversation-v1\n", "utf8")
184
+ .update(JSON.stringify(tuple), "utf8").digest("hex").slice(0, 40)}`;
185
+ }