patchcord 0.5.98 → 0.5.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/patchcord.mjs +43 -5
  2. package/package.json +1 -1
package/bin/patchcord.mjs CHANGED
@@ -273,7 +273,7 @@ async function _resolveBearer(options = {}) {
273
273
  while (dir && dir !== "/") {
274
274
  for (const r of projectReaders) {
275
275
  const found = r(dir);
276
- if (found) return found;
276
+ if (found) { found.scope = "project"; return found; }
277
277
  }
278
278
  dir = dirname(dir);
279
279
  }
@@ -323,7 +323,7 @@ async function _resolveBearer(options = {}) {
323
323
  : [...defaultGlobalCandidates, kimiGlobalReader, kimiCodeGlobalReader];
324
324
  for (const r of globalCandidates) {
325
325
  const found = r();
326
- if (found) return found;
326
+ if (found) { found.scope = "global"; return found; }
327
327
  }
328
328
 
329
329
  return null;
@@ -353,6 +353,12 @@ if (cmd === "whoami") {
353
353
  console.error("No patchcord config found in current directory or any parent. Run `npx patchcord@latest` from a project directory first.");
354
354
  process.exit(1);
355
355
  }
356
+ if (found.scope === "global") {
357
+ console.error(`\x1b[33m⚠ No project patchcord config in ${process.cwd()} or any parent.`);
358
+ console.error(` Falling back to a GLOBAL config: ${found.configFile} (tool: ${found.tool}).`);
359
+ console.error(` If this isn't the agent you expected, you're in a directory without its own .mcp.json —`);
360
+ console.error(` the identity below belongs to that global config, NOT to whatever harness launched this.\x1b[0m`);
361
+ }
356
362
  const { token, baseUrl } = found;
357
363
  if (!isSafeToken(token) || !isSafeUrl(baseUrl)) {
358
364
  console.error(`Invalid patchcord URL or token in config.`);
@@ -931,6 +937,16 @@ if (cmd === "master" || cmd === "provision" || cmd === "team") {
931
937
  if (role) {
932
938
  try { writeFileSync(join(dir, "AGENTS.md"), `# ${arg} — role: ${role}\n\nYou are \`${arg}\` in the \`${ns}\` Patchcord team. Role: ${role}.\nCoordinate with teammates over Patchcord (inbox / send_message / reply).\n`); } catch {}
933
939
  }
940
+ // Record in the local team manifest so `team launch` / `team status` see it.
941
+ try {
942
+ const tj = join(process.cwd(), ".patchcord", "team.json");
943
+ if (existsSync(tj)) {
944
+ const man = JSON.parse(readFileSync(tj, "utf-8"));
945
+ man.agents = (man.agents || []).filter((a) => a.agent !== arg);
946
+ man.agents.push({ agent: arg, tool, role, dir: subdir, namespace: ns });
947
+ writeFileSync(tj, JSON.stringify(man, null, 2) + "\n");
948
+ }
949
+ } catch {}
934
950
  console.log(`✓ provisioned ${M.green}${ns}:${arg}${M.rst} [${tool}${role ? "/" + role : ""}] → ${dir}`);
935
951
  process.exit(0);
936
952
  }
@@ -939,13 +955,35 @@ if (cmd === "master" || cmd === "provision" || cmd === "team") {
939
955
  const sub = process.argv[3];
940
956
  if (sub === "init") {
941
957
  const project = process.argv[4];
942
- if (!project) { console.error("Usage: patchcord team init <project> [--namespace ns]"); process.exit(1); }
958
+ if (!project) { console.error("Usage: patchcord team init <project> [--namespace ns] [--tool <master-harness>]"); process.exit(1); }
943
959
  const ns = flagVal("namespace", project.replace(/[^a-z0-9-]/gi, "-").toLowerCase());
960
+ const masterTool = flagVal("tool", "claude_code");
944
961
  const root = join(process.cwd(), project);
945
962
  mkdirSync(join(root, ".patchcord"), { recursive: true });
946
- writeFileSync(join(root, ".patchcord", "team.json"), JSON.stringify({ project, namespace: ns, pattern: "architect-workers-reviewer", agents: [] }, null, 2) + "\n");
947
- writeFileSync(join(root, "AGENTS.md"), `# ${project} Patchcord team\n\nNamespace: ${ns}\nProvision: patchcord provision <agent> --tool X --role Y --namespace ${ns} --dir <agent>/\n`);
963
+ const manifest = { project, namespace: ns, pattern: "architect-workers-reviewer", master: null, agents: [] };
964
+ // Provision the master's OWN messaging identity IN the team namespace and
965
+ // write its config at the project root, so the master — running here —
966
+ // resolves to ns:master and SEES every worker it provisions into ns.
967
+ // Without this the master has no identity and whoami grabs a stale global.
968
+ const m = readMaster();
969
+ if (m) {
970
+ const hostname = run("hostname -s") || run("hostname") || "unknown";
971
+ const { status, json } = await _httpJSON("POST", `${m.baseUrl}/api/provision`, m.token, { namespace_id: ns, agent_id: "master", tool: masterTool, role: "master", label: "master:self" });
972
+ if (status === "200" && json?.token) {
973
+ const base = String(json.url || `${m.baseUrl}/mcp`).replace(/\/mcp$/, "");
974
+ writeWorkerConfig(masterTool, root, base, json.token, hostname);
975
+ manifest.master = { agent: "master", tool: masterTool };
976
+ console.log(`✓ master identity: ${M.green}${ns}:master${M.rst} [${masterTool}] — config written at ${root}`);
977
+ } else {
978
+ console.log(`⚠ could not provision master identity (HTTP ${status}: ${json?.error || ""}) — scaffolding only`);
979
+ }
980
+ } else {
981
+ console.log(`⚠ no master token — run 'patchcord master connect' first, then re-run team init`);
982
+ }
983
+ writeFileSync(join(root, ".patchcord", "team.json"), JSON.stringify(manifest, null, 2) + "\n");
984
+ writeFileSync(join(root, "AGENTS.md"), `# ${project} — Patchcord team\n\nNamespace: ${ns}\nMaster identity: ${ns}:master (you, when running patchcord from this folder)\nProvision workers: patchcord provision <agent> --tool X --role Y --namespace ${ns} --dir <agent>/\n`);
948
985
  console.log(`✓ team scaffolded: ${root} (namespace ${ns})`);
986
+ console.log(` ${M.dim}cd ${project} — your identity there is ${ns}:master; you'll see every worker you provision into ${ns}.${M.rst}`);
949
987
  process.exit(0);
950
988
  }
951
989
  if (sub === "list") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.5.98",
3
+ "version": "0.5.99",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "author": "ppravdin",
6
6
  "license": "MIT",