@seat-mesh/core 0.1.26 → 0.1.29

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 (116) hide show
  1. package/dist/chatfile/store.d.ts +1 -1
  2. package/dist/chatfile/store.d.ts.map +1 -1
  3. package/dist/chatfile/store.js +2 -2
  4. package/dist/chatfile/store.js.map +1 -1
  5. package/dist/chatroom/calls.d.ts +1 -1
  6. package/dist/chatroom/calls.d.ts.map +1 -1
  7. package/dist/chatroom/calls.js +1 -1
  8. package/dist/chatroom/calls.js.map +1 -1
  9. package/dist/chatroom/calls.test.js +1 -1
  10. package/dist/chatroom/calls.test.js.map +1 -1
  11. package/dist/chatroom/read-state.d.ts +10 -0
  12. package/dist/chatroom/read-state.d.ts.map +1 -1
  13. package/dist/chatroom/read-state.js +30 -0
  14. package/dist/chatroom/read-state.js.map +1 -1
  15. package/dist/chatroom/read-state.test.d.ts +2 -0
  16. package/dist/chatroom/read-state.test.d.ts.map +1 -0
  17. package/dist/chatroom/read-state.test.js +37 -0
  18. package/dist/chatroom/read-state.test.js.map +1 -0
  19. package/dist/chatroom/room.d.ts +1 -1
  20. package/dist/chatroom/room.d.ts.map +1 -1
  21. package/dist/chatroom/room.js +2 -2
  22. package/dist/chatroom/room.js.map +1 -1
  23. package/dist/chatroom/room.test.js +1 -1
  24. package/dist/chatroom/room.test.js.map +1 -1
  25. package/dist/chatroom/types.d.ts +2 -2
  26. package/dist/comms/envelope.d.ts +11 -11
  27. package/dist/contracts/balance.d.ts +1 -1
  28. package/dist/contracts/balance.d.ts.map +1 -1
  29. package/dist/contracts/supervise.d.ts +3 -3
  30. package/dist/contracts/supervise.d.ts.map +1 -1
  31. package/dist/contracts/supervise.js +1 -1
  32. package/dist/contracts/supervise.js.map +1 -1
  33. package/dist/index.d.ts +9 -9
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +9 -9
  36. package/dist/index.js.map +1 -1
  37. package/dist/paths/engine-paths.d.ts +4 -0
  38. package/dist/paths/engine-paths.d.ts.map +1 -0
  39. package/dist/paths/engine-paths.js +45 -0
  40. package/dist/paths/engine-paths.js.map +1 -0
  41. package/dist/paths/paths-manifest.d.ts +34 -0
  42. package/dist/paths/paths-manifest.d.ts.map +1 -0
  43. package/dist/paths/paths-manifest.js +79 -0
  44. package/dist/paths/paths-manifest.js.map +1 -0
  45. package/dist/paths/paths-manifest.test.d.ts +2 -0
  46. package/dist/paths/paths-manifest.test.d.ts.map +1 -0
  47. package/dist/paths/paths-manifest.test.js +58 -0
  48. package/dist/paths/paths-manifest.test.js.map +1 -0
  49. package/dist/paths/paths.d.ts +5 -0
  50. package/dist/paths/paths.d.ts.map +1 -0
  51. package/dist/paths/paths.js +17 -0
  52. package/dist/paths/paths.js.map +1 -0
  53. package/dist/paths/runtime-paths.d.ts +43 -0
  54. package/dist/paths/runtime-paths.d.ts.map +1 -0
  55. package/dist/paths/runtime-paths.js +94 -0
  56. package/dist/paths/runtime-paths.js.map +1 -0
  57. package/dist/paths/runtime-paths.test.d.ts +2 -0
  58. package/dist/paths/runtime-paths.test.d.ts.map +1 -0
  59. package/dist/paths/runtime-paths.test.js +86 -0
  60. package/dist/paths/runtime-paths.test.js.map +1 -0
  61. package/dist/profile/profile-edit.d.ts +26 -0
  62. package/dist/profile/profile-edit.d.ts.map +1 -0
  63. package/dist/profile/profile-edit.js +87 -0
  64. package/dist/profile/profile-edit.js.map +1 -0
  65. package/dist/profile/profile-edit.test.d.ts +2 -0
  66. package/dist/profile/profile-edit.test.d.ts.map +1 -0
  67. package/dist/profile/profile-edit.test.js +111 -0
  68. package/dist/profile/profile-edit.test.js.map +1 -0
  69. package/dist/profile/profile.d.ts +52 -0
  70. package/dist/profile/profile.d.ts.map +1 -0
  71. package/dist/profile/profile.js +93 -0
  72. package/dist/profile/profile.js.map +1 -0
  73. package/dist/profile/profile.test.d.ts +2 -0
  74. package/dist/profile/profile.test.d.ts.map +1 -0
  75. package/dist/profile/profile.test.js +25 -0
  76. package/dist/profile/profile.test.js.map +1 -0
  77. package/dist/runtime/dotdir.d.ts +11 -0
  78. package/dist/runtime/dotdir.d.ts.map +1 -0
  79. package/dist/runtime/dotdir.js +30 -0
  80. package/dist/runtime/dotdir.js.map +1 -0
  81. package/dist/runtime/dotdir.test.d.ts +2 -0
  82. package/dist/runtime/dotdir.test.d.ts.map +1 -0
  83. package/dist/runtime/dotdir.test.js +26 -0
  84. package/dist/runtime/dotdir.test.js.map +1 -0
  85. package/dist/runtime/global-registry.d.ts +28 -0
  86. package/dist/runtime/global-registry.d.ts.map +1 -0
  87. package/dist/runtime/global-registry.js +124 -0
  88. package/dist/runtime/global-registry.js.map +1 -0
  89. package/dist/runtime/mesh-state-merge.d.ts +7 -0
  90. package/dist/runtime/mesh-state-merge.d.ts.map +1 -0
  91. package/dist/runtime/mesh-state-merge.js +48 -0
  92. package/dist/runtime/mesh-state-merge.js.map +1 -0
  93. package/dist/runtime/mesh-state-merge.test.d.ts +2 -0
  94. package/dist/runtime/mesh-state-merge.test.d.ts.map +1 -0
  95. package/dist/runtime/mesh-state-merge.test.js +36 -0
  96. package/dist/runtime/mesh-state-merge.test.js.map +1 -0
  97. package/dist/runtime/role-index.d.ts +53 -0
  98. package/dist/runtime/role-index.d.ts.map +1 -0
  99. package/dist/runtime/role-index.js +179 -0
  100. package/dist/runtime/role-index.js.map +1 -0
  101. package/dist/runtime/role-index.test.d.ts +2 -0
  102. package/dist/runtime/role-index.test.d.ts.map +1 -0
  103. package/dist/runtime/role-index.test.js +85 -0
  104. package/dist/runtime/role-index.test.js.map +1 -0
  105. package/dist/schema/agents.d.ts +75 -75
  106. package/dist/schema/profile.d.ts +2 -2
  107. package/dist/stack/exec.d.ts +1 -1
  108. package/dist/stack/exec.d.ts.map +1 -1
  109. package/dist/stack/stack.test.js +2 -2
  110. package/dist/stack/stack.test.js.map +1 -1
  111. package/dist/ux/evaluate.d.ts.map +1 -1
  112. package/dist/ux/evaluate.js +7 -3
  113. package/dist/ux/evaluate.js.map +1 -1
  114. package/dist/ux/evaluate.test.js +18 -0
  115. package/dist/ux/evaluate.test.js.map +1 -1
  116. package/package.json +1 -1
@@ -0,0 +1,86 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import path from "node:path";
3
+ import { meshRuntimePaths, resolveDaemonPort, resolveSessionName, workspaceScopeId, } from "./runtime-paths.js";
4
+ function stubProfile(overrides = {}) {
5
+ return {
6
+ name: "test",
7
+ workspace: ".",
8
+ session: {
9
+ name: "mesh",
10
+ scope: "workspace",
11
+ idLength: 6,
12
+ workerCount: 4,
13
+ miniMax: 4,
14
+ },
15
+ seats: { root: "seats", templates: ["FOCUS"], dirs: {} },
16
+ state: { agentsJson: "a.json", meshAgentsJson: "m.json" },
17
+ roles: { dir: "roles" },
18
+ providers: ["empty"],
19
+ ...overrides,
20
+ };
21
+ }
22
+ function stubLoaded(workspace, profile = stubProfile()) {
23
+ const workspaceId = workspaceScopeId(workspace);
24
+ return {
25
+ profile,
26
+ profileDir: "/tmp/profile",
27
+ profilePath: "/tmp/profile/mesh.config.yaml",
28
+ workspace,
29
+ workspaceId,
30
+ sessionName: resolveSessionName(profile, workspace),
31
+ };
32
+ }
33
+ describe("workspaceScopeId", () => {
34
+ it("is stable for the same path", () => {
35
+ const ws = "/tmp/my-project";
36
+ expect(workspaceScopeId(ws)).toBe(workspaceScopeId(ws));
37
+ });
38
+ it("differs across projects", () => {
39
+ expect(workspaceScopeId("/tmp/a")).not.toBe(workspaceScopeId("/tmp/b"));
40
+ });
41
+ });
42
+ describe("resolveSessionName", () => {
43
+ it("suffixes workspace hash by default", () => {
44
+ const ws = "/tmp/my-project";
45
+ const name = resolveSessionName(stubProfile(), ws);
46
+ expect(name).toMatch(/^mesh-[a-f0-9]{6}$/);
47
+ expect(name).toBe(`mesh-${workspaceScopeId(ws)}`);
48
+ });
49
+ it("returns base name when scope global", () => {
50
+ const p = stubProfile({ session: { ...stubProfile().session, scope: "global" } });
51
+ expect(resolveSessionName(p, "/tmp/x")).toBe("mesh");
52
+ });
53
+ });
54
+ describe("resolveDaemonPort", () => {
55
+ it("offsets port per workspace by default", () => {
56
+ const p = stubProfile();
57
+ const portA = resolveDaemonPort(p, "/tmp/project-a");
58
+ const portB = resolveDaemonPort(p, "/tmp/project-b");
59
+ expect(portA).toBeGreaterThanOrEqual(31670);
60
+ expect(portA).toBeLessThan(31670 + 90);
61
+ expect(portA).not.toBe(portB);
62
+ });
63
+ it("uses fixed port when portScope profile", () => {
64
+ const p = stubProfile({
65
+ daemon: { port: 3200, portScope: "profile" },
66
+ });
67
+ expect(resolveDaemonPort(p, "/tmp/a")).toBe(3200);
68
+ expect(resolveDaemonPort(p, "/tmp/b")).toBe(3200);
69
+ });
70
+ });
71
+ describe("meshRuntimePaths", () => {
72
+ it("places daemon under profileDir data.root when scope=profile", () => {
73
+ const profile = stubProfile({
74
+ paths: { scope: "profile" },
75
+ data: { root: "runtime" },
76
+ });
77
+ const loaded = stubLoaded("/tmp/ws", profile);
78
+ loaded.profileDir = "/tmp/profile";
79
+ const rt = meshRuntimePaths(loaded);
80
+ expect(rt.daemonDir).toBe(path.join("/tmp/profile", "runtime", "daemon"));
81
+ expect(rt.sqlitePath).toBe(path.join("/tmp/profile", "runtime", "mesh.sqlite"));
82
+ expect(rt.storageBackend).toBe("sqlite");
83
+ expect(rt.minisJson).toBe(path.join("/tmp/profile", "runtime", "minis.json"));
84
+ });
85
+ });
86
+ //# sourceMappingURL=runtime-paths.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-paths.test.js","sourceRoot":"","sources":["../../src/paths/runtime-paths.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { LoadedProfile } from "./profile.js";
2
+ /**
3
+ * Programmatic edits to `mesh.config.yaml`'s `layout.base.columns` (+ the optional
4
+ * per-column `cli` / `humanCoTyped` maps). N managers/secretaries are config, not
5
+ * an enum (see docs/ARCHITECTURE.md "Coordinator columns") -- these helpers are the
6
+ * one supported way to add/remove a column so nobody hand-edits the yaml array or
7
+ * cargo-cults a per-instance `seats.dirs` entry that `seatDirSegment` already
8
+ * defaults to identity for.
9
+ */
10
+ export interface AddColumnOptions {
11
+ /** CLI provider override for this column (default: agent, or opencode for secretary-kind). */
12
+ cli?: string;
13
+ /** Insert immediately after this existing column id (default: append at end). */
14
+ after?: string;
15
+ /** Add to `layout.base.humanCoTyped` (daemon queues injects while the human types). */
16
+ coTyped?: boolean;
17
+ }
18
+ export interface ColumnEditResult {
19
+ id: string;
20
+ columns: string[];
21
+ profilePath: string;
22
+ }
23
+ export declare function addBaseColumn(loaded: LoadedProfile, rawId: string, opts?: AddColumnOptions): ColumnEditResult;
24
+ export declare function removeBaseColumn(loaded: LoadedProfile, rawId: string): ColumnEditResult;
25
+ export declare function listBaseColumns(loaded: LoadedProfile): string[];
26
+ //# sourceMappingURL=profile-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-edit.d.ts","sourceRoot":"","sources":["../../src/profile/profile-edit.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD;;;;;;;GAOG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,8FAA8F;IAC9F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAwBD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,gBAAqB,GAC1B,gBAAgB,CAmClB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAyBvF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CAG/D"}
@@ -0,0 +1,87 @@
1
+ import fs from "node:fs";
2
+ import YAML from "yaml";
3
+ import { COLUMN_ID_RE } from "../schema/seat-kind.js";
4
+ function normalizeId(id) {
5
+ const trimmed = id.trim().toLowerCase();
6
+ if (!COLUMN_ID_RE.test(trimmed)) {
7
+ throw new Error(`bad column id: ${id} (want ${COLUMN_ID_RE})`);
8
+ }
9
+ return trimmed;
10
+ }
11
+ function readColumnsSeq(doc) {
12
+ const columns = doc.getIn(["layout", "base", "columns"]);
13
+ if (!YAML.isSeq(columns)) {
14
+ throw new Error("layout.base.columns missing or not a sequence in profile yaml");
15
+ }
16
+ return columns;
17
+ }
18
+ function seqStrings(seq) {
19
+ return seq.items.map((n) => String(YAML.isScalar(n) ? n.value : n));
20
+ }
21
+ const MAX_BASE_COLUMNS = 128;
22
+ export function addBaseColumn(loaded, rawId, opts = {}) {
23
+ const id = normalizeId(rawId);
24
+ const doc = YAML.parseDocument(fs.readFileSync(loaded.profilePath, "utf8"));
25
+ const columns = readColumnsSeq(doc);
26
+ const existing = seqStrings(columns);
27
+ if (existing.includes(id))
28
+ throw new Error(`column already exists: ${id}`);
29
+ if (existing.length >= MAX_BASE_COLUMNS) {
30
+ throw new Error(`base columns at max (${MAX_BASE_COLUMNS})`);
31
+ }
32
+ let insertAt = columns.items.length;
33
+ if (opts.after) {
34
+ const afterId = normalizeId(opts.after);
35
+ const idx = existing.indexOf(afterId);
36
+ if (idx === -1)
37
+ throw new Error(`--after column not found: ${afterId}`);
38
+ insertAt = idx + 1;
39
+ }
40
+ columns.items.splice(insertAt, 0, doc.createNode(id));
41
+ if (opts.cli) {
42
+ doc.setIn(["layout", "base", "cli", id], opts.cli);
43
+ }
44
+ if (opts.coTyped) {
45
+ const coTyped = doc.getIn(["layout", "base", "humanCoTyped"]);
46
+ if (YAML.isSeq(coTyped)) {
47
+ if (!seqStrings(coTyped).includes(id))
48
+ coTyped.items.push(doc.createNode(id));
49
+ }
50
+ else {
51
+ doc.setIn(["layout", "base", "humanCoTyped"], [id]);
52
+ }
53
+ }
54
+ fs.writeFileSync(loaded.profilePath, doc.toString());
55
+ return { id, columns: seqStrings(readColumnsSeq(doc)), profilePath: loaded.profilePath };
56
+ }
57
+ export function removeBaseColumn(loaded, rawId) {
58
+ const id = normalizeId(rawId);
59
+ const doc = YAML.parseDocument(fs.readFileSync(loaded.profilePath, "utf8"));
60
+ const columns = readColumnsSeq(doc);
61
+ const existing = seqStrings(columns);
62
+ const idx = existing.indexOf(id);
63
+ if (idx === -1)
64
+ throw new Error(`column not found: ${id}`);
65
+ if (columns.items.length <= 1)
66
+ throw new Error("cannot remove the last base column");
67
+ columns.items.splice(idx, 1);
68
+ const cli = doc.getIn(["layout", "base", "cli"]);
69
+ if (YAML.isMap(cli))
70
+ cli.delete(id);
71
+ const coTyped = doc.getIn(["layout", "base", "humanCoTyped"]);
72
+ if (YAML.isSeq(coTyped)) {
73
+ const hIdx = seqStrings(coTyped).indexOf(id);
74
+ if (hIdx !== -1)
75
+ coTyped.items.splice(hIdx, 1);
76
+ }
77
+ const dirs = doc.getIn(["seats", "dirs"]);
78
+ if (YAML.isMap(dirs))
79
+ dirs.delete(id);
80
+ fs.writeFileSync(loaded.profilePath, doc.toString());
81
+ return { id, columns: existing.filter((c) => c !== id), profilePath: loaded.profilePath };
82
+ }
83
+ export function listBaseColumns(loaded) {
84
+ const doc = YAML.parseDocument(fs.readFileSync(loaded.profilePath, "utf8"));
85
+ return seqStrings(readColumnsSeq(doc));
86
+ }
87
+ //# sourceMappingURL=profile-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-edit.js","sourceRoot":"","sources":["../../src/profile/profile-edit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=profile-edit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-edit.test.d.ts","sourceRoot":"","sources":["../../src/profile/profile-edit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,111 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import { loadProfile } from "./profile.js";
6
+ import { addBaseColumn, listBaseColumns, removeBaseColumn } from "./profile-edit.js";
7
+ const MINIMAL_CONFIG = `# fixture profile
8
+ name: fixture
9
+ workspace: ..
10
+
11
+ session:
12
+ name: dev
13
+ workerCount: 2
14
+ miniMax: 4
15
+
16
+ layout:
17
+ base:
18
+ window: base
19
+ columns: [manager, secretary]
20
+ cli:
21
+ manager: claude
22
+ secretaryWidthPct: 40
23
+
24
+ seats:
25
+ root: seats
26
+ templates: [FOCUS, TASKS, REMINDER]
27
+
28
+ state:
29
+ agentsJson: tmux-main-agents.json
30
+
31
+ daemon:
32
+ port: 31699
33
+ portScope: profile
34
+ managerPromptPrefix: "[agent-manager]"
35
+
36
+ ports:
37
+ worker: "30{n}0/30{n}1"
38
+
39
+ roles:
40
+ dir: roles
41
+ `;
42
+ describe("profile-edit: base columns", () => {
43
+ let tmp = "";
44
+ let profileDir = "";
45
+ beforeEach(() => {
46
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sm-profile-edit-"));
47
+ profileDir = path.join(tmp, ".sm");
48
+ fs.mkdirSync(profileDir, { recursive: true });
49
+ fs.writeFileSync(path.join(profileDir, "mesh.config.yaml"), MINIMAL_CONFIG);
50
+ });
51
+ afterEach(() => {
52
+ fs.rmSync(tmp, { recursive: true, force: true });
53
+ });
54
+ it("adds an Nth manager column with no role yaml or seats.dirs entry required", () => {
55
+ const loaded = loadProfile(profileDir);
56
+ const result = addBaseColumn(loaded, "manager-2", { cli: "claude" });
57
+ expect(result.columns).toEqual(["manager", "secretary", "manager-2"]);
58
+ const reloaded = loadProfile(profileDir);
59
+ expect(reloaded.profile.layout?.base.columns).toEqual(["manager", "secretary", "manager-2"]);
60
+ expect(reloaded.profile.layout?.base.cli?.["manager-2"]).toBe("claude");
61
+ // no seats.dirs entry was written -- seatDirSegment falls back to the id itself
62
+ expect(reloaded.profile.seats.dirs?.["manager-2"]).toBeUndefined();
63
+ });
64
+ it("preserves comments and inserts --after a given column", () => {
65
+ const loaded = loadProfile(profileDir);
66
+ addBaseColumn(loaded, "manager-2", { after: "manager" });
67
+ const raw = fs.readFileSync(path.join(profileDir, "mesh.config.yaml"), "utf8");
68
+ expect(raw).toContain("# fixture profile");
69
+ expect(listBaseColumns(loaded)).toEqual(["manager", "manager-2", "secretary"]);
70
+ });
71
+ it("marks a column human-co-typed", () => {
72
+ const loaded = loadProfile(profileDir);
73
+ addBaseColumn(loaded, "manager-2", { coTyped: true });
74
+ const reloaded = loadProfile(profileDir);
75
+ expect(reloaded.profile.layout?.base.humanCoTyped).toEqual(["manager-2"]);
76
+ });
77
+ it("rejects a duplicate column id", () => {
78
+ const loaded = loadProfile(profileDir);
79
+ expect(() => addBaseColumn(loaded, "manager")).toThrow(/already exists/);
80
+ });
81
+ it("rejects a bad column id", () => {
82
+ const loaded = loadProfile(profileDir);
83
+ expect(() => addBaseColumn(loaded, "Manager_2!")).toThrow(/bad column id/);
84
+ });
85
+ it("removes a column and its cli/humanCoTyped/seats.dirs entries", () => {
86
+ const loaded = loadProfile(profileDir);
87
+ addBaseColumn(loaded, "manager-2", { cli: "claude", coTyped: true });
88
+ const removed = removeBaseColumn(loadProfile(profileDir), "manager-2");
89
+ expect(removed.columns).toEqual(["manager", "secretary"]);
90
+ const reloaded = loadProfile(profileDir);
91
+ expect(reloaded.profile.layout?.base.cli?.["manager-2"]).toBeUndefined();
92
+ expect(reloaded.profile.layout?.base.humanCoTyped ?? []).not.toContain("manager-2");
93
+ });
94
+ it("refuses to remove the last base column", () => {
95
+ const loaded = loadProfile(profileDir);
96
+ removeBaseColumn(loaded, "secretary");
97
+ expect(() => removeBaseColumn(loadProfile(profileDir), "manager")).toThrow(/cannot remove the last/);
98
+ });
99
+ it("supports 100+ manager columns (no per-instance code, just config)", () => {
100
+ let loaded = loadProfile(profileDir);
101
+ for (let n = 2; n <= 101; n++) {
102
+ addBaseColumn(loaded, `manager-${n}`);
103
+ loaded = loadProfile(profileDir);
104
+ }
105
+ const cols = listBaseColumns(loaded);
106
+ expect(cols.length).toBe(102); // manager, secretary, manager-2..manager-101
107
+ expect(cols).toContain("manager-101");
108
+ expect(loaded.profile.layout?.base.columns.length).toBe(102);
109
+ });
110
+ });
111
+ //# sourceMappingURL=profile-edit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-edit.test.js","sourceRoot":"","sources":["../../src/profile/profile-edit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { type MeshProfile } from "../schema/profile.js";
2
+ import { type MeshRuntimePaths } from "../paths/runtime-paths.js";
3
+ export interface LoadedProfile {
4
+ profile: MeshProfile;
5
+ profileDir: string;
6
+ profilePath: string;
7
+ workspace: string;
8
+ /** Short hash of resolved workspace path. */
9
+ workspaceId: string;
10
+ /** Resolved tmux session name (may include workspace suffix). */
11
+ sessionName: string;
12
+ }
13
+ export type { MeshRuntimePaths };
14
+ export { meshRuntimePaths, resolveDaemonPort, resolveSessionName, workspaceScopeId, resolveConnectivityHooks, runtimePathHint, } from "../paths/runtime-paths.js";
15
+ export { seatMeshPackageRoot, resolveDaemonScript } from "../paths/engine-paths.js";
16
+ /** Default profile: workspace `.sm/` when present, else bundled minimal. No flags required. */
17
+ export declare function defaultProfilePath(): string;
18
+ export declare function findProfilePath(explicit?: string, searchFrom?: string): string;
19
+ export declare function loadProfile(explicit?: string): LoadedProfile;
20
+ export declare function profilePaths(loaded: LoadedProfile): {
21
+ dataRoot: string;
22
+ daemonDir: string;
23
+ sqlitePath: string;
24
+ storageBackend: import("../paths/paths-manifest.js").StorageBackend;
25
+ inboxJsonl: string;
26
+ peerJsonl: string;
27
+ checkbackJsonl: string;
28
+ paneOpsJsonl: string;
29
+ callsJsonl: string;
30
+ meshInboxMeta: string;
31
+ meshInboxStop: string;
32
+ meshInboxLog: string;
33
+ coldStartState: string;
34
+ ppaState: string;
35
+ wifiProbeLock: string;
36
+ minisJson: string;
37
+ miniDone: string;
38
+ miniManifest: string;
39
+ gateQueue: string;
40
+ seatsRoot: string;
41
+ agentsJson: string;
42
+ meshAgentsJson: string;
43
+ chatRoomsRoot: string;
44
+ chatFilesRoot: string;
45
+ rolesDir: string;
46
+ contractsDir: string;
47
+ managerDir: string;
48
+ secretaryDir: string;
49
+ daemonPort: number;
50
+ pathsManifest: string;
51
+ };
52
+ //# sourceMappingURL=profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/profile/profile.ts"],"names":[],"mappings":"AAKA,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAO3E,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AAOnC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,YAAY,EAAE,gBAAgB,EAAE,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,GAChB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpF,+FAA+F;AAC/F,wBAAgB,kBAAkB,IAAI,MAAM,CAO3C;AAED,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,SAAgB,GAAG,MAAM,CAqBrF;AAED,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,CAgB5D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCjD"}
@@ -0,0 +1,93 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import YAML from "yaml";
4
+ import { seatMeshPackageRoot } from "../paths/engine-paths.js";
5
+ import { findDotSmConfig } from "../runtime/dotdir.js";
6
+ import { MeshProfileSchema } from "../schema/profile.js";
7
+ import { resolveWorkspace } from "../paths/paths.js";
8
+ import { buildResolvedPaths, writePathsManifest, assertHarnessUnderDotdir, } from "../paths/paths-manifest.js";
9
+ import { meshRuntimePaths, resolveDaemonPort, resolveSessionName, workspaceScopeId, } from "../paths/runtime-paths.js";
10
+ import { primaryManagerColumn, primarySecretaryColumn, seatDirSegment, } from "../schema/seat-kind.js";
11
+ export { meshRuntimePaths, resolveDaemonPort, resolveSessionName, workspaceScopeId, resolveConnectivityHooks, runtimePathHint, } from "../paths/runtime-paths.js";
12
+ export { seatMeshPackageRoot, resolveDaemonScript } from "../paths/engine-paths.js";
13
+ /** Default profile: workspace `.sm/` when present, else bundled minimal. No flags required. */
14
+ export function defaultProfilePath() {
15
+ const root = seatMeshPackageRoot();
16
+ const candidates = [path.join(root, "profiles/minimal/mesh.config.yaml")];
17
+ for (const cfg of candidates) {
18
+ if (fs.existsSync(cfg))
19
+ return cfg;
20
+ }
21
+ throw new Error(`no default profile under ${root}/profiles/`);
22
+ }
23
+ export function findProfilePath(explicit, searchFrom = process.cwd()) {
24
+ if (explicit) {
25
+ const p = path.resolve(explicit);
26
+ if (fs.statSync(p).isDirectory()) {
27
+ const dotCfg = path.join(p, ".sm", "mesh.config.yaml");
28
+ const cfg = fs.existsSync(dotCfg) ? dotCfg : path.join(p, "mesh.config.yaml");
29
+ if (!fs.existsSync(cfg)) {
30
+ throw new Error(`profile directory missing mesh.config.yaml (or .sm/mesh.config.yaml): ${p}`);
31
+ }
32
+ return cfg;
33
+ }
34
+ if (!fs.existsSync(p))
35
+ throw new Error(`profile not found: ${p}`);
36
+ return p;
37
+ }
38
+ const dotCfg = findDotSmConfig(searchFrom);
39
+ if (dotCfg)
40
+ return dotCfg;
41
+ return defaultProfilePath();
42
+ }
43
+ export function loadProfile(explicit) {
44
+ const profilePath = findProfilePath(explicit);
45
+ const profileDir = path.dirname(profilePath);
46
+ const raw = YAML.parse(fs.readFileSync(profilePath, "utf8"));
47
+ const profile = MeshProfileSchema.parse(raw);
48
+ const workspace = resolveWorkspace(profile.workspace, profileDir);
49
+ const workspaceId = workspaceScopeId(workspace);
50
+ const sessionName = resolveSessionName(profile, workspace);
51
+ const loaded = { profile, profileDir, profilePath, workspace, workspaceId, sessionName };
52
+ try {
53
+ writePathsManifest(loaded);
54
+ }
55
+ catch {
56
+ /* non-fatal on read-only profile dir */
57
+ }
58
+ return loaded;
59
+ }
60
+ export function profilePaths(loaded) {
61
+ const { profile } = loaded;
62
+ const resolved = buildResolvedPaths(loaded);
63
+ const rt = meshRuntimePaths(loaded);
64
+ const dirs = profile.seats.dirs;
65
+ const primaryMgr = primaryManagerColumn(profile.layout);
66
+ const primarySec = primarySecretaryColumn(profile.layout);
67
+ for (const [label, abs] of [
68
+ ["dataRoot", resolved.dataRoot],
69
+ ["daemonDir", resolved.daemonDir],
70
+ ["seatsRoot", resolved.seatsRoot],
71
+ ["meshAgentsJson", resolved.meshAgentsJson],
72
+ ["chatRoomsRoot", resolved.chatRoomsRoot],
73
+ ["chatFilesRoot", resolved.chatFilesRoot],
74
+ ["sqlitePath", resolved.sqlitePath],
75
+ ]) {
76
+ assertHarnessUnderDotdir(loaded, abs, label);
77
+ }
78
+ return {
79
+ seatsRoot: resolved.seatsRoot,
80
+ agentsJson: resolved.agentsJson,
81
+ meshAgentsJson: resolved.meshAgentsJson,
82
+ chatRoomsRoot: resolved.chatRoomsRoot,
83
+ chatFilesRoot: resolved.chatFilesRoot,
84
+ rolesDir: resolved.rolesDir,
85
+ contractsDir: resolved.contractsDir,
86
+ managerDir: path.join(resolved.seatsRoot, seatDirSegment(dirs, primaryMgr)),
87
+ secretaryDir: path.join(resolved.seatsRoot, seatDirSegment(dirs, primarySec)),
88
+ daemonPort: resolveDaemonPort(profile, loaded.workspace),
89
+ pathsManifest: path.join(loaded.profileDir, "paths.json"),
90
+ ...rt,
91
+ };
92
+ }
93
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/profile/profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=profile.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.test.d.ts","sourceRoot":"","sources":["../../src/profile/profile.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import path from "node:path";
3
+ import { defaultProfilePath, loadProfile, portsForSlot } from "../index.js";
4
+ describe("loadProfile", () => {
5
+ it("loads default profile without --profile", () => {
6
+ const loaded = loadProfile();
7
+ expect(["consumer", "minimal"]).toContain(loaded.profile.name);
8
+ expect(loaded.workspace).toBeTruthy();
9
+ });
10
+ it("default profile resolves bundled minimal mesh.config.yaml", () => {
11
+ const cfg = defaultProfilePath();
12
+ expect(cfg).toContain("profiles");
13
+ expect(cfg.endsWith("mesh.config.yaml")).toBe(true);
14
+ });
15
+ it("loads bundled minimal profile", () => {
16
+ const minimalDir = path.resolve(import.meta.dirname, "../../../../profiles/minimal");
17
+ const loaded = loadProfile(minimalDir);
18
+ expect(loaded.profile.name).toBe("minimal");
19
+ expect(loaded.workspace).toBeTruthy();
20
+ });
21
+ it("formats worker ports from formula", () => {
22
+ expect(portsForSlot("30{n}0/30{n}1", 3)).toBe("3030/3031");
23
+ });
24
+ });
25
+ //# sourceMappingURL=profile.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.test.js","sourceRoot":"","sources":["../../src/profile/profile.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5E,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAC7B,MAAM,CAAC,IAAI,CAAC,OAAO,EACnB,8BAA8B,CAC/B,CAAC;QACF,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ export declare const SM_DIR = ".sm";
2
+ export declare const SM_CONFIG = "mesh.config.yaml";
3
+ /** Absolute path to `.sm/mesh.config.yaml` under `dir`, or null. */
4
+ export declare function dotSmConfigIn(dir: string): string | null;
5
+ /**
6
+ * Walk from `startDir` up to filesystem root for `.sm/mesh.config.yaml`.
7
+ * Default start: process.cwd().
8
+ */
9
+ export declare function findDotSmConfig(startDir?: string): string | null;
10
+ export declare function dotSmDirFromConfig(configPath: string): string;
11
+ //# sourceMappingURL=dotdir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dotdir.d.ts","sourceRoot":"","sources":["../../src/runtime/dotdir.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,eAAO,MAAM,SAAS,qBAAqB,CAAC;AAE5C,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGxD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,SAAgB,GAAG,MAAM,GAAG,IAAI,CAUvE;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE7D"}
@@ -0,0 +1,30 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ export const SM_DIR = ".sm";
4
+ export const SM_CONFIG = "mesh.config.yaml";
5
+ /** Absolute path to `.sm/mesh.config.yaml` under `dir`, or null. */
6
+ export function dotSmConfigIn(dir) {
7
+ const cfg = path.join(dir, SM_DIR, SM_CONFIG);
8
+ return fs.existsSync(cfg) ? cfg : null;
9
+ }
10
+ /**
11
+ * Walk from `startDir` up to filesystem root for `.sm/mesh.config.yaml`.
12
+ * Default start: process.cwd().
13
+ */
14
+ export function findDotSmConfig(startDir = process.cwd()) {
15
+ let dir = path.resolve(startDir);
16
+ for (;;) {
17
+ const hit = dotSmConfigIn(dir);
18
+ if (hit)
19
+ return hit;
20
+ const parent = path.dirname(dir);
21
+ if (parent === dir)
22
+ break;
23
+ dir = parent;
24
+ }
25
+ return null;
26
+ }
27
+ export function dotSmDirFromConfig(configPath) {
28
+ return path.dirname(configPath);
29
+ }
30
+ //# sourceMappingURL=dotdir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dotdir.js","sourceRoot":"","sources":["../../src/runtime/dotdir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC;AAC5B,MAAM,CAAC,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAE5C,oEAAoE;AACpE,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9C,OAAO,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE;IACtD,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,CAAC;QACR,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,UAAkB;IACnD,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dotdir.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dotdir.test.d.ts","sourceRoot":"","sources":["../../src/runtime/dotdir.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { afterEach, describe, expect, it } from "vitest";
5
+ import { dotSmConfigIn, findDotSmConfig } from "./dotdir.js";
6
+ describe("dotdir", () => {
7
+ let tmp = "";
8
+ afterEach(() => {
9
+ if (tmp)
10
+ fs.rmSync(tmp, { recursive: true, force: true });
11
+ });
12
+ it("finds .sm/mesh.config.yaml walking up from subdir", () => {
13
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sm-dot-"));
14
+ const sm = path.join(tmp, ".sm");
15
+ fs.mkdirSync(sm, { recursive: true });
16
+ fs.writeFileSync(path.join(sm, "mesh.config.yaml"), "name: t\n");
17
+ const nested = path.join(tmp, "apps", "api");
18
+ fs.mkdirSync(nested, { recursive: true });
19
+ expect(findDotSmConfig(nested)).toBe(path.join(sm, "mesh.config.yaml"));
20
+ });
21
+ it("dotSmConfigIn returns null when missing", () => {
22
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sm-dot-"));
23
+ expect(dotSmConfigIn(tmp)).toBeNull();
24
+ });
25
+ });
26
+ //# sourceMappingURL=dotdir.test.js.map