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

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 +101 -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 +277 -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,180 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { lstatSync, readFileSync } from "node:fs";
3
+ import fs from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { applyCurrentUserAcl, defaultNeutralHostStoreRoot, withNeutralHostStoreLock } from "./hellolynk-neutral-host-installation-store.mjs";
6
+
7
+ export const ACCOUNT_CLIENTS = Object.freeze(["codex", "openclaw", "trae-work", "workbuddy", "dsh", "claude-code"]);
8
+ const GENERATION = /^[a-f0-9]{32}$/;
9
+ const INITIAL = "initial";
10
+
11
+ // Packages and account data have separate lifetimes. Existing installations
12
+ // keep their shared account until the user disconnects one particular client.
13
+ export function clientAccountBaseRoot(root = defaultNeutralHostStoreRoot()) {
14
+ if (!path.isAbsolute(root)) throw failure("workbench_account_path_invalid");
15
+ root = path.resolve(root);
16
+ const generation = path.dirname(root), client = path.dirname(generation), accounts = path.dirname(client);
17
+ if (path.basename(root) === "host" && GENERATION.test(path.basename(generation))
18
+ && ACCOUNT_CLIENTS.includes(path.basename(client)) && path.basename(accounts) === "account-data") {
19
+ return path.join(path.dirname(accounts), "host");
20
+ }
21
+ return root;
22
+ }
23
+
24
+ function statePath(client, baseRoot) {
25
+ if (!ACCOUNT_CLIENTS.includes(client)) throw failure("workbench_account_client_invalid");
26
+ return path.join(baseRoot, `client-account-${client}.json`);
27
+ }
28
+
29
+ export function readClientAccount(client, root = defaultNeutralHostStoreRoot()) {
30
+ const baseRoot = clientAccountBaseRoot(root);
31
+ const file = statePath(client, baseRoot);
32
+ let record;
33
+ try {
34
+ assertPath(file);
35
+ const stat = lstatSync(file);
36
+ if (!stat.isFile() || stat.nlink !== 1 || stat.size > 1024) throw failure("workbench_account_state_invalid");
37
+ record = JSON.parse(readFileSync(file, "utf8"));
38
+ } catch (error) {
39
+ if (error.code !== "ENOENT") throw failure("workbench_account_state_invalid");
40
+ return Object.freeze({ client, baseRoot, root: baseRoot, revision: INITIAL, phase: "ready", previousRevision: null });
41
+ }
42
+ if (record?.version !== 1 || !GENERATION.test(record.revision)
43
+ || !["disconnecting", "ready"].includes(record.phase)
44
+ || (record.previousRevision !== INITIAL && !GENERATION.test(record.previousRevision))
45
+ || Object.keys(record).sort().join(",") !== "phase,previousRevision,revision,version") {
46
+ throw failure("workbench_account_state_invalid");
47
+ }
48
+ return Object.freeze({ client, baseRoot, root: generationRoot(client, baseRoot, record.revision), ...record });
49
+ }
50
+
51
+ export function resolveClientAccountRoot(client, root) {
52
+ const account = readClientAccount(client, root);
53
+ if (account.phase !== "ready") throw failure("workbench_account_disconnect_incomplete");
54
+ return account.root;
55
+ }
56
+
57
+ export function assertClientAccountCurrent(client, root) {
58
+ if (!ACCOUNT_CLIENTS.includes(client)) return;
59
+ const account = readClientAccount(client, root);
60
+ if (account.phase !== "ready" || !samePath(root, account.root)) throw failure("workbench_account_changed");
61
+ }
62
+
63
+ export function withClientAccountLock(client, root, operation) {
64
+ const baseRoot = clientAccountBaseRoot(root);
65
+ statePath(client, baseRoot);
66
+ return withNeutralHostStoreLock(baseRoot, `client-account-${client}`, operation);
67
+ }
68
+
69
+ export function createClientAccountActions(options) {
70
+ const client = options?.client;
71
+ const root = options?.storeRoot || defaultNeutralHostStoreRoot("win32", options?.env || process.env);
72
+ statePath(client, clientAccountBaseRoot(root));
73
+ const readAccountState = () => {
74
+ const state = readClientAccount(client, root);
75
+ return { revision: state.revision, disconnecting: state.phase === "disconnecting", canDisconnect: true };
76
+ };
77
+ const assertRevision = (revision) => {
78
+ const state = readClientAccount(client, root);
79
+ if (state.revision !== revision) throw failure("workbench_account_changed");
80
+ if (state.phase !== "ready") throw failure("workbench_account_disconnect_incomplete");
81
+ return state.root;
82
+ };
83
+ return Object.freeze({
84
+ readAccountState, assertRevision,
85
+ runForAccount(revision, operation) {
86
+ return withClientAccountLock(client, root, () => operation(assertRevision(revision)));
87
+ },
88
+ async runSafetyVerificationForAccount(revision, operation) {
89
+ // Only native safety verification may wait outside the account lock.
90
+ // The Host fences its eventual write with the original attachment and
91
+ // exact device identity; the account revision also fences its UI result.
92
+ const pending = await withClientAccountLock(client, root, () => ({
93
+ completion: Promise.resolve(operation(assertRevision(revision))).then(
94
+ (value) => ({ value }), (error) => ({ error }),
95
+ ),
96
+ }));
97
+ const outcome = await pending.completion;
98
+ return withClientAccountLock(client, root, () => {
99
+ assertRevision(revision);
100
+ if (Object.hasOwn(outcome, "error")) throw outcome.error;
101
+ return outcome.value;
102
+ });
103
+ },
104
+ async disconnectAccount(input) {
105
+ if (!input || Object.keys(input).join(",") !== "revision"
106
+ || typeof input.revision !== "string" || !/^(?:initial|[a-f0-9]{32})$/.test(input.revision)) {
107
+ throw failure("workbench_disconnect_input_invalid");
108
+ }
109
+ return disconnectClientAccount({ client, root, revision: input.revision }, async (previousRoot) => {
110
+ const { createHostProtectedStore } = await import("./hellolynk-host-protected-store.mjs");
111
+ await createHostProtectedStore({ root: previousRoot, followClientAccount: false,
112
+ ...(options.helperPath ? { helperPath: options.helperPath } : {}),
113
+ }).disconnectLocalClient(client);
114
+ });
115
+ },
116
+ });
117
+ }
118
+
119
+ // The pending record is a durable fence: a crash while revoking the old local
120
+ // capability must never make it usable again. Retrying resumes that same fence.
121
+ export async function disconnectClientAccount({ client, root, revision }, revokePrevious) {
122
+ return withClientAccountLock(client, root, async () => {
123
+ let account = readClientAccount(client, root);
124
+ if (account.phase === "ready" && account.previousRevision === revision) {
125
+ return { disconnected: true, revision: account.revision };
126
+ }
127
+ if (revision !== account.revision && !(account.phase === "disconnecting" && revision === account.previousRevision)) {
128
+ throw failure("workbench_account_changed");
129
+ }
130
+ if (account.phase === "ready") {
131
+ await save(client, account.baseRoot, {
132
+ version: 1, revision: randomBytes(16).toString("hex"), previousRevision: account.revision, phase: "disconnecting",
133
+ });
134
+ account = readClientAccount(client, root);
135
+ }
136
+ const previousRoot = generationRoot(client, account.baseRoot, account.previousRevision);
137
+ await revokePrevious(previousRoot);
138
+ await save(client, account.baseRoot, {
139
+ version: 1, revision: account.revision, previousRevision: account.previousRevision, phase: "ready",
140
+ });
141
+ return { disconnected: true, revision: account.revision };
142
+ });
143
+ }
144
+
145
+ function generationRoot(client, baseRoot, revision) {
146
+ return revision === INITIAL ? baseRoot : path.join(path.dirname(baseRoot), "account-data", client, revision, "host");
147
+ }
148
+
149
+ async function save(client, root, record) {
150
+ const file = statePath(client, root);
151
+ assertPath(root);
152
+ const temporary = `${file}.${process.pid}.${randomBytes(6).toString("hex")}`;
153
+ let handle;
154
+ try {
155
+ handle = await fs.open(temporary, "wx", 0o600);
156
+ await handle.writeFile(`${JSON.stringify(record)}\n`);
157
+ await handle.sync();
158
+ await handle.close(); handle = null;
159
+ await fs.chmod(temporary, 0o600);
160
+ await applyCurrentUserAcl(temporary, false);
161
+ await fs.rename(temporary, file);
162
+ } finally {
163
+ await handle?.close();
164
+ await fs.unlink(temporary).catch((error) => { if (error.code !== "ENOENT") throw error; });
165
+ }
166
+ }
167
+
168
+ function assertPath(file) {
169
+ let cursor = path.resolve(file);
170
+ while (cursor !== path.dirname(cursor)) {
171
+ try { if (lstatSync(cursor).isSymbolicLink()) throw failure("workbench_account_path_invalid"); }
172
+ catch (error) { if (error.code !== "ENOENT") throw error; }
173
+ cursor = path.dirname(cursor);
174
+ }
175
+ }
176
+ function samePath(a, b) {
177
+ const normalize = (v) => process.platform === "win32" ? path.resolve(v).toLowerCase() : path.resolve(v);
178
+ return normalize(a) === normalize(b);
179
+ }
180
+ function failure(code) { return Object.assign(new Error(code), { code, status: 409 }); }