@nyte-ai/host 0.0.0-stage → 0.0.19
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/LICENSE +21 -0
- package/README.md +6 -2
- package/THIRD-PARTY-NOTICES.md +866 -0
- package/dist/chunks/canvas-preview-0cmbkp2j.js +65 -0
- package/dist/chunks/canvas-preview-0nq75h9k.js +7 -0
- package/dist/chunks/canvas-preview-11nadadc.js +241 -0
- package/dist/chunks/canvas-preview-1sq7z9jq.js +17 -0
- package/dist/chunks/canvas-preview-2jwbe14k.js +130 -0
- package/dist/chunks/canvas-preview-2zdyh9ny.js +26 -0
- package/dist/chunks/canvas-preview-31w7xm8z.js +34 -0
- package/dist/chunks/canvas-preview-4b6sayhg.js +295 -0
- package/dist/chunks/canvas-preview-4e0pxa32.js +63 -0
- package/dist/chunks/canvas-preview-518dh8by.js +169 -0
- package/dist/chunks/canvas-preview-55s0y68g.js +387 -0
- package/dist/chunks/canvas-preview-5ekjx6sw.js +613 -0
- package/dist/chunks/canvas-preview-5mex725c.js +14 -0
- package/dist/chunks/canvas-preview-5z63am63.js +295 -0
- package/dist/chunks/canvas-preview-65xqjw7f.js +20 -0
- package/dist/chunks/canvas-preview-69fkk9yn.js +95 -0
- package/dist/chunks/canvas-preview-8xc0vn7v.js +458 -0
- package/dist/chunks/canvas-preview-9aqczacs.js +73 -0
- package/dist/chunks/canvas-preview-af86jz8t.js +141 -0
- package/dist/chunks/canvas-preview-aq5j4p25.js +240 -0
- package/dist/chunks/canvas-preview-b2v8wfnz.js +36 -0
- package/dist/chunks/canvas-preview-befkjea2.js +60 -0
- package/dist/chunks/canvas-preview-bxnqt8cd.js +103 -0
- package/dist/chunks/canvas-preview-cawy6vbz.js +352 -0
- package/dist/chunks/canvas-preview-crmzxxt8.js +518 -0
- package/dist/chunks/canvas-preview-drctegz4.js +591 -0
- package/dist/chunks/canvas-preview-e3vnkkc5.js +134 -0
- package/dist/chunks/canvas-preview-ec2mt7es.js +108 -0
- package/dist/chunks/canvas-preview-fxa0rfb0.js +61 -0
- package/dist/chunks/canvas-preview-g5fkjs34.js +598 -0
- package/dist/chunks/canvas-preview-jeddjex8.js +166 -0
- package/dist/chunks/canvas-preview-k1yg4fgp.js +571 -0
- package/dist/chunks/canvas-preview-kdqgrstc.js +194 -0
- package/dist/chunks/canvas-preview-kn7kvbfj.js +12 -0
- package/dist/chunks/canvas-preview-kp75gb63.js +141 -0
- package/dist/chunks/canvas-preview-mgcx2b2p.js +271 -0
- package/dist/chunks/canvas-preview-n2a35zv5.js +81 -0
- package/dist/chunks/canvas-preview-pkzqg96v.js +63 -0
- package/dist/chunks/canvas-preview-rp4x6y1h.js +144 -0
- package/dist/chunks/canvas-preview-s94ebwf5.js +112 -0
- package/dist/chunks/canvas-preview-skzwvw4d.js +23 -0
- package/dist/chunks/canvas-preview-srgfpdmf.js +60 -0
- package/dist/chunks/canvas-preview-tjhabynd.js +252 -0
- package/dist/chunks/canvas-preview-tnqe7k0b.js +374 -0
- package/dist/chunks/canvas-preview-vaatfznm.js +189 -0
- package/dist/chunks/canvas-preview-vm9zdp2t.js +398 -0
- package/dist/chunks/canvas-preview-w54ymtb3.js +272 -0
- package/dist/chunks/canvas-preview-wg80rbc2.js +46 -0
- package/dist/chunks/canvas-preview-y5y6ghaw.js +125 -0
- package/dist/chunks/canvas-preview-ycepb05s.js +176 -0
- package/dist/chunks/canvas-preview-yjz0f7n4.js +50 -0
- package/dist/chunks/canvas-preview-zaaj99wd.js +244 -0
- package/dist/src/canvas-preview.d.ts +29 -0
- package/dist/src/canvas-preview.js +271 -0
- package/dist/src/credentials.d.ts +44 -0
- package/dist/src/credentials.js +10 -0
- package/dist/src/deploy/cloudflare/worker.d.ts +50 -0
- package/dist/src/deploy/cloudflare/worker.js +196 -0
- package/dist/src/deploy/vercel/nitro.config.d.ts +2 -0
- package/dist/src/deploy/vercel/nitro.config.js +30 -0
- package/dist/src/deploy/vercel/server/routes/[...].d.ts +2 -0
- package/dist/src/deploy/vercel/server/routes/[...].js +18 -0
- package/dist/src/deploy/vercel/server/utils/host.d.ts +13 -0
- package/dist/src/deploy/vercel/server/utils/host.js +7 -0
- package/dist/src/deploy/vercel/server/utils/repair.d.ts +1 -0
- package/dist/src/deploy/vercel/server/utils/repair.js +6 -0
- package/dist/src/deploy/vercel/server/utils/step.d.ts +10 -0
- package/dist/src/deploy/vercel/server/utils/step.js +6 -0
- package/dist/src/deploy/vercel/server/workflows/drive.d.ts +14 -0
- package/dist/src/deploy/vercel/server/workflows/drive.js +13 -0
- package/dist/src/durable-object.d.ts +14 -0
- package/dist/src/durable-object.js +231 -0
- package/dist/src/hash.d.ts +1 -0
- package/dist/src/hash.js +6 -0
- package/dist/src/identity-key.d.ts +11 -0
- package/dist/src/identity-key.js +9 -0
- package/dist/src/identity.d.ts +12 -0
- package/dist/src/identity.js +6 -0
- package/dist/src/images/exif.d.ts +1 -0
- package/dist/src/images/exif.js +6 -0
- package/dist/src/images/node.d.ts +37 -0
- package/dist/src/images/node.js +12 -0
- package/dist/src/images/photon.d.ts +3 -0
- package/dist/src/images/photon.js +7 -0
- package/dist/src/images/worker.d.ts +1 -0
- package/dist/src/images/worker.js +23 -0
- package/dist/src/index.d.ts +20 -0
- package/dist/src/index.js +121 -0
- package/dist/src/key-file.d.ts +1 -0
- package/dist/src/key-file.js +7 -0
- package/dist/src/listen-fetch.d.ts +8 -0
- package/dist/src/listen-fetch.js +9 -0
- package/dist/src/listen.d.ts +4 -0
- package/dist/src/listen.js +10 -0
- package/dist/src/local/command.d.ts +20 -0
- package/dist/src/local/command.js +12 -0
- package/dist/src/local/feed.d.ts +7 -0
- package/dist/src/local/feed.js +6 -0
- package/dist/src/local/files.d.ts +18 -0
- package/dist/src/local/files.js +13 -0
- package/dist/src/local/git-watch.d.ts +15 -0
- package/dist/src/local/git-watch.js +7 -0
- package/dist/src/local/git.d.ts +5 -0
- package/dist/src/local/git.js +13 -0
- package/dist/src/local/github.d.ts +30 -0
- package/dist/src/local/github.js +9 -0
- package/dist/src/local/identity.d.ts +3 -0
- package/dist/src/local/identity.js +7 -0
- package/dist/src/local/jobs.d.ts +7 -0
- package/dist/src/local/jobs.js +7 -0
- package/dist/src/local/legacy-trust.d.ts +10 -0
- package/dist/src/local/legacy-trust.js +6 -0
- package/dist/src/local/patch.d.ts +16 -0
- package/dist/src/local/patch.js +17 -0
- package/dist/src/local/provider.d.ts +11 -0
- package/dist/src/local/provider.js +20 -0
- package/dist/src/local/snapshots.d.ts +7 -0
- package/dist/src/local/snapshots.js +11 -0
- package/dist/src/local/text.d.ts +1 -0
- package/dist/src/local/text.js +6 -0
- package/dist/src/local/tree.d.ts +50 -0
- package/dist/src/local/tree.js +16 -0
- package/dist/src/local/workspace-migration.d.ts +2 -0
- package/dist/src/local/workspace-migration.js +7 -0
- package/dist/src/local/worktrees.d.ts +46 -0
- package/dist/src/local/worktrees.js +14 -0
- package/dist/src/mcp/config.d.ts +75 -0
- package/dist/src/mcp/config.js +12 -0
- package/dist/src/mcp/connect.d.ts +15 -0
- package/dist/src/mcp/connect.js +9 -0
- package/dist/src/mcp/hub.d.ts +19 -0
- package/dist/src/mcp/hub.js +11 -0
- package/dist/src/mcp/oauth.d.ts +46 -0
- package/dist/src/mcp/oauth.js +12 -0
- package/dist/src/mcp/tools.d.ts +29 -0
- package/dist/src/mcp/tools.js +12 -0
- package/dist/src/open.d.ts +14 -0
- package/dist/src/open.js +46 -0
- package/dist/src/plugins/loader.d.ts +21 -0
- package/dist/src/plugins/loader.js +11 -0
- package/dist/src/postgres.d.ts +19 -0
- package/dist/src/postgres.js +8 -0
- package/dist/src/providers.d.ts +16 -0
- package/dist/src/providers.js +112 -0
- package/dist/src/secrets.d.ts +12 -0
- package/dist/src/secrets.js +8 -0
- package/dist/src/serve/binding.d.ts +39 -0
- package/dist/src/serve/binding.js +6 -0
- package/dist/src/serve/handler.d.ts +15 -0
- package/dist/src/serve/handler.js +8 -0
- package/dist/src/serve/stream-server.d.ts +6 -0
- package/dist/src/serve/stream-server.js +6 -0
- package/dist/src/session-index.d.ts +11 -0
- package/dist/src/session-index.js +11 -0
- package/dist/src/shell-env.d.ts +14 -0
- package/dist/src/shell-env.js +108 -0
- package/dist/src/sqlite-workers.d.ts +6 -0
- package/dist/src/sqlite-workers.js +6 -0
- package/dist/src/sqlite.d.ts +8 -0
- package/dist/src/sqlite.js +11 -0
- package/dist/src/store-rows.d.ts +13 -0
- package/dist/src/store-rows.js +26 -0
- package/dist/src/store-usage.d.ts +25 -0
- package/dist/src/store-usage.js +19 -0
- package/dist/src/usage-history.d.ts +54 -0
- package/dist/src/usage-history.js +14 -0
- package/dist/src/usage-scan.d.ts +24 -0
- package/dist/src/usage-scan.js +65 -0
- package/dist/src/usage-service.d.ts +23 -0
- package/dist/src/usage-service.js +16 -0
- package/dist/src/usage-summary.d.ts +9 -0
- package/dist/src/usage-summary.js +16 -0
- package/dist/src/usage-types.d.ts +86 -0
- package/dist/src/usage-types.js +0 -0
- package/dist/src/usage-worker.d.ts +1 -0
- package/dist/src/usage-worker.js +29 -0
- package/dist/src/usage.d.ts +195 -0
- package/dist/src/usage.js +23 -0
- package/package.json +140 -3
- package/src/canvas-preview.ts +403 -0
- package/src/credentials.ts +294 -0
- package/src/deploy/cloudflare/README.md +3 -0
- package/src/deploy/cloudflare/worker.ts +306 -0
- package/src/deploy/cloudflare/wrangler.jsonc +12 -0
- package/src/deploy/vercel/README.md +3 -0
- package/src/deploy/vercel/nitro.config.ts +29 -0
- package/src/deploy/vercel/server/routes/[...].ts +10 -0
- package/src/deploy/vercel/server/utils/host.ts +104 -0
- package/src/deploy/vercel/server/utils/repair.ts +35 -0
- package/src/deploy/vercel/server/utils/step.ts +25 -0
- package/src/deploy/vercel/server/workflows/drive.ts +46 -0
- package/src/deploy/vercel/tsconfig.json +9 -0
- package/src/deploy/vercel/types/bun.d.ts +2 -0
- package/src/durable-object.ts +386 -0
- package/src/hash.ts +5 -0
- package/src/identity-key.ts +20 -0
- package/src/identity.ts +66 -0
- package/src/images/exif.ts +69 -0
- package/src/images/node.ts +163 -0
- package/src/images/photon.ts +141 -0
- package/src/images/worker.ts +29 -0
- package/src/index.ts +39 -0
- package/src/key-file.ts +53 -0
- package/src/listen-fetch.ts +409 -0
- package/src/listen.ts +228 -0
- package/src/local/command.ts +161 -0
- package/src/local/feed.ts +70 -0
- package/src/local/files.ts +817 -0
- package/src/local/git-watch.ts +199 -0
- package/src/local/git.ts +919 -0
- package/src/local/github.ts +691 -0
- package/src/local/identity.ts +21 -0
- package/src/local/jobs.ts +573 -0
- package/src/local/legacy-trust.ts +105 -0
- package/src/local/patch.ts +334 -0
- package/src/local/provider.ts +184 -0
- package/src/local/snapshots.ts +778 -0
- package/src/local/text.ts +9 -0
- package/src/local/tree.ts +398 -0
- package/src/local/workspace-migration.ts +95 -0
- package/src/local/worktrees.ts +239 -0
- package/src/mcp/config.ts +330 -0
- package/src/mcp/connect.ts +92 -0
- package/src/mcp/hub.ts +836 -0
- package/src/mcp/oauth.ts +436 -0
- package/src/mcp/tools.ts +333 -0
- package/src/open.ts +449 -0
- package/src/plugins/loader.ts +186 -0
- package/src/postgres.ts +492 -0
- package/src/providers.ts +135 -0
- package/src/secrets.ts +31 -0
- package/src/serve/binding.ts +629 -0
- package/src/serve/handler.ts +362 -0
- package/src/serve/stream-server.ts +176 -0
- package/src/session-index.ts +99 -0
- package/src/shell-env.ts +153 -0
- package/src/sqlite-workers.ts +283 -0
- package/src/sqlite.ts +553 -0
- package/src/store-rows.ts +110 -0
- package/src/store-usage.ts +347 -0
- package/src/usage-history.ts +219 -0
- package/src/usage-scan.ts +81 -0
- package/src/usage-service.ts +82 -0
- package/src/usage-summary.ts +79 -0
- package/src/usage-types.ts +87 -0
- package/src/usage-worker.ts +24 -0
- package/src/usage.ts +776 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseText2,
|
|
3
|
+
parseRef2
|
|
4
|
+
} from "./canvas-preview-69fkk9yn.js";
|
|
5
|
+
|
|
6
|
+
// src/session-index.ts
|
|
7
|
+
import { projectSessionIndex, sessionIndexRef } from "@nyte-ai/core/store";
|
|
8
|
+
import { asId } from "@nyte-ai/schema";
|
|
9
|
+
function sessionIndexChanges2(name, object, revision) {
|
|
10
|
+
const ref = sessionIndexRef(name);
|
|
11
|
+
if (ref === null)
|
|
12
|
+
return [];
|
|
13
|
+
const entry = projectSessionIndex(name, object);
|
|
14
|
+
if (ref.kind === "session") {
|
|
15
|
+
return entry?.kind === "session" ? [
|
|
16
|
+
{
|
|
17
|
+
text: "INSERT INTO session_index (name, session, parent, sort_at, version) VALUES (?, ?, ?, ?, ?) ON CONFLICT (name) DO UPDATE SET session = excluded.session, parent = excluded.parent, sort_at = excluded.sort_at, version = excluded.version",
|
|
18
|
+
values: [name, entry.session, entry.parent, -entry.at, revision]
|
|
19
|
+
}
|
|
20
|
+
] : [{ text: "DELETE FROM session_index WHERE name = ?", values: [name] }];
|
|
21
|
+
}
|
|
22
|
+
return entry !== null && entry.kind !== "session" ? [
|
|
23
|
+
{
|
|
24
|
+
text: "INSERT INTO pending_work (name, session, kind) VALUES (?, ?, ?) ON CONFLICT (name) DO UPDATE SET session = excluded.session, kind = excluded.kind",
|
|
25
|
+
values: [name, entry.session, entry.kind]
|
|
26
|
+
}
|
|
27
|
+
] : [{ text: "DELETE FROM pending_work WHERE name = ?", values: [name] }];
|
|
28
|
+
}
|
|
29
|
+
function sqlSessionIndex2(read) {
|
|
30
|
+
return {
|
|
31
|
+
async list({ parents, after, limit }) {
|
|
32
|
+
const conditions = [];
|
|
33
|
+
const values = [];
|
|
34
|
+
if (parents.kind === "roots")
|
|
35
|
+
conditions.push("s.parent IS NULL");
|
|
36
|
+
if (parents.kind === "children") {
|
|
37
|
+
conditions.push("s.parent = ?");
|
|
38
|
+
values.push(parents.session);
|
|
39
|
+
}
|
|
40
|
+
if (after !== undefined) {
|
|
41
|
+
conditions.push("(s.sort_at, s.session) > (?, ?)");
|
|
42
|
+
values.push(-after.at, after.id);
|
|
43
|
+
}
|
|
44
|
+
values.push(limit);
|
|
45
|
+
return (await read(`SELECT r.name, r.target, r.revision, s.version FROM session_index s JOIN refs r ON r.name = s.name${conditions.length === 0 ? "" : ` WHERE ${conditions.join(" AND ")}`} ORDER BY s.sort_at, s.session LIMIT ?`, values)).map((row) => ({
|
|
46
|
+
ref: parseRef2(row),
|
|
47
|
+
version: asId(parseText2(row.version) ?? "")
|
|
48
|
+
}));
|
|
49
|
+
},
|
|
50
|
+
async work({ after, limit }) {
|
|
51
|
+
return (await read(`SELECT r.name, r.target, r.revision FROM (SELECT DISTINCT session FROM pending_work${after === undefined ? "" : " WHERE session > ?"}) p JOIN session_index s ON s.session = p.session JOIN refs r ON r.name = s.name ORDER BY p.session LIMIT ?`, after === undefined ? [limit] : [after, limit])).map(parseRef2);
|
|
52
|
+
},
|
|
53
|
+
async pending({ kind, sessions }) {
|
|
54
|
+
if (sessions?.length === 0)
|
|
55
|
+
return [];
|
|
56
|
+
return (await read(`SELECT r.name, r.target, r.revision FROM pending_work p JOIN refs r ON r.name = p.name WHERE p.kind = ?${sessions === undefined ? "" : ` AND p.session IN (${sessions.map(() => "?").join(", ")})`} ORDER BY p.name`, [kind, ...sessions ?? []])).map(parseRef2);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function postgresSessionIndexQuery2(text) {
|
|
61
|
+
let parameter = 0;
|
|
62
|
+
return text.replaceAll("?", () => `$${++parameter}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { sessionIndexChanges2, sqlSessionIndex2, postgresSessionIndexQuery2 };
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decodeEvent2,
|
|
3
|
+
parseNumber2,
|
|
4
|
+
parseText2
|
|
5
|
+
} from "./canvas-preview-69fkk9yn.js";
|
|
6
|
+
import {
|
|
7
|
+
storePath2
|
|
8
|
+
} from "./canvas-preview-tnqe7k0b.js";
|
|
9
|
+
import {
|
|
10
|
+
cacheSavings2,
|
|
11
|
+
usageTokens2
|
|
12
|
+
} from "./canvas-preview-srgfpdmf.js";
|
|
13
|
+
|
|
14
|
+
// src/store-usage.ts
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
|
+
import { DatabaseSync } from "node:sqlite";
|
|
17
|
+
import {
|
|
18
|
+
decodeObject,
|
|
19
|
+
decodeSessionRecord,
|
|
20
|
+
decodeWorkspaceRecord,
|
|
21
|
+
parseSessionRef
|
|
22
|
+
} from "@nyte-ai/core/store";
|
|
23
|
+
var EMPTY_TOTALS = {
|
|
24
|
+
input: 0,
|
|
25
|
+
output: 0,
|
|
26
|
+
cacheRead: 0,
|
|
27
|
+
cacheWrite: 0,
|
|
28
|
+
reasoning: 0,
|
|
29
|
+
tokens: 0,
|
|
30
|
+
cost: 0,
|
|
31
|
+
cacheSavings: 0
|
|
32
|
+
};
|
|
33
|
+
function add(totals, usage) {
|
|
34
|
+
return {
|
|
35
|
+
input: totals.input + usage.input,
|
|
36
|
+
output: totals.output + usage.output,
|
|
37
|
+
cacheRead: totals.cacheRead + usage.cacheRead,
|
|
38
|
+
cacheWrite: totals.cacheWrite + usage.cacheWrite,
|
|
39
|
+
reasoning: totals.reasoning + (usage.reasoning ?? 0),
|
|
40
|
+
tokens: totals.tokens + usageTokens2(usage),
|
|
41
|
+
cost: totals.cost + usage.cost.total,
|
|
42
|
+
cacheSavings: totals.cacheSavings + cacheSavings2(usage)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
var USAGE_EVENTS2 = "SELECT session, seq, at, event FROM log WHERE json_extract(event, '$.kind') = 'request' OR (json_extract(event, '$.kind') = 'run' AND json_extract(event, '$.change') = 'started') ORDER BY session, seq";
|
|
46
|
+
function localDay2(at) {
|
|
47
|
+
const date = new Date(at);
|
|
48
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
49
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
50
|
+
return `${String(date.getFullYear())}-${month}-${day}`;
|
|
51
|
+
}
|
|
52
|
+
function shiftDay2(day, delta) {
|
|
53
|
+
const date = new Date(`${day}T00:00:00`);
|
|
54
|
+
date.setDate(date.getDate() + delta);
|
|
55
|
+
return localDay2(date.getTime());
|
|
56
|
+
}
|
|
57
|
+
function priorWindow(sinceDay, untilDay) {
|
|
58
|
+
if (sinceDay === null)
|
|
59
|
+
return;
|
|
60
|
+
const priorUntil = shiftDay2(sinceDay, -1);
|
|
61
|
+
const span = (Date.parse(`${untilDay}T00:00:00Z`) - Date.parse(`${sinceDay}T00:00:00Z`)) / 86400000 + 1;
|
|
62
|
+
return { sinceDay: shiftDay2(priorUntil, -(span - 1)), untilDay: priorUntil };
|
|
63
|
+
}
|
|
64
|
+
function projectUsageReport2(stores, window, readAt) {
|
|
65
|
+
const requestedSince = window.sinceDay;
|
|
66
|
+
const untilDay = window.untilDay;
|
|
67
|
+
const prior = priorWindow(requestedSince, untilDay);
|
|
68
|
+
const cells = new Map;
|
|
69
|
+
const sessions = new Map;
|
|
70
|
+
const sources = [];
|
|
71
|
+
let priorCost = 0;
|
|
72
|
+
let priorTokens = 0;
|
|
73
|
+
let sawPrior = false;
|
|
74
|
+
let earliestDay;
|
|
75
|
+
for (const store of stores) {
|
|
76
|
+
sources.push({
|
|
77
|
+
workspacePath: store.workspacePath,
|
|
78
|
+
status: store.failure === null ? "ok" : "failed",
|
|
79
|
+
sessions: store.sessions.length,
|
|
80
|
+
message: store.failure?.message ?? null
|
|
81
|
+
});
|
|
82
|
+
for (const session of store.sessions) {
|
|
83
|
+
let lastActivityAt = 0;
|
|
84
|
+
let spentInWindow = false;
|
|
85
|
+
for (const spend of session.records) {
|
|
86
|
+
const { usage } = spend;
|
|
87
|
+
const amounts = [
|
|
88
|
+
usage.total,
|
|
89
|
+
usage.input,
|
|
90
|
+
usage.output,
|
|
91
|
+
usage.cacheRead,
|
|
92
|
+
usage.cacheWrite,
|
|
93
|
+
usage.cost.total
|
|
94
|
+
];
|
|
95
|
+
if (!amounts.some((amount) => amount > 0))
|
|
96
|
+
continue;
|
|
97
|
+
const day = localDay2(spend.at);
|
|
98
|
+
if (earliestDay === undefined || day < earliestDay)
|
|
99
|
+
earliestDay = day;
|
|
100
|
+
if (prior !== undefined && day >= prior.sinceDay && day <= prior.untilDay) {
|
|
101
|
+
sawPrior = true;
|
|
102
|
+
priorCost += spend.usage.cost.total;
|
|
103
|
+
priorTokens += usageTokens2(spend.usage);
|
|
104
|
+
}
|
|
105
|
+
if (day > untilDay)
|
|
106
|
+
continue;
|
|
107
|
+
if (requestedSince !== null && day < requestedSince)
|
|
108
|
+
continue;
|
|
109
|
+
const key = JSON.stringify([day, store.workspacePath, session.sessionId, spend.subject]);
|
|
110
|
+
const cell = cells.get(key);
|
|
111
|
+
if (cell === undefined) {
|
|
112
|
+
cells.set(key, {
|
|
113
|
+
entry: {
|
|
114
|
+
day,
|
|
115
|
+
workspacePath: store.workspacePath,
|
|
116
|
+
sessionId: session.sessionId,
|
|
117
|
+
subject: spend.subject
|
|
118
|
+
},
|
|
119
|
+
totals: add(EMPTY_TOTALS, spend.usage)
|
|
120
|
+
});
|
|
121
|
+
} else {
|
|
122
|
+
cell.totals = add(cell.totals, spend.usage);
|
|
123
|
+
}
|
|
124
|
+
spentInWindow = true;
|
|
125
|
+
lastActivityAt = Math.max(lastActivityAt, spend.at);
|
|
126
|
+
}
|
|
127
|
+
if (spentInWindow) {
|
|
128
|
+
sessions.set(session.sessionId, {
|
|
129
|
+
sessionId: session.sessionId,
|
|
130
|
+
name: session.name,
|
|
131
|
+
workspacePath: store.workspacePath,
|
|
132
|
+
lastActivityAt: session.lastActivityAt ?? lastActivityAt
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
readAt,
|
|
139
|
+
sinceDay: requestedSince ?? earliestDay ?? untilDay,
|
|
140
|
+
untilDay,
|
|
141
|
+
entries: [...cells.values()].map((cell) => ({ ...cell.entry, totals: cell.totals })).toSorted((left, right) => left.day.localeCompare(right.day)),
|
|
142
|
+
sessions: [...sessions.values()],
|
|
143
|
+
sources,
|
|
144
|
+
previous: sawPrior ? { cost: priorCost, tokens: priorTokens } : undefined,
|
|
145
|
+
earliestDay
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function readNyteUsage2(home, window) {
|
|
149
|
+
const readAt = Date.now();
|
|
150
|
+
const path = storePath2(home);
|
|
151
|
+
if (!existsSync(path))
|
|
152
|
+
return projectUsageReport2([], window, readAt);
|
|
153
|
+
let database;
|
|
154
|
+
try {
|
|
155
|
+
database = new DatabaseSync(path, { readOnly: true, timeout: 5000 });
|
|
156
|
+
database.exec("BEGIN");
|
|
157
|
+
const workspaces = new Map;
|
|
158
|
+
const sessions = new Map;
|
|
159
|
+
const refs = database.prepare("SELECT refs.name, objects.body FROM refs JOIN objects ON objects.id = refs.target WHERE refs.name LIKE 'workspaces/%' OR (refs.name LIKE 'sessions/%' AND instr(substr(refs.name, 10), '/') = 0)").all();
|
|
160
|
+
for (const row of refs) {
|
|
161
|
+
const name = parseText2(row.name);
|
|
162
|
+
const body = parseText2(row.body);
|
|
163
|
+
if (name === null || body === null || !name.startsWith("workspaces/"))
|
|
164
|
+
continue;
|
|
165
|
+
const workspace = decodeWorkspaceRecord(decodeObject(body));
|
|
166
|
+
if (workspace !== null)
|
|
167
|
+
workspaces.set(workspace.id, workspace.target.kind === "local" && "path" in workspace.target ? parseText2(workspace.target.path) : null);
|
|
168
|
+
}
|
|
169
|
+
for (const row of refs) {
|
|
170
|
+
const name = parseText2(row.name);
|
|
171
|
+
const body = parseText2(row.body);
|
|
172
|
+
if (name === null || body === null || name.split("/").length !== 2)
|
|
173
|
+
continue;
|
|
174
|
+
const id = parseSessionRef(name);
|
|
175
|
+
if (id === null)
|
|
176
|
+
continue;
|
|
177
|
+
const session = decodeSessionRecord(decodeObject(body));
|
|
178
|
+
if (session === null)
|
|
179
|
+
throw new Error(`Cannot read session ${id}.`);
|
|
180
|
+
sessions.set(id, {
|
|
181
|
+
workspacePath: workspaces.get(session.workspace) ?? null,
|
|
182
|
+
name: session.name ?? undefined,
|
|
183
|
+
lastActivityAt: session.lastActivityAt,
|
|
184
|
+
records: []
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const models = new Map;
|
|
188
|
+
for (const row of database.prepare(USAGE_EVENTS2).iterate()) {
|
|
189
|
+
const session = parseSessionRef(`sessions/${parseText2(row.session) ?? ""}`);
|
|
190
|
+
if (session === null)
|
|
191
|
+
throw new Error("Cannot read usage session.");
|
|
192
|
+
const event = decodeEvent2(parseNumber2(row.seq), parseNumber2(row.at), parseText2(row.event) ?? "");
|
|
193
|
+
let heads = models.get(session);
|
|
194
|
+
if (heads === undefined) {
|
|
195
|
+
heads = new Map;
|
|
196
|
+
models.set(session, heads);
|
|
197
|
+
}
|
|
198
|
+
if (event.kind === "run" && event.change === "started")
|
|
199
|
+
heads.set(event.head, event.view.configuration.model);
|
|
200
|
+
if (event.kind !== "request")
|
|
201
|
+
continue;
|
|
202
|
+
const model = heads.get(event.head);
|
|
203
|
+
const subject = event.step === "compaction" || event.step === "summary" ? { kind: "compaction" } : event.step === "plugin" ? { kind: "tool" } : {
|
|
204
|
+
kind: "model",
|
|
205
|
+
provider: model?.provider ?? "unknown",
|
|
206
|
+
model: model?.id ?? "unknown"
|
|
207
|
+
};
|
|
208
|
+
let info = sessions.get(session);
|
|
209
|
+
if (info === undefined) {
|
|
210
|
+
info = { workspacePath: null, name: undefined, lastActivityAt: undefined, records: [] };
|
|
211
|
+
sessions.set(session, info);
|
|
212
|
+
}
|
|
213
|
+
info.records.push({ at: event.at, subject, usage: event.usage });
|
|
214
|
+
}
|
|
215
|
+
database.exec("COMMIT");
|
|
216
|
+
const stores = new Map;
|
|
217
|
+
for (const [sessionId, info] of sessions) {
|
|
218
|
+
const group = stores.get(info.workspacePath) ?? [];
|
|
219
|
+
group.push({
|
|
220
|
+
sessionId,
|
|
221
|
+
name: info.name,
|
|
222
|
+
records: info.records,
|
|
223
|
+
lastActivityAt: info.lastActivityAt
|
|
224
|
+
});
|
|
225
|
+
stores.set(info.workspacePath, group);
|
|
226
|
+
}
|
|
227
|
+
return projectUsageReport2([...stores].map(([workspacePath, sessions]) => ({ workspacePath, sessions, failure: null })), window, readAt);
|
|
228
|
+
} catch (cause) {
|
|
229
|
+
return projectUsageReport2([
|
|
230
|
+
{
|
|
231
|
+
workspacePath: null,
|
|
232
|
+
sessions: [],
|
|
233
|
+
failure: { message: cause instanceof Error ? cause.message : String(cause) }
|
|
234
|
+
}
|
|
235
|
+
], window, readAt);
|
|
236
|
+
} finally {
|
|
237
|
+
database?.close();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export { USAGE_EVENTS2, localDay2, shiftDay2, projectUsageReport2, readNyteUsage2 };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sha2562
|
|
3
|
+
} from "./canvas-preview-0nq75h9k.js";
|
|
4
|
+
|
|
5
|
+
// src/local/identity.ts
|
|
6
|
+
import { realpath, stat } from "node:fs/promises";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import { asId } from "@nyte-ai/schema";
|
|
9
|
+
async function folderIdentity2(path) {
|
|
10
|
+
const real = await realpath(path).catch(() => null);
|
|
11
|
+
if (real === null)
|
|
12
|
+
return asId(sha2562(resolve(path)));
|
|
13
|
+
const stats = await stat(real, { bigint: true }).catch(() => null);
|
|
14
|
+
return asId(sha2562(stats === null || stats.ino === 0n || stats.birthtimeNs === 0n ? real : `${stats.birthtimeNs}:${stats.ino}`));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { folderIdentity2 };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sha2562
|
|
3
|
+
} from "./canvas-preview-0nq75h9k.js";
|
|
4
|
+
import {
|
|
5
|
+
run2
|
|
6
|
+
} from "./canvas-preview-bxnqt8cd.js";
|
|
7
|
+
|
|
8
|
+
// src/local/worktrees.ts
|
|
9
|
+
import { randomUUID } from "node:crypto";
|
|
10
|
+
import { copyFile, mkdir, realpath, rm, stat } from "node:fs/promises";
|
|
11
|
+
import { homedir, tmpdir } from "node:os";
|
|
12
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
13
|
+
import { SdkError } from "@nyte-ai/schema";
|
|
14
|
+
var ENV = { GIT_TERMINAL_PROMPT: "0", LC_ALL: "C" };
|
|
15
|
+
function gitCommand(binary = "git") {
|
|
16
|
+
return async (cwd, args, env) => {
|
|
17
|
+
const ran = await run2(binary, ["-c", "core.quotepath=off", ...args], {
|
|
18
|
+
cwd,
|
|
19
|
+
env: { ...ENV, ...env }
|
|
20
|
+
});
|
|
21
|
+
if (ran.code !== 0)
|
|
22
|
+
throw new SdkError("unavailable", ran.stderr.trim() || `git ${args[0] ?? ""} failed.`);
|
|
23
|
+
return ran.stdout.toString("utf8");
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async function listWorktrees2(cwd, options) {
|
|
27
|
+
const out = await gitCommand(options?.git)(cwd, ["worktree", "list", "--porcelain", "-z"]);
|
|
28
|
+
return out.split("\x00\x00").flatMap((record) => {
|
|
29
|
+
const fields = record.split("\x00");
|
|
30
|
+
const path = fields.find((field) => field.startsWith("worktree "))?.slice(9);
|
|
31
|
+
const branch = fields.find((field) => field.startsWith("branch refs/heads/"))?.slice(18);
|
|
32
|
+
return path === undefined ? [] : [{ path: resolve(path), branch: branch ?? null }];
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async function addWorktree2(cwd, input, options) {
|
|
36
|
+
await gitCommand(options?.git)(cwd, input.from === undefined ? ["worktree", "add", input.path, input.branch] : ["worktree", "add", "-b", input.branch, input.path, input.from]);
|
|
37
|
+
}
|
|
38
|
+
async function hasBranch2(cwd, name, options) {
|
|
39
|
+
return gitCommand(options?.git)(cwd, ["show-ref", "--verify", "--quiet", `refs/heads/${name}`]).then(() => true).catch(() => false);
|
|
40
|
+
}
|
|
41
|
+
function localWorktrees2(options) {
|
|
42
|
+
const git = gitCommand(options?.git);
|
|
43
|
+
const folders = join(options?.home ?? homedir(), ".nyte", "worktrees");
|
|
44
|
+
const commitAt = (cwd, revision) => git(cwd, ["rev-parse", "--verify", "--quiet", `${revision}^{commit}`]).then((out) => out.trim(), () => null);
|
|
45
|
+
const workingTree = async (repo) => {
|
|
46
|
+
const index = join(tmpdir(), `nyte-worktree-index-${randomUUID()}`);
|
|
47
|
+
const indexEnv = { GIT_INDEX_FILE: index };
|
|
48
|
+
try {
|
|
49
|
+
await copyFile(join(repo.gitDir, "index"), index).catch(() => {
|
|
50
|
+
return;
|
|
51
|
+
});
|
|
52
|
+
await git(repo.root, ["add", "-A", "--", "."], indexEnv);
|
|
53
|
+
return (await git(repo.root, ["write-tree"], indexEnv)).trim();
|
|
54
|
+
} finally {
|
|
55
|
+
await rm(index, { force: true });
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
async create(env, input) {
|
|
60
|
+
const repo = await readRepository(git, env.cwd);
|
|
61
|
+
if (repo === null)
|
|
62
|
+
throw new SdkError("unavailable", `${env.cwd} is not in a git repository, so it cannot have a worktree.`);
|
|
63
|
+
const head = await commitAt(repo.root, "HEAD");
|
|
64
|
+
if (head === null)
|
|
65
|
+
throw new SdkError("unavailable", `${repo.root} has no commits yet, so a worktree has nothing to branch from.`);
|
|
66
|
+
const slug = worktreeSlug(input.name, input.title);
|
|
67
|
+
const branch = `nyte/${slug}`;
|
|
68
|
+
const below = (root) => ({
|
|
69
|
+
kind: "local",
|
|
70
|
+
path: resolve(root, repo.prefix)
|
|
71
|
+
});
|
|
72
|
+
const listed = (await listWorktrees2(repo.root, options)).find((worktree) => worktree.branch === branch);
|
|
73
|
+
if (listed !== undefined)
|
|
74
|
+
return {
|
|
75
|
+
target: below(listed.path),
|
|
76
|
+
branch,
|
|
77
|
+
base: await commitAt(repo.root, `refs/heads/${branch}`) ?? head
|
|
78
|
+
};
|
|
79
|
+
const folder = join(folders, basename(repo.root), slug);
|
|
80
|
+
const branched = await hasBranch2(repo.root, branch, options);
|
|
81
|
+
const base = branched ? await commitAt(repo.root, `refs/heads/${branch}`) ?? head : head;
|
|
82
|
+
const tree = await workingTree(repo);
|
|
83
|
+
await mkdir(dirname(folder), { recursive: true });
|
|
84
|
+
await addWorktree2(repo.root, branched ? { path: folder, branch } : { path: folder, branch, from: head }, options);
|
|
85
|
+
if (tree !== (await git(folder, ["rev-parse", "HEAD^{tree}"])).trim()) {
|
|
86
|
+
await git(folder, ["read-tree", "-m", "-u", "HEAD", tree]);
|
|
87
|
+
await git(folder, ["reset", "-q"]);
|
|
88
|
+
}
|
|
89
|
+
return { target: below(await realpath(folder)), branch, base };
|
|
90
|
+
},
|
|
91
|
+
async remove(worktree) {
|
|
92
|
+
const path = "path" in worktree.target ? worktree.target.path : null;
|
|
93
|
+
if (path === null || await stat(path).catch(() => null) === null)
|
|
94
|
+
return { folder: "removed", branch: "kept" };
|
|
95
|
+
const [root = path, common = ""] = (await git(path, [
|
|
96
|
+
"rev-parse",
|
|
97
|
+
"--show-toplevel",
|
|
98
|
+
"--path-format=absolute",
|
|
99
|
+
"--git-common-dir"
|
|
100
|
+
])).split(`
|
|
101
|
+
`);
|
|
102
|
+
const status = await git(root, ["status", "--porcelain", "--ignored", "-z"]);
|
|
103
|
+
if (status.split("\x00").some((entry) => entry !== "" && !(entry.startsWith("!! ") && entry.endsWith("/"))))
|
|
104
|
+
return { folder: "kept", branch: "kept" };
|
|
105
|
+
await git(common, ["worktree", "remove", root]);
|
|
106
|
+
if (await commitAt(common, `refs/heads/${worktree.branch}`) !== worktree.base)
|
|
107
|
+
return { folder: "removed", branch: "kept" };
|
|
108
|
+
await git(common, ["branch", "-D", worktree.branch]);
|
|
109
|
+
return { folder: "removed", branch: "deleted" };
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
async function readRepository(git, cwd) {
|
|
114
|
+
const out = await git(cwd, [
|
|
115
|
+
"rev-parse",
|
|
116
|
+
"--show-toplevel",
|
|
117
|
+
"--absolute-git-dir",
|
|
118
|
+
"--show-prefix"
|
|
119
|
+
]).catch(() => null);
|
|
120
|
+
const [root, gitDir, prefix = ""] = out?.split(`
|
|
121
|
+
`) ?? [];
|
|
122
|
+
return root === undefined || gitDir === undefined || root === "" ? null : { root: resolve(root), gitDir: resolve(gitDir), prefix };
|
|
123
|
+
}
|
|
124
|
+
function worktreeSlug(name, title) {
|
|
125
|
+
const words = (title ?? "").toLowerCase().replace(/[^a-z0-9]+/gu, "-").slice(0, 40).replace(/^-+|-+$/gu, "");
|
|
126
|
+
const key = sha2562(name).slice(0, 8);
|
|
127
|
+
return words === "" ? key : `${words}-${key}`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { listWorktrees2, addWorktree2, hasBranch2, localWorktrees2 };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/deploy/vercel/server/utils/repair.ts
|
|
2
|
+
import { createHash, timingSafeEqual } from "node:crypto";
|
|
3
|
+
import { SdkError } from "@nyte-ai/schema";
|
|
4
|
+
import { encodeError, errorStatus } from "@nyte-ai/protocol";
|
|
5
|
+
async function answerRepair2(request, secret, repair) {
|
|
6
|
+
if (request.method !== "GET" || new URL(request.url).pathname !== "/.nyte/repair")
|
|
7
|
+
return;
|
|
8
|
+
if (secret === undefined || secret === "")
|
|
9
|
+
return failure(new SdkError("unknown", "This deployment sets no CRON_SECRET."));
|
|
10
|
+
const given = /^Bearer\s+(\S+)\s*$/i.exec(request.headers.get("Authorization") ?? "")?.[1] ?? "";
|
|
11
|
+
if (!timingSafeEqual(digest(given), digest(secret)))
|
|
12
|
+
return failure(new SdkError("unauthenticated", "Send Authorization: Bearer <CRON_SECRET>."));
|
|
13
|
+
await repair();
|
|
14
|
+
return new Response(null, { status: 204 });
|
|
15
|
+
}
|
|
16
|
+
function digest(text) {
|
|
17
|
+
return createHash("sha256").update(text).digest();
|
|
18
|
+
}
|
|
19
|
+
function failure(error) {
|
|
20
|
+
return new Response(JSON.stringify(encodeError(error)), {
|
|
21
|
+
status: errorStatus[error.code],
|
|
22
|
+
headers: { "Content-Type": "application/json" }
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { answerRepair2 };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// src/identity.ts
|
|
2
|
+
import { SdkError } from "@nyte-ai/schema";
|
|
3
|
+
var PKCS8_PREFIX = Uint8Array.fromHex("302e020100300506032b657004220420");
|
|
4
|
+
var encoder = new TextEncoder;
|
|
5
|
+
async function seedSigner2(id, seed) {
|
|
6
|
+
const { signing, publicKey } = await identityKeys(seed);
|
|
7
|
+
return {
|
|
8
|
+
id,
|
|
9
|
+
async sign(nonce) {
|
|
10
|
+
const signature = new Uint8Array(await crypto.subtle.sign("Ed25519", signing, encoder.encode(`nyte/identity
|
|
11
|
+
${id}
|
|
12
|
+
${nonce}`)));
|
|
13
|
+
return {
|
|
14
|
+
hostId: id,
|
|
15
|
+
nonce,
|
|
16
|
+
signature: signature.toBase64({ alphabet: "base64url", omitPadding: true }),
|
|
17
|
+
publicKey
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
async function identityKeys(seed) {
|
|
23
|
+
if (seed.length !== 32)
|
|
24
|
+
throw new SdkError("invalid", `The identity seed is ${seed.length} bytes, not 32.`);
|
|
25
|
+
const pkcs8 = new Uint8Array([...PKCS8_PREFIX, ...seed]);
|
|
26
|
+
const readable = await crypto.subtle.importKey("pkcs8", pkcs8, "Ed25519", true, ["sign"]);
|
|
27
|
+
const { x } = await crypto.subtle.exportKey("jwk", readable);
|
|
28
|
+
if (x === undefined)
|
|
29
|
+
throw new SdkError("internal", "The identity key has no public half.");
|
|
30
|
+
const signing = await crypto.subtle.importKey("pkcs8", pkcs8, "Ed25519", false, ["sign"]);
|
|
31
|
+
return { signing, publicKey: x };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { seedSigner2 };
|