@mean-weasel/lineage 0.1.22 → 0.1.24
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/CHANGELOG.md +15 -0
- package/MANUAL_INSTALL_DOGFOOD.md +1 -0
- package/README.md +45 -5
- package/dist/cli/lineage-dev.js +612 -37
- package/dist/cli/lineage-dev.js.map +4 -4
- package/dist/cli/lineage-preview.js +612 -37
- package/dist/cli/lineage-preview.js.map +4 -4
- package/dist/cli/lineage.js +612 -37
- package/dist/cli/lineage.js.map +4 -4
- package/dist/docs-site/404.html +41 -0
- package/dist/docs-site/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.BcSo_yiZ.js +1 -0
- package/dist/docs-site/_astro/Search.astro_astro_type_script_index_0_lang.x2pVooPA.js +1 -0
- package/dist/docs-site/_astro/TableOfContents.astro_astro_type_script_index_0_lang.Csloo1VZ.js +1 -0
- package/dist/docs-site/_astro/common.DarLW4Vf.css +3 -0
- package/dist/docs-site/_astro/ec.0vx5m.js +3 -0
- package/dist/docs-site/_astro/ec.w36nc.css +1 -0
- package/dist/docs-site/_astro/page.LAbJoB63.js +1 -0
- package/dist/docs-site/_astro/print.ehPL0gv-.css +1 -0
- package/dist/docs-site/_astro/starlight-toc.CTCQXEge.js +1 -0
- package/dist/docs-site/_astro/ui-core.DWIqd25E.js +2 -0
- package/dist/docs-site/concepts/agent-claims-handoffs/index.html +99 -0
- package/dist/docs-site/concepts/attempts-current-version/index.html +86 -0
- package/dist/docs-site/concepts/branches-vs-rerolls/index.html +114 -0
- package/dist/docs-site/concepts/projects-workspaces-assets/index.html +89 -0
- package/dist/docs-site/concepts/selections-next-variations/index.html +86 -0
- package/dist/docs-site/index.html +92 -0
- package/dist/docs-site/integrations/cloud-storage/index.html +92 -0
- package/dist/docs-site/integrations/image-generation/index.html +93 -0
- package/dist/docs-site/integrations/index.html +112 -0
- package/dist/docs-site/integrations/social-scheduling/index.html +89 -0
- package/dist/docs-site/operations/backup-recovery/index.html +87 -0
- package/dist/docs-site/operations/channels/index.html +97 -0
- package/dist/docs-site/operations/local-first-data/index.html +90 -0
- package/dist/docs-site/operations/profiles-database-identity/index.html +104 -0
- package/dist/docs-site/operations/troubleshooting/index.html +89 -0
- package/dist/docs-site/pagefind/fragment/en_1126abb.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_19b3f6c.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_31aa611.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_38817cc.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_4184ad1.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_41db543.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_469f895.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_56e45b6.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_56fe7ca.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_5be5e44.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_603c2be.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_66b3118.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_6a19c31.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_74e9307.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_761fab1.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_7c9d5a2.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_818744b.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_8269752.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_88b38c1.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_98d9b16.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_a3d636e.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_b15ecf0.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_bd3e194.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_bfb13e9.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_d0fca9e.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_d49ed00.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_e0786b9.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_e298dee.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_ee82be6.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_f4db9e2.pf_fragment +0 -0
- package/dist/docs-site/pagefind/fragment/en_f6179a8.pf_fragment +0 -0
- package/dist/docs-site/pagefind/index/en_7b1363c.pf_index +0 -0
- package/dist/docs-site/pagefind/pagefind-component-ui.css +1509 -0
- package/dist/docs-site/pagefind/pagefind-component-ui.js +56 -0
- package/dist/docs-site/pagefind/pagefind-entry.json +1 -0
- package/dist/docs-site/pagefind/pagefind-highlight.js +1070 -0
- package/dist/docs-site/pagefind/pagefind-modular-ui.css +214 -0
- package/dist/docs-site/pagefind/pagefind-modular-ui.js +8 -0
- package/dist/docs-site/pagefind/pagefind-ui.css +1 -0
- package/dist/docs-site/pagefind/pagefind-ui.js +2 -0
- package/dist/docs-site/pagefind/pagefind-worker.js +6 -0
- package/dist/docs-site/pagefind/pagefind.en_4e77743529.pf_meta +0 -0
- package/dist/docs-site/pagefind/pagefind.js +6 -0
- package/dist/docs-site/pagefind/wasm.en.pagefind +0 -0
- package/dist/docs-site/pagefind/wasm.unknown.pagefind +0 -0
- package/dist/docs-site/reference/cli/index.html +95 -0
- package/dist/docs-site/reference/interface-guide/index.html +86 -0
- package/dist/docs-site/reference/release-notes/index.html +80 -0
- package/dist/docs-site/reference/settings/index.html +86 -0
- package/dist/docs-site/reference/terminology/index.html +94 -0
- package/dist/docs-site/sitemap-0.xml +1 -0
- package/dist/docs-site/sitemap-index.xml +1 -0
- package/dist/docs-site/start-here/example-projects/index.html +88 -0
- package/dist/docs-site/start-here/first-workspace/index.html +91 -0
- package/dist/docs-site/start-here/installation-first-run/index.html +92 -0
- package/dist/docs-site/start-here/what-is-lineage/index.html +96 -0
- package/dist/docs-site/workflows/back-up-approved-assets/index.html +88 -0
- package/dist/docs-site/workflows/content-batches/index.html +88 -0
- package/dist/docs-site/workflows/continue-new-agent-session/index.html +89 -0
- package/dist/docs-site/workflows/create-grow-lineage/index.html +89 -0
- package/dist/docs-site/workflows/generate-import-variations/index.html +92 -0
- package/dist/docs-site/workflows/restore-earlier-attempt/index.html +87 -0
- package/dist/docs-site/workflows/review-approve-assets/index.html +87 -0
- package/dist/pages/.nojekyll +0 -0
- package/dist/pages/assets/agent-shared-state-DOfpTLiw.webp +0 -0
- package/dist/pages/assets/agent-to-canvas-DtIu_cPq.mp4 +0 -0
- package/dist/{web/assets/app-B-fAyNsU.css → pages/assets/app-CuBsKrS-.css} +1 -1
- package/dist/pages/assets/app-TEMX-pOn.js +50 -0
- package/dist/pages/assets/attempt-history-D6wdic6n.webp +0 -0
- package/dist/pages/assets/branching-tree-B8I5_S6D.png +0 -0
- package/dist/pages/assets/canvas-cli-DHBacq7r.png +0 -0
- package/dist/pages/assets/hero-agent-sync-D8ibW83E.mp4 +0 -0
- package/dist/pages/assets/hero-agent-sync-poster-zBB3KpbO.png +0 -0
- package/dist/pages/assets/hero-board-DG3ED4AW.webp +0 -0
- package/dist/pages/assets/hero-lineage-growth-Bsl9tiq-.mp4 +0 -0
- package/dist/pages/assets/hero-trace-connections-Bb52ABBc.mp4 +0 -0
- package/dist/pages/assets/human-selection-BdDBDE-I.webp +0 -0
- package/dist/pages/assets/human-to-agent-D1z92ZO9.mp4 +0 -0
- package/dist/pages/assets/jsx-runtime-DAFSxiwi.js +8 -0
- package/dist/pages/assets/landing-MwOFmHoi.js +2 -0
- package/dist/pages/assets/landing-wy4L-yBm.css +1 -0
- package/dist/pages/assets/reroll-history-DQcEH42R.mp4 +0 -0
- package/dist/pages/docs/404.html +41 -0
- package/dist/pages/docs/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.BcSo_yiZ.js +1 -0
- package/dist/pages/docs/_astro/Search.astro_astro_type_script_index_0_lang.x2pVooPA.js +1 -0
- package/dist/pages/docs/_astro/TableOfContents.astro_astro_type_script_index_0_lang.Csloo1VZ.js +1 -0
- package/dist/pages/docs/_astro/common.DarLW4Vf.css +3 -0
- package/dist/pages/docs/_astro/ec.0vx5m.js +3 -0
- package/dist/pages/docs/_astro/ec.w36nc.css +1 -0
- package/dist/pages/docs/_astro/page.LAbJoB63.js +1 -0
- package/dist/pages/docs/_astro/print.ehPL0gv-.css +1 -0
- package/dist/pages/docs/_astro/starlight-toc.CTCQXEge.js +1 -0
- package/dist/pages/docs/_astro/ui-core.DWIqd25E.js +2 -0
- package/dist/pages/docs/concepts/agent-claims-handoffs/index.html +99 -0
- package/dist/pages/docs/concepts/attempts-current-version/index.html +86 -0
- package/dist/pages/docs/concepts/branches-vs-rerolls/index.html +114 -0
- package/dist/pages/docs/concepts/projects-workspaces-assets/index.html +89 -0
- package/dist/pages/docs/concepts/selections-next-variations/index.html +86 -0
- package/dist/pages/docs/index.html +92 -0
- package/dist/pages/docs/integrations/cloud-storage/index.html +92 -0
- package/dist/pages/docs/integrations/image-generation/index.html +93 -0
- package/dist/pages/docs/integrations/index.html +112 -0
- package/dist/pages/docs/integrations/social-scheduling/index.html +89 -0
- package/dist/pages/docs/operations/backup-recovery/index.html +87 -0
- package/dist/pages/docs/operations/channels/index.html +97 -0
- package/dist/pages/docs/operations/local-first-data/index.html +90 -0
- package/dist/pages/docs/operations/profiles-database-identity/index.html +104 -0
- package/dist/pages/docs/operations/troubleshooting/index.html +89 -0
- package/dist/pages/docs/pagefind/fragment/en_1126abb.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_19b3f6c.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_31aa611.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_38817cc.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_4184ad1.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_41db543.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_469f895.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_56e45b6.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_56fe7ca.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_5be5e44.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_603c2be.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_66b3118.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_6a19c31.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_74e9307.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_761fab1.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_7c9d5a2.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_818744b.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_8269752.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_88b38c1.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_98d9b16.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_a3d636e.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_b15ecf0.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_bd3e194.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_bfb13e9.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_d0fca9e.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_d49ed00.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_e0786b9.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_e298dee.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_ee82be6.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_f4db9e2.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/fragment/en_f6179a8.pf_fragment +0 -0
- package/dist/pages/docs/pagefind/index/en_7b1363c.pf_index +0 -0
- package/dist/pages/docs/pagefind/pagefind-component-ui.css +1509 -0
- package/dist/pages/docs/pagefind/pagefind-component-ui.js +56 -0
- package/dist/pages/docs/pagefind/pagefind-entry.json +1 -0
- package/dist/pages/docs/pagefind/pagefind-highlight.js +1070 -0
- package/dist/pages/docs/pagefind/pagefind-modular-ui.css +214 -0
- package/dist/pages/docs/pagefind/pagefind-modular-ui.js +8 -0
- package/dist/pages/docs/pagefind/pagefind-ui.css +1 -0
- package/dist/pages/docs/pagefind/pagefind-ui.js +2 -0
- package/dist/pages/docs/pagefind/pagefind-worker.js +6 -0
- package/dist/pages/docs/pagefind/pagefind.en_4e77743529.pf_meta +0 -0
- package/dist/pages/docs/pagefind/pagefind.js +6 -0
- package/dist/pages/docs/pagefind/wasm.en.pagefind +0 -0
- package/dist/pages/docs/pagefind/wasm.unknown.pagefind +0 -0
- package/dist/pages/docs/reference/cli/index.html +95 -0
- package/dist/pages/docs/reference/interface-guide/index.html +86 -0
- package/dist/pages/docs/reference/release-notes/index.html +80 -0
- package/dist/pages/docs/reference/settings/index.html +86 -0
- package/dist/pages/docs/reference/terminology/index.html +94 -0
- package/dist/pages/docs/sitemap-0.xml +1 -0
- package/dist/pages/docs/sitemap-index.xml +1 -0
- package/dist/pages/docs/start-here/example-projects/index.html +88 -0
- package/dist/pages/docs/start-here/first-workspace/index.html +91 -0
- package/dist/pages/docs/start-here/installation-first-run/index.html +92 -0
- package/dist/pages/docs/start-here/what-is-lineage/index.html +96 -0
- package/dist/pages/docs/workflows/back-up-approved-assets/index.html +88 -0
- package/dist/pages/docs/workflows/content-batches/index.html +88 -0
- package/dist/pages/docs/workflows/continue-new-agent-session/index.html +89 -0
- package/dist/pages/docs/workflows/create-grow-lineage/index.html +89 -0
- package/dist/pages/docs/workflows/generate-import-variations/index.html +92 -0
- package/dist/pages/docs/workflows/restore-earlier-attempt/index.html +87 -0
- package/dist/pages/docs/workflows/review-approve-assets/index.html +87 -0
- package/dist/pages/index.html +42 -0
- package/dist/pages/landing/index.html +42 -0
- package/dist/pages/lineage-showcase-cover-16x9.png +0 -0
- package/dist/runtime-build.json +5 -5
- package/dist/server.js +431 -46
- package/dist/server.js.map +4 -4
- package/dist/web/assets/app-CuBsKrS-.css +1 -0
- package/dist/web/assets/app-TEMX-pOn.js +50 -0
- package/dist/web/assets/landing-MwOFmHoi.js +2 -0
- package/dist/web/index.html +3 -3
- package/dist/web/landing/index.html +26 -3
- package/dist/web/lineage-showcase-cover-16x9.png +0 -0
- package/package.json +11 -2
- package/dist/web/assets/app-D-7R33Mc.js +0 -16
- package/dist/web/assets/landing-DIjBBL33.js +0 -2
package/dist/server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/server.ts
|
|
2
2
|
import express2 from "express";
|
|
3
3
|
import multer from "multer";
|
|
4
|
-
import { existsSync as
|
|
4
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
5
5
|
import { join as join14 } from "node:path";
|
|
6
6
|
|
|
7
7
|
// src/server/assetCore.ts
|
|
@@ -980,6 +980,21 @@ function lineageDb() {
|
|
|
980
980
|
where status = 'pending';
|
|
981
981
|
create index if not exists asset_reroll_requests_root_status
|
|
982
982
|
on asset_reroll_requests(project_id, root_asset_id, status, created_at);
|
|
983
|
+
create table if not exists asset_social_marks (
|
|
984
|
+
id text primary key,
|
|
985
|
+
project_id text not null references projects(id),
|
|
986
|
+
root_asset_id text not null references assets(id),
|
|
987
|
+
asset_id text not null references assets(id),
|
|
988
|
+
notes text,
|
|
989
|
+
marked_by text not null,
|
|
990
|
+
marked_at text not null,
|
|
991
|
+
unmarked_by text,
|
|
992
|
+
unmarked_at text,
|
|
993
|
+
updated_at text not null,
|
|
994
|
+
unique(project_id, root_asset_id, asset_id)
|
|
995
|
+
);
|
|
996
|
+
create index if not exists asset_social_marks_root_active
|
|
997
|
+
on asset_social_marks(project_id, root_asset_id, unmarked_at, marked_at);
|
|
983
998
|
create table if not exists asset_reviews (
|
|
984
999
|
asset_id text primary key references assets(id),
|
|
985
1000
|
review_state text not null check (review_state in ('unreviewed', 'approved', 'needs_revision', 'rejected', 'ignored')),
|
|
@@ -2177,7 +2192,7 @@ function lookupAssets(project, assetIds) {
|
|
|
2177
2192
|
}
|
|
2178
2193
|
|
|
2179
2194
|
// src/server/assetLineage.ts
|
|
2180
|
-
import { join as join7 } from "node:path";
|
|
2195
|
+
import { isAbsolute as isAbsolute2, join as join7, resolve as resolve5 } from "node:path";
|
|
2181
2196
|
|
|
2182
2197
|
// src/shared/edgeSummary.ts
|
|
2183
2198
|
var edgeSummaryWordLimit = 2;
|
|
@@ -3493,6 +3508,11 @@ function collectAssets(project, source) {
|
|
|
3493
3508
|
}
|
|
3494
3509
|
return assets;
|
|
3495
3510
|
}
|
|
3511
|
+
function absoluteLocalPath(localPath) {
|
|
3512
|
+
if (!localPath) return void 0;
|
|
3513
|
+
if (isAbsolute2(localPath)) return localPath;
|
|
3514
|
+
return resolve5(repoRoot, ".asset-scratch", localPath);
|
|
3515
|
+
}
|
|
3496
3516
|
function upsertProject(database, project) {
|
|
3497
3517
|
const timestamp = nowIso();
|
|
3498
3518
|
database.prepare(`
|
|
@@ -3972,6 +3992,19 @@ function getLineageSnapshot(project, assetId) {
|
|
|
3972
3992
|
const request = rerollRequestFrom(row);
|
|
3973
3993
|
return [request.node_asset_id, withRerollTask(request, lineageTasksByNode.get(request.node_asset_id)?.reroll)];
|
|
3974
3994
|
}));
|
|
3995
|
+
const hasSocialMarks = database.prepare("select 1 from sqlite_master where type = 'table' and name = 'asset_social_marks'").get() !== void 0;
|
|
3996
|
+
const socialMarkRows = ids.length > 0 && hasSocialMarks ? database.prepare(`select * from asset_social_marks where project_id = ? and root_asset_id = ? and unmarked_at is null and asset_id in (${placeholders2})`).all(project, root, ...ids) : [];
|
|
3997
|
+
const socialMarksByNode = new Map(socialMarkRows.map((row) => [String(row.asset_id), {
|
|
3998
|
+
active: true,
|
|
3999
|
+
asset_id: String(row.asset_id),
|
|
4000
|
+
id: String(row.id),
|
|
4001
|
+
marked_at: String(row.marked_at),
|
|
4002
|
+
marked_by: String(row.marked_by),
|
|
4003
|
+
notes: rowString(row.notes),
|
|
4004
|
+
project_id: String(row.project_id),
|
|
4005
|
+
root_asset_id: String(row.root_asset_id),
|
|
4006
|
+
updated_at: String(row.updated_at)
|
|
4007
|
+
}]));
|
|
3975
4008
|
const childIds = new Set(edges.map((edge) => edge.parent_asset_id));
|
|
3976
4009
|
const selectedIds = new Set(selected.map((row) => row.asset_id));
|
|
3977
4010
|
const selections = selected.map((row) => ({
|
|
@@ -3991,6 +4024,7 @@ function getLineageSnapshot(project, assetId) {
|
|
|
3991
4024
|
const lineageTasks = lineageTasksByNode.get(row.asset_id);
|
|
3992
4025
|
return {
|
|
3993
4026
|
...node,
|
|
4027
|
+
absolute_path: absoluteLocalPath(row.local_path),
|
|
3994
4028
|
attempt_count: attempts.length,
|
|
3995
4029
|
current_attempt: currentAttempt,
|
|
3996
4030
|
is_latest: !childIds.has(row.asset_id),
|
|
@@ -3999,6 +4033,7 @@ function getLineageSnapshot(project, assetId) {
|
|
|
3999
4033
|
preview_url: canPreviewLocally(row.media_type, previewPath) ? localPreviewUrl(project, previewPath) : void 0,
|
|
4000
4034
|
reroll_request: rerollsByNode.get(row.asset_id),
|
|
4001
4035
|
selection_note: nodeSelection?.notes,
|
|
4036
|
+
social_mark: socialMarksByNode.get(row.asset_id),
|
|
4002
4037
|
user_selected: selectedIds.has(row.asset_id)
|
|
4003
4038
|
};
|
|
4004
4039
|
});
|
|
@@ -4763,6 +4798,11 @@ function removeLineageNode(project, fields) {
|
|
|
4763
4798
|
`);
|
|
4764
4799
|
for (const edge of reparentedEdges) insertEdge.run(edge.id, project, edge.parent_asset_id, edge.child_asset_id, edge.created_at);
|
|
4765
4800
|
database.prepare("delete from asset_layouts where project_id = ? and root_asset_id = ? and asset_id = ?").run(project, root, fields.assetId);
|
|
4801
|
+
database.prepare(`
|
|
4802
|
+
update asset_social_marks
|
|
4803
|
+
set unmarked_by = 'lineage:remove-node', unmarked_at = ?, updated_at = ?
|
|
4804
|
+
where project_id = ? and root_asset_id = ? and asset_id = ? and unmarked_at is null
|
|
4805
|
+
`).run(timestamp, timestamp, project, root, fields.assetId);
|
|
4766
4806
|
compactSelectionsAfterRemove(database, project, root, fields.assetId, timestamp);
|
|
4767
4807
|
database.exec("commit");
|
|
4768
4808
|
} catch (error) {
|
|
@@ -4783,6 +4823,277 @@ function removeLineageNode(project, fields) {
|
|
|
4783
4823
|
};
|
|
4784
4824
|
}
|
|
4785
4825
|
|
|
4826
|
+
// src/server/assetSocialMarks.ts
|
|
4827
|
+
import { accessSync, constants, existsSync as existsSync8 } from "node:fs";
|
|
4828
|
+
import { isAbsolute as isAbsolute3, resolve as resolve6 } from "node:path";
|
|
4829
|
+
function markFromRow(row) {
|
|
4830
|
+
return {
|
|
4831
|
+
active: row.unmarked_at === null,
|
|
4832
|
+
asset_id: row.asset_id,
|
|
4833
|
+
id: row.id,
|
|
4834
|
+
marked_at: row.marked_at,
|
|
4835
|
+
marked_by: row.marked_by,
|
|
4836
|
+
notes: row.notes || void 0,
|
|
4837
|
+
project_id: row.project_id,
|
|
4838
|
+
root_asset_id: row.root_asset_id,
|
|
4839
|
+
unmarked_at: row.unmarked_at || void 0,
|
|
4840
|
+
unmarked_by: row.unmarked_by || void 0,
|
|
4841
|
+
updated_at: row.updated_at
|
|
4842
|
+
};
|
|
4843
|
+
}
|
|
4844
|
+
function requireCanonicalSnapshot(project, rootAssetId) {
|
|
4845
|
+
const snapshot = getLineageSnapshot(project, rootAssetId);
|
|
4846
|
+
if (snapshot.root_asset_id !== rootAssetId) {
|
|
4847
|
+
throw new LineageError(`Asset ${rootAssetId} is not a canonical lineage canvas root`, 400);
|
|
4848
|
+
}
|
|
4849
|
+
return snapshot;
|
|
4850
|
+
}
|
|
4851
|
+
function resolveVisibleNode(snapshot, asset) {
|
|
4852
|
+
const exactId = snapshot.nodes.find((node) => node.asset_id === asset);
|
|
4853
|
+
if (exactId) return exactId;
|
|
4854
|
+
const title = asset.trim().toLocaleLowerCase();
|
|
4855
|
+
const matches = snapshot.nodes.filter((node) => node.title.trim().toLocaleLowerCase() === title);
|
|
4856
|
+
if (matches.length > 1) throw new LineageError(`Asset title "${asset}" matches multiple visible nodes; use an exact asset ID.`, 409);
|
|
4857
|
+
if (matches.length === 1) return matches[0];
|
|
4858
|
+
throw new LineageError(`Asset ${asset} is not visible in lineage canvas ${snapshot.root_asset_id}`, 404);
|
|
4859
|
+
}
|
|
4860
|
+
function rootChannel(snapshot) {
|
|
4861
|
+
return snapshot.nodes.find((node) => node.asset_id === snapshot.root_asset_id)?.channel;
|
|
4862
|
+
}
|
|
4863
|
+
function requireActor(actor, field) {
|
|
4864
|
+
const normalized = actor.trim();
|
|
4865
|
+
if (!normalized) throw new LineageError(`Social mark ${field} is required`);
|
|
4866
|
+
return normalized;
|
|
4867
|
+
}
|
|
4868
|
+
function socialMarkId(project, rootAssetId, assetId) {
|
|
4869
|
+
return `${project}:${rootAssetId}:social:${assetId}`;
|
|
4870
|
+
}
|
|
4871
|
+
function activeRow(project, rootAssetId, assetId) {
|
|
4872
|
+
const database = lineageDb();
|
|
4873
|
+
try {
|
|
4874
|
+
return database.prepare(`
|
|
4875
|
+
select * from asset_social_marks
|
|
4876
|
+
where project_id = ? and root_asset_id = ? and asset_id = ? and unmarked_at is null
|
|
4877
|
+
`).get(project, rootAssetId, assetId);
|
|
4878
|
+
} finally {
|
|
4879
|
+
database.close();
|
|
4880
|
+
}
|
|
4881
|
+
}
|
|
4882
|
+
function mutationResponse(project, rootAssetId, active, mark, dryRun) {
|
|
4883
|
+
return {
|
|
4884
|
+
active,
|
|
4885
|
+
...dryRun ? { dryRun } : {},
|
|
4886
|
+
...mark ? { mark } : {},
|
|
4887
|
+
ok: true,
|
|
4888
|
+
snapshot: getLineageSnapshot(project, rootAssetId)
|
|
4889
|
+
};
|
|
4890
|
+
}
|
|
4891
|
+
function markAssetSocial(project, fields) {
|
|
4892
|
+
const snapshot = requireCanonicalSnapshot(project, fields.rootAssetId);
|
|
4893
|
+
const node = resolveVisibleNode(snapshot, fields.asset);
|
|
4894
|
+
const markedBy = requireActor(fields.markedBy, "markedBy");
|
|
4895
|
+
requireLineageWorkspaceClaimForWrite({
|
|
4896
|
+
channel: rootChannel(snapshot),
|
|
4897
|
+
claimToken: fields.claimToken,
|
|
4898
|
+
confirmWrite: fields.confirmWrite,
|
|
4899
|
+
project,
|
|
4900
|
+
rootAssetId: fields.rootAssetId,
|
|
4901
|
+
writeKind: "social_mark"
|
|
4902
|
+
});
|
|
4903
|
+
const existing = activeRow(project, fields.rootAssetId, node.asset_id);
|
|
4904
|
+
if (existing) return mutationResponse(project, fields.rootAssetId, true, markFromRow(existing), fields.confirmWrite ? void 0 : true);
|
|
4905
|
+
const timestamp = nowIso();
|
|
4906
|
+
const preview = {
|
|
4907
|
+
active: true,
|
|
4908
|
+
asset_id: node.asset_id,
|
|
4909
|
+
id: socialMarkId(project, fields.rootAssetId, node.asset_id),
|
|
4910
|
+
marked_at: timestamp,
|
|
4911
|
+
marked_by: markedBy,
|
|
4912
|
+
notes: fields.notes?.trim() || void 0,
|
|
4913
|
+
project_id: project,
|
|
4914
|
+
root_asset_id: fields.rootAssetId,
|
|
4915
|
+
updated_at: timestamp
|
|
4916
|
+
};
|
|
4917
|
+
if (!fields.confirmWrite) return mutationResponse(project, fields.rootAssetId, true, preview, true);
|
|
4918
|
+
const database = lineageDb();
|
|
4919
|
+
try {
|
|
4920
|
+
database.prepare(`
|
|
4921
|
+
insert into asset_social_marks (
|
|
4922
|
+
id, project_id, root_asset_id, asset_id, notes, marked_by, marked_at,
|
|
4923
|
+
unmarked_by, unmarked_at, updated_at
|
|
4924
|
+
) values (?, ?, ?, ?, ?, ?, ?, null, null, ?)
|
|
4925
|
+
on conflict(project_id, root_asset_id, asset_id) do update set
|
|
4926
|
+
notes = excluded.notes,
|
|
4927
|
+
marked_by = excluded.marked_by,
|
|
4928
|
+
marked_at = excluded.marked_at,
|
|
4929
|
+
unmarked_by = null,
|
|
4930
|
+
unmarked_at = null,
|
|
4931
|
+
updated_at = excluded.updated_at
|
|
4932
|
+
`).run(
|
|
4933
|
+
preview.id,
|
|
4934
|
+
project,
|
|
4935
|
+
fields.rootAssetId,
|
|
4936
|
+
node.asset_id,
|
|
4937
|
+
preview.notes || null,
|
|
4938
|
+
markedBy,
|
|
4939
|
+
timestamp,
|
|
4940
|
+
timestamp
|
|
4941
|
+
);
|
|
4942
|
+
} finally {
|
|
4943
|
+
database.close();
|
|
4944
|
+
}
|
|
4945
|
+
return mutationResponse(project, fields.rootAssetId, true, markFromRow(activeRow(project, fields.rootAssetId, node.asset_id)));
|
|
4946
|
+
}
|
|
4947
|
+
function unmarkAssetSocial(project, fields) {
|
|
4948
|
+
const snapshot = requireCanonicalSnapshot(project, fields.rootAssetId);
|
|
4949
|
+
const node = resolveVisibleNode(snapshot, fields.asset);
|
|
4950
|
+
const unmarkedBy = requireActor(fields.unmarkedBy, "unmarkedBy");
|
|
4951
|
+
requireLineageWorkspaceClaimForWrite({
|
|
4952
|
+
channel: rootChannel(snapshot),
|
|
4953
|
+
claimToken: fields.claimToken,
|
|
4954
|
+
confirmWrite: fields.confirmWrite,
|
|
4955
|
+
project,
|
|
4956
|
+
rootAssetId: fields.rootAssetId,
|
|
4957
|
+
writeKind: "social_unmark"
|
|
4958
|
+
});
|
|
4959
|
+
const existing = activeRow(project, fields.rootAssetId, node.asset_id);
|
|
4960
|
+
if (!existing) return mutationResponse(project, fields.rootAssetId, false, void 0, fields.confirmWrite ? void 0 : true);
|
|
4961
|
+
const timestamp = nowIso();
|
|
4962
|
+
const preview = markFromRow({
|
|
4963
|
+
...existing,
|
|
4964
|
+
unmarked_at: timestamp,
|
|
4965
|
+
unmarked_by: unmarkedBy,
|
|
4966
|
+
updated_at: timestamp
|
|
4967
|
+
});
|
|
4968
|
+
if (!fields.confirmWrite) return mutationResponse(project, fields.rootAssetId, false, preview, true);
|
|
4969
|
+
const database = lineageDb();
|
|
4970
|
+
try {
|
|
4971
|
+
database.prepare(`
|
|
4972
|
+
update asset_social_marks
|
|
4973
|
+
set unmarked_by = ?, unmarked_at = ?, updated_at = ?
|
|
4974
|
+
where project_id = ? and root_asset_id = ? and asset_id = ? and unmarked_at is null
|
|
4975
|
+
`).run(unmarkedBy, timestamp, timestamp, project, fields.rootAssetId, node.asset_id);
|
|
4976
|
+
} finally {
|
|
4977
|
+
database.close();
|
|
4978
|
+
}
|
|
4979
|
+
return mutationResponse(project, fields.rootAssetId, false, preview);
|
|
4980
|
+
}
|
|
4981
|
+
function absoluteLocalPath2(reference) {
|
|
4982
|
+
if (!reference) return void 0;
|
|
4983
|
+
if (isAbsolute3(reference)) return reference;
|
|
4984
|
+
const repoRelative = resolve6(repoRoot, reference);
|
|
4985
|
+
return existsSync8(repoRelative) || reference === ".asset-scratch" || reference.startsWith(".asset-scratch/") ? repoRelative : resolve6(repoRoot, ".asset-scratch", reference);
|
|
4986
|
+
}
|
|
4987
|
+
function isReadable(path) {
|
|
4988
|
+
try {
|
|
4989
|
+
accessSync(path, constants.R_OK);
|
|
4990
|
+
return true;
|
|
4991
|
+
} catch {
|
|
4992
|
+
return false;
|
|
4993
|
+
}
|
|
4994
|
+
}
|
|
4995
|
+
function listItem(project, rootAssetId, node, row) {
|
|
4996
|
+
const relativePath = node.current_attempt?.file_path || node.local_path;
|
|
4997
|
+
const absolutePath = absoluteLocalPath2(relativePath);
|
|
4998
|
+
const exists = absolutePath ? existsSync8(absolutePath) : false;
|
|
4999
|
+
const warnings = [];
|
|
5000
|
+
if (absolutePath && !exists) warnings.push(`Asset ${node.asset_id} local file is missing: ${absolutePath}`);
|
|
5001
|
+
if (absolutePath && exists && !isReadable(absolutePath)) {
|
|
5002
|
+
warnings.push(`Asset ${node.asset_id} local file is unreadable: ${absolutePath}. Check file permissions before handoff.`);
|
|
5003
|
+
}
|
|
5004
|
+
if (!absolutePath && node.s3_key) {
|
|
5005
|
+
warnings.push(`Asset ${node.asset_id} is only available in non-local storage; create a readable local copy before handoff.`);
|
|
5006
|
+
}
|
|
5007
|
+
if (!absolutePath && !node.s3_key) warnings.push(`Asset ${node.asset_id} has no local file or storage key.`);
|
|
5008
|
+
const base = `--project ${shellQuote(project)} --root ${shellQuote(rootAssetId)} --asset ${shellQuote(node.asset_id)}`;
|
|
5009
|
+
return {
|
|
5010
|
+
...markFromRow(row),
|
|
5011
|
+
checksum_sha256: node.current_attempt?.checksum_sha256 || node.checksum_sha256,
|
|
5012
|
+
commands: {
|
|
5013
|
+
mark: lineageCliCommand(`social mark ${base} --confirm-write`),
|
|
5014
|
+
unmark: lineageCliCommand(`social unmark ${base} --confirm-write`)
|
|
5015
|
+
},
|
|
5016
|
+
current_attempt: node.current_attempt,
|
|
5017
|
+
local: {
|
|
5018
|
+
absolute_path: absolutePath,
|
|
5019
|
+
exists,
|
|
5020
|
+
relative_path: relativePath
|
|
5021
|
+
},
|
|
5022
|
+
media_type: node.media_type,
|
|
5023
|
+
s3: node.s3_key ? { key: node.s3_key } : void 0,
|
|
5024
|
+
source: node.source,
|
|
5025
|
+
title: node.title,
|
|
5026
|
+
warnings
|
|
5027
|
+
};
|
|
5028
|
+
}
|
|
5029
|
+
function listAssetSocialMarks(project, rootAssetId) {
|
|
5030
|
+
const snapshot = requireCanonicalSnapshot(project, rootAssetId);
|
|
5031
|
+
const database = lineageDb();
|
|
5032
|
+
let rows;
|
|
5033
|
+
try {
|
|
5034
|
+
const hasSocialMarks = database.prepare("select 1 from sqlite_master where type = 'table' and name = 'asset_social_marks'").get() !== void 0;
|
|
5035
|
+
rows = hasSocialMarks ? database.prepare(`
|
|
5036
|
+
select * from asset_social_marks
|
|
5037
|
+
where project_id = ? and root_asset_id = ? and unmarked_at is null
|
|
5038
|
+
order by marked_at, asset_id
|
|
5039
|
+
`).all(project, rootAssetId) : [];
|
|
5040
|
+
} finally {
|
|
5041
|
+
database.close();
|
|
5042
|
+
}
|
|
5043
|
+
const nodesById = new Map(snapshot.nodes.map((node) => [node.asset_id, node]));
|
|
5044
|
+
return {
|
|
5045
|
+
commands: {
|
|
5046
|
+
mark: lineageCliCommand(`social mark --project ${shellQuote(project)} --root ${shellQuote(rootAssetId)} --asset <asset-id> --confirm-write`)
|
|
5047
|
+
},
|
|
5048
|
+
fetchedAt: nowIso(),
|
|
5049
|
+
marks: rows.flatMap((row) => {
|
|
5050
|
+
const node = nodesById.get(row.asset_id);
|
|
5051
|
+
return node ? [listItem(project, rootAssetId, node, row)] : [];
|
|
5052
|
+
}),
|
|
5053
|
+
project,
|
|
5054
|
+
root_asset_id: rootAssetId,
|
|
5055
|
+
schema_version: "lineage.social_marks.v1",
|
|
5056
|
+
workspace: {
|
|
5057
|
+
id: lineageWorkspaceId(project, rootAssetId),
|
|
5058
|
+
root_asset_id: rootAssetId
|
|
5059
|
+
}
|
|
5060
|
+
};
|
|
5061
|
+
}
|
|
5062
|
+
function bodyString(req, key) {
|
|
5063
|
+
const value = req.body?.[key];
|
|
5064
|
+
return typeof value === "string" ? value : void 0;
|
|
5065
|
+
}
|
|
5066
|
+
function requestClaimToken(req) {
|
|
5067
|
+
return req.header("X-Lineage-Claim-Token") || bodyString(req, "claimToken");
|
|
5068
|
+
}
|
|
5069
|
+
function registerAssetSocialMarkRoutes(app2, projectFrom2, asyncRoute2) {
|
|
5070
|
+
app2.get("/api/lineage/:rootAssetId/social-marks", asyncRoute2((req, res) => {
|
|
5071
|
+
res.json(listAssetSocialMarks(
|
|
5072
|
+
projectFrom2({ query: req.query }),
|
|
5073
|
+
req.params.rootAssetId
|
|
5074
|
+
));
|
|
5075
|
+
}));
|
|
5076
|
+
app2.post("/api/lineage/:rootAssetId/social-marks/:assetId", asyncRoute2((req, res) => {
|
|
5077
|
+
res.json(markAssetSocial(projectFrom2({ body: req.body, query: req.query }), {
|
|
5078
|
+
asset: req.params.assetId,
|
|
5079
|
+
claimToken: requestClaimToken(req),
|
|
5080
|
+
confirmWrite: req.body?.confirmWrite === true,
|
|
5081
|
+
markedBy: bodyString(req, "markedBy") || bodyString(req, "actor") || "human",
|
|
5082
|
+
notes: bodyString(req, "notes"),
|
|
5083
|
+
rootAssetId: req.params.rootAssetId
|
|
5084
|
+
}));
|
|
5085
|
+
}));
|
|
5086
|
+
app2.post("/api/lineage/:rootAssetId/social-marks/:assetId/unmark", asyncRoute2((req, res) => {
|
|
5087
|
+
res.json(unmarkAssetSocial(projectFrom2({ body: req.body, query: req.query }), {
|
|
5088
|
+
asset: req.params.assetId,
|
|
5089
|
+
claimToken: requestClaimToken(req),
|
|
5090
|
+
confirmWrite: req.body?.confirmWrite === true,
|
|
5091
|
+
rootAssetId: req.params.rootAssetId,
|
|
5092
|
+
unmarkedBy: bodyString(req, "unmarkedBy") || bodyString(req, "actor") || "human"
|
|
5093
|
+
}));
|
|
5094
|
+
}));
|
|
5095
|
+
}
|
|
5096
|
+
|
|
4786
5097
|
// src/server/assetLedger.ts
|
|
4787
5098
|
function allAssets(project, source) {
|
|
4788
5099
|
const first = listAssets(project, { page: 1, pageSize: 100, source });
|
|
@@ -5929,6 +6240,49 @@ function registerAgentClaimRoutes(app2, projectFrom2, asyncRoute2) {
|
|
|
5929
6240
|
}));
|
|
5930
6241
|
}
|
|
5931
6242
|
|
|
6243
|
+
// src/shared/adapterCatalog.ts
|
|
6244
|
+
var adapterCatalogJson = `[
|
|
6245
|
+
{
|
|
6246
|
+
"adapterType": "cloud",
|
|
6247
|
+
"capabilityId": "cloud-storage",
|
|
6248
|
+
"capabilityLabel": "Cloud storage",
|
|
6249
|
+
"description": "Inspect and back up approved assets with an explicitly configured cloud storage provider.",
|
|
6250
|
+
"docsSlug": "integrations/cloud-storage",
|
|
6251
|
+
"liveBehavior": "available",
|
|
6252
|
+
"maturity": "Available",
|
|
6253
|
+
"providerId": "s3",
|
|
6254
|
+
"providerLabel": "Amazon S3"
|
|
6255
|
+
},
|
|
6256
|
+
{
|
|
6257
|
+
"adapterType": "scheduler",
|
|
6258
|
+
"capabilityId": "social-scheduling",
|
|
6259
|
+
"capabilityLabel": "Social scheduling",
|
|
6260
|
+
"description": "Prepare and validate reviewed social posts for an external scheduler without publishing them live.",
|
|
6261
|
+
"docsSlug": "integrations/social-scheduling",
|
|
6262
|
+
"liveBehavior": "disabled",
|
|
6263
|
+
"maturity": "Preview",
|
|
6264
|
+
"providerId": "buffer",
|
|
6265
|
+
"providerLabel": "Buffer"
|
|
6266
|
+
},
|
|
6267
|
+
{
|
|
6268
|
+
"adapterType": "image_generator",
|
|
6269
|
+
"capabilityId": "image-generation",
|
|
6270
|
+
"capabilityLabel": "Image generation",
|
|
6271
|
+
"description": "Create Codex generation handoffs and durable import receipts without embedding a model service.",
|
|
6272
|
+
"docsSlug": "integrations/image-generation",
|
|
6273
|
+
"liveBehavior": "handoff",
|
|
6274
|
+
"maturity": "Available",
|
|
6275
|
+
"providerId": "codex-handoff",
|
|
6276
|
+
"providerLabel": "Codex handoff"
|
|
6277
|
+
}
|
|
6278
|
+
]`;
|
|
6279
|
+
var adapterCatalog = JSON.parse(adapterCatalogJson);
|
|
6280
|
+
function findAdapterCatalogEntry(adapterType, providerId) {
|
|
6281
|
+
const entry = adapterCatalog.find((item) => item.adapterType === adapterType && item.providerId === providerId);
|
|
6282
|
+
if (!entry) throw new Error(`Missing public adapter catalog entry: ${adapterType}/${providerId}`);
|
|
6283
|
+
return entry;
|
|
6284
|
+
}
|
|
6285
|
+
|
|
5932
6286
|
// src/server/adapters/adapterSettings.ts
|
|
5933
6287
|
var AdapterSettingsError = class extends Error {
|
|
5934
6288
|
constructor(message, status = 400) {
|
|
@@ -5944,8 +6298,8 @@ var definitions = [
|
|
|
5944
6298
|
{
|
|
5945
6299
|
adapter_type: "cloud",
|
|
5946
6300
|
default_enabled: false,
|
|
5947
|
-
description: "
|
|
5948
|
-
label: "
|
|
6301
|
+
description: findAdapterCatalogEntry("cloud", "s3").description,
|
|
6302
|
+
label: findAdapterCatalogEntry("cloud", "s3").providerLabel,
|
|
5949
6303
|
provider: "s3",
|
|
5950
6304
|
safeConfig: (project) => {
|
|
5951
6305
|
if (project === defaultProject) return { bucket: "", mode: "local-public-fallback", region: "" };
|
|
@@ -5957,8 +6311,8 @@ var definitions = [
|
|
|
5957
6311
|
{
|
|
5958
6312
|
adapter_type: "scheduler",
|
|
5959
6313
|
default_enabled: false,
|
|
5960
|
-
description: "
|
|
5961
|
-
label: "
|
|
6314
|
+
description: findAdapterCatalogEntry("scheduler", "buffer").description,
|
|
6315
|
+
label: findAdapterCatalogEntry("scheduler", "buffer").providerLabel,
|
|
5962
6316
|
provider: "buffer",
|
|
5963
6317
|
safeConfig: () => ({ defaultMode: "dry-run" }),
|
|
5964
6318
|
secret_ref: "env:LINEAGE_SCHEDULER_TOKEN"
|
|
@@ -5966,8 +6320,8 @@ var definitions = [
|
|
|
5966
6320
|
{
|
|
5967
6321
|
adapter_type: "image_generator",
|
|
5968
6322
|
default_enabled: true,
|
|
5969
|
-
description: "
|
|
5970
|
-
label: "
|
|
6323
|
+
description: findAdapterCatalogEntry("image_generator", "codex-handoff").description,
|
|
6324
|
+
label: findAdapterCatalogEntry("image_generator", "codex-handoff").providerLabel,
|
|
5971
6325
|
provider: "codex-handoff",
|
|
5972
6326
|
safeConfig: () => ({ clearSelectionAfterImport: true, defaultVariationCount: 3, receipts: "sqlite" }),
|
|
5973
6327
|
secret_ref: null
|
|
@@ -6818,7 +7172,7 @@ function registerAdapterRoutes(app2, projectFrom2, asyncRoute2) {
|
|
|
6818
7172
|
import { Router } from "express";
|
|
6819
7173
|
|
|
6820
7174
|
// src/server/contentBatchImport.ts
|
|
6821
|
-
import { existsSync as
|
|
7175
|
+
import { existsSync as existsSync9, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "node:fs";
|
|
6822
7176
|
import { basename as basename3, join as join10, relative as relative3 } from "node:path";
|
|
6823
7177
|
function walk(dir) {
|
|
6824
7178
|
return readdirSync3(dir, { withFileTypes: true }).flatMap((entry) => {
|
|
@@ -6873,7 +7227,7 @@ function itemFromFile(file) {
|
|
|
6873
7227
|
}
|
|
6874
7228
|
function demoMarkdownItems(kind) {
|
|
6875
7229
|
const root = process.env.LINEAGE_CONTENT_SOURCE_ROOT || join10(repoRoot, "demo-project", "channels");
|
|
6876
|
-
if (!
|
|
7230
|
+
if (!existsSync9(root)) return [];
|
|
6877
7231
|
return walk(root).map(itemFromFile).filter((item) => Boolean(item)).filter((item) => kind === "all" || `${item.kind}s` === kind).sort((a, b) => a.sourcePath.localeCompare(b.sourcePath));
|
|
6878
7232
|
}
|
|
6879
7233
|
function importDemoContentBatch(project, options) {
|
|
@@ -7212,8 +7566,8 @@ function contentBatchRouter(projectFrom2) {
|
|
|
7212
7566
|
}
|
|
7213
7567
|
|
|
7214
7568
|
// src/server/generationReceipts.ts
|
|
7215
|
-
import { existsSync as
|
|
7216
|
-
import { relative as relative4, resolve as
|
|
7569
|
+
import { existsSync as existsSync10, realpathSync as realpathSync2, statSync as statSync4 } from "node:fs";
|
|
7570
|
+
import { relative as relative4, resolve as resolve7 } from "node:path";
|
|
7217
7571
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
7218
7572
|
|
|
7219
7573
|
// src/shared/generationOutputManifest.ts
|
|
@@ -7751,8 +8105,8 @@ function isPathInside2(child, parent) {
|
|
|
7751
8105
|
return Boolean(rel) && !rel.startsWith("..") && !rel.startsWith("/");
|
|
7752
8106
|
}
|
|
7753
8107
|
function scratchCandidate(file) {
|
|
7754
|
-
const scratchRoot =
|
|
7755
|
-
const candidate = file.startsWith(".asset-scratch/") ||
|
|
8108
|
+
const scratchRoot = resolve7(repoRoot, ".asset-scratch");
|
|
8109
|
+
const candidate = file.startsWith(".asset-scratch/") || resolve7(file).startsWith(scratchRoot) ? resolve7(repoRoot, file) : resolve7(scratchRoot, file);
|
|
7756
8110
|
if (!isPathInside2(candidate, scratchRoot)) throw new GenerationReceiptError(`Import file must be under .asset-scratch: ${file}`);
|
|
7757
8111
|
return { candidate, scratchRoot };
|
|
7758
8112
|
}
|
|
@@ -7762,7 +8116,7 @@ function resolveScratchManifestPath(file) {
|
|
|
7762
8116
|
}
|
|
7763
8117
|
function resolveScratchFile(file) {
|
|
7764
8118
|
const { candidate, scratchRoot } = scratchCandidate(file);
|
|
7765
|
-
if (!
|
|
8119
|
+
if (!existsSync10(candidate)) throw new GenerationReceiptError(`Missing import file: ${file}`, 404);
|
|
7766
8120
|
const realScratchRoot = realpathSync2(scratchRoot);
|
|
7767
8121
|
const realCandidate = realpathSync2(candidate);
|
|
7768
8122
|
if (!isPathInside2(realCandidate, realScratchRoot)) throw new GenerationReceiptError(`Import file must be under .asset-scratch: ${file}`);
|
|
@@ -8094,7 +8448,7 @@ function registerLineageTaskRoutes(app2, projectFrom2, asyncRoute2) {
|
|
|
8094
8448
|
|
|
8095
8449
|
// src/server/assetLineageDemo.ts
|
|
8096
8450
|
import { createHash as createHash5 } from "node:crypto";
|
|
8097
|
-
import { copyFileSync as copyFileSync3, existsSync as
|
|
8451
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync11, mkdirSync as mkdirSync7, mkdtempSync, readFileSync as readFileSync6, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
8098
8452
|
import { tmpdir } from "node:os";
|
|
8099
8453
|
import { dirname as dirname5, join as join11, posix } from "node:path";
|
|
8100
8454
|
import { gunzipSync } from "node:zlib";
|
|
@@ -8166,9 +8520,9 @@ function swissifierRerollFixturePath(attempt) {
|
|
|
8166
8520
|
}
|
|
8167
8521
|
function swissifierSourcePath(manifest, asset, sourceDir) {
|
|
8168
8522
|
const direct = join11(sourceDir, asset.file);
|
|
8169
|
-
if (
|
|
8523
|
+
if (existsSync11(direct)) return direct;
|
|
8170
8524
|
const nested = join11(sourceDir, manifest.media.target_dir, asset.file);
|
|
8171
|
-
return
|
|
8525
|
+
return existsSync11(nested) ? nested : null;
|
|
8172
8526
|
}
|
|
8173
8527
|
function swissifierMediaState(manifest) {
|
|
8174
8528
|
const missing = [];
|
|
@@ -8176,7 +8530,7 @@ function swissifierMediaState(manifest) {
|
|
|
8176
8530
|
for (const asset of manifest.assets) {
|
|
8177
8531
|
const relativePath = swissifierRelativePath(manifest, asset);
|
|
8178
8532
|
const path = swissifierFilePath(manifest, asset);
|
|
8179
|
-
if (!
|
|
8533
|
+
if (!existsSync11(path)) {
|
|
8180
8534
|
missing.push(relativePath);
|
|
8181
8535
|
continue;
|
|
8182
8536
|
}
|
|
@@ -8268,7 +8622,7 @@ async function downloadBuffer(url, maxBytes) {
|
|
|
8268
8622
|
return buffer;
|
|
8269
8623
|
}
|
|
8270
8624
|
function missingDemoMedia(project) {
|
|
8271
|
-
return demoAssets.filter((asset) => !
|
|
8625
|
+
return demoAssets.filter((asset) => !existsSync11(demoFilePath(project, asset))).map((asset) => demoRelativePath(project, asset));
|
|
8272
8626
|
}
|
|
8273
8627
|
function demoSeedMediaStatus(project = defaultProject) {
|
|
8274
8628
|
const missing = missingDemoMedia(project);
|
|
@@ -8463,7 +8817,7 @@ function writeDemoFiles(project) {
|
|
|
8463
8817
|
}
|
|
8464
8818
|
function swissifierRerollAsset(attempt) {
|
|
8465
8819
|
const source = swissifierRerollFixturePath(attempt);
|
|
8466
|
-
if (!
|
|
8820
|
+
if (!existsSync11(source)) throw new Error(`Missing Swissifier re-roll fixture media: ${attempt.file}`);
|
|
8467
8821
|
const body = readFileSync6(source);
|
|
8468
8822
|
if (body.length !== attempt.size_bytes) throw new Error(`Unexpected Swissifier re-roll fixture size for ${attempt.file}`);
|
|
8469
8823
|
const checksumSha256 = sha256Hex(body);
|
|
@@ -8886,8 +9240,8 @@ function registerLineageWorkspaceRoutes(app2, projectFrom2, asyncRoute2) {
|
|
|
8886
9240
|
// src/server/runtimeInfo.ts
|
|
8887
9241
|
import { createHash as createHash6 } from "node:crypto";
|
|
8888
9242
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
8889
|
-
import { existsSync as
|
|
8890
|
-
import { dirname as dirname6, isAbsolute as
|
|
9243
|
+
import { existsSync as existsSync12, lstatSync as lstatSync3, readFileSync as readFileSync7, readdirSync as readdirSync4, readlinkSync, realpathSync as realpathSync3, statSync as statSync5 } from "node:fs";
|
|
9244
|
+
import { dirname as dirname6, isAbsolute as isAbsolute4, join as join12, resolve as resolve8 } from "node:path";
|
|
8891
9245
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
8892
9246
|
|
|
8893
9247
|
// src/shared/runtimeInfoTypes.ts
|
|
@@ -8906,7 +9260,7 @@ function isLineagePackageRoot(root) {
|
|
|
8906
9260
|
}
|
|
8907
9261
|
function executingCodeRoot() {
|
|
8908
9262
|
const moduleDirectory = dirname6(fileURLToPath2(import.meta.url));
|
|
8909
|
-
const candidates = [
|
|
9263
|
+
const candidates = [resolve8(moduleDirectory, "../.."), resolve8(moduleDirectory, "..")];
|
|
8910
9264
|
const root = candidates.find(isLineagePackageRoot);
|
|
8911
9265
|
if (!root) throw new Error(`Unable to derive Lineage code root from executing module ${fileURLToPath2(import.meta.url)}`);
|
|
8912
9266
|
return canonicalRoot(root);
|
|
@@ -8919,7 +9273,7 @@ function canonicalRoot(root) {
|
|
|
8919
9273
|
try {
|
|
8920
9274
|
return realpathSync3(root);
|
|
8921
9275
|
} catch {
|
|
8922
|
-
return
|
|
9276
|
+
return resolve8(root);
|
|
8923
9277
|
}
|
|
8924
9278
|
}
|
|
8925
9279
|
function packageInfo(root = codeRoot) {
|
|
@@ -9019,7 +9373,7 @@ function readInstallReceipt(path, errors) {
|
|
|
9019
9373
|
return void 0;
|
|
9020
9374
|
}
|
|
9021
9375
|
let receipt;
|
|
9022
|
-
const receiptPath =
|
|
9376
|
+
const receiptPath = resolve8(path);
|
|
9023
9377
|
try {
|
|
9024
9378
|
receipt = JSON.parse(readFileSync7(receiptPath, "utf8"));
|
|
9025
9379
|
} catch (error) {
|
|
@@ -9027,7 +9381,7 @@ function readInstallReceipt(path, errors) {
|
|
|
9027
9381
|
return void 0;
|
|
9028
9382
|
}
|
|
9029
9383
|
if (receipt.schema_version !== lineageRuntimeInstallSchemaVersion) errors.push(`Unsupported runtime install receipt schema: ${String(receipt.schema_version)}`);
|
|
9030
|
-
if (!
|
|
9384
|
+
if (!isAbsolute4(receipt.package_root || "")) errors.push("Runtime install receipt package_root must be absolute");
|
|
9031
9385
|
if (!receipt.package_integrity?.startsWith("sha512-")) errors.push("Runtime install receipt package integrity is invalid");
|
|
9032
9386
|
if (receipt.package_source !== "registry" && receipt.package_source !== "local") errors.push("Runtime install receipt package source is invalid");
|
|
9033
9387
|
if (typeof receipt.package_spec !== "string" || !receipt.package_spec) errors.push("Runtime install receipt package spec is invalid");
|
|
@@ -9108,8 +9462,8 @@ function packageCodeIdentity(root, channel, info, receiptPath) {
|
|
|
9108
9462
|
function getLineageCodeIdentity(channel, options = {}) {
|
|
9109
9463
|
const root = canonicalRoot(options.root || codeRoot);
|
|
9110
9464
|
const info = packageInfo(root);
|
|
9111
|
-
if (
|
|
9112
|
-
if (
|
|
9465
|
+
if (existsSync12(join12(root, ".git"))) return checkoutCodeIdentity(root, channel, info.version);
|
|
9466
|
+
if (existsSync12(join12(root, "package.json"))) {
|
|
9113
9467
|
return packageCodeIdentity(root, channel, info, options.receiptPath ?? process.env.LINEAGE_RUNTIME_RECEIPT);
|
|
9114
9468
|
}
|
|
9115
9469
|
const errors = [`Code root has neither checkout metadata nor package.json: ${root}`];
|
|
@@ -9148,7 +9502,7 @@ function getLineageRuntimeInfo(options = {}) {
|
|
|
9148
9502
|
const dbPath = options.dbPath || lineageDbPath();
|
|
9149
9503
|
const channel = normalizeRuntimeChannel(options.channel || process.env.LINEAGE_CHANNEL || process.env.LINEAGE_RELEASE_CHANNEL);
|
|
9150
9504
|
const code = options.code || getLineageCodeIdentity(channel);
|
|
9151
|
-
const databaseInfo = { exists:
|
|
9505
|
+
const databaseInfo = { exists: existsSync12(dbPath), path: dbPath };
|
|
9152
9506
|
const schema = { migration_keys: [] };
|
|
9153
9507
|
const serviceInstanceId = process.env.LINEAGE_SERVICE_INSTANCE_ID;
|
|
9154
9508
|
const launcherPid = process.env.LINEAGE_LAUNCHER_PID ? Number(process.env.LINEAGE_LAUNCHER_PID) : void 0;
|
|
@@ -9288,14 +9642,14 @@ function registerManagedWriterRoute(app2, fields) {
|
|
|
9288
9642
|
}
|
|
9289
9643
|
|
|
9290
9644
|
// src/cli/lineageCli.ts
|
|
9291
|
-
import { existsSync as
|
|
9292
|
-
import { dirname as dirname7, join as join13, resolve as
|
|
9645
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "node:fs";
|
|
9646
|
+
import { dirname as dirname7, join as join13, resolve as resolve10 } from "node:path";
|
|
9293
9647
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
9294
9648
|
|
|
9295
9649
|
// src/server/lineageSelectionPacket.ts
|
|
9296
9650
|
import { createHash as createHash7 } from "node:crypto";
|
|
9297
|
-
import { existsSync as
|
|
9298
|
-
import { isAbsolute as
|
|
9651
|
+
import { existsSync as existsSync13, statSync as statSync6 } from "node:fs";
|
|
9652
|
+
import { isAbsolute as isAbsolute5, resolve as resolve9 } from "node:path";
|
|
9299
9653
|
var LineageSelectionPacketError = class extends Error {
|
|
9300
9654
|
constructor(message, warnings = [], errors = [], diagnostics = []) {
|
|
9301
9655
|
super(message);
|
|
@@ -9341,13 +9695,13 @@ function resolveWorkspace(project, options) {
|
|
|
9341
9695
|
}
|
|
9342
9696
|
function resolveLocalReference(reference) {
|
|
9343
9697
|
if (!reference) return void 0;
|
|
9344
|
-
if (
|
|
9345
|
-
const repoRelative =
|
|
9346
|
-
if (
|
|
9347
|
-
return
|
|
9698
|
+
if (isAbsolute5(reference)) return reference;
|
|
9699
|
+
const repoRelative = resolve9(repoRoot, reference);
|
|
9700
|
+
if (existsSync13(repoRelative)) return repoRelative;
|
|
9701
|
+
return resolve9(repoRoot, ".asset-scratch", reference);
|
|
9348
9702
|
}
|
|
9349
9703
|
function fileSize(path) {
|
|
9350
|
-
if (!path || !
|
|
9704
|
+
if (!path || !existsSync13(path)) return void 0;
|
|
9351
9705
|
try {
|
|
9352
9706
|
return statSync6(path).size;
|
|
9353
9707
|
} catch {
|
|
@@ -9375,7 +9729,7 @@ function currentAttemptFor(node) {
|
|
|
9375
9729
|
function assetForNode(node, catalogAsset, warnings) {
|
|
9376
9730
|
const localReference = catalogAsset?.local?.absolute_path || node.current_attempt?.file_path || node.local_path || catalogAsset?.local?.relative_path;
|
|
9377
9731
|
const absolutePath = catalogAsset?.local?.absolute_path || resolveLocalReference(localReference);
|
|
9378
|
-
const localExists = absolutePath ?
|
|
9732
|
+
const localExists = absolutePath ? existsSync13(absolutePath) : false;
|
|
9379
9733
|
const hasLocalClaim = Boolean(absolutePath || node.local_path || catalogAsset?.local?.relative_path);
|
|
9380
9734
|
const s3Key = catalogAsset?.s3?.key || node.s3_key;
|
|
9381
9735
|
const hasS3 = Boolean(s3Key);
|
|
@@ -9532,7 +9886,7 @@ function assetForNodeV2(node, visibleCatalogAsset, catalogById, warnings, errors
|
|
|
9532
9886
|
const mediaCatalogAsset = currentAttemptCatalogAsset || (isVisibleNodeAttempt ? visibleCatalogAsset : void 0);
|
|
9533
9887
|
const localReference = currentAttempt.file_path || mediaCatalogAsset?.local?.absolute_path || mediaCatalogAsset?.local?.relative_path || (isVisibleNodeAttempt ? node.local_path : void 0);
|
|
9534
9888
|
const absolutePath = resolveLocalReference(localReference);
|
|
9535
|
-
const localExists = absolutePath ?
|
|
9889
|
+
const localExists = absolutePath ? existsSync13(absolutePath) : false;
|
|
9536
9890
|
const hasLocalClaim = Boolean(localReference);
|
|
9537
9891
|
const s3Key = mediaCatalogAsset?.s3?.key || (isVisibleNodeAttempt ? node.s3_key : void 0);
|
|
9538
9892
|
const hasS3 = Boolean(s3Key);
|
|
@@ -9797,7 +10151,7 @@ function getLineageSelectionPacket(project, options = {}) {
|
|
|
9797
10151
|
|
|
9798
10152
|
// src/cli/lineageCli.ts
|
|
9799
10153
|
function packageRoot2() {
|
|
9800
|
-
return
|
|
10154
|
+
return resolve10(dirname7(fileURLToPath3(import.meta.url)), "..", "..");
|
|
9801
10155
|
}
|
|
9802
10156
|
function packageVersion() {
|
|
9803
10157
|
try {
|
|
@@ -9830,7 +10184,7 @@ function readOptions(args, name) {
|
|
|
9830
10184
|
}
|
|
9831
10185
|
function readJsonFile(path, label) {
|
|
9832
10186
|
try {
|
|
9833
|
-
return JSON.parse(readFileSync8(
|
|
10187
|
+
return JSON.parse(readFileSync8(resolve10(path), "utf8"));
|
|
9834
10188
|
} catch (error) {
|
|
9835
10189
|
throw new Error(`${label} must be a readable JSON file: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
9836
10190
|
}
|
|
@@ -9849,7 +10203,7 @@ function parentFilesOption(value) {
|
|
|
9849
10203
|
return mappings;
|
|
9850
10204
|
}
|
|
9851
10205
|
function resolveCliAssetRoot(args) {
|
|
9852
|
-
return
|
|
10206
|
+
return resolve10(readOption(args, "--asset-root") || process.env.LINEAGE_ASSET_ROOT || packageRoot);
|
|
9853
10207
|
}
|
|
9854
10208
|
function configureCliAssetRoot(args) {
|
|
9855
10209
|
const assetRoot = resolveCliAssetRoot(args);
|
|
@@ -9914,7 +10268,7 @@ function runLineageDataCommand(command, args) {
|
|
|
9914
10268
|
});
|
|
9915
10269
|
const out = readOption(args, "--out");
|
|
9916
10270
|
if (out) {
|
|
9917
|
-
const outPath =
|
|
10271
|
+
const outPath = resolve10(out);
|
|
9918
10272
|
mkdirSync8(dirname7(outPath), { recursive: true });
|
|
9919
10273
|
writeFileSync6(outPath, `${JSON.stringify(packet, null, 2)}
|
|
9920
10274
|
`);
|
|
@@ -10025,6 +10379,35 @@ function runLineageDataCommand(command, args) {
|
|
|
10025
10379
|
}
|
|
10026
10380
|
throw new Error(`Unknown reroll command: ${subcommand}`);
|
|
10027
10381
|
}
|
|
10382
|
+
if (command === "social") {
|
|
10383
|
+
const subcommand = positionalArgs(args)[0] || "";
|
|
10384
|
+
const explicitProject = readOption(args, "--project");
|
|
10385
|
+
const asset = readOption(args, "--asset");
|
|
10386
|
+
if (!explicitProject) throw new Error(`lineage social ${subcommand || "command"} requires --project`);
|
|
10387
|
+
if (!options.rootAssetId) throw new Error(`lineage social ${subcommand || "command"} requires --root`);
|
|
10388
|
+
if (subcommand === "list") return listAssetSocialMarks(explicitProject, options.rootAssetId);
|
|
10389
|
+
if (!asset) throw new Error(`lineage social ${subcommand || "command"} requires --asset`);
|
|
10390
|
+
if (subcommand === "mark") {
|
|
10391
|
+
return markAssetSocial(explicitProject, {
|
|
10392
|
+
asset,
|
|
10393
|
+
claimToken: options.claimToken,
|
|
10394
|
+
confirmWrite: options.confirmWrite,
|
|
10395
|
+
markedBy: readOption(args, "--actor") || "agent",
|
|
10396
|
+
notes: readOption(args, "--notes"),
|
|
10397
|
+
rootAssetId: options.rootAssetId
|
|
10398
|
+
});
|
|
10399
|
+
}
|
|
10400
|
+
if (subcommand === "unmark") {
|
|
10401
|
+
return unmarkAssetSocial(explicitProject, {
|
|
10402
|
+
asset,
|
|
10403
|
+
claimToken: options.claimToken,
|
|
10404
|
+
confirmWrite: options.confirmWrite,
|
|
10405
|
+
rootAssetId: options.rootAssetId,
|
|
10406
|
+
unmarkedBy: readOption(args, "--actor") || "agent"
|
|
10407
|
+
});
|
|
10408
|
+
}
|
|
10409
|
+
throw new Error(`Unknown social command: ${subcommand}`);
|
|
10410
|
+
}
|
|
10028
10411
|
if (command === "tasks") {
|
|
10029
10412
|
const subcommand = positionalArgs(args)[0] || "";
|
|
10030
10413
|
const taskId = readOption(args, "--task");
|
|
@@ -10097,6 +10480,7 @@ function lineageCliCanDelegateMutation(command, args) {
|
|
|
10097
10480
|
if (command === "link-child") return true;
|
|
10098
10481
|
if (command === "generate") return positions[0] === "image" && ["plan", "import"].includes(positions[1] || "");
|
|
10099
10482
|
if (command === "reroll") return ["mark", "cancel", "plan", "import"].includes(subcommand);
|
|
10483
|
+
if (command === "social") return ["mark", "unmark"].includes(subcommand);
|
|
10100
10484
|
if (command === "tasks") return ["claim", "start", "comment", "cancel", "override", "instructions"].includes(subcommand);
|
|
10101
10485
|
if (command === "agent") return ["claim", "heartbeat", "release", "revoke", "transfer"].includes(subcommand);
|
|
10102
10486
|
return false;
|
|
@@ -10330,6 +10714,7 @@ app.get(
|
|
|
10330
10714
|
);
|
|
10331
10715
|
registerLineageWorkspaceRoutes(app, projectFrom, asyncRoute);
|
|
10332
10716
|
registerLineageTaskRoutes(app, projectFrom, asyncRoute);
|
|
10717
|
+
registerAssetSocialMarkRoutes(app, projectFrom, asyncRoute);
|
|
10333
10718
|
app.get("/api/lineage/:rootAssetId/rerolls", asyncRoute((req, res) => {
|
|
10334
10719
|
res.json(listLineageRerollRequests(projectFrom(req), req.params.rootAssetId));
|
|
10335
10720
|
}));
|
|
@@ -10581,7 +10966,7 @@ app.post(
|
|
|
10581
10966
|
);
|
|
10582
10967
|
if (isProduction) {
|
|
10583
10968
|
const dist = join14(packageRoot, "dist", "web");
|
|
10584
|
-
if (
|
|
10969
|
+
if (existsSync15(dist)) {
|
|
10585
10970
|
app.use(express2.static(dist));
|
|
10586
10971
|
app.get("*", (_req, res) => res.sendFile(join14(dist, "index.html")));
|
|
10587
10972
|
}
|