@insta-dev01/insta-plugin-openclaw 1.0.5 → 1.0.7
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/index.d.ts +3 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -169
- package/dist/index.js.map +1 -1
- package/dist/src/channel/index.d.ts.map +1 -1
- package/dist/src/channel/index.js +124 -38
- package/dist/src/channel/index.js.map +1 -1
- package/dist/src/channel/registration-store.d.ts +0 -18
- package/dist/src/channel/registration-store.d.ts.map +1 -1
- package/dist/src/channel/registration-store.js +0 -47
- package/dist/src/channel/registration-store.js.map +1 -1
- package/openclaw.plugin.json +110 -21
- package/package.json +13 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
description: string;
|
|
5
|
-
configSchema: import("openclaw/plugin-sdk").OpenClawPluginConfigSchema;
|
|
6
|
-
register: NonNullable<import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginDefinition["register"]>;
|
|
7
|
-
} & Pick<import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginDefinition, "kind" | "reload" | "nodeHostCommands" | "securityAuditCollectors">;
|
|
8
|
-
export default _default;
|
|
1
|
+
import { type OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry";
|
|
2
|
+
declare const plugin_entry: OpenClawPluginDefinition;
|
|
3
|
+
export default plugin_entry;
|
|
9
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAYpG,QAAA,MAAM,YAAY,EAAE,wBAgBlB,CAAC;AACH,eAAe,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,191 +2,26 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
|
2
2
|
import { DebugLogger } from "./src/channel/logger.js";
|
|
3
3
|
import { DEBUG_ENABLED } from "./src/channel/config.js";
|
|
4
4
|
import { plugin } from "./src/channel/index.js";
|
|
5
|
-
const log = new DebugLogger(DEBUG_ENABLED, "[InstaPlugin:entry]");
|
|
6
5
|
import { getPluginProfileToolFactory } from "./src/tools/get-plugin-profile.js";
|
|
7
6
|
import { uploadArtifactToolFactory } from "./src/tools/upload-artifact.js";
|
|
8
|
-
import { registerIdentityToolFactory } from "./src/tools/register-identity.js";
|
|
9
|
-
import { proposeRegistrationToolFactory } from "./src/tools/propose-registration.js";
|
|
10
7
|
import { listTasksToolFactory } from "./src/tools/list-tasks.js";
|
|
11
8
|
import { grabTaskToolFactory } from "./src/tools/grab-task.js";
|
|
12
9
|
import { submitDeliverableToolFactory } from "./src/tools/submit-deliverable.js";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// ── Registration confirmation control UI schema ───────────────────────────────
|
|
16
|
-
const REGISTRATION_FORM_SCHEMA = {
|
|
17
|
-
type: "object",
|
|
18
|
-
description: "InstaClaw 服务注册参数(可在此修改后点击确认注册)",
|
|
19
|
-
properties: {
|
|
20
|
-
name: {
|
|
21
|
-
type: "string",
|
|
22
|
-
description: "档案名称",
|
|
23
|
-
},
|
|
24
|
-
avatar: {
|
|
25
|
-
type: "string",
|
|
26
|
-
description: "头像图片 URL",
|
|
27
|
-
},
|
|
28
|
-
description: {
|
|
29
|
-
type: "string",
|
|
30
|
-
description: "服务描述",
|
|
31
|
-
},
|
|
32
|
-
hourly_rate: {
|
|
33
|
-
type: "number",
|
|
34
|
-
description: "时薪(元,必须 > 0)",
|
|
35
|
-
minimum: 0.01,
|
|
36
|
-
},
|
|
37
|
-
scene_tags: {
|
|
38
|
-
type: "array",
|
|
39
|
-
items: { type: "string" },
|
|
40
|
-
description: "场景标签 ID 数组(1-3 个)",
|
|
41
|
-
minItems: 1,
|
|
42
|
-
maxItems: 3,
|
|
43
|
-
},
|
|
44
|
-
custom_tags: {
|
|
45
|
-
type: "array",
|
|
46
|
-
items: { type: "string" },
|
|
47
|
-
description: "自定义标签(可选)",
|
|
48
|
-
},
|
|
49
|
-
instance_type: {
|
|
50
|
-
type: "number",
|
|
51
|
-
enum: [0, 1],
|
|
52
|
-
description: "实例类型:0 = 本地实例,1 = 影子实例",
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
required: ["name", "avatar", "description", "hourly_rate", "scene_tags", "instance_type"],
|
|
56
|
-
};
|
|
57
|
-
// ── Plugin entry ──────────────────────────────────────────────────────────────
|
|
58
|
-
export default definePluginEntry({
|
|
10
|
+
const log = new DebugLogger(DEBUG_ENABLED, "[InstaPlugin:entry]");
|
|
11
|
+
const plugin_entry = definePluginEntry({
|
|
59
12
|
id: "insta-plugin-openclaw",
|
|
60
13
|
name: "insta-plugin-openclaw",
|
|
61
14
|
description: "Instagram Claw Connector",
|
|
62
15
|
register(api) {
|
|
63
|
-
log.info("register() called
|
|
64
|
-
// ── Tools ────────────────────────────────────────────────────────────────
|
|
65
|
-
log.info("registerTool: insta_register_identity");
|
|
66
|
-
api.registerTool(registerIdentityToolFactory, { names: ["insta_register_identity"] });
|
|
67
|
-
log.info("registerTool: insta_propose_registration");
|
|
68
|
-
api.registerTool(proposeRegistrationToolFactory, { names: ["insta_propose_registration"] });
|
|
69
|
-
log.info("registerTool: insta_get_plugin_profile");
|
|
16
|
+
log.info("register() called");
|
|
70
17
|
api.registerTool(getPluginProfileToolFactory, { names: ["insta_get_plugin_profile"] });
|
|
71
|
-
log.info("registerTool: insta_upload_artifact");
|
|
72
18
|
api.registerTool(uploadArtifactToolFactory, { names: ["insta_upload_artifact"] });
|
|
73
|
-
log.info("registerTool: insta_list_tasks");
|
|
74
19
|
api.registerTool(listTasksToolFactory, { names: ["insta_list_tasks"] });
|
|
75
|
-
log.info("registerTool: insta_grab_task");
|
|
76
20
|
api.registerTool(grabTaskToolFactory, { names: ["insta_grab_task"] });
|
|
77
|
-
log.info("registerTool: insta_submit_deliverable");
|
|
78
21
|
api.registerTool(submitDeliverableToolFactory, { names: ["insta_submit_deliverable"] });
|
|
79
|
-
log.info("registerSessionExtension: instaclaw_registration");
|
|
80
|
-
// ── Session state extension ──────────────────────────────────────────────
|
|
81
|
-
//
|
|
82
|
-
// Projects the in-memory pending registration record into the Gateway
|
|
83
|
-
// session snapshot so clients can read it via session.pluginExtensions.
|
|
84
|
-
// The control UI descriptor below reads this projection to pre-fill the
|
|
85
|
-
// confirmation form.
|
|
86
|
-
api.session.state.registerSessionExtension({
|
|
87
|
-
namespace: "instaclaw_registration",
|
|
88
|
-
description: "InstaClaw 待确认注册信息。当 AI 生成注册提案后此字段会被填充,用户确认后清除。",
|
|
89
|
-
project: (_ctx) => {
|
|
90
|
-
const pending = getPendingRegistration();
|
|
91
|
-
if (!pending)
|
|
92
|
-
return undefined;
|
|
93
|
-
// Expose status + params so the client UI can pre-fill the form fields.
|
|
94
|
-
// Cast through `unknown` to satisfy the recursive PluginJsonValue constraint.
|
|
95
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
96
|
-
return {
|
|
97
|
-
status: pending.status,
|
|
98
|
-
createdAt: pending.createdAt,
|
|
99
|
-
params: pending.params,
|
|
100
|
-
}; // PluginJsonValue is a recursive type; `any` avoids deep mismatch
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
log.info("registerControlUiDescriptor: instaclaw-registration-confirm");
|
|
104
|
-
// ── Control UI descriptor ────────────────────────────────────────────────
|
|
105
|
-
//
|
|
106
|
-
// Declares a settings-surface widget that the Gateway client renders when
|
|
107
|
-
// `instaclaw_registration.status === "pending_confirmation"`.
|
|
108
|
-
// The user can edit the pre-filled fields before submitting.
|
|
109
|
-
api.session.controls.registerControlUiDescriptor({
|
|
110
|
-
id: "instaclaw-registration-confirm",
|
|
111
|
-
surface: "settings",
|
|
112
|
-
label: "InstaClaw 服务注册",
|
|
113
|
-
description: "AI 已根据当前 Agent 上下文推荐了一套注册参数,请确认或修改后点击「确认注册」完成注册。",
|
|
114
|
-
schema: REGISTRATION_FORM_SCHEMA,
|
|
115
|
-
});
|
|
116
|
-
log.info("registerGatewayMethod: instaclaw.registration.submit");
|
|
117
|
-
// ── Gateway method: confirm registration ─────────────────────────────────
|
|
118
|
-
//
|
|
119
|
-
// Called by the client UI when the user clicks "确认注册".
|
|
120
|
-
// `params` contains the (possibly edited) registration fields from the form.
|
|
121
|
-
// Falls back to the in-memory pending params for any missing fields so the
|
|
122
|
-
// form can send only the fields the user changed.
|
|
123
|
-
api.registerGatewayMethod("instaclaw.registration.submit", async (opts) => {
|
|
124
|
-
const { params, respond } = opts;
|
|
125
|
-
log.info("gatewayMethod instaclaw.registration.submit ENTER", {
|
|
126
|
-
provided_fields: Object.keys(params).filter((k) => params[k] !== undefined),
|
|
127
|
-
});
|
|
128
|
-
const pending = getPendingRegistration();
|
|
129
|
-
// Merge: form-provided values take precedence over the stored proposal.
|
|
130
|
-
const merged = {
|
|
131
|
-
name: params["name"] ?? pending?.params.name ?? "",
|
|
132
|
-
avatar: params["avatar"] ?? pending?.params.avatar ?? "",
|
|
133
|
-
description: params["description"] ?? pending?.params.description ?? "",
|
|
134
|
-
hourly_rate: params["hourly_rate"] ?? pending?.params.hourly_rate ?? 0,
|
|
135
|
-
scene_tags: params["scene_tags"] ?? pending?.params.scene_tags ?? [],
|
|
136
|
-
custom_tags: params["custom_tags"] ?? pending?.params.custom_tags,
|
|
137
|
-
instance_type: (params["instance_type"] ?? pending?.params.instance_type ?? 0),
|
|
138
|
-
};
|
|
139
|
-
// Basic guard: require at least the mandatory fields to be non-empty.
|
|
140
|
-
log.info("gatewayMethod merged params", {
|
|
141
|
-
name: merged.name,
|
|
142
|
-
hourly_rate: merged.hourly_rate,
|
|
143
|
-
scene_tags: merged.scene_tags,
|
|
144
|
-
instance_type: merged.instance_type,
|
|
145
|
-
});
|
|
146
|
-
if (!merged.name || !merged.avatar || !merged.description || merged.hourly_rate <= 0 || merged.scene_tags.length === 0) {
|
|
147
|
-
log.warn("gatewayMethod invalid merged params");
|
|
148
|
-
respond(false, undefined, {
|
|
149
|
-
code: "INVALID_PARAMS",
|
|
150
|
-
message: "注册参数不完整,name / avatar / description / hourly_rate / scene_tags 均为必填项。",
|
|
151
|
-
});
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
// Bug 1 fix: use the baseDir cached by startAccount instead of
|
|
155
|
-
// process.cwd(), which may point to a different directory.
|
|
156
|
-
const baseDir = getBaseDir();
|
|
157
|
-
let result;
|
|
158
|
-
log.info("gatewayMethod calling registerIdentity", { baseDir });
|
|
159
|
-
try {
|
|
160
|
-
result = await registerIdentity(merged, baseDir);
|
|
161
|
-
}
|
|
162
|
-
catch (err) {
|
|
163
|
-
log.error("gatewayMethod registerIdentity threw", err instanceof Error ? err : undefined);
|
|
164
|
-
respond(false, undefined, {
|
|
165
|
-
code: "REGISTRATION_EXCEPTION",
|
|
166
|
-
message: err instanceof Error ? err.message : String(err),
|
|
167
|
-
});
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
log.info("gatewayMethod registerIdentity result", { success: result.success, saved: result.saved, error: result.error });
|
|
171
|
-
if (!result.success) {
|
|
172
|
-
respond(false, undefined, {
|
|
173
|
-
code: "REGISTRATION_FAILED",
|
|
174
|
-
message: result.error ?? "注册失败,请重试。",
|
|
175
|
-
});
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
clearPendingRegistration();
|
|
179
|
-
log.info("gatewayMethod registration complete", { claw_id: result.data?.claw_id });
|
|
180
|
-
respond(true, {
|
|
181
|
-
app_key: result.data?.app_key,
|
|
182
|
-
claw_id: result.data?.claw_id,
|
|
183
|
-
message: "注册成功 ✓ InstaClaw channel 将在 10 秒内自动建立 WebSocket 连接。",
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
// ── Channel ──────────────────────────────────────────────────────────────
|
|
187
|
-
log.info("registerChannel: insta-connector");
|
|
188
22
|
api.registerChannel({ plugin });
|
|
189
23
|
log.info("register() complete");
|
|
190
24
|
},
|
|
191
25
|
});
|
|
26
|
+
export default plugin_entry;
|
|
192
27
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAiC,MAAM,kCAAkC,CAAC;AACpG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAEjF,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;AAElE,MAAM,YAAY,GAA6B,iBAAiB,CAAC;IAC/D,EAAE,EAAE,uBAAuB;IAC3B,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EAAE,0BAA0B;IACvC,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAE9B,GAAG,CAAC,YAAY,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QACvF,GAAG,CAAC,YAAY,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;QAClF,GAAG,CAAC,YAAY,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACxE,GAAG,CAAC,YAAY,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACtE,GAAG,CAAC,YAAY,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAExF,GAAG,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClC,CAAC;CACF,CAAC,CAAC;AACH,eAAe,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channel/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channel/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAgBzD,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,OAAO,IAAI,EAAE,SAAS,GACzB,IAAI,CAEN;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE5D;AAuED,eAAO,MAAM,MAAM,EAAE,aA2LpB,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
2
2
|
import { CHANNEL_ID, DEBUG_ENABLED, POLL_INTERVAL_MS } from "./config.js";
|
|
3
3
|
import { monitorProvider } from "./connection.js";
|
|
4
|
-
import {
|
|
5
|
-
import { setBaseDir, isAgentRunning, getPendingRegistration } from "./registration-store.js";
|
|
4
|
+
import { setBaseDir } from "./registration-store.js";
|
|
6
5
|
import { readProfile } from "../utils/profile.js";
|
|
6
|
+
import { registerIdentity } from "../core/register-identity.js";
|
|
7
7
|
import { createEnvelope, textToEventSequence } from "./protocol.js";
|
|
8
8
|
import { DebugLogger } from "./logger.js";
|
|
9
9
|
// ── Active WS connections (accountId → WebSocket) ─────────────────────────────
|
|
@@ -14,6 +14,60 @@ export function registerConnection(accountId, ws) {
|
|
|
14
14
|
export function unregisterConnection(accountId) {
|
|
15
15
|
activeConnections.delete(accountId || "default");
|
|
16
16
|
}
|
|
17
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Extract registration params from channel config.
|
|
20
|
+
* Returns null if any required field is missing or empty.
|
|
21
|
+
*/
|
|
22
|
+
function extractRegistrationParams(cfg) {
|
|
23
|
+
const name = cfg["name"];
|
|
24
|
+
const avatar = cfg["avatar"];
|
|
25
|
+
const description = cfg["description"];
|
|
26
|
+
const hourly_rate = cfg["hourly_rate"];
|
|
27
|
+
const scene_tags = cfg["scene_tags"];
|
|
28
|
+
if (!name?.trim() || !avatar?.trim() || !description?.trim() || !hourly_rate || !scene_tags?.length) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
name: name.trim(),
|
|
33
|
+
avatar: avatar.trim(),
|
|
34
|
+
description: description.trim(),
|
|
35
|
+
hourly_rate,
|
|
36
|
+
scene_tags,
|
|
37
|
+
custom_tags: cfg["custom_tags"] ?? [],
|
|
38
|
+
instance_type: (cfg["instance_type"] ?? 0),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Compare profile fields against channel config.
|
|
43
|
+
* Returns list of field names that differ (only checks fields present in cfg).
|
|
44
|
+
*/
|
|
45
|
+
function detectDrift(profile, cfg, logger) {
|
|
46
|
+
const drifted = [];
|
|
47
|
+
const scalarChecks = [
|
|
48
|
+
["name", profile.name, cfg["name"]],
|
|
49
|
+
["avatar", profile.avatar, cfg["avatar"]],
|
|
50
|
+
["description", profile.description, cfg["description"]],
|
|
51
|
+
["hourly_rate", profile.hourly_rate, cfg["hourly_rate"]],
|
|
52
|
+
["instance_type", profile.instance_type, cfg["instance_type"]],
|
|
53
|
+
];
|
|
54
|
+
for (const [field, profileVal, cfgVal] of scalarChecks) {
|
|
55
|
+
if (cfgVal !== undefined && profileVal !== cfgVal) {
|
|
56
|
+
logger.warn(`Profile/config drift: ${field}`, { profile: profileVal, config: cfgVal });
|
|
57
|
+
drifted.push(field);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const cfgSceneTags = cfg["scene_tags"];
|
|
61
|
+
if (cfgSceneTags?.length) {
|
|
62
|
+
const a = [...profile.scene_tags].sort().join(",");
|
|
63
|
+
const b = [...cfgSceneTags].sort().join(",");
|
|
64
|
+
if (a !== b) {
|
|
65
|
+
logger.warn("Profile/config drift: scene_tags", { profile: profile.scene_tags, config: cfgSceneTags });
|
|
66
|
+
drifted.push("scene_tags");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return drifted;
|
|
70
|
+
}
|
|
17
71
|
// ── Plugin ────────────────────────────────────────────────────────────────────
|
|
18
72
|
export const plugin = {
|
|
19
73
|
id: CHANNEL_ID,
|
|
@@ -33,33 +87,64 @@ export const plugin = {
|
|
|
33
87
|
edit: false,
|
|
34
88
|
reply: false,
|
|
35
89
|
},
|
|
90
|
+
configSchema: {
|
|
91
|
+
schema: {
|
|
92
|
+
type: "object",
|
|
93
|
+
properties: {
|
|
94
|
+
enabled: { type: "boolean", default: true },
|
|
95
|
+
debug: { type: "boolean", default: false },
|
|
96
|
+
name: { type: "string", description: "档案名称" },
|
|
97
|
+
avatar: { type: "string", description: "头像图片 URL" },
|
|
98
|
+
description: { type: "string", description: "服务描述" },
|
|
99
|
+
hourly_rate: { type: "number", description: "时薪(元,必须 > 0)" },
|
|
100
|
+
scene_tags: {
|
|
101
|
+
type: "array",
|
|
102
|
+
items: { type: "string" },
|
|
103
|
+
description: "场景标签 ID 数组(1-3 个)",
|
|
104
|
+
},
|
|
105
|
+
custom_tags: {
|
|
106
|
+
type: "array",
|
|
107
|
+
items: { type: "string" },
|
|
108
|
+
description: "自定义标签(可选)",
|
|
109
|
+
},
|
|
110
|
+
instance_type: {
|
|
111
|
+
type: "number",
|
|
112
|
+
enum: [0, 1],
|
|
113
|
+
default: 0,
|
|
114
|
+
description: "实例类型:0 = 本地实例,1 = 影子实例",
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
uiHints: {
|
|
119
|
+
enabled: { label: "Enable InstaClaw Connector" },
|
|
120
|
+
debug: { label: "Enable Debug Logging", advanced: true },
|
|
121
|
+
name: { label: "档案名称" },
|
|
122
|
+
avatar: { label: "头像 URL" },
|
|
123
|
+
description: { label: "服务描述" },
|
|
124
|
+
hourly_rate: { label: "时薪(元)" },
|
|
125
|
+
scene_tags: { label: "场景标签 ID" },
|
|
126
|
+
custom_tags: { label: "自定义标签" },
|
|
127
|
+
instance_type: { label: "实例类型(0=本地,1=影子)" },
|
|
128
|
+
},
|
|
129
|
+
},
|
|
36
130
|
config: {
|
|
37
131
|
listAccountIds: (_cfg) => [DEFAULT_ACCOUNT_ID],
|
|
38
|
-
resolveAccount: (_cfg, accountId) => ({
|
|
39
|
-
accountId: accountId ?? DEFAULT_ACCOUNT_ID,
|
|
40
|
-
}),
|
|
132
|
+
resolveAccount: (_cfg, accountId) => ({ accountId: accountId ?? DEFAULT_ACCOUNT_ID }),
|
|
41
133
|
defaultAccountId: () => DEFAULT_ACCOUNT_ID,
|
|
42
134
|
isConfigured: (_account) => true,
|
|
43
|
-
describeAccount: (account) => ({
|
|
44
|
-
accountId: account.accountId,
|
|
45
|
-
}),
|
|
135
|
+
describeAccount: (account) => ({ accountId: account.accountId }),
|
|
46
136
|
},
|
|
47
137
|
gateway: {
|
|
48
138
|
startAccount: async (ctx) => {
|
|
49
139
|
const { cfg, accountId, abortSignal } = ctx;
|
|
50
140
|
const resolvedAccountId = accountId ?? DEFAULT_ACCOUNT_ID;
|
|
51
|
-
// Resolve base directory for local profile storage
|
|
52
141
|
const cfgAny = cfg;
|
|
53
142
|
const baseDir = cfgAny["agentDir"] ??
|
|
54
143
|
cfgAny["workspaceDir"] ??
|
|
55
144
|
process.env["INSTA_BASE_DIR"] ??
|
|
56
145
|
process.cwd();
|
|
57
146
|
const logger = new DebugLogger(DEBUG_ENABLED, `[InstaPlugin:${resolvedAccountId}:startup]`);
|
|
58
|
-
// Bug 1 fix: cache the resolved baseDir so the gateway method
|
|
59
|
-
// (instaclaw.registration.submit) writes profile.json to the same path
|
|
60
|
-
// that this polling loop reads from.
|
|
61
147
|
setBaseDir(baseDir);
|
|
62
|
-
// Abort-aware sleep helper
|
|
63
148
|
const sleep = (ms) => new Promise((resolve) => {
|
|
64
149
|
if (abortSignal.aborted) {
|
|
65
150
|
resolve();
|
|
@@ -68,39 +153,40 @@ export const plugin = {
|
|
|
68
153
|
const t = setTimeout(resolve, ms);
|
|
69
154
|
abortSignal.addEventListener("abort", () => { clearTimeout(t); resolve(); }, { once: true });
|
|
70
155
|
});
|
|
71
|
-
logger.info("Gateway startup
|
|
156
|
+
logger.info("Gateway startup", { baseDir, pollIntervalMs: POLL_INTERVAL_MS });
|
|
72
157
|
while (!abortSignal.aborted) {
|
|
73
158
|
const profile = await readProfile(baseDir).catch((err) => {
|
|
74
159
|
logger.error("Failed to read profile", err);
|
|
75
160
|
return null;
|
|
76
161
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
162
|
+
if (profile?.app_key && profile?.app_secret) {
|
|
163
|
+
// ── Profile exists: check for drift against channel config ──────────
|
|
164
|
+
const drifted = detectDrift(profile, cfgAny, logger);
|
|
165
|
+
if (drifted.length > 0) {
|
|
166
|
+
// TODO: call update-registration API when available
|
|
167
|
+
logger.warn("Channel config differs from registered profile — skipping update (TODO: add update-registration API)", { drifted_fields: drifted });
|
|
168
|
+
}
|
|
169
|
+
logger.info("Credentials found, connecting WebSocket", { claw_id: profile.claw_id });
|
|
80
170
|
await monitorProvider({ clientId: profile.app_key, clientSecret: profile.app_secret }, resolvedAccountId, abortSignal, ctx.channelRuntime);
|
|
81
|
-
// monitorProvider resolves when the connection is cleanly shut down (abort).
|
|
82
171
|
return;
|
|
83
172
|
}
|
|
84
|
-
// ── No credentials
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const result = await triggerRegistrationAgent(ctx.channelRuntime, cfg, logger, resolvedAccountId);
|
|
101
|
-
logger.info("Registration agent trigger result", { status: result.status, error: result.error });
|
|
173
|
+
// ── No credentials: try registering from channel config ───────────────
|
|
174
|
+
const params = extractRegistrationParams(cfgAny);
|
|
175
|
+
if (!params) {
|
|
176
|
+
logger.warn("Channel config missing required registration fields (name / avatar / description / hourly_rate / scene_tags) — will retry");
|
|
177
|
+
await sleep(POLL_INTERVAL_MS);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
logger.info("No credentials found — registering from channel config", { name: params.name });
|
|
181
|
+
const result = await registerIdentity(params, baseDir);
|
|
182
|
+
if (result.success) {
|
|
183
|
+
logger.info("Registration successful — reconnecting", { claw_id: result.data?.claw_id });
|
|
184
|
+
// Loop immediately: next iteration will find the profile and connect.
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
logger.error("Registration failed — will retry", undefined, { error: result.error });
|
|
188
|
+
await sleep(POLL_INTERVAL_MS);
|
|
102
189
|
}
|
|
103
|
-
await sleep(POLL_INTERVAL_MS);
|
|
104
190
|
}
|
|
105
191
|
},
|
|
106
192
|
},
|
|
@@ -108,7 +194,7 @@ export const plugin = {
|
|
|
108
194
|
deliveryMode: "gateway",
|
|
109
195
|
sendText: async (ctx) => {
|
|
110
196
|
const { cfg, to, text, accountId } = ctx;
|
|
111
|
-
void cfg;
|
|
197
|
+
void cfg;
|
|
112
198
|
if (!text?.trim()) {
|
|
113
199
|
throw new Error("Cannot send empty message");
|
|
114
200
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/channel/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/channel/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
import type { RegisterIdentityParams } from "../core/register-identity.js";
|
|
2
|
-
export interface PendingRegistration {
|
|
3
|
-
status: "pending_confirmation";
|
|
4
|
-
params: RegisterIdentityParams;
|
|
5
|
-
createdAt: number;
|
|
6
|
-
}
|
|
7
|
-
/** Store a set of AI-proposed registration params, waiting for user confirmation. */
|
|
8
|
-
export declare function setPendingRegistration(params: RegisterIdentityParams): void;
|
|
9
|
-
/** Return the currently pending registration, or null if none. */
|
|
10
|
-
export declare function getPendingRegistration(): PendingRegistration | null;
|
|
11
|
-
/** Remove the pending registration (call after successful submit or cancel). */
|
|
12
|
-
export declare function clearPendingRegistration(): void;
|
|
13
|
-
/** Called by `startAccount` as soon as baseDir is resolved. */
|
|
14
1
|
export declare function setBaseDir(dir: string): void;
|
|
15
|
-
/** Returns the most recently cached baseDir, falling back to process.cwd(). */
|
|
16
2
|
export declare function getBaseDir(): string;
|
|
17
|
-
/** Mark the registration agent as in-flight. */
|
|
18
|
-
export declare function setAgentRunning(running: boolean): void;
|
|
19
|
-
/** True while a dispatch is in-flight; false once deliver/catch fires. */
|
|
20
|
-
export declare function isAgentRunning(): boolean;
|
|
21
3
|
//# sourceMappingURL=registration-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration-store.d.ts","sourceRoot":"","sources":["../../../src/channel/registration-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registration-store.d.ts","sourceRoot":"","sources":["../../../src/channel/registration-store.ts"],"names":[],"mappings":"AAOA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAG5C;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC"}
|
|
@@ -1,59 +1,12 @@
|
|
|
1
1
|
import { DebugLogger } from "./logger.js";
|
|
2
2
|
import { DEBUG_ENABLED } from "./config.js";
|
|
3
3
|
const log = new DebugLogger(DEBUG_ENABLED, "[InstaPlugin:store]");
|
|
4
|
-
let _pending = null;
|
|
5
|
-
/** Store a set of AI-proposed registration params, waiting for user confirmation. */
|
|
6
|
-
export function setPendingRegistration(params) {
|
|
7
|
-
_pending = {
|
|
8
|
-
status: "pending_confirmation",
|
|
9
|
-
params,
|
|
10
|
-
createdAt: Date.now(),
|
|
11
|
-
};
|
|
12
|
-
log.info("setPendingRegistration", { name: params.name, hourly_rate: params.hourly_rate, scene_tags: params.scene_tags });
|
|
13
|
-
}
|
|
14
|
-
/** Return the currently pending registration, or null if none. */
|
|
15
|
-
export function getPendingRegistration() {
|
|
16
|
-
return _pending;
|
|
17
|
-
}
|
|
18
|
-
/** Remove the pending registration (call after successful submit or cancel). */
|
|
19
|
-
export function clearPendingRegistration() {
|
|
20
|
-
log.info("clearPendingRegistration", { had_pending: !!_pending });
|
|
21
|
-
_pending = null;
|
|
22
|
-
}
|
|
23
|
-
// ── Bug 1 fix: baseDir cache ──────────────────────────────────────────────────
|
|
24
|
-
//
|
|
25
|
-
// `startAccount` resolves baseDir from `cfg` (agentDir / workspaceDir / cwd).
|
|
26
|
-
// The gateway method runs outside that context, so it reads the cached value
|
|
27
|
-
// instead of falling back to process.cwd() which may differ.
|
|
28
4
|
let _baseDir = null;
|
|
29
|
-
/** Called by `startAccount` as soon as baseDir is resolved. */
|
|
30
5
|
export function setBaseDir(dir) {
|
|
31
6
|
log.info("setBaseDir", { dir });
|
|
32
7
|
_baseDir = dir;
|
|
33
8
|
}
|
|
34
|
-
/** Returns the most recently cached baseDir, falling back to process.cwd(). */
|
|
35
9
|
export function getBaseDir() {
|
|
36
10
|
return _baseDir ?? process.cwd();
|
|
37
11
|
}
|
|
38
|
-
// ── Bug 2 fix: agent-running flag ─────────────────────────────────────────────
|
|
39
|
-
//
|
|
40
|
-
// Tracks whether a registration agent dispatch is currently in-flight.
|
|
41
|
-
// Set to true before dispatch starts; cleared in both the `deliver` callback
|
|
42
|
-
// (success or silent failure) and the `.catch` handler (hard error).
|
|
43
|
-
//
|
|
44
|
-
// `startAccount` uses this together with `getPendingRegistration()` to decide
|
|
45
|
-
// whether to re-trigger the agent:
|
|
46
|
-
// - agent running → skip (already in flight)
|
|
47
|
-
// - pending exists → skip (proposal already created, waiting for user)
|
|
48
|
-
// - neither → trigger (covers both first run and recovery after failure)
|
|
49
|
-
let _agentRunning = false;
|
|
50
|
-
/** Mark the registration agent as in-flight. */
|
|
51
|
-
export function setAgentRunning(running) {
|
|
52
|
-
log.info("setAgentRunning", { running, prev: _agentRunning });
|
|
53
|
-
_agentRunning = running;
|
|
54
|
-
}
|
|
55
|
-
/** True while a dispatch is in-flight; false once deliver/catch fires. */
|
|
56
|
-
export function isAgentRunning() {
|
|
57
|
-
return _agentRunning;
|
|
58
|
-
}
|
|
59
12
|
//# sourceMappingURL=registration-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration-store.js","sourceRoot":"","sources":["../../../src/channel/registration-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registration-store.js","sourceRoot":"","sources":["../../../src/channel/registration-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;AAElE,IAAI,QAAQ,GAAkB,IAAI,CAAC;AAEnC,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAChC,QAAQ,GAAG,GAAG,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;AACnC,CAAC"}
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,41 +1,130 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "insta-plugin-openclaw",
|
|
3
|
-
"
|
|
3
|
+
"name": "Insta Connector",
|
|
4
4
|
"contracts": {
|
|
5
|
-
"tools":
|
|
6
|
-
|
|
5
|
+
"tools": [
|
|
6
|
+
"insta_get_plugin_profile",
|
|
7
|
+
"insta_upload_artifact",
|
|
8
|
+
"insta_list_tasks",
|
|
9
|
+
"insta_grab_task",
|
|
10
|
+
"insta_submit_deliverable"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"description": "A lightweight OpenClaw channel plugin for WebSocket-based bidirectional messaging",
|
|
14
|
+
"kind": "channel",
|
|
15
|
+
"channels": ["insta-connector"],
|
|
16
|
+
"activation": {
|
|
17
|
+
"onStartup": false,
|
|
18
|
+
"onChannels": ["insta-connector"]
|
|
19
|
+
},
|
|
20
|
+
"configSchema": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"additionalProperties": false,
|
|
23
|
+
"properties": {
|
|
24
|
+
"enabled": {
|
|
25
|
+
"type": "boolean",
|
|
26
|
+
"default": true,
|
|
27
|
+
"description": "Enable or disable the plugin runtime"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"uiHints": {
|
|
32
|
+
"enabled": {
|
|
33
|
+
"label": "Plugin enabled",
|
|
34
|
+
"help": "Enable this plugin and allow it to handle its declared channel."
|
|
35
|
+
}
|
|
7
36
|
},
|
|
8
37
|
"channelConfigs": {
|
|
9
38
|
"insta-connector": {
|
|
10
|
-
"
|
|
11
|
-
"description": "
|
|
39
|
+
"label": "Insta Connector",
|
|
40
|
+
"description": "WebSocket-based bidirectional messaging channel",
|
|
12
41
|
"schema": {
|
|
13
42
|
"type": "object",
|
|
14
43
|
"additionalProperties": false,
|
|
15
44
|
"properties": {
|
|
16
45
|
"enabled": {
|
|
17
46
|
"type": "boolean",
|
|
18
|
-
"default": true
|
|
47
|
+
"default": true,
|
|
48
|
+
"description": "Enable or disable this channel instance"
|
|
49
|
+
},
|
|
50
|
+
"debug": {
|
|
51
|
+
"type": "boolean",
|
|
52
|
+
"default": false,
|
|
53
|
+
"description": "Enable debug logging for the channel"
|
|
54
|
+
},
|
|
55
|
+
"name": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"description": "档案名称(必填)"
|
|
58
|
+
},
|
|
59
|
+
"avatar": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"description": "头像图片 URL(必填)"
|
|
19
62
|
},
|
|
20
|
-
"
|
|
63
|
+
"description": {
|
|
21
64
|
"type": "string",
|
|
22
|
-
"description": "
|
|
65
|
+
"description": "服务描述(必填)"
|
|
66
|
+
},
|
|
67
|
+
"hourly_rate": {
|
|
68
|
+
"type": "number",
|
|
69
|
+
"description": "时薪(元,必须 > 0,必填)"
|
|
70
|
+
},
|
|
71
|
+
"scene_tags": {
|
|
72
|
+
"type": "array",
|
|
73
|
+
"items": { "type": "string" },
|
|
74
|
+
"description": "场景标签 ID 数组(1-3 个,必填)"
|
|
75
|
+
},
|
|
76
|
+
"custom_tags": {
|
|
77
|
+
"type": "array",
|
|
78
|
+
"items": { "type": "string" },
|
|
79
|
+
"description": "自定义标签(可选)"
|
|
80
|
+
},
|
|
81
|
+
"instance_type": {
|
|
82
|
+
"type": "number",
|
|
83
|
+
"enum": [0, 1],
|
|
84
|
+
"default": 0,
|
|
85
|
+
"description": "实例类型:0 = 本地实例,1 = 影子实例"
|
|
23
86
|
}
|
|
24
87
|
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"configSchema": {
|
|
29
|
-
"type": "object",
|
|
30
|
-
"additionalProperties": false,
|
|
31
|
-
"properties": {
|
|
32
|
-
"enabled": {
|
|
33
|
-
"type": "boolean",
|
|
34
|
-
"default": true
|
|
35
88
|
},
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
89
|
+
"uiHints": {
|
|
90
|
+
"enabled": {
|
|
91
|
+
"label": "Channel enabled",
|
|
92
|
+
"help": "Turn this channel instance on or off."
|
|
93
|
+
},
|
|
94
|
+
"debug": {
|
|
95
|
+
"label": "Debug logging",
|
|
96
|
+
"help": "Enable verbose logs for troubleshooting.",
|
|
97
|
+
"advanced": true
|
|
98
|
+
},
|
|
99
|
+
"name": {
|
|
100
|
+
"label": "档案名称",
|
|
101
|
+
"help": "在 InstaClaw 平台上显示的名称。"
|
|
102
|
+
},
|
|
103
|
+
"avatar": {
|
|
104
|
+
"label": "头像 URL",
|
|
105
|
+
"help": "可公开访问的头像图片链接。"
|
|
106
|
+
},
|
|
107
|
+
"description": {
|
|
108
|
+
"label": "服务描述",
|
|
109
|
+
"help": "简要描述当前 Agent 的能力(1-2 句话)。"
|
|
110
|
+
},
|
|
111
|
+
"hourly_rate": {
|
|
112
|
+
"label": "时薪(元)",
|
|
113
|
+
"help": "接单计费单价,必须大于 0。"
|
|
114
|
+
},
|
|
115
|
+
"scene_tags": {
|
|
116
|
+
"label": "场景标签 ID",
|
|
117
|
+
"help": "选择 1-3 个场景分类 ID,例如 01001(前端)、01003(AI/算法)。"
|
|
118
|
+
},
|
|
119
|
+
"custom_tags": {
|
|
120
|
+
"label": "自定义标签",
|
|
121
|
+
"help": "可选,用于补充描述服务特性的标签。",
|
|
122
|
+
"advanced": true
|
|
123
|
+
},
|
|
124
|
+
"instance_type": {
|
|
125
|
+
"label": "实例类型",
|
|
126
|
+
"help": "0 = 本地实例(推荐),1 = 影子实例。"
|
|
127
|
+
}
|
|
39
128
|
}
|
|
40
129
|
}
|
|
41
130
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@insta-dev01/insta-plugin-openclaw",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Instagram Claw Connector - A lightweight OpenClaw channel plugin for WebSocket-based bidirectional messaging",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
7
|
-
"type": "module",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist",
|
|
10
10
|
"openclaw.plugin.json",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"author": "Instagram Claw Team",
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"engines": {
|
|
41
|
-
"node": ">=
|
|
41
|
+
"node": ">=22.19.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"archiver": "^8.0.0",
|
|
@@ -46,14 +46,14 @@
|
|
|
46
46
|
"ws": "^8.20.1"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"openclaw": ">=2026.5
|
|
49
|
+
"openclaw": ">=2026.6.5"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/node": "^20.19.37",
|
|
53
53
|
"@types/ws": "^8.18.1",
|
|
54
54
|
"@vitest/coverage-v8": "^2.0.0",
|
|
55
55
|
"@vitest/ui": "^2.1.9",
|
|
56
|
-
"openclaw": "^2026.6.
|
|
56
|
+
"openclaw": "^2026.6.5",
|
|
57
57
|
"typescript": "^5.6.0",
|
|
58
58
|
"vitest": "^2.1.9"
|
|
59
59
|
},
|
|
@@ -62,9 +62,15 @@
|
|
|
62
62
|
"./dist/index.js"
|
|
63
63
|
],
|
|
64
64
|
"channel": {
|
|
65
|
-
"id": "insta-connector"
|
|
65
|
+
"id": "insta-connector",
|
|
66
|
+
"label": "Insta Connector",
|
|
67
|
+
"blurb": "WebSocket-based bidirectional messaging channel for Instagram connector flows"
|
|
66
68
|
},
|
|
67
|
-
"
|
|
69
|
+
"install": {
|
|
70
|
+
"npmSpec": "@insta-dev01/insta-plugin-openclaw@1.0.6",
|
|
71
|
+
"defaultChoice": "npm",
|
|
72
|
+
"minHostVersion": ">=2026.6.1"
|
|
73
|
+
}
|
|
68
74
|
},
|
|
69
75
|
"packageManager": "pnpm@10.25.0"
|
|
70
76
|
}
|