@paradow/ledge 0.25.1 → 0.26.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.
Files changed (32) hide show
  1. package/dist/cli/{action-WNQ3NJGD.js → action-SCMMRWYI.js} +4 -4
  2. package/dist/cli/{attach-UHM7QQ4W.js → attach-EFIN5VU6.js} +8 -8
  3. package/dist/cli/{bridge-R37AHVXS.js → bridge-QT5X6TWJ.js} +1 -1
  4. package/dist/cli/{chunk-KRFXWD5S.js → chunk-2V2OJR2N.js} +614 -77
  5. package/dist/cli/chunk-3PLC745L.js +6 -0
  6. package/dist/cli/{chunk-PUJLMKZC.js → chunk-5PTC732E.js} +3 -3
  7. package/dist/cli/{chunk-TOFVC6IV.js → chunk-6F6JTPMC.js} +2 -2
  8. package/dist/cli/{chunk-JNLARCUC.js → chunk-HCTXTN2X.js} +49 -19
  9. package/dist/cli/{chunk-AVKFQSRP.js → chunk-II6VRGLU.js} +45 -17
  10. package/dist/cli/{chunk-5VFFJ3ZC.js → chunk-JHUIHBC7.js} +2 -2
  11. package/dist/cli/{chunk-RKV5KYKL.js → chunk-L3GYGJRE.js} +3 -3
  12. package/dist/cli/{chunk-TZBI2RVU.js → chunk-NYGLT5G2.js} +1 -1
  13. package/dist/cli/{chunk-ZDEEHFU3.js → chunk-PTY4LXTG.js} +1 -1
  14. package/dist/cli/{chunk-ARB4BKZJ.js → chunk-QRD74KPO.js} +732 -557
  15. package/dist/cli/{chunk-O6FTIYJV.js → chunk-SYXW4YB6.js} +3 -3
  16. package/dist/cli/{chunk-RYUDIFSI.js → chunk-TYNRKZFE.js} +6 -2
  17. package/dist/cli/{chunk-7XMGYJTN.js → chunk-WYVMCF2K.js} +5 -5
  18. package/dist/cli/{daemon-ESBBZW7O.js → daemon-U6NA6PVD.js} +7 -7
  19. package/dist/cli/{decide-UWJMKDR4.js → decide-XOUTZT3S.js} +3 -3
  20. package/dist/cli/{handover-5JHFA5EF.js → handover-6CQKUZJV.js} +4 -4
  21. package/dist/cli/{hook-XBSMUMZ7.js → hook-ZIJACTCF.js} +10 -10
  22. package/dist/cli/index.js +16 -16
  23. package/dist/cli/{launch-OVB66BZJ.js → launch-QWPA2P66.js} +8 -8
  24. package/dist/cli/{send-Y2C3BIGK.js → send-T5IOOVGX.js} +4 -4
  25. package/dist/cli/{status-5YEORNTH.js → status-EZPFE5CL.js} +2 -2
  26. package/dist/cli/{task-R44VWZHR.js → task-B2QVGHDF.js} +4 -4
  27. package/dist/cli/{team-F7B3IG3I.js → team-V6VPO3CB.js} +6 -6
  28. package/dist/cli/{tui-YK6TXFYX.js → tui-MM64KSQ2.js} +8 -8
  29. package/dist/cli/{version-NFURQHXH.js → version-SK4VC4AE.js} +1 -1
  30. package/dist/cli/{who-YMSQI64I.js → who-XXZUCJPD.js} +3 -3
  31. package/package.json +1 -1
  32. package/dist/cli/chunk-PA2JU476.js +0 -6
@@ -0,0 +1,6 @@
1
+ // src/version.ts
2
+ var LEDGE_VERSION = true ? "0.26.0" : "0.0.0-dev";
3
+
4
+ export {
5
+ LEDGE_VERSION
6
+ };
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  CODEX_HOOK_VAR
3
- } from "./chunk-ZDEEHFU3.js";
3
+ } from "./chunk-PTY4LXTG.js";
4
4
  import {
5
5
  connect
6
- } from "./chunk-TZBI2RVU.js";
6
+ } from "./chunk-NYGLT5G2.js";
7
7
  import {
8
8
  LEDGE_GIVER,
9
9
  TASK_TEXT_MAX,
10
10
  TASK_TITLE_MAX
11
- } from "./chunk-ARB4BKZJ.js";
11
+ } from "./chunk-QRD74KPO.js";
12
12
 
13
13
  // src/cli/task.ts
14
14
  import { randomUUID } from "crypto";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  CODEX_HOOK_VAR
3
- } from "./chunk-ZDEEHFU3.js";
3
+ } from "./chunk-PTY4LXTG.js";
4
4
  import {
5
5
  connect,
6
6
  sendMessageAndAwaitAck
7
- } from "./chunk-TZBI2RVU.js";
7
+ } from "./chunk-NYGLT5G2.js";
8
8
 
9
9
  // src/cli/send.ts
10
10
  import { randomUUID } from "crypto";
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  definitionDirs,
3
3
  definitionFiles,
4
+ definitionHash,
4
5
  listRoles,
6
+ quoteScalar,
5
7
  readSmall,
6
- unquote
7
- } from "./chunk-AVKFQSRP.js";
8
+ scalarValue
9
+ } from "./chunk-II6VRGLU.js";
8
10
  import {
9
11
  SeatsSchema,
10
12
  TeamNameSchema
11
- } from "./chunk-ARB4BKZJ.js";
13
+ } from "./chunk-QRD74KPO.js";
12
14
  import {
13
15
  log
14
16
  } from "./chunk-6IYPRUQG.js";
@@ -19,7 +21,7 @@ import {
19
21
  // src/daemon/teams.ts
20
22
  import { existsSync, writeFileSync, mkdirSync, renameSync } from "fs";
21
23
  import { join } from "path";
22
- var scalar = (raw) => unquote(raw.replace(/\s+#.*$/, "").trim());
24
+ var scalar = scalarValue;
23
25
  function flowMap(raw) {
24
26
  const inner = raw.trim().replace(/^\{/, "").replace(/\}$/, "");
25
27
  const out = {};
@@ -102,6 +104,22 @@ function parseTemplate(id, text, source, path) {
102
104
  }
103
105
  return { id, name: name.data, seats: seats.data, source, path };
104
106
  }
107
+ function loadTemplate(id, path, source, problems) {
108
+ let t;
109
+ try {
110
+ const text = readSmall(path);
111
+ t = parseTemplate(id, text, source, path);
112
+ if (typeof t !== "string") t = { ...t, hash: definitionHash(text) };
113
+ } catch (e) {
114
+ t = e.message;
115
+ }
116
+ if (typeof t === "string") {
117
+ log(`team ${path} skipped: ${t}`);
118
+ problems.push({ path, reason: t });
119
+ return void 0;
120
+ }
121
+ return t;
122
+ }
105
123
  function listTemplates(cwd) {
106
124
  const templates = /* @__PURE__ */ new Map();
107
125
  const problems = [];
@@ -109,18 +127,8 @@ function listTemplates(cwd) {
109
127
  for (const path of definitionFiles(dir, [".yaml", ".yml"])) {
110
128
  const id = path.slice(dir.length + 1).replace(/\.ya?ml$/, "");
111
129
  if (templates.has(id)) continue;
112
- let t;
113
- try {
114
- t = parseTemplate(id, readSmall(path), source, path);
115
- } catch (e) {
116
- t = e.message;
117
- }
118
- if (typeof t === "string") {
119
- log(`team ${path} skipped: ${t}`);
120
- problems.push({ path, reason: t });
121
- continue;
122
- }
123
- templates.set(id, t);
130
+ const t = loadTemplate(id, path, source, problems);
131
+ if (t) templates.set(id, t);
124
132
  }
125
133
  }
126
134
  return { templates: [...templates.values()].sort((a, b) => a.id.localeCompare(b.id)), problems };
@@ -147,22 +155,44 @@ function templateId(name) {
147
155
  const id = name.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
148
156
  return id || "team";
149
157
  }
150
- var yamlScalar = (v) => /^[\w./@:+-]+$/.test(v) && !/^(true|false|null|yes|no|~)$/i.test(v) ? v : JSON.stringify(v);
158
+ var SEAT_KEYS = ["role", "tool", "model", "effort", "name"];
159
+ function templateText(name, seats) {
160
+ const q = (v) => v.includes(" ") ? null : quoteScalar(v);
161
+ const head = q(name);
162
+ if (head === null) return null;
163
+ const lines = [`name: ${head}`, "seats:"];
164
+ for (const s of seats) {
165
+ let first = true;
166
+ for (const k of SEAT_KEYS) {
167
+ if (s[k] === void 0) continue;
168
+ const v = q(String(s[k]));
169
+ if (v === null) return null;
170
+ lines.push(`${first ? " - " : " "}${k}: ${v}`);
171
+ first = false;
172
+ }
173
+ }
174
+ return `${lines.join("\n")}
175
+ `;
176
+ }
151
177
  var templatePath = (name, dir) => join(dir, `${templateId(name)}.yaml`);
152
178
  var templateExists = (name, dir = join(ledgeDir(), "teams")) => existsSync(templatePath(name, dir));
153
179
  function saveTemplate(name, seats, dir = join(ledgeDir(), "teams")) {
154
180
  const path = templatePath(name, dir);
155
- const lines = [`name: ${yamlScalar(name)}`, "seats:", ...seats.map((s) => ` - { ${Object.entries(s).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}: ${yamlScalar(String(v))}`).join(", ")} }`), ""];
181
+ const text = templateText(name, seats);
182
+ if (text === null) throw new Error("a team name or seat value cannot be written as YAML");
156
183
  mkdirSync(dir, { recursive: true });
157
184
  const tmp = `${path}.tmp`;
158
- writeFileSync(tmp, lines.join("\n"));
185
+ writeFileSync(tmp, text);
159
186
  renameSync(tmp, path);
160
187
  return path;
161
188
  }
162
189
 
163
190
  export {
191
+ loadTemplate,
164
192
  resolveSeats,
165
193
  listDefinitions,
194
+ templateId,
195
+ templateText,
166
196
  templateExists,
167
197
  saveTemplate
168
198
  };
@@ -2,7 +2,7 @@ import {
2
2
  ROLE_LABEL_MAX,
3
3
  ROLE_PROMPT_MAX,
4
4
  RoleSchema
5
- } from "./chunk-ARB4BKZJ.js";
5
+ } from "./chunk-QRD74KPO.js";
6
6
  import {
7
7
  log
8
8
  } from "./chunk-6IYPRUQG.js";
@@ -11,6 +11,7 @@ import {
11
11
  } from "./chunk-HOOHS3MX.js";
12
12
 
13
13
  // src/daemon/roles.ts
14
+ import { createHash } from "crypto";
14
15
  import { existsSync, readdirSync, readFileSync, statSync } from "fs";
15
16
  import { dirname, join, resolve } from "path";
16
17
  var FILE_MAX = 64 * 1024;
@@ -51,14 +52,31 @@ function frontMatter(text) {
51
52
  if (!m) return { fields: {}, body: src.trim() };
52
53
  const fields = {};
53
54
  for (const raw of m[1].split("\n")) {
54
- const line = raw.replace(/\s+#.*$/, "").trim();
55
+ const line = raw.trim();
55
56
  if (!line || line.startsWith("#")) continue;
56
57
  const i = line.indexOf(":");
57
- if (i <= 0) throw new Error(`front matter line without a key: ${line.slice(0, 60)}`);
58
- fields[line.slice(0, i).trim()] = unquote(line.slice(i + 1).trim());
58
+ if (i <= 0) throw new Error(`front matter line without a key: ${line.replace(/\s+#.*$/, "").slice(0, 60)}`);
59
+ fields[line.slice(0, i).trim()] = scalarValue(line.slice(i + 1));
59
60
  }
60
61
  return { fields, body: src.slice(m[0].length).trim() };
61
62
  }
63
+ function scalarValue(raw) {
64
+ const v = raw.trim();
65
+ const q = v[0];
66
+ if (q === '"' || q === "'") {
67
+ const end = v.indexOf(q, 1);
68
+ if (end > 0 && /^(\s+#.*)?$/.test(v.slice(end + 1))) return v.slice(1, end);
69
+ }
70
+ return unquote(v.replace(/(^|\s)#.*$/, "").trim());
71
+ }
72
+ function quoteScalar(v) {
73
+ if (/[\r\n]/.test(v)) return null;
74
+ if (/^[\w./@:+-]+$/.test(v) && !/^(true|false|null|yes|no|~)$/i.test(v)) return v;
75
+ if (!v.includes('"')) return `"${v}"`;
76
+ if (!v.includes("'")) return `'${v}'`;
77
+ return null;
78
+ }
79
+ var definitionHash = (text) => createHash("sha256").update(text).digest("hex").slice(0, 16);
62
80
  var unquote = (v) => v.length >= 2 && (v[0] === '"' || v[0] === "'") && v.at(-1) === v[0] ? v.slice(1, -1) : v;
63
81
  var ROLE_KEYS = /* @__PURE__ */ new Set(["label", "tool", "model", "effort", "autonomy"]);
64
82
  function parseRole(id, text, source, path) {
@@ -90,6 +108,22 @@ function parseRole(id, text, source, path) {
90
108
  }
91
109
  return r.data;
92
110
  }
111
+ function loadRole(id, path, source, problems) {
112
+ let r;
113
+ try {
114
+ const text = readSmall(path);
115
+ r = parseRole(id, text, source, path);
116
+ if (typeof r !== "string") r = { ...r, hash: definitionHash(text) };
117
+ } catch (e) {
118
+ r = e.message;
119
+ }
120
+ if (typeof r === "string") {
121
+ log(`role ${path} skipped: ${r}`);
122
+ problems.push({ path, reason: r });
123
+ return void 0;
124
+ }
125
+ return r;
126
+ }
93
127
  function listRoles(cwd) {
94
128
  const roles = /* @__PURE__ */ new Map();
95
129
  const problems = [];
@@ -101,18 +135,8 @@ function listRoles(cwd) {
101
135
  if (source === "home") roles.set(id, { ...won, shadows: path });
102
136
  continue;
103
137
  }
104
- let r;
105
- try {
106
- r = parseRole(id, readSmall(path), source, path);
107
- } catch (e) {
108
- r = e.message;
109
- }
110
- if (typeof r === "string") {
111
- log(`role ${path} skipped: ${r}`);
112
- problems.push({ path, reason: r });
113
- continue;
114
- }
115
- roles.set(id, r);
138
+ const r = loadRole(id, path, source, problems);
139
+ if (r) roles.set(id, r);
116
140
  }
117
141
  }
118
142
  return { roles: [...roles.values()].sort((a, b) => a.id.localeCompare(b.id)), problems };
@@ -122,10 +146,14 @@ function findRole(id, cwd) {
122
146
  }
123
147
 
124
148
  export {
149
+ repoRoot,
125
150
  definitionDirs,
126
151
  definitionFiles,
127
152
  readSmall,
128
- unquote,
153
+ scalarValue,
154
+ quoteScalar,
155
+ definitionHash,
156
+ loadRole,
129
157
  listRoles,
130
158
  findRole
131
159
  };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  connect
3
- } from "./chunk-TZBI2RVU.js";
3
+ } from "./chunk-NYGLT5G2.js";
4
4
  import {
5
5
  isArchived
6
- } from "./chunk-ARB4BKZJ.js";
6
+ } from "./chunk-QRD74KPO.js";
7
7
 
8
8
  // src/cli/who.ts
9
9
  import { basename } from "path";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  CODEX_HOOK_VAR
3
- } from "./chunk-ZDEEHFU3.js";
3
+ } from "./chunk-PTY4LXTG.js";
4
4
  import {
5
5
  connect
6
- } from "./chunk-TZBI2RVU.js";
6
+ } from "./chunk-NYGLT5G2.js";
7
7
  import {
8
8
  BRIEF_MAX
9
- } from "./chunk-ARB4BKZJ.js";
9
+ } from "./chunk-QRD74KPO.js";
10
10
 
11
11
  // src/cli/handover.ts
12
12
  import { randomUUID } from "crypto";
@@ -4,7 +4,7 @@ import {
4
4
  SUMMARY_MAX,
5
5
  parseServerMessage,
6
6
  readDaemonToken
7
- } from "./chunk-ARB4BKZJ.js";
7
+ } from "./chunk-QRD74KPO.js";
8
8
 
9
9
  // src/client.ts
10
10
  import WebSocket from "ws";
@@ -3,7 +3,7 @@ import {
3
3
  SESSION_KEY_VAR,
4
4
  pickName,
5
5
  sessionKey
6
- } from "./chunk-ARB4BKZJ.js";
6
+ } from "./chunk-QRD74KPO.js";
7
7
  import {
8
8
  paths
9
9
  } from "./chunk-HOOHS3MX.js";