burhan-mop 0.1.7 → 0.1.8

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/.MOP/PROTOCOL.md CHANGED
@@ -123,6 +123,11 @@ Routing rules:
123
123
  genuinely requires several areas of expertise.
124
124
  - If the route reports `partyMode.active: true`, run Party Mode before the final
125
125
  answer. Name any missing participant agents first.
126
+ - If the route reports `nextAction: "name-required-party-agents"`, stop and ask
127
+ every question in `missingAgentQuestions`. Do not continue with the task until
128
+ all required party agents have names.
129
+ - Explicit requests such as `party mode`, `multi-agent`, `semua agent`, or
130
+ `agent bincang` must activate Party Mode automatically.
126
131
  - The route JSON includes an `answerContract`. The assistant must restore
127
132
  monthly memory, start the visible answer with `answerContract.firstLine`, and
128
133
  save a one-line memory after meaningful work.
@@ -163,6 +168,8 @@ PARTY MODE
163
168
  - Do not include irrelevant agents just because they exist.
164
169
  - If a needed party role has no named agent, ask the user to name that agent
165
170
  before using it.
171
+ - If several party agents are missing, ask for all missing names in one reply:
172
+ `Kita ada <N> agent belum ada nama. Beri nama untuk ...`
166
173
 
167
174
  Visible dialogue format:
168
175
 
@@ -188,6 +195,32 @@ agent: <from-name> (<from-role>)
188
195
  <explanation>
189
196
  ```
190
197
 
198
+ ## Browser And Scraping Gate
199
+
200
+ Browser, scraping, rendered extraction, clicking, login flow, bot-detection, and
201
+ form-filling tasks must pass browser preflight before any browser automation.
202
+
203
+ Run:
204
+
205
+ ```bash
206
+ node .MOP/scripts/mop-core.mjs browser preflight
207
+ ```
208
+
209
+ Rules:
210
+
211
+ - First scan the default browser automatically. On Linux this uses
212
+ `xdg-settings get default-web-browser`; fallback is `$BROWSER`.
213
+ - If Chrome or Chromium is detected, browser automation may proceed with normal
214
+ Chrome-compatible mode.
215
+ - If Edge, Brave, or Opera is detected, use browser-act `chrome-direct` mode and
216
+ guide the user to start that browser with `--remote-debugging-port`.
217
+ - If no supported browser is detected, ask the user which browser they use
218
+ before scraping or browser automation.
219
+ - Do not start a default Chrome session first when the user uses Edge, Brave, or
220
+ Opera.
221
+ - If `agent route` includes `browserPreflight.needsQuestion: true`, ask
222
+ `browserPreflight.question` and stop.
223
+
191
224
  ## MOP Workflow
192
225
 
193
226
  MOP Workflow is BMAD-inspired and MOP-native. It is the default
package/.MOP/STATE.json CHANGED
@@ -77,7 +77,34 @@
77
77
  "Normal Party mode should use at least 3 participants and prefer 4 when the task has enough relevant roles.",
78
78
  "The primary agent coordinates the party and keeps the user intent visible.",
79
79
  "Every visible agent message must use the configured dialogue format.",
80
- "Agents should ask each other focused questions, answer directly, then hand a clear result to the user."
80
+ "Agents should ask each other focused questions, answer directly, then hand a clear result to the user.",
81
+ "Explicit requests such as party mode, multi-agent, semua agent, or agent discussion must activate Party Mode.",
82
+ "If Party Mode needs unnamed agents, ask for all missing agent names before doing the task."
83
+ ]
84
+ },
85
+ "browserPolicy": {
86
+ "requirePreflightBeforeBrowserWork": true,
87
+ "requireDefaultBrowserCheck": true,
88
+ "supportedChoices": [
89
+ "Chrome",
90
+ "Edge",
91
+ "Brave",
92
+ "Opera"
93
+ ],
94
+ "builtinChromeBrowsers": [
95
+ "chrome",
96
+ "chromium"
97
+ ],
98
+ "directModeBrowsers": [
99
+ "brave",
100
+ "edge",
101
+ "opera"
102
+ ],
103
+ "rules": [
104
+ "Before browser, scraping, extraction, click automation, login flow, or form filling, run browser preflight.",
105
+ "Check the user's default browser automatically when possible.",
106
+ "If the default browser is Edge, Brave, or Opera, use chrome-direct mode and guide the user to start remote debugging.",
107
+ "If no supported browser is detected, ask the user which browser they use before continuing."
81
108
  ]
82
109
  },
83
110
  "workflow": {
@@ -531,6 +558,12 @@
531
558
  "kind": "operations",
532
559
  "purpose": "GitHub repo, branch, PR, issue, release, and merge workflow."
533
560
  },
561
+ {
562
+ "role": "browser",
563
+ "title": "Browser Automation Agent",
564
+ "kind": "operations",
565
+ "purpose": "Browser preflight, scraping, rendered extraction, clicking, form filling, login flows, and browser-act coordination."
566
+ },
534
567
  {
535
568
  "role": "devops",
536
569
  "title": "DevOps Engineer",
@@ -232,6 +232,66 @@ function answerContractFor(state, actor, agent = activeAgentFor(state, actor)) {
232
232
  };
233
233
  }
234
234
 
235
+ function browserPolicy(state) {
236
+ return state.browserPolicy || {
237
+ requirePreflightBeforeBrowserWork: true,
238
+ requireDefaultBrowserCheck: true,
239
+ directModeBrowsers: ['brave', 'edge', 'opera'],
240
+ builtinChromeBrowsers: ['chrome', 'chromium'],
241
+ supportedChoices: ['Chrome', 'Edge', 'Brave', 'Opera']
242
+ };
243
+ }
244
+
245
+ function detectDefaultBrowser() {
246
+ const xdg = spawnSync('xdg-settings', ['get', 'default-web-browser'], {
247
+ cwd: rootDir,
248
+ encoding: 'utf8'
249
+ });
250
+ const raw = (xdg.status === 0 ? xdg.stdout : '').trim() || process.env.BROWSER || '';
251
+ const value = raw.toLowerCase();
252
+ let family = 'unknown';
253
+ if (/(google-chrome|chrome)/.test(value) && !/chromium/.test(value)) family = 'chrome';
254
+ else if (/chromium/.test(value)) family = 'chromium';
255
+ else if (/brave/.test(value)) family = 'brave';
256
+ else if (/(microsoft-edge|edge)/.test(value)) family = 'edge';
257
+ else if (/opera/.test(value)) family = 'opera';
258
+ else if (/firefox/.test(value)) family = 'firefox';
259
+ return {
260
+ raw: raw || null,
261
+ family,
262
+ source: raw ? (xdg.status === 0 ? 'xdg-settings' : 'BROWSER') : 'not-detected'
263
+ };
264
+ }
265
+
266
+ function browserPreflightFor(state) {
267
+ const policy = browserPolicy(state);
268
+ const detected = detectDefaultBrowser();
269
+ const direct = (policy.directModeBrowsers || []).includes(detected.family);
270
+ const builtin = (policy.builtinChromeBrowsers || []).includes(detected.family);
271
+ const supported = direct || builtin;
272
+ const mode = builtin ? 'chrome' : direct ? 'chrome-direct' : 'ask-user-browser';
273
+ const needsQuestion = !supported;
274
+ return {
275
+ required: policy.requirePreflightBeforeBrowserWork !== false,
276
+ defaultBrowser: detected,
277
+ mode,
278
+ ready: supported,
279
+ needsQuestion,
280
+ question: needsQuestion
281
+ ? `Saya tak dapat kesan Chrome/Edge/Brave/Opera sebagai browser default. Awak guna browser apa? Pilih: ${(policy.supportedChoices || ['Chrome', 'Edge', 'Brave', 'Opera']).join(', ')}.`
282
+ : '',
283
+ instructions: direct
284
+ ? [
285
+ `Use browser-act chrome-direct for ${detected.family}.`,
286
+ 'Guide the user to start that browser with --remote-debugging-port before scraping or form automation.',
287
+ 'Do not create a default chrome session first.'
288
+ ]
289
+ : builtin
290
+ ? ['Use normal Chrome-compatible browser automation.', 'Do not ask the user again unless automation fails.']
291
+ : ['Ask the user which browser they use before scraping or browser automation.']
292
+ };
293
+ }
294
+
235
295
  function requireActiveAgent(state, actor, role = 'core', title = 'Core Agent') {
236
296
  const agent = activeAgentFor(state, actor);
237
297
  if (agent) return agent;
@@ -383,7 +443,7 @@ const routeRules = [
383
443
  {
384
444
  role: 'browser',
385
445
  support: ['researcher', 'tester'],
386
- keywords: ['browser', 'browse', 'scrape', 'scraping', 'extract', 'click', 'login flow', 'fill form', 'captcha', 'bot detection', 'website', 'url', 'webpage']
446
+ keywords: ['agent browser', 'browser agent', 'browser automation', 'browser', 'browse', 'scrape', 'scraping', 'web scraping', 'extract', 'click', 'login flow', 'fill form', 'captcha', 'bot detection', 'website', 'url', 'webpage']
387
447
  },
388
448
  {
389
449
  role: 'researcher',
@@ -407,6 +467,10 @@ function routeScore(task, rule) {
407
467
  return rule.keywords.reduce((score, keyword) => task.includes(keyword) ? score + Math.max(1, keyword.split(/\s+/).length) : score, 0);
408
468
  }
409
469
 
470
+ function hasBrowserWorkIntent(task) {
471
+ return /\b(agent browser|browser agent|browser automation|browse|scrape|scraping|web scraping|extract|click|login flow|fill form|captcha|bot detection|webpage|url)\b/.test(task);
472
+ }
473
+
410
474
  function uniqueValues(values) {
411
475
  return [...new Set(values.filter(Boolean))];
412
476
  }
@@ -420,6 +484,7 @@ function maybeLimit(values, limit) {
420
484
 
421
485
  function shouldActivatePartyMode(state, task, primaryRole, supportRoles, newSystemIntent) {
422
486
  if (state.partyMode?.enabled === false || state.partyMode?.autoActivateWhenNeeded === false) return false;
487
+ const explicitPartyIntent = /\b(party mode|party|multi[- ]?agent|swarm|semua agent|banyak agent|agent.*bincang|bincang.*agent|agent.*discuss|discuss.*agent)\b/.test(task);
423
488
  const multiDomainIntent = [
424
489
  ['ui', 'backend'],
425
490
  ['frontend', 'backend'],
@@ -429,10 +494,11 @@ function shouldActivatePartyMode(state, task, primaryRole, supportRoles, newSyst
429
494
  ['security', 'auth'],
430
495
  ['prompt', 'system']
431
496
  ].some(([first, second]) => task.includes(first) && task.includes(second));
497
+ const browserRiskIntent = hasBrowserWorkIntent(task);
432
498
  const connectiveIntent = /\b(connect|connected|integrate|integration|bersambung|sambung|hubung|flow|workflow)\b/.test(task);
433
499
  const broadBuild = newSystemIntent && supportRoles.length >= 2;
434
500
  const specialistStack = supportRoles.length >= 3 && ['architect', 'planner', 'core'].includes(primaryRole);
435
- return multiDomainIntent || connectiveIntent || broadBuild || specialistStack;
501
+ return explicitPartyIntent || multiDomainIntent || browserRiskIntent || connectiveIntent || broadBuild || specialistStack;
436
502
  }
437
503
 
438
504
  function partyFormat(state) {
@@ -453,12 +519,14 @@ function partyParticipantsFor(state, primaryRole, supportRoles, scored, partyAct
453
519
  const minimum = Number(state.partyMode?.minimumParticipants || 3);
454
520
  const floor = Number.isFinite(preferredMinimum) ? Math.max(minimum, preferredMinimum) : minimum;
455
521
  const fallbackRoles = ['planner', 'researcher', 'reviewer', 'coder', 'architect', 'prompt', 'tester'];
456
- const participants = uniqueValues([
522
+ const relevant = uniqueValues([
457
523
  primaryRole,
458
524
  ...supportRoles,
459
- ...scored.map((rule) => rule.role),
460
- ...fallbackRoles
525
+ ...scored.map((rule) => rule.role)
461
526
  ]);
527
+ const participants = relevant.length >= floor
528
+ ? relevant
529
+ : uniqueValues([...relevant, ...fallbackRoles]).slice(0, floor);
462
530
  const catalogRoles = new Set((state.agentCatalog || []).map((item) => item.role));
463
531
  const filtered = participants.filter((role) => catalogRoles.has(role));
464
532
  const enough = filtered.length >= floor ? filtered : participants;
@@ -476,15 +544,16 @@ function inferAgentRoute(state, taskText) {
476
544
  const newSystemIntent = /\b(system|sistem|app|tool|platform|website|dashboard|engine|core)\b/.test(task)
477
545
  || /buat sebuah|bina sebuah|create a|build a/.test(task);
478
546
  const implementationIntent = /\b(code|coding|implement|fix|ubah file|buat file)\b/.test(task);
547
+ const browserWorkIntent = hasBrowserWorkIntent(task);
479
548
  const top = scored[0];
480
- let primaryRole = top?.role || state.agentPolicy?.defaultRole || 'core';
549
+ let primaryRole = browserWorkIntent ? 'browser' : (top?.role || state.agentPolicy?.defaultRole || 'core');
481
550
 
482
- if (newSystemIntent && !implementationIntent && state.agentRouter?.preferHighReasoningForNewSystems !== false) {
551
+ if (newSystemIntent && !implementationIntent && !browserWorkIntent && state.agentRouter?.preferHighReasoningForNewSystems !== false) {
483
552
  primaryRole = state.agentRouter?.defaultHighReasoningRole || 'architect';
484
553
  }
485
554
 
486
555
  const primary = catalogForRole(state, primaryRole);
487
- const baseSupport = newSystemIntent
556
+ const baseSupport = newSystemIntent && !browserWorkIntent
488
557
  ? ['planner', 'researcher', 'prompt', 'coder', 'reviewer']
489
558
  : (top?.support || []);
490
559
  const supportRoles = maybeLimit(uniqueValues([
@@ -495,7 +564,7 @@ function inferAgentRoute(state, taskText) {
495
564
  const partyActive = shouldActivatePartyMode(state, task, primaryRole, supportRoles, newSystemIntent);
496
565
  const partyParticipants = partyParticipantsFor(state, primaryRole, supportRoles, scored, partyActive);
497
566
 
498
- const ambiguousNewSystem = newSystemIntent && words.length < 18;
567
+ const ambiguousNewSystem = newSystemIntent && !browserWorkIntent && words.length < 18;
499
568
  const noClearMatch = scored.length === 0 && words.length > 3;
500
569
  const needsClarification = state.agentRouter?.clarifyBeforeActionWhenAmbiguous !== false
501
570
  && (ambiguousNewSystem || noClearMatch || /\b(maybe|mungkin|lebih kurang|macam)\b/.test(task));
@@ -526,7 +595,7 @@ function inferAgentRoute(state, taskText) {
526
595
  confidence: top ? Math.min(0.95, 0.45 + (top.score * 0.08)) : 0.35,
527
596
  needsClarification,
528
597
  questions,
529
- reason: newSystemIntent
598
+ reason: newSystemIntent && !browserWorkIntent
530
599
  ? `New or broad system task routed to ${primary.title} for high-reasoning planning before implementation.`
531
600
  : top
532
601
  ? `Matched keywords for ${primary.title}: ${top.keywords.filter((keyword) => task.includes(keyword)).join(', ')}.`
@@ -734,13 +803,27 @@ function agentRoute(args) {
734
803
  };
735
804
  }) : [];
736
805
  const missingPartyAgents = partyAgents.filter((item) => item.missing);
806
+ const missingAgentCommands = missingPartyAgents.map((item) => (
807
+ `node .MOP/scripts/mop-core.mjs agent activate --actor ${actor} --role ${item.role} --title "${item.title}" --name "<agent-name>"`
808
+ ));
809
+ const missingAgentQuestions = missingPartyAgents.map((item) => (
810
+ `Beri nama untuk ${item.title} (${item.role}) kamu:`
811
+ ));
812
+ const browserPreflight = route.primaryRole === 'browser'
813
+ || route.supportRoles.includes('browser')
814
+ || route.partyMode?.participants?.includes('browser')
815
+ || hasBrowserWorkIntent(route.task || '')
816
+ ? browserPreflightFor(state)
817
+ : null;
737
818
  const response = {
738
819
  ok: Boolean(agent),
739
820
  actor,
740
821
  route,
741
822
  partyAgents,
823
+ missingAgents: missingPartyAgents,
742
824
  activeAgent: null,
743
825
  answerContract: null,
826
+ browserPreflight,
744
827
  monthlyMemory: {
745
828
  restoreCommand: `node .MOP/scripts/mop-core.mjs memory brief --actor ${actor}`,
746
829
  saveCommand: `node .MOP/scripts/mop-core.mjs memory add --actor ${actor} --kind conversation --summary "<one-line outcome>"`
@@ -763,18 +846,33 @@ function agentRoute(args) {
763
846
  if (route.partyMode.active && missingPartyAgents.length) {
764
847
  response.ok = false;
765
848
  response.nextAction = 'name-required-party-agents';
766
- response.message = 'Party mode diperlukan, tetapi ada agent terlibat yang belum dinamakan.';
767
- response.missingAgentCommands = missingPartyAgents.map((item) => (
768
- `node .MOP/scripts/mop-core.mjs agent activate --actor ${actor} --role ${item.role} --title "${item.title}" --name "<agent-name>"`
769
- ));
849
+ response.message = `Party Mode perlukan ${missingPartyAgents.length} agent yang belum ada nama. Minta nama semua agent ini dahulu sebelum sambung kerja.`;
850
+ response.ask = `Kita ada ${missingPartyAgents.length} agent belum ada nama. ${missingAgentQuestions.join(' ')}`;
851
+ response.missingAgentQuestions = missingAgentQuestions;
852
+ response.missingAgentCommands = missingAgentCommands;
853
+ } else if (browserPreflight?.required && browserPreflight.needsQuestion) {
854
+ response.ok = false;
855
+ response.nextAction = 'ask-browser-before-browser-work';
856
+ response.message = 'Browser preflight belum ready. Tanya browser user dahulu sebelum scraping/browser automation.';
857
+ response.ask = browserPreflight.question;
770
858
  } else {
771
859
  response.nextAction = route.needsClarification ? 'ask-clarifying-questions' : 'proceed-with-agent';
772
860
  }
773
861
  } else {
774
- response.nextAction = 'name-required-agent';
775
- response.message = `Task ini perlukan ${route.primaryTitle}. Agent ini belum ada nama lagi atau belum dipilih.`;
776
- response.ask = `Beri nama untuk ${route.primaryTitle} kamu:`;
862
+ response.nextAction = route.partyMode.active && missingPartyAgents.length
863
+ ? 'name-required-party-agents'
864
+ : 'name-required-agent';
865
+ response.message = route.partyMode.active && missingPartyAgents.length
866
+ ? `Party Mode perlukan ${missingPartyAgents.length} agent yang belum ada nama. Minta nama semua agent ini dahulu sebelum sambung kerja.`
867
+ : `Task ini perlukan ${route.primaryTitle}. Agent ini belum ada nama lagi atau belum dipilih.`;
868
+ response.ask = route.partyMode.active && missingPartyAgents.length
869
+ ? `Kita ada ${missingPartyAgents.length} agent belum ada nama. ${missingAgentQuestions.join(' ')}`
870
+ : `Beri nama untuk ${route.primaryTitle} kamu:`;
777
871
  response.command = `node .MOP/scripts/mop-core.mjs agent activate --actor ${actor} --role ${route.primaryRole} --title "${route.primaryTitle}" --name "<agent-name>"`;
872
+ if (route.partyMode.active && missingPartyAgents.length) {
873
+ response.missingAgentQuestions = missingAgentQuestions;
874
+ response.missingAgentCommands = missingAgentCommands;
875
+ }
778
876
  if (route.needsClarification) response.afterNaming = route.questions;
779
877
  }
780
878
 
@@ -789,6 +887,11 @@ function agentList() {
789
887
  }, null, 2));
790
888
  }
791
889
 
890
+ function browserPreflight() {
891
+ const state = readState();
892
+ console.log(JSON.stringify(browserPreflightFor(state), null, 2));
893
+ }
894
+
792
895
  function memoryAdd(args) {
793
896
  const state = readState();
794
897
  if (!state.initialized) throw new Error('MOP is not initialized.');
@@ -883,6 +986,7 @@ function validate() {
883
986
  if (state.agentPolicy && typeof state.agentPolicy !== 'object') errors.push('agentPolicy must be object');
884
987
  if (state.answerPolicy && typeof state.answerPolicy !== 'object') errors.push('answerPolicy must be object');
885
988
  if (state.memoryPolicy && typeof state.memoryPolicy !== 'object') errors.push('memoryPolicy must be object');
989
+ if (state.browserPolicy && typeof state.browserPolicy !== 'object') errors.push('browserPolicy must be object');
886
990
  if (state.agentRouter && typeof state.agentRouter !== 'object') errors.push('agentRouter must be object');
887
991
  if (state.partyMode && typeof state.partyMode !== 'object') errors.push('partyMode must be object');
888
992
  if (state.autosync?.githubIdentity && typeof state.autosync.githubIdentity !== 'object') {
@@ -970,6 +1074,7 @@ function status() {
970
1074
  agentPolicy: state.agentPolicy || {},
971
1075
  answerPolicy: answerPolicy(state),
972
1076
  memoryPolicy: memoryPolicy(state),
1077
+ browserPolicy: browserPolicy(state),
973
1078
  agentRouter: state.agentRouter || {},
974
1079
  partyMode: state.partyMode || {},
975
1080
  workflow: {
@@ -1023,6 +1128,7 @@ function main() {
1023
1128
  if (command === 'agent' && subcommand === 'require') return agentRequire(args);
1024
1129
  if (command === 'agent' && subcommand === 'route') return agentRoute(args);
1025
1130
  if (command === 'agent' && subcommand === 'list') return agentList();
1131
+ if (command === 'browser' && subcommand === 'preflight') return browserPreflight();
1026
1132
  if (command === 'memory' && subcommand === 'add') return memoryAdd(args);
1027
1133
  if (command === 'memory' && subcommand === 'brief') return memoryBrief(args);
1028
1134
  if (command === 'memory' && subcommand === 'restore') return memoryRestore(args);
@@ -1039,6 +1145,7 @@ function main() {
1039
1145
  node .MOP/scripts/mop-core.mjs agent require --actor CODE [--role ROLE] [--title TITLE]
1040
1146
  node .MOP/scripts/mop-core.mjs agent route --actor CODE --task "task text"
1041
1147
  node .MOP/scripts/mop-core.mjs agent list
1148
+ node .MOP/scripts/mop-core.mjs browser preflight
1042
1149
  node .MOP/scripts/mop-core.mjs memory brief --actor CODE [--month YYYY-MM]
1043
1150
  node .MOP/scripts/mop-core.mjs memory add --actor CODE --kind conversation --summary "what happened"
1044
1151
  node .MOP/scripts/mop-core.mjs memory restore --actor CODE`);
package/.agents/AGENTS.md CHANGED
@@ -23,6 +23,14 @@ Before doing anything, read `.MOP/STATE.json` and follow
23
23
  `mop-core.mjs memory add --actor <codename> --kind conversation --summary "<outcome>"`.
24
24
  - If the router says clarification is needed, ask the clarifying questions
25
25
  before implementation.
26
+ - If the router returns `nextAction: "name-required-party-agents"`, ask every
27
+ question in `missingAgentQuestions` and stop until those agents are named.
28
+ - Before browser, scraping, extraction, click automation, login flow,
29
+ bot-detection, or form-filling work, run `mop-core.mjs browser preflight`. If
30
+ it reports Edge, Brave, or Opera, use browser-act `chrome-direct` mode and
31
+ guide the user to start remote debugging (`--remote-debugging-port`). If it
32
+ cannot detect a supported browser, ask which browser they use before doing
33
+ browser work.
26
34
  - If the router activates Party Mode, show visible agent-to-agent dialogue using
27
35
  the exact format in `.MOP/PROTOCOL.md`, with `PARTY MODE` shown in
28
36
  large uppercase before the dialogue. Party Mode normally uses at least 3
package/AGENTS.md CHANGED
@@ -31,7 +31,16 @@ follow `.MOP/PROTOCOL.md`.
31
31
 
32
32
  - If the router marks the task as ambiguous, the named primary agent must ask
33
33
  clarifying questions before implementation.
34
- - **[browser] Agent Rule**: Before creating a new browser session with `browser-act`, you must check the user's default browser (e.g., using `xdg-settings get default-web-browser` on Linux) or ask them what browser they use (Chrome, Edge, Brave, Opera). If they use something other than the built-in Chrome, use `browser-act`'s `chrome-direct` mode and guide them to start their browser with remote debugging (`--remote-debugging-port`), rather than just creating a default `chrome` browser.
34
+ - If the router returns `nextAction: "name-required-party-agents"`, ask every
35
+ question in `missingAgentQuestions` and stop until those agents are named.
36
+ - **[browser] Agent Rule**: Before browser, scraping, extraction, click
37
+ automation, login flow, bot-detection, or form-filling work, run
38
+ `mop-core.mjs browser preflight`. It scans the default browser when possible.
39
+ If it reports Edge, Brave, or Opera, use browser-act `chrome-direct` mode and
40
+ guide the user to start remote debugging (`--remote-debugging-port`). If it
41
+ cannot detect a supported browser, ask which browser they use before doing
42
+ browser work. Never create a default Chrome session first when the user uses
43
+ another supported browser.
35
44
  - If the router returns `partyMode.active: true`, use Party Mode. Show
36
45
  `PARTY MODE` in large uppercase before the dialogue, then generate the
37
46
  agent-to-agent and agent-to-user dialogue explicitly in your response using this exact format:
package/CLAUDE.md CHANGED
@@ -23,6 +23,14 @@ follow `.MOP/PROTOCOL.md`.
23
23
  `mop-core.mjs memory add --actor <codename> --kind conversation --summary "<one-line outcome>"`.
24
24
  - If the router marks the task as ambiguous, the named primary agent must ask
25
25
  clarifying questions before implementation.
26
+ - If the router returns `nextAction: "name-required-party-agents"`, ask every
27
+ question in `missingAgentQuestions` and stop until those agents are named.
28
+ - Before browser, scraping, extraction, click automation, login flow,
29
+ bot-detection, or form-filling work, run `mop-core.mjs browser preflight`. If
30
+ it reports Edge, Brave, or Opera, use browser-act `chrome-direct` mode and
31
+ guide the user to start remote debugging (`--remote-debugging-port`). If it
32
+ cannot detect a supported browser, ask which browser they use before doing
33
+ browser work.
26
34
  - If the router returns `partyMode.active: true`, use Party Mode. Show
27
35
  `PARTY MODE` in large uppercase before the dialogue, then show
28
36
  agent-to-agent and agent-to-user dialogue with the exact format from
package/GEMINI.md CHANGED
@@ -16,6 +16,11 @@ rules are imported below.
16
16
  example: `agent: <agent-name> (<agent-role>) to <user>`.
17
17
  - Save a one-line memory after meaningful work with
18
18
  `mop-core.mjs memory add --actor <codename> --kind conversation --summary "<outcome>"`.
19
+ - If `agent route` returns `nextAction: "name-required-party-agents"`, ask every
20
+ question in `missingAgentQuestions` and stop until those agents are named.
21
+ - Before browser, scraping, extraction, click automation, login flow,
22
+ bot-detection, or form-filling work, run `mop-core.mjs browser preflight` and
23
+ follow its mode/question before doing browser work.
19
24
  - Autosycn member commits must use the active member GitHub account. MOP derives
20
25
  `ID+USERNAME@users.noreply.github.com` from `gh api user` by default and
21
26
  refuses mismatched GitHub accounts.
package/README.bm.md CHANGED
@@ -142,7 +142,7 @@ dan merge hanya bila workflow selamat.
142
142
  | --- | --- |
143
143
  | npm package | [`burhan-mop`](https://www.npmjs.com/package/burhan-mop) |
144
144
  | command latest | `npx burhan-mop install` |
145
- | GitHub release | [`v0.1.7`](https://github.com/BURHANDEV-ENTERPRISE/BURHAN-MOP/releases/tag/v0.1.7) |
145
+ | GitHub release | [`v0.1.8`](https://github.com/BURHANDEV-ENTERPRISE/BURHAN-MOP/releases/tag/v0.1.8) |
146
146
  | Node | `>=20` |
147
147
 
148
148
  ## Links
package/README.md CHANGED
@@ -141,7 +141,7 @@ and merges only when the workflow is safe.
141
141
  | --- | --- |
142
142
  | npm package | [`burhan-mop`](https://www.npmjs.com/package/burhan-mop) |
143
143
  | latest command | `npx burhan-mop install` |
144
- | GitHub release | [`v0.1.7`](https://github.com/BURHANDEV-ENTERPRISE/BURHAN-MOP/releases/tag/v0.1.7) |
144
+ | GitHub release | [`v0.1.8`](https://github.com/BURHANDEV-ENTERPRISE/BURHAN-MOP/releases/tag/v0.1.8) |
145
145
  | Node | `>=20` |
146
146
 
147
147
  ## Links
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "burhan-mop",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "MOP portable agent memory core installer and CLI.",
5
5
  "type": "module",
6
6
  "author": "BURHANDEV ENTERPRISE",