@reconcrap/boss-recommend-mcp 1.3.38 → 2.0.0
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/README.md +53 -33
- package/package.json +61 -9
- package/skills/boss-recommend-pipeline/SKILL.md +4 -0
- package/src/chat-mcp.js +1333 -0
- package/src/chat-runtime-config.js +559 -0
- package/src/cli.js +1095 -196
- package/src/core/browser/index.js +378 -0
- package/src/core/capture/index.js +298 -0
- package/src/core/cv-acquisition/index.js +219 -0
- package/src/core/greet-quota/index.js +54 -0
- package/src/core/infinite-list/index.js +459 -0
- package/src/core/reporting/legacy-csv.js +332 -0
- package/src/core/run/index.js +286 -0
- package/src/core/screening/index.js +1166 -0
- package/src/core/self-heal/index.js +848 -0
- package/src/domains/chat/cards.js +129 -0
- package/src/domains/chat/constants.js +183 -0
- package/src/domains/chat/detail.js +1369 -0
- package/src/domains/chat/index.js +7 -0
- package/src/domains/chat/jobs.js +334 -0
- package/src/domains/chat/page-guard.js +88 -0
- package/src/domains/chat/roots.js +56 -0
- package/src/domains/chat/run-service.js +1101 -0
- package/src/domains/recommend/actions.js +457 -0
- package/src/domains/recommend/cards.js +228 -0
- package/src/domains/recommend/constants.js +141 -0
- package/src/domains/recommend/detail.js +341 -0
- package/src/domains/recommend/filters.js +581 -0
- package/src/domains/recommend/index.js +10 -0
- package/src/domains/recommend/jobs.js +232 -0
- package/src/domains/recommend/refresh.js +204 -0
- package/src/domains/recommend/roots.js +78 -0
- package/src/domains/recommend/run-service.js +903 -0
- package/src/domains/recommend/scopes.js +245 -0
- package/src/domains/recruit/actions.js +277 -0
- package/src/domains/recruit/cards.js +67 -0
- package/src/domains/recruit/constants.js +130 -0
- package/src/domains/recruit/detail.js +414 -0
- package/src/domains/recruit/index.js +9 -0
- package/src/domains/recruit/instruction-parser.js +451 -0
- package/src/domains/recruit/refresh.js +40 -0
- package/src/domains/recruit/roots.js +68 -0
- package/src/domains/recruit/run-service.js +580 -0
- package/src/domains/recruit/search.js +1149 -0
- package/src/index.js +578 -419
- package/src/recommend-mcp.js +1257 -0
- package/src/recruit-mcp.js +1035 -0
- package/src/adapters.js +0 -3079
- package/src/boss-chat.js +0 -1037
- package/src/pipeline.js +0 -2249
- package/src/recommend-healing-config.js +0 -131
- package/src/recommend-healing-rules.json +0 -261
- package/src/self-heal.js +0 -2237
- package/src/test-adapters-runtime.js +0 -628
- package/src/test-boss-chat.js +0 -3196
- package/src/test-index-async.js +0 -498
- package/src/test-parser.js +0 -742
- package/src/test-pipeline.js +0 -2703
- package/src/test-run-state.js +0 -152
- package/src/test-self-heal.js +0 -224
- package/vendor/boss-chat-cli/README.md +0 -134
- package/vendor/boss-chat-cli/package.json +0 -53
- package/vendor/boss-chat-cli/src/app.js +0 -1501
- package/vendor/boss-chat-cli/src/browser/chat-page.js +0 -3562
- package/vendor/boss-chat-cli/src/cli.js +0 -1713
- package/vendor/boss-chat-cli/src/mcp/server.js +0 -149
- package/vendor/boss-chat-cli/src/mcp/tool-runtime.js +0 -193
- package/vendor/boss-chat-cli/src/runtime/async-run-state.js +0 -260
- package/vendor/boss-chat-cli/src/runtime/interaction.js +0 -102
- package/vendor/boss-chat-cli/src/runtime/run-control.js +0 -102
- package/vendor/boss-chat-cli/src/services/chrome-client.js +0 -107
- package/vendor/boss-chat-cli/src/services/llm.js +0 -1292
- package/vendor/boss-chat-cli/src/services/llm.test.js +0 -326
- package/vendor/boss-chat-cli/src/services/profile-store.js +0 -173
- package/vendor/boss-chat-cli/src/services/report-store.js +0 -317
- package/vendor/boss-chat-cli/src/services/resume-capture.js +0 -469
- package/vendor/boss-chat-cli/src/services/resume-network.js +0 -727
- package/vendor/boss-chat-cli/src/services/state-store.js +0 -90
- package/vendor/boss-chat-cli/src/utils/customer-key.js +0 -82
- package/vendor/boss-recommend-screen-cli/boss-recommend-screen-cli.cjs +0 -6927
- package/vendor/boss-recommend-screen-cli/scripts/capture-full-resume-canvas.cjs +0 -817
- package/vendor/boss-recommend-screen-cli/scripts/stitch_resume_chunks.py +0 -141
- package/vendor/boss-recommend-screen-cli/test-recoverable-resume-failures.cjs +0 -2294
- package/vendor/boss-recommend-search-cli/src/cli.js +0 -1698
- package/vendor/boss-recommend-search-cli/src/test-job-selection.js +0 -211
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import process from "node:process";
|
|
4
|
-
import { createRequire } from "node:module";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
-
|
|
7
|
-
const require = createRequire(import.meta.url);
|
|
8
|
-
const currentFilePath = fileURLToPath(import.meta.url);
|
|
9
|
-
const defaultRulesPath = path.join(path.dirname(currentFilePath), "recommend-healing-rules.json");
|
|
10
|
-
|
|
11
|
-
let cachedRulesPath = null;
|
|
12
|
-
let cachedRulesMtime = null;
|
|
13
|
-
let cachedRules = null;
|
|
14
|
-
|
|
15
|
-
function clone(value) {
|
|
16
|
-
return JSON.parse(JSON.stringify(value));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function normalizePathLike(value) {
|
|
20
|
-
return String(value || "").trim();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function getNestedValue(root, pathParts = []) {
|
|
24
|
-
let current = root;
|
|
25
|
-
for (const part of pathParts) {
|
|
26
|
-
if (!current || typeof current !== "object" || Array.isArray(current)) {
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
29
|
-
current = current[part];
|
|
30
|
-
}
|
|
31
|
-
return current;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function getRecommendHealingRulesPath() {
|
|
35
|
-
const fromEnv = normalizePathLike(process.env.BOSS_RECOMMEND_HEALING_RULES_FILE);
|
|
36
|
-
return fromEnv ? path.resolve(fromEnv) : defaultRulesPath;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function loadRecommendHealingRules(options = {}) {
|
|
40
|
-
const fresh = options.fresh === true;
|
|
41
|
-
const rulesPath = getRecommendHealingRulesPath();
|
|
42
|
-
const stats = fs.statSync(rulesPath);
|
|
43
|
-
if (
|
|
44
|
-
!fresh
|
|
45
|
-
&& cachedRules
|
|
46
|
-
&& cachedRulesPath === rulesPath
|
|
47
|
-
&& cachedRulesMtime === Number(stats.mtimeMs)
|
|
48
|
-
) {
|
|
49
|
-
return clone(cachedRules);
|
|
50
|
-
}
|
|
51
|
-
const nextRules = require(rulesPath);
|
|
52
|
-
cachedRulesPath = rulesPath;
|
|
53
|
-
cachedRulesMtime = Number(stats.mtimeMs);
|
|
54
|
-
cachedRules = clone(nextRules);
|
|
55
|
-
return clone(cachedRules);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function saveRecommendHealingRules(nextRules) {
|
|
59
|
-
const rulesPath = getRecommendHealingRulesPath();
|
|
60
|
-
const serialized = `${JSON.stringify(nextRules, null, 2)}\n`;
|
|
61
|
-
fs.writeFileSync(rulesPath, serialized, "utf8");
|
|
62
|
-
cachedRulesPath = rulesPath;
|
|
63
|
-
cachedRulesMtime = Number(fs.statSync(rulesPath).mtimeMs);
|
|
64
|
-
cachedRules = clone(nextRules);
|
|
65
|
-
return rulesPath;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function getRecommendSelectorRule(pathParts = [], fallback = []) {
|
|
69
|
-
const value = getNestedValue(loadRecommendHealingRules(), ["selectors", ...pathParts]);
|
|
70
|
-
return Array.isArray(value) && value.length > 0 ? value.map((item) => String(item)) : fallback.slice();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function getRecommendNetworkRule(pathParts = [], fallback = null) {
|
|
74
|
-
const value = getNestedValue(loadRecommendHealingRules(), ["network", ...pathParts]);
|
|
75
|
-
if (Array.isArray(value)) return value.map((item) => String(item));
|
|
76
|
-
if (value && typeof value === "object") return clone(value);
|
|
77
|
-
if (typeof value === "string") return value;
|
|
78
|
-
if (Array.isArray(fallback)) return fallback.slice();
|
|
79
|
-
if (fallback && typeof fallback === "object") return clone(fallback);
|
|
80
|
-
return fallback;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function compileRegexList(patterns = []) {
|
|
84
|
-
return (Array.isArray(patterns) ? patterns : [])
|
|
85
|
-
.map((pattern) => {
|
|
86
|
-
try {
|
|
87
|
-
return new RegExp(String(pattern), "i");
|
|
88
|
-
} catch {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
})
|
|
92
|
-
.filter(Boolean);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export function findFirstMatchingPattern(value, patterns = []) {
|
|
96
|
-
const text = String(value || "");
|
|
97
|
-
for (const pattern of compileRegexList(patterns)) {
|
|
98
|
-
if (pattern.test(text)) return pattern.source;
|
|
99
|
-
}
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function matchesAnyPattern(value, patterns = []) {
|
|
104
|
-
return Boolean(findFirstMatchingPattern(value, patterns));
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function buildFirstSelectorLookupExpression(selectors = [], rootExpr = "document") {
|
|
108
|
-
return `(() => {
|
|
109
|
-
const selectors = ${JSON.stringify(selectors)};
|
|
110
|
-
for (const selector of selectors) {
|
|
111
|
-
try {
|
|
112
|
-
const node = ${rootExpr}.querySelector(selector);
|
|
113
|
-
if (node) return node;
|
|
114
|
-
} catch {}
|
|
115
|
-
}
|
|
116
|
-
return null;
|
|
117
|
-
})()`;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export function buildSelectorCollectionExpression(selectors = [], rootExpr = "document") {
|
|
121
|
-
return `(() => {
|
|
122
|
-
const selectors = ${JSON.stringify(selectors)};
|
|
123
|
-
const nodes = [];
|
|
124
|
-
for (const selector of selectors) {
|
|
125
|
-
try {
|
|
126
|
-
nodes.push(...Array.from(${rootExpr}.querySelectorAll(selector)));
|
|
127
|
-
} catch {}
|
|
128
|
-
}
|
|
129
|
-
return Array.from(new Set(nodes));
|
|
130
|
-
})()`;
|
|
131
|
-
}
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 1,
|
|
3
|
-
"selectors": {
|
|
4
|
-
"top": {
|
|
5
|
-
"recommend_iframe": [
|
|
6
|
-
"iframe[name=\"recommendFrame\"]",
|
|
7
|
-
"iframe[src*=\"/web/frame/recommend/\"]",
|
|
8
|
-
"iframe"
|
|
9
|
-
]
|
|
10
|
-
},
|
|
11
|
-
"frame": {
|
|
12
|
-
"tab_items": [
|
|
13
|
-
"li.tab-item[data-status]",
|
|
14
|
-
"li[data-status][class*=\"tab\"]"
|
|
15
|
-
],
|
|
16
|
-
"filter_trigger": [
|
|
17
|
-
".filter-label-wrap",
|
|
18
|
-
".recommend-filter.op-filter"
|
|
19
|
-
],
|
|
20
|
-
"filter_panel": [
|
|
21
|
-
".recommend-filter.op-filter .filter-panel",
|
|
22
|
-
".recommend-filter .filter-panel",
|
|
23
|
-
".filter-panel"
|
|
24
|
-
],
|
|
25
|
-
"filter_confirm_button": [
|
|
26
|
-
".recommend-filter.op-filter .filter-panel .btn",
|
|
27
|
-
".recommend-filter.op-filter .filter-panel button",
|
|
28
|
-
".filter-panel .btn",
|
|
29
|
-
".filter-panel button"
|
|
30
|
-
],
|
|
31
|
-
"filter_group_container": [
|
|
32
|
-
".check-box"
|
|
33
|
-
],
|
|
34
|
-
"filter_group_school": [
|
|
35
|
-
".check-box.school"
|
|
36
|
-
],
|
|
37
|
-
"filter_group_degree": [
|
|
38
|
-
".check-box.degree"
|
|
39
|
-
],
|
|
40
|
-
"filter_group_gender": [
|
|
41
|
-
".check-box.gender"
|
|
42
|
-
],
|
|
43
|
-
"filter_group_recent_not_view": [
|
|
44
|
-
".check-box.recentNotView"
|
|
45
|
-
],
|
|
46
|
-
"filter_option": [
|
|
47
|
-
".check-box .default.option",
|
|
48
|
-
".check-box .options .option",
|
|
49
|
-
".check-box .option"
|
|
50
|
-
],
|
|
51
|
-
"filter_option_all": [
|
|
52
|
-
".default.option, .options .option, .option"
|
|
53
|
-
],
|
|
54
|
-
"filter_option_active": [
|
|
55
|
-
".default.option.active, .options .option.active, .option.active"
|
|
56
|
-
],
|
|
57
|
-
"filter_scroll_container": [
|
|
58
|
-
".recommend-filter.op-filter .filter-panel .top",
|
|
59
|
-
".recommend-filter.op-filter .top",
|
|
60
|
-
".recommend-filter.op-filter .filter-panel"
|
|
61
|
-
],
|
|
62
|
-
"filter_confirm_candidates": [
|
|
63
|
-
".btn, button"
|
|
64
|
-
],
|
|
65
|
-
"job_dropdown_trigger": [
|
|
66
|
-
".top-chat-search",
|
|
67
|
-
".chat-job-select",
|
|
68
|
-
".chat-job-selector",
|
|
69
|
-
".job-selecter",
|
|
70
|
-
".job-selector",
|
|
71
|
-
".job-select-wrap",
|
|
72
|
-
".job-select",
|
|
73
|
-
".job-select-box",
|
|
74
|
-
".job-wrap",
|
|
75
|
-
".chat-job-name"
|
|
76
|
-
],
|
|
77
|
-
"job_list_items": [
|
|
78
|
-
".ui-dropmenu-list .job-list .job-item",
|
|
79
|
-
".job-selecter-options .job-list .job-item",
|
|
80
|
-
".job-selector-options .job-list .job-item",
|
|
81
|
-
".dropmenu-list .job-list .job-item",
|
|
82
|
-
".job-list .job-item"
|
|
83
|
-
],
|
|
84
|
-
"job_item_label": [
|
|
85
|
-
".ui-dropmenu-list .job-list .job-item .label",
|
|
86
|
-
".job-list .job-item .label",
|
|
87
|
-
".label"
|
|
88
|
-
],
|
|
89
|
-
"job_search_input": [
|
|
90
|
-
".top-chat-search"
|
|
91
|
-
],
|
|
92
|
-
"job_selected_label": [
|
|
93
|
-
".job-selecter-wrap .ui-dropmenu-label",
|
|
94
|
-
".ui-dropmenu-label",
|
|
95
|
-
".chat-job-name",
|
|
96
|
-
".job-selecter .label",
|
|
97
|
-
".job-selecter .job-name",
|
|
98
|
-
".job-select .label"
|
|
99
|
-
],
|
|
100
|
-
"recommend_cards": [
|
|
101
|
-
"ul.card-list > li.card-item"
|
|
102
|
-
],
|
|
103
|
-
"recommend_card_inner": [
|
|
104
|
-
".card-inner[data-geekid]"
|
|
105
|
-
],
|
|
106
|
-
"featured_cards": [
|
|
107
|
-
"li.geek-info-card"
|
|
108
|
-
],
|
|
109
|
-
"featured_card_anchor": [
|
|
110
|
-
"a[data-geekid]"
|
|
111
|
-
],
|
|
112
|
-
"latest_cards": [
|
|
113
|
-
".candidate-card-wrap"
|
|
114
|
-
],
|
|
115
|
-
"latest_card_inner": [
|
|
116
|
-
".candidate-card-wrap .card-inner[data-geek]",
|
|
117
|
-
".candidate-card-wrap [data-geek]"
|
|
118
|
-
],
|
|
119
|
-
"refresh_finished_wrap": [
|
|
120
|
-
".finished-wrap"
|
|
121
|
-
],
|
|
122
|
-
"refresh_button": [
|
|
123
|
-
".finished-wrap .btn.btn-refresh",
|
|
124
|
-
".finished-wrap .btn-refresh",
|
|
125
|
-
".no-data-refresh .btn-refresh"
|
|
126
|
-
]
|
|
127
|
-
},
|
|
128
|
-
"detail": {
|
|
129
|
-
"popup": [
|
|
130
|
-
".dialog-wrap.active",
|
|
131
|
-
".boss-popup__wrapper",
|
|
132
|
-
".boss-popup_wrapper",
|
|
133
|
-
".boss-dialog_wrapper",
|
|
134
|
-
".boss-dialog",
|
|
135
|
-
".resume-item-detail",
|
|
136
|
-
".geek-detail-modal",
|
|
137
|
-
"[class*=\"popup\"][class*=\"wrapper\"]",
|
|
138
|
-
"[class*=\"dialog\"][class*=\"wrapper\"]"
|
|
139
|
-
],
|
|
140
|
-
"resume_iframe": [
|
|
141
|
-
"iframe[src*=\"/web/frame/c-resume/\"]",
|
|
142
|
-
"iframe[name*=\"resume\"]"
|
|
143
|
-
],
|
|
144
|
-
"close_button": [
|
|
145
|
-
".boss-popup__close",
|
|
146
|
-
".popup-close",
|
|
147
|
-
".modal-close",
|
|
148
|
-
".dialog-close",
|
|
149
|
-
".close-btn",
|
|
150
|
-
"button[aria-label*=\"关闭\"]",
|
|
151
|
-
"button[title*=\"关闭\"]",
|
|
152
|
-
".icon-close"
|
|
153
|
-
],
|
|
154
|
-
"close_fallback_candidates": [
|
|
155
|
-
"[aria-label*=\"关闭\"]",
|
|
156
|
-
"[aria-label*=\"返回\"]",
|
|
157
|
-
"[title*=\"关闭\"]",
|
|
158
|
-
"[title*=\"返回\"]",
|
|
159
|
-
"[class*=\"close\"]",
|
|
160
|
-
"[class*=\"Close\"]",
|
|
161
|
-
"[class*=\"back\"]",
|
|
162
|
-
"[class*=\"Back\"]",
|
|
163
|
-
"button",
|
|
164
|
-
"a",
|
|
165
|
-
"i",
|
|
166
|
-
"span"
|
|
167
|
-
],
|
|
168
|
-
"ack_button": [
|
|
169
|
-
"button.btn-v2.btn-sure-v2",
|
|
170
|
-
"button.btn",
|
|
171
|
-
".boss-dialog button",
|
|
172
|
-
".boss-popup__wrapper button"
|
|
173
|
-
],
|
|
174
|
-
"favorite_button": [
|
|
175
|
-
".like-icon-and-text",
|
|
176
|
-
".resume-footer.item-operate [class*=\"collect\"]",
|
|
177
|
-
".resume-footer.item-operate [class*=\"favorite\"]",
|
|
178
|
-
".resume-footer-wrap [class*=\"collect\"]",
|
|
179
|
-
".resume-footer-wrap [class*=\"favorite\"]"
|
|
180
|
-
],
|
|
181
|
-
"greet_button_recommend": [
|
|
182
|
-
"button.btn-v2.btn-sure-v2.btn-greet",
|
|
183
|
-
".resume-footer.item-operate button.btn-v2",
|
|
184
|
-
".resume-footer-wrap button.btn-v2",
|
|
185
|
-
".resume-footer.item-operate button",
|
|
186
|
-
".resume-footer-wrap button"
|
|
187
|
-
],
|
|
188
|
-
"greet_button_featured": [
|
|
189
|
-
"button.btn-v2.position-rights.btn-sure-v2",
|
|
190
|
-
"button.btn-v2.btn-sure-v2.position-rights",
|
|
191
|
-
".resume-footer.item-operate button.btn-v2",
|
|
192
|
-
".resume-footer-wrap button.btn-v2",
|
|
193
|
-
".resume-footer.item-operate button",
|
|
194
|
-
".resume-footer-wrap button"
|
|
195
|
-
]
|
|
196
|
-
}
|
|
197
|
-
},
|
|
198
|
-
"network": {
|
|
199
|
-
"resume": {
|
|
200
|
-
"info_url_patterns": [
|
|
201
|
-
"\\/wapi\\/zpjob\\/view\\/geek\\/info\\b",
|
|
202
|
-
"\\/wapi\\/zpitem\\/web\\/boss\\/[^?#]*\\/geek\\/info\\b",
|
|
203
|
-
"\\/boss\\/[^?#]*\\/geek\\/info\\b",
|
|
204
|
-
"\\/geek\\/info\\b",
|
|
205
|
-
"[?&](?:geekid|geek_id|encryptgeekid|encryptjid|jid|securityid)="
|
|
206
|
-
],
|
|
207
|
-
"related_keywords": [
|
|
208
|
-
"geek",
|
|
209
|
-
"resume",
|
|
210
|
-
"candidate",
|
|
211
|
-
"friend"
|
|
212
|
-
]
|
|
213
|
-
},
|
|
214
|
-
"favorite": {
|
|
215
|
-
"request_source_keywords": [
|
|
216
|
-
"usermark",
|
|
217
|
-
"actionlog/common.json"
|
|
218
|
-
],
|
|
219
|
-
"add_patterns": [
|
|
220
|
-
"(?:^|[_\\W])(add|favorite|collect|interest(?:ed)?)(?:$|[_\\W])",
|
|
221
|
-
"\\/add(?:\\/|$)|[?&](?:action|op|operation|type)=add\\b|[?&](?:status|p3|favorite|collect|interested)=1\\b"
|
|
222
|
-
],
|
|
223
|
-
"remove_patterns": [
|
|
224
|
-
"(?:^|[_\\W])(del|delete|remove|cancel|unfavorite|uncollect|uninterest)(?:$|[_\\W])",
|
|
225
|
-
"\\/del(?:\\/|$)|[?&](?:action|op|operation|type)=del\\b|[?&](?:status|p3|favorite|collect|interested)=0\\b"
|
|
226
|
-
],
|
|
227
|
-
"actionlog_action_name": "star-interest-click",
|
|
228
|
-
"status_keys": [
|
|
229
|
-
"p3",
|
|
230
|
-
"status",
|
|
231
|
-
"state",
|
|
232
|
-
"favorite",
|
|
233
|
-
"collect",
|
|
234
|
-
"interested",
|
|
235
|
-
"markstatus",
|
|
236
|
-
"isfavorite",
|
|
237
|
-
"iscollect"
|
|
238
|
-
],
|
|
239
|
-
"operation_keys": [
|
|
240
|
-
"action",
|
|
241
|
-
"op",
|
|
242
|
-
"operation",
|
|
243
|
-
"type",
|
|
244
|
-
"mode",
|
|
245
|
-
"mark",
|
|
246
|
-
"interest"
|
|
247
|
-
]
|
|
248
|
-
},
|
|
249
|
-
"greet": {
|
|
250
|
-
"url_patterns": [
|
|
251
|
-
"greet",
|
|
252
|
-
"sayhi",
|
|
253
|
-
"hello",
|
|
254
|
-
"friend/add",
|
|
255
|
-
"chat/start",
|
|
256
|
-
"boss\\/friend",
|
|
257
|
-
"boss\\/dialog"
|
|
258
|
-
]
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|