@chalky/chalky 0.1.5 → 0.1.6
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 +8 -2
- package/agent/SYSTEM.md +2 -1
- package/agent/extensions/app/README.md +15 -11
- package/agent/extensions/app/skills/test-your-app/SKILL.md +23 -0
- package/agent/extensions/board/browser.js +5 -9
- package/agent/extensions/card/index.ts +18 -18
- package/agent/extensions/file/browser.js +46 -7
- package/agent/extensions/file/index.ts +3 -2
- package/agent/extensions/frame/README.md +2 -2
- package/agent/extensions/frame/index.ts +16 -7
- package/agent/extensions/history/index.ts +3 -1
- package/agent/extensions/note/README.md +3 -1
- package/agent/extensions/note/browser.js +33 -7
- package/agent/extensions/note/guide.md +2 -1
- package/agent/extensions/note/index.ts +36 -13
- package/agent/extensions/page/browser.js +453 -0
- package/agent/extensions/page/index.ts +70 -1
- package/agent/extensions/page/page.html +47 -0
- package/agent/extensions/page/skills/interact-with-page/SKILL.md +59 -0
- package/agent/extensions/screen/browser.js +6 -19
- package/agent/extensions/version/browser.js +9 -0
- package/agent/extensions/version/index.ts +73 -21
- package/agent/skills/design/SKILL.md +1 -1
- package/agent/skills/show-me/SKILL.md +66 -0
- package/package.json +2 -1
- package/server.ts +169 -7
- package/node_modules/xlsx/CHANGELOG.md +0 -361
- package/node_modules/xlsx/LICENSE +0 -201
- package/node_modules/xlsx/README.md +0 -41
- package/node_modules/xlsx/bin/xlsx.njs +0 -310
- package/node_modules/xlsx/bower.json +0 -22
- package/node_modules/xlsx/dist/LICENSE +0 -201
- package/node_modules/xlsx/dist/cpexcel.d.ts +0 -39
- package/node_modules/xlsx/dist/cpexcel.full.mjs +0 -1502
- package/node_modules/xlsx/dist/cpexcel.js +0 -1506
- package/node_modules/xlsx/dist/shim.min.js +0 -2
- package/node_modules/xlsx/dist/xlsx.core.min.js +0 -18
- package/node_modules/xlsx/dist/xlsx.core.min.map +0 -1
- package/node_modules/xlsx/dist/xlsx.extendscript.js +0 -28259
- package/node_modules/xlsx/dist/xlsx.full.min.js +0 -24
- package/node_modules/xlsx/dist/xlsx.full.min.map +0 -1
- package/node_modules/xlsx/dist/xlsx.mini.min.js +0 -10
- package/node_modules/xlsx/dist/xlsx.mini.min.map +0 -1
- package/node_modules/xlsx/dist/xlsx.zahl.js +0 -4
- package/node_modules/xlsx/dist/xlsx.zahl.mjs +0 -2
- package/node_modules/xlsx/dist/zahl.d.ts +0 -4
- package/node_modules/xlsx/package.json +0 -183
- package/node_modules/xlsx/types/index.d.ts +0 -1065
- package/node_modules/xlsx/types/tsconfig.json +0 -15
- package/node_modules/xlsx/xlsx.js +0 -28103
- package/node_modules/xlsx/xlsx.mjs +0 -28228
- package/node_modules/xlsx/xlsxworker.js +0 -14
package/server.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// - keeps one pi AgentSession per agent (session name = agent name; saved under data/sessions/<agent>);
|
|
6
6
|
// - keeps the rule for the version history (host.history) and serves /recover, going back to a working version
|
|
7
7
|
// when an agent broke the page (the safety net);
|
|
8
|
+
// - brings a new release of this package into the home's agent/, merged with what the agents changed (host.update);
|
|
8
9
|
// - hands each agent's pi events to the extensions that asked (host.eventHandlers), and tells them when a page
|
|
9
10
|
// opens (host.connectHandlers). The page extension turns pi's messages into the page's and replays them.
|
|
10
11
|
// Extensions reach the host through globalThis.chalky (pi loads them with jiti, so they don't share our imports).
|
|
@@ -17,6 +18,7 @@ import path from "node:path";
|
|
|
17
18
|
import { createAgentSession, createCodemodeExtension, createMcpExtension, createToolSearchExtension, DefaultResourceLoader, SessionManager,
|
|
18
19
|
SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
19
20
|
import git from "isomorphic-git";
|
|
21
|
+
import diff3Merge from "diff3";
|
|
20
22
|
import { WebSocketServer } from "ws";
|
|
21
23
|
|
|
22
24
|
const ROOT = import.meta.dirname; // this package: server.ts and the starting agent/
|
|
@@ -97,9 +99,9 @@ function migrate() {
|
|
|
97
99
|
.replaceAll("/ui/agents.js", "/app/agents.js").replaceAll("/ui/voice.js", "/voice/voice.js")
|
|
98
100
|
.replaceAll("/ui-api/app-data/", "/app/data/").replaceAll("/ui/apps/", "/built/apps/"));
|
|
99
101
|
}
|
|
100
|
-
migrate();
|
|
101
|
-
if (!fs.existsSync(AGENT)) startAgent(); // first run: the starting agent
|
|
102
|
+
migrate(); // (a new home's agent/ comes from the update below: the first release, merged into nothing)
|
|
102
103
|
if (HOME !== ROOT) { // HOME/agent's extensions import our dependencies: Node looks for a node_modules above them
|
|
104
|
+
fs.mkdirSync(HOME, { recursive: true }); // a new home: nothing made it yet
|
|
103
105
|
const link = path.join(HOME, "node_modules");
|
|
104
106
|
if (fs.lstatSync(link, { throwIfNoEntry: false })?.isSymbolicLink()) fs.unlinkSync(link); // again each start: the package may have moved
|
|
105
107
|
if (fs.existsSync(link)) throw new Error(`${link} is in the way: Chalky links it to ${MODULES}`);
|
|
@@ -266,19 +268,174 @@ function file(res: http.ServerResponse, p: string) {
|
|
|
266
268
|
// The version extension commits and rolls back with this; /recover too, so it works when that extension is broken.
|
|
267
269
|
// repo isomorphic-git's {fs, dir: HOME, gitdir}
|
|
268
270
|
// stage() git add -A for what inHistory keeps (.gitignore files play no part); returns the changed paths
|
|
271
|
+
// restore(oid) that version's agent/ and built/ into the folders and the index, removing files it doesn't have
|
|
272
|
+
// (the branch stays where it is; what the history doesn't keep, logins and endpoints, isn't touched)
|
|
273
|
+
// versions() the user's versions, newest first, as git.log gives them ({oid, commit}): main's own line, without
|
|
274
|
+
// the releases an update merged in (see "updates" below)
|
|
269
275
|
const REPO = { fs, dir: HOME, gitdir: path.join(DATA, "version", "git") };
|
|
270
276
|
const KEPT = { filepaths: ["agent", "built"], ignored: true, filter: inHistory }; // statusMatrix's walk: only these
|
|
277
|
+
// isomorphic-git 1.44.2 takes a file whose size and mtime (whole seconds) match the index as unchanged: a same-size
|
|
278
|
+
// change in the second after it was staged would be missed (and an update would write over it). Real git checks
|
|
279
|
+
// those "racy" files; here every file that looks unchanged is checked by its content. Its status also misses a change
|
|
280
|
+
// of the x bit alone: checked too.
|
|
271
281
|
async function stage() {
|
|
272
|
-
const changed = [];
|
|
282
|
+
const changed = [], staged = new Map<string, string>(); // the index: path -> "oid mode"
|
|
283
|
+
await git.walk({ ...REPO, trees: [git.STAGE()], map: async (f, [e]) => {
|
|
284
|
+
if (e && f !== "." && (await e.type()) === "blob") staged.set(f, `${await e.oid()} ${await e.mode()}`);
|
|
285
|
+
return true;
|
|
286
|
+
} });
|
|
287
|
+
const now = async (f: string) => { const p = path.join(HOME, f); // the file as git would stage it
|
|
288
|
+
return `${(await git.hashBlob({ object: fs.readFileSync(p) })).oid} ${fs.statSync(p).mode & 0o111 ? 0o100755 : 0o100644}`; };
|
|
273
289
|
for (const [filepath, head, workdir, index] of await git.statusMatrix({ ...REPO, ...KEPT })) {
|
|
274
|
-
if (head === 1 && workdir === 1 && index === 1) continue; // unchanged
|
|
290
|
+
if (head === 1 && workdir === 1 && index === 1 && await now(filepath) === staged.get(filepath)) continue; // unchanged
|
|
275
291
|
if (workdir === 0) { if (index !== 0) await git.remove({ ...REPO, filepath }); }
|
|
276
292
|
else await git.add({ ...REPO, filepath, force: true });
|
|
277
293
|
changed.push(filepath);
|
|
278
294
|
}
|
|
279
295
|
return changed;
|
|
280
296
|
}
|
|
281
|
-
|
|
297
|
+
// Only the folders that either version has files in: for a folder neither has (built/ before anything was made, still
|
|
298
|
+
// on disk as built/apps/), isomorphic-git 1.44.2's checkout takes it for a file to delete and throws EISDIR.
|
|
299
|
+
async function restore(oid: string) {
|
|
300
|
+
const has = async (ref: string, dir: string) => (await git.listFiles({ ...REPO, ref })).some((f) => f.startsWith(`${dir}/`));
|
|
301
|
+
const head = await git.resolveRef({ ...REPO, ref: "HEAD" });
|
|
302
|
+
const filepaths = [];
|
|
303
|
+
for (const dir of KEPT.filepaths) if (await has(oid, dir) || await has(head, dir)) filepaths.push(dir);
|
|
304
|
+
if (filepaths.length) await git.checkout({ ...REPO, ref: oid, noUpdateHead: true, force: true, filepaths });
|
|
305
|
+
}
|
|
306
|
+
Object.assign(host, { history: { repo: REPO, kept: KEPT, stage, restore } });
|
|
307
|
+
|
|
308
|
+
// ---- updates: each release of this package is a commit on the history's "package" branch, merged into main ----
|
|
309
|
+
// The package's agent/ is a release; the home's agent/ is what runs, and the agents change it. At start, a release
|
|
310
|
+
// not merged yet is committed on "package" (its agent/ only) and merged into main, file by file. The base is the
|
|
311
|
+
// release merged last (git's merge base), so for each file:
|
|
312
|
+
// only the release changed it -> the release's only the home changed it -> the home's
|
|
313
|
+
// both, in different lines -> both changes (diff3)
|
|
314
|
+
// both, in the same lines, or one side deleted it -> the home's stays; the release's goes next to it as
|
|
315
|
+
// <file>.new, and agent1 is asked to merge them (host.update.conflicts)
|
|
316
|
+
// First a "Before update" commit of unsaved changes, then one commit with both parents: the version panel undoes an
|
|
317
|
+
// update like any change. A new home is the first release merged into nothing; a home from before this has no
|
|
318
|
+
// "package" yet: its base is its "original" version (the release it started from). If the update fails, the home
|
|
319
|
+
// runs as it was and the page says why (host.update.error). Not when the home is this folder (node server.ts here).
|
|
320
|
+
// agent/mcp.json is the user's own list of MCP servers: the package never ships it, so no release brings or removes it.
|
|
321
|
+
const RELEASE = `Chalky ${JSON.parse(fs.readFileSync(path.join(ROOT, "package.json"), "utf8")).version}`;
|
|
322
|
+
const CHALKY = { name: "chalky", email: "chalky@chalky" };
|
|
323
|
+
const OWN = ["agent/mcp.json"];
|
|
324
|
+
const ref = (r: string) => git.resolveRef({ ...REPO, ref: r }).catch(() => undefined);
|
|
325
|
+
const blob = async (oid: string) => Buffer.from((await git.readBlob({ ...REPO, oid })).blob);
|
|
326
|
+
|
|
327
|
+
// The user's versions: from HEAD by first parents only (an update's first parent is the version before it; its
|
|
328
|
+
// second, the release), stopping at a release (a new home's first version comes after one). Not git.log: it walks
|
|
329
|
+
// both parents, so the releases would be listed as versions (going back to one would take the agents' changes and
|
|
330
|
+
// built/ away), the first release twice, and versions made in the same second out of order.
|
|
331
|
+
async function versions() {
|
|
332
|
+
const releases = new Set<string>(), original = await ref("refs/tags/original"); // a home from before: its "original" isn't one
|
|
333
|
+
for (let oid = await ref("package"); oid && oid !== original; oid = (await git.readCommit({ ...REPO, oid })).commit.parent[0])
|
|
334
|
+
releases.add(oid);
|
|
335
|
+
const out = [];
|
|
336
|
+
for (let oid = await ref("HEAD"); oid && !releases.has(oid); ) {
|
|
337
|
+
const c = await git.readCommit({ ...REPO, oid });
|
|
338
|
+
out.push(c);
|
|
339
|
+
oid = c.commit.parent[0];
|
|
340
|
+
}
|
|
341
|
+
return out;
|
|
342
|
+
}
|
|
343
|
+
Object.assign(host.history, { versions });
|
|
344
|
+
|
|
345
|
+
async function releaseTree(dir: string): Promise<string | null> { // the package's agent/ (what startAgent copies) as a git tree
|
|
346
|
+
const tree = [];
|
|
347
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
348
|
+
const p = path.join(dir, e.name);
|
|
349
|
+
const rel = path.relative(path.join(ROOT, "agent"), p);
|
|
350
|
+
if (!isAgentPart(rel) || OWN.includes(`agent/${rel}`)) continue;
|
|
351
|
+
if (e.isFile()) tree.push({ mode: fs.statSync(p).mode & 0o111 ? "100755" : "100644", path: e.name, type: "blob" as const,
|
|
352
|
+
oid: await git.writeBlob({ ...REPO, blob: fs.readFileSync(p) }) });
|
|
353
|
+
else if (e.isDirectory()) { const oid = await releaseTree(p); if (oid) tree.push({ mode: "040000", path: e.name, type: "tree" as const, oid }); }
|
|
354
|
+
}
|
|
355
|
+
return tree.length ? git.writeTree({ ...REPO, tree }) : null;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async function filesOf(commit?: string) { // agent/'s files in a commit: path -> {oid, mode}
|
|
359
|
+
const files = new Map<string, { oid: string; mode: number }>();
|
|
360
|
+
if (commit) await git.walk({ ...REPO, trees: [git.TREE({ ref: commit })], map: async (p, [e]) => {
|
|
361
|
+
if (p !== "." && p !== "agent" && !p.startsWith("agent/")) return null; // built/: not the release's
|
|
362
|
+
if (e && (await e.type()) === "blob") files.set(p, { oid: await e.oid(), mode: await e.mode() });
|
|
363
|
+
return true;
|
|
364
|
+
} });
|
|
365
|
+
return files;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function merge3(base: Buffer, ours: Buffer, theirs: Buffer) { // both changes, or null if they touch the same lines
|
|
369
|
+
if ([base, ours, theirs].some((b) => b.includes(0))) return null; // not text
|
|
370
|
+
const lines = (b: Buffer) => b.toString("utf8").match(/^.*(\r?\n|$)/gm) ?? [];
|
|
371
|
+
const parts = diff3Merge(lines(ours), lines(base), lines(theirs));
|
|
372
|
+
return parts.some((p: any) => p.conflict) ? null : parts.flatMap((p: any) => p.ok).join("");
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
async function update() {
|
|
376
|
+
let main = await ref("main"), pkg = await ref("package");
|
|
377
|
+
const last = pkg && (await git.readCommit({ ...REPO, oid: pkg })).commit.message.trim();
|
|
378
|
+
if (last === RELEASE && main && (await git.findMergeBase({ ...REPO, oids: [main, pkg!] }))[0] === pkg) return; // merged
|
|
379
|
+
await git.init({ ...REPO, defaultBranch: "main" }); // (does nothing if there is one)
|
|
380
|
+
if ((await stage()).length) main = await git.commit({ ...REPO, message: `Before update to ${RELEASE}`, author: CHALKY });
|
|
381
|
+
if (last !== RELEASE) {
|
|
382
|
+
const agent = await releaseTree(path.join(ROOT, "agent"));
|
|
383
|
+
const tree = await git.writeTree({ ...REPO, tree: agent ? [{ mode: "040000", path: "agent", type: "tree", oid: agent }] : [] });
|
|
384
|
+
const parent = pkg ?? (main && await ref("refs/tags/original")); // a home from before this: the release it started from
|
|
385
|
+
pkg = await git.commit({ ...REPO, ref: "refs/heads/package", tree, parent: parent ? [parent] : [], message: RELEASE, author: CHALKY });
|
|
386
|
+
}
|
|
387
|
+
const [base] = main ? await git.findMergeBase({ ...REPO, oids: [main, pkg!] }) : [];
|
|
388
|
+
const [B, O, T] = await Promise.all([base, main, pkg].map(filesOf));
|
|
389
|
+
const writes: [string, Buffer | null, number?][] = [], conflicts: string[] = []; // [path in HOME, content (null: delete), mode]
|
|
390
|
+
for (const f of new Set([...O.keys(), ...T.keys()])) {
|
|
391
|
+
if (OWN.includes(f)) continue;
|
|
392
|
+
const [b, o, t] = [B.get(f), O.get(f), T.get(f)], same = (x?: typeof b, y?: typeof b) => x?.oid === y?.oid && x?.mode === y?.mode;
|
|
393
|
+
if (same(o, t) || same(b, t)) continue; // the same, or the release didn't change it: the home's
|
|
394
|
+
if (same(b, o)) { writes.push([f, t ? await blob(t.oid) : null, t?.mode]); continue; } // only the release changed it
|
|
395
|
+
const merged = b && o && t && merge3(await blob(b.oid), await blob(o.oid), await blob(t.oid)); // (and the x bit: whose changed)
|
|
396
|
+
if (merged != null) { writes.push([f, Buffer.from(merged), b!.mode === t!.mode ? o!.mode : t!.mode]); continue; }
|
|
397
|
+
if (t) writes.push([`${f}.new`, await blob(t.oid), t.mode]);
|
|
398
|
+
conflicts.push(!o ? `${f}: you had deleted it; this release changed it (its version: ${f}.new)`
|
|
399
|
+
: !t ? `${f}: this release removed it; you had changed it (yours is kept)`
|
|
400
|
+
: `${f}: you and this release changed the same lines (its version: ${f}.new)`);
|
|
401
|
+
}
|
|
402
|
+
try { // (then saved: main moves only when every file is written)
|
|
403
|
+
for (const [f, content, mode] of writes) {
|
|
404
|
+
const p = path.join(HOME, f);
|
|
405
|
+
if (!content) { // and the folders that leaves empty
|
|
406
|
+
fs.rmSync(p, { force: true });
|
|
407
|
+
for (let d = path.dirname(p); d !== AGENT && fs.existsSync(d) && !fs.readdirSync(d).length; d = path.dirname(d)) fs.rmdirSync(d);
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
411
|
+
fs.writeFileSync(p, content);
|
|
412
|
+
if (mode) fs.chmodSync(p, mode & 0o777);
|
|
413
|
+
}
|
|
414
|
+
await stage();
|
|
415
|
+
await git.commit({ ...REPO, message: main ? `Updated to ${RELEASE}` : `Started with ${RELEASE}`, author: CHALKY,
|
|
416
|
+
parent: main ? [main, pkg!] : [pkg!] });
|
|
417
|
+
} catch (e) { // each file written goes back as main has it (contents and x bit), or away (.new files too)
|
|
418
|
+
for (const [f] of writes) {
|
|
419
|
+
const p = path.join(HOME, f), o = O.get(f);
|
|
420
|
+
try {
|
|
421
|
+
if (!o) { fs.rmSync(p, { force: true }); continue; }
|
|
422
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
423
|
+
fs.writeFileSync(p, await blob(o.oid));
|
|
424
|
+
fs.chmodSync(p, o.mode & 0o777);
|
|
425
|
+
} catch (e2) { console.error(`could not put ${f} back:`, e2); }
|
|
426
|
+
}
|
|
427
|
+
throw e;
|
|
428
|
+
}
|
|
429
|
+
const files = writes.length - writes.filter(([f]) => f.endsWith(".new")).length;
|
|
430
|
+
if (main) return { release: RELEASE, files, conflicts }; // (a new home: nothing to tell)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (HOME !== ROOT) try { Object.assign(host, { update: await update() }); } catch (e: any) { // run as it was: main didn't move
|
|
434
|
+
console.error(`update to ${RELEASE} failed:`, e);
|
|
435
|
+
const main = await ref("main");
|
|
436
|
+
if (main) await restore(main).catch((e) => console.error("could not put agent/ and built/ back as main has them:", e)); // and the index
|
|
437
|
+
Object.assign(host, { update: { release: RELEASE, error: String(e?.message ?? e) } });
|
|
438
|
+
}
|
|
282
439
|
|
|
283
440
|
// ---- recovery: the safety net for when an agent breaks the page (or the version extension, so its panel) ----
|
|
284
441
|
// Here, not in an extension, so agents can't break it too. Plain HTML forms, no script: it works whatever agent/ holds.
|
|
@@ -292,7 +449,7 @@ const esc = (s: string) => s.replace(/[&<>"]/g, (c) => `&#${c.charCodeAt(0)};`);
|
|
|
292
449
|
|
|
293
450
|
async function recoverPage(res: http.ServerResponse) {
|
|
294
451
|
// the history's folder comes before its first commit: right after a start there may be no versions yet
|
|
295
|
-
const log =
|
|
452
|
+
const log = await versions(); // (none yet: [])
|
|
296
453
|
const rows = log.map(({ oid, commit: c }, i) => `<tr><td>${new Date(c.author.timestamp * 1000).toLocaleString()}</td>
|
|
297
454
|
<td>${esc(c.author.name)}</td><td>${esc(c.message.split("\n")[0])}</td>
|
|
298
455
|
<td>${fs.existsSync(path.join(DATA, "version", "shots", `${oid}.png`)) ? "the page worked" : ""}</td>
|
|
@@ -315,7 +472,7 @@ async function recover(sha: string, res: http.ServerResponse) {
|
|
|
315
472
|
const subject = `${sha.slice(0, 7)} ${(await git.readCommit({ ...REPO, oid: sha })).commit.message.split("\n")[0]}`;
|
|
316
473
|
await stage();
|
|
317
474
|
try { await git.commit({ ...REPO, message: "uncommitted changes before recovery", author, disallowEmpty: true }); } catch {}
|
|
318
|
-
await
|
|
475
|
+
await restore(sha);
|
|
319
476
|
const files = await stage();
|
|
320
477
|
for (const f of files) for (let d = path.dirname(f); !["agent", "built", "."].includes(d); d = path.dirname(d)) { // folders it emptied
|
|
321
478
|
try { fs.rmdirSync(path.join(HOME, d)); } catch { break; }
|
|
@@ -366,6 +523,11 @@ new WebSocketServer({ server, path: "/ws" }).on("connection", (sock) => {
|
|
|
366
523
|
|
|
367
524
|
// agent1, then every agent saved by an earlier run (their conversations come back from their session files)
|
|
368
525
|
await host.createAgent("agent1", "the user's main agent");
|
|
526
|
+
const conflicts: string[] = (host as any).update?.conflicts ?? []; // the update's files to merge: agent1's task
|
|
527
|
+
if (conflicts.length) host.send("chalky", "agent1", `Chalky was updated to ${(host as any).update.release}. These files `
|
|
528
|
+
+ `were changed both by you (or another agent) and by the update, so yours were kept:\n${conflicts.map((c) => `- ${c}`).join("\n")}\n`
|
|
529
|
+
+ "For each, read both versions and make one that keeps what the user had and adds what the update brings, then "
|
|
530
|
+
+ "delete the .new file. If you can't tell what the user would want, keep theirs and tell them what the update had.");
|
|
369
531
|
for (const name of fs.readdirSync(path.join(DATA, "sessions")).filter((n) => n !== "agent1")) {
|
|
370
532
|
const { role, app } = JSON.parse(fs.readFileSync(path.join(DATA, "sessions", name, "role.json"), "utf8"));
|
|
371
533
|
await host.createAgent(name, role, app);
|
|
@@ -1,361 +0,0 @@
|
|
|
1
|
-
# CHANGELOG
|
|
2
|
-
|
|
3
|
-
This log is intended to keep track of backwards-incompatible changes, including
|
|
4
|
-
but not limited to API changes and file location changes. Minor behavioral
|
|
5
|
-
changes may not be included if they are not expected to break existing code.
|
|
6
|
-
|
|
7
|
-
## v0.20.3
|
|
8
|
-
|
|
9
|
-
* Correct parsing of NUMBERS and ODS merge cells (h/t @s-ashwin)
|
|
10
|
-
* More precise treatment of infinite and NaN values
|
|
11
|
-
* XLML Streaming Write
|
|
12
|
-
* Parse `Int8Array` objects (for compatibility with JS engines in Java)
|
|
13
|
-
* CSV Export only quote leading ID (h/t @lako12)
|
|
14
|
-
|
|
15
|
-
## v0.20.2
|
|
16
|
-
|
|
17
|
-
* Reworked parsing methods to avoid slow regexes (CVE-2024-22363)
|
|
18
|
-
* HTML properly encode data-v attribute
|
|
19
|
-
* SYLK read and write error cells
|
|
20
|
-
|
|
21
|
-
## v0.20.1
|
|
22
|
-
|
|
23
|
-
* `init` use packaged test files to work around GitHub breaking changes
|
|
24
|
-
* SSF date code rounding to 15 decimal digits (h/t @davidtamaki)
|
|
25
|
-
* `sheet_to_json` force UTC interpretation for formatted strings (h/t @Blanay)
|
|
26
|
-
* QPW extract result of string formula
|
|
27
|
-
* XLSX parse non-compliant merge cell expressions
|
|
28
|
-
* NUMBERS correctly handle rows omitted from official exports
|
|
29
|
-
* DBF parse empty logical field (h/t @Roman91)
|
|
30
|
-
* `dense` option added to types
|
|
31
|
-
* package.json add mini and core scripts to export map (h/t @stof)
|
|
32
|
-
|
|
33
|
-
## v0.20.0
|
|
34
|
-
|
|
35
|
-
* Use UTC interpretation of Date objects for date cells (potentially breaking)
|
|
36
|
-
* API functions support UTC and local time value interpretations
|
|
37
|
-
* Export `NaN` values to `#NUM!` and infinite values to `#DIV/0!`
|
|
38
|
-
|
|
39
|
-
## v0.19.3
|
|
40
|
-
|
|
41
|
-
* XLSX Ensure comment address is valid (h/t @slonser)
|
|
42
|
-
* Enforce Excel worksheet name restrictions
|
|
43
|
-
* Fixed "Prototype Pollution" vulnerability (CVE-2023-30533)
|
|
44
|
-
|
|
45
|
-
## v0.19.2
|
|
46
|
-
|
|
47
|
-
* XLSX proper decoding of hyperlinks (h/t @tw-yaxu)
|
|
48
|
-
* XLSX ignore unexpected attributes in rich text (h/t @colin4)
|
|
49
|
-
* `sheet_to_json` type fix (h/t @chsdwn)
|
|
50
|
-
|
|
51
|
-
## v0.19.1
|
|
52
|
-
|
|
53
|
-
* Fixed types issue in strict mode (h/t @younes-io)
|
|
54
|
-
* Numbers 12.2 parsing skip ActivityStream.iwa
|
|
55
|
-
|
|
56
|
-
## v0.19.0
|
|
57
|
-
|
|
58
|
-
* XLSX export hyperlinks compatible with google sheets (h/t Evan Bovie)
|
|
59
|
-
* NUMBERS export multiple sheets, full worksheet range
|
|
60
|
-
* formalized `dense` mode
|
|
61
|
-
|
|
62
|
-
## v0.18.12
|
|
63
|
-
|
|
64
|
-
* `package.json` added types in `exports` structure
|
|
65
|
-
* uncapped NUMBERS single-sheet single-table export
|
|
66
|
-
* DBF export records using supported codepages
|
|
67
|
-
|
|
68
|
-
## v0.18.11
|
|
69
|
-
|
|
70
|
-
* Base64 input ignore data URI wrapper
|
|
71
|
-
* Parse ZIP files that use ZIP64 extended information field
|
|
72
|
-
* More precise handling of time-only values
|
|
73
|
-
* Threaded Comment fallback text for older Excel
|
|
74
|
-
|
|
75
|
-
## v0.18.10
|
|
76
|
-
|
|
77
|
-
* `exports` field in package.json to satiate ViteJS and newer tooling
|
|
78
|
-
* JSC (Safari / Bun) perf, see <https://bugs.webkit.org/show_bug.cgi?id=243148>
|
|
79
|
-
* workbook `bookType` property to denote the origin format when parsed from file
|
|
80
|
-
* XLSX force export of stub cells with number formats when `sheetStubs` is set
|
|
81
|
-
|
|
82
|
-
## v0.18.9
|
|
83
|
-
|
|
84
|
-
* XLSX / ODS write defined names
|
|
85
|
-
* sync defined names to AutoFilter setting on export
|
|
86
|
-
* 1904 date system setting properly roundtripped
|
|
87
|
-
* ODS read/write number formats
|
|
88
|
-
|
|
89
|
-
## v0.18.8
|
|
90
|
-
|
|
91
|
-
* Plaintext parsing of dateless meridien time values (`1:23:45 PM`)
|
|
92
|
-
* Legacy format (SYLK / WK# / Multiplan) minutiae
|
|
93
|
-
|
|
94
|
-
## v0.18.7
|
|
95
|
-
|
|
96
|
-
* Normalized handling of `\r` and `\n` newline characters
|
|
97
|
-
|
|
98
|
-
## v0.18.6
|
|
99
|
-
|
|
100
|
-
* Removed all npm dependencies
|
|
101
|
-
* Auto-correct bad Google Sheets format `d.m`
|
|
102
|
-
* NUMBERS write merge cells, cells up to column "ALL"
|
|
103
|
-
|
|
104
|
-
## v0.18.5
|
|
105
|
-
|
|
106
|
-
* Enabled `sideEffects: false` in package.json
|
|
107
|
-
* Basic NUMBERS write support
|
|
108
|
-
|
|
109
|
-
## v0.18.4
|
|
110
|
-
|
|
111
|
-
* CSV output omits trailing record separator
|
|
112
|
-
* Properly terminate NodeJS Streams
|
|
113
|
-
* DBF preserve column types on import and use when applicable on export
|
|
114
|
-
|
|
115
|
-
## v0.18.3
|
|
116
|
-
|
|
117
|
-
* Removed references to `require` and `process` in browser builds
|
|
118
|
-
|
|
119
|
-
## v0.18.2
|
|
120
|
-
|
|
121
|
-
* Hotfix for unicode processing of XLSX exports
|
|
122
|
-
|
|
123
|
-
## v0.18.1
|
|
124
|
-
|
|
125
|
-
* Removed Node ESM build script and folded into standard ESM build
|
|
126
|
-
* Removed undocumented aliases including `make_formulae` and `get_formulae`
|
|
127
|
-
|
|
128
|
-
## v0.18.0
|
|
129
|
-
|
|
130
|
-
* Browser scripts only expose `XLSX` variable
|
|
131
|
-
* Module no longer ships with `dist/jszip.js` browser script
|
|
132
|
-
|
|
133
|
-
## v0.17.4
|
|
134
|
-
|
|
135
|
-
* CLI script moved to `xlsx-cli` package
|
|
136
|
-
|
|
137
|
-
## v0.17.3
|
|
138
|
-
|
|
139
|
-
* `window.XLSX` explicit assignment to satiate LWC
|
|
140
|
-
* CSV Proper formatting of errors
|
|
141
|
-
* HTML emit data-\* attributes
|
|
142
|
-
|
|
143
|
-
## v0.17.2
|
|
144
|
-
|
|
145
|
-
* Browser and Node optional ESM support
|
|
146
|
-
* DSV correct handling of bare quotes (h/t @bgamrat)
|
|
147
|
-
|
|
148
|
-
## v0.17.1
|
|
149
|
-
|
|
150
|
-
* `XLSB` writer uses short cell form when viable
|
|
151
|
-
|
|
152
|
-
## 0.17.0:
|
|
153
|
-
|
|
154
|
-
* mini build includes ODS parse/write support
|
|
155
|
-
* DBF explicitly cap worksheet to 1<<20 rows
|
|
156
|
-
* XLS throw errors on truncated records
|
|
157
|
-
|
|
158
|
-
## v0.16.2
|
|
159
|
-
|
|
160
|
-
* Disabled `PRN` parsing by default (better support for CSV without delimeters)
|
|
161
|
-
|
|
162
|
-
## v0.16.1
|
|
163
|
-
|
|
164
|
-
* skip empty custom property tags if data is absent (fixes DocSecurity issue)
|
|
165
|
-
* HTML output add raw value, type, number format
|
|
166
|
-
* DOM parse look for `v` / `t` / `z` attributes when determining value
|
|
167
|
-
* double quotes in properties escaped using `_x0022_`
|
|
168
|
-
* changed AMD structure for NetSuite and other RequireJS implementations
|
|
169
|
-
- `encode_cell` and `decode_cell` do not rely on `encode_col` / `decode_col`
|
|
170
|
-
|
|
171
|
-
## v0.16.0
|
|
172
|
-
|
|
173
|
-
* Date handling changed
|
|
174
|
-
* XLML certain tag tests are now case insensitive
|
|
175
|
-
* Fixed potentially vulnerable regular expressions
|
|
176
|
-
|
|
177
|
-
## v0.15.6
|
|
178
|
-
|
|
179
|
-
* CFB prevent infinite loop
|
|
180
|
-
* ODS empty cells marked as stub (type "z")
|
|
181
|
-
* `cellStyles` option implies `sheetStubs`
|
|
182
|
-
|
|
183
|
-
## v0.15.5
|
|
184
|
-
|
|
185
|
-
* `sheets` parse option to specify which sheets to parse
|
|
186
|
-
|
|
187
|
-
## v0.15.4
|
|
188
|
-
|
|
189
|
-
* AOA utilities properly preserve number formats
|
|
190
|
-
* Number formats captured in stub cells
|
|
191
|
-
|
|
192
|
-
## v0.15.3
|
|
193
|
-
|
|
194
|
-
* Properties and Custom Properties properly XML-encoded
|
|
195
|
-
|
|
196
|
-
## v0.15.2
|
|
197
|
-
|
|
198
|
-
- `sheet_get_cell` utility function
|
|
199
|
-
- `sheet_to_json` explicitly support `null` as alias for default behavior
|
|
200
|
-
- `encode_col` throw on negative column index
|
|
201
|
-
- HTML properly handle whitespace around tags in a run
|
|
202
|
-
- HTML use `id` option on write
|
|
203
|
-
- Files starting with `0x09` followed by a display character are now TSV files
|
|
204
|
-
- XLS parse references col/row indices mod by the correct number for BIFF ver
|
|
205
|
-
- XLSX comments moved to avoid overlapping cell
|
|
206
|
-
- XLSB outline level
|
|
207
|
-
- AutoFilter update `_FilterDatabase` defined name on write
|
|
208
|
-
- XLML skip CDATA blocks
|
|
209
|
-
|
|
210
|
-
## v0.15.1 (2019-08-14)
|
|
211
|
-
|
|
212
|
-
* XLSX ignore XML artifacts
|
|
213
|
-
* HTML capture and persist merges
|
|
214
|
-
|
|
215
|
-
## v0.15.0
|
|
216
|
-
|
|
217
|
-
* `dist/xlsx.mini.min.js` mini build with XLSX read/write and some utilities
|
|
218
|
-
* Removed legacy conversion utility functions
|
|
219
|
-
|
|
220
|
-
## v0.14.5
|
|
221
|
-
|
|
222
|
-
* XLS PtgNameX lookup
|
|
223
|
-
* XLS always create stub cells for blank cells with comments
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
## v0.14.4
|
|
227
|
-
|
|
228
|
-
* Better treatment of `skipHidden` in CSV output
|
|
229
|
-
* Ignore CLSID in XLS
|
|
230
|
-
* SYLK 7-bit character encoding
|
|
231
|
-
* SYLK and DBF codepage support
|
|
232
|
-
|
|
233
|
-
## v0.14.3
|
|
234
|
-
|
|
235
|
-
* Proper shifting of addresses in Shared Formulae
|
|
236
|
-
|
|
237
|
-
## v0.14.2
|
|
238
|
-
|
|
239
|
-
* Proper XML encoding of comments
|
|
240
|
-
|
|
241
|
-
## v0.14.1
|
|
242
|
-
|
|
243
|
-
* raw cell objects can be passed to `sheet_add_aoa`
|
|
244
|
-
* `_FilterDatabase` fix for AutoFilter-related crashes
|
|
245
|
-
* `stream.to_json` doesn't end up accidentally scanning to max row
|
|
246
|
-
|
|
247
|
-
## 0.14.0 (2018-09-06)
|
|
248
|
-
|
|
249
|
-
* `sheet_to_json` default flipped to `raw: true`
|
|
250
|
-
|
|
251
|
-
## 0.13.5 (2018-08-25)
|
|
252
|
-
|
|
253
|
-
* HTML output generates `<br/>` instead of encoded newline character
|
|
254
|
-
|
|
255
|
-
## 0.13.2 (2018-07-08)
|
|
256
|
-
|
|
257
|
-
* Buffer.from shim replaced, will not be defined in node `<=0.12`
|
|
258
|
-
|
|
259
|
-
## 0.13.0 (2018-06-01)
|
|
260
|
-
|
|
261
|
-
* Library reshaped to support AMD out of the box
|
|
262
|
-
|
|
263
|
-
## 0.12.11 (2018-04-27)
|
|
264
|
-
|
|
265
|
-
* XLS/XLSX/XLSB range truncation (errors in `WTF` mode)
|
|
266
|
-
|
|
267
|
-
## 0.12.4 (2018-03-04)
|
|
268
|
-
|
|
269
|
-
* `JSZip` renamed to `JSZipSync`
|
|
270
|
-
|
|
271
|
-
## 0.12.0 (2018-02-08)
|
|
272
|
-
|
|
273
|
-
* Extendscript target script in NPM package
|
|
274
|
-
|
|
275
|
-
## 0.11.19 (2018-02-03)
|
|
276
|
-
|
|
277
|
-
* Error on empty workbook
|
|
278
|
-
|
|
279
|
-
## 0.11.16 (2017-12-30)
|
|
280
|
-
|
|
281
|
-
* XLS ANSI/CP separation
|
|
282
|
-
* 'array' write type and ArrayBuffer processing
|
|
283
|
-
|
|
284
|
-
## 0.11.6 (2017-10-16)
|
|
285
|
-
|
|
286
|
-
* Semicolon-delimited files are detected
|
|
287
|
-
|
|
288
|
-
## 0.11.5 (2017-09-30)
|
|
289
|
-
|
|
290
|
-
* Bower main script shifted to full version
|
|
291
|
-
* 'binary' / 'string' encoding
|
|
292
|
-
|
|
293
|
-
## 0.11.3 (2017-08-19)
|
|
294
|
-
|
|
295
|
-
* XLS cell ixfe/XF removed
|
|
296
|
-
|
|
297
|
-
## 0.11.0 (2017-07-31)
|
|
298
|
-
|
|
299
|
-
* Strip `require` statements from minified version
|
|
300
|
-
* minifier mangler enabled
|
|
301
|
-
|
|
302
|
-
## 0.10.9 (2017-07-28)
|
|
303
|
-
|
|
304
|
-
* XLML/HTML resolution logic looks further into the data stream to decide type
|
|
305
|
-
* Errors thrown on suspected RTF files
|
|
306
|
-
|
|
307
|
-
## 0.10.5 (2017-06-09)
|
|
308
|
-
|
|
309
|
-
* HTML Table output header/footer should not include `<table>` tag
|
|
310
|
-
|
|
311
|
-
## 0.10.2 (2017-05-16)
|
|
312
|
-
|
|
313
|
-
* Dates are converted to numbers by default (set `cellDates:true` to emit Dates)
|
|
314
|
-
* Module does not export CFB
|
|
315
|
-
|
|
316
|
-
## 0.9.10 (2017-04-08)
|
|
317
|
-
|
|
318
|
-
* `--perf` renamed to `--read-only`
|
|
319
|
-
|
|
320
|
-
## 0.9.9 (2017-04-03)
|
|
321
|
-
|
|
322
|
-
* default output format changed to XLSB
|
|
323
|
-
* comment text line endings are now normalized
|
|
324
|
-
* errors thrown on write when worksheets have invalid names
|
|
325
|
-
|
|
326
|
-
## 0.9.7 (2017-03-28)
|
|
327
|
-
|
|
328
|
-
* XLS legacy `!range` field removed
|
|
329
|
-
* Hyperlink tooltip is stored in the `Tooltip` field
|
|
330
|
-
|
|
331
|
-
## 0.9.6 (2017-03-25)
|
|
332
|
-
|
|
333
|
-
* `sheet_to_json` now passes `null` values when `raw` is set to `true`
|
|
334
|
-
* `sheet_to_json` treats `null` stub cells as values in conjunction with `raw`
|
|
335
|
-
|
|
336
|
-
## 0.9.5 (2017-03-22)
|
|
337
|
-
|
|
338
|
-
* `cellDates` affects parsing in non-XLSX formats
|
|
339
|
-
|
|
340
|
-
## 0.9.3 (2017-03-15)
|
|
341
|
-
|
|
342
|
-
* XLML property names are more closely mapped to the XLSX equivalent
|
|
343
|
-
* Stub cells are now cell type `z`
|
|
344
|
-
|
|
345
|
-
## 0.9.2 (2017-03-13)
|
|
346
|
-
|
|
347
|
-
* Removed stale TypeScript definition files. Flowtype comments are used in the
|
|
348
|
-
`xlsx.flow.js` source and stripped to produce `xlsx.js`.
|
|
349
|
-
* sed usage reworked to support GNU sed in-place form. BSD sed seems to work,
|
|
350
|
-
but the build script has not been tested on other sed variants:
|
|
351
|
-
|
|
352
|
-
```bash
|
|
353
|
-
$ sed -i.ext [...] # GNU
|
|
354
|
-
$ sed -i .ext [...] # bsd
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
## 0.9.0 (2017-03-09)
|
|
358
|
-
|
|
359
|
-
* Removed ods.js source. The xlsx.js source absorbed the ODS logic and exposes
|
|
360
|
-
the ODS variable, so projects should remove references to ods.js
|
|
361
|
-
|