forge-openclaw-plugin 0.3.18 → 0.3.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/dist/assets/{action-bar-BAZevCEA.js → action-bar-B3ttL3XF.js} +1 -1
- package/dist/assets/{activity-page-CnT_hnCU.js → activity-page-CoNcd0PX.js} +1 -1
- package/dist/assets/{ai-surface-workspace-GPZzIIut.js → ai-surface-workspace-Db34puL5.js} +1 -1
- package/dist/assets/artifacts-page-C09tfJTW.js +2 -0
- package/dist/assets/{atlas-panel-B95nrYpZ.js → atlas-panel-DRMA3RbG.js} +1 -1
- package/dist/assets/{board-CGgOvBP9.js → board-Dl7As76Q.js} +1 -1
- package/dist/assets/{calendar-page-mlr94wIS.js → calendar-page-CagtpmrB.js} +1 -1
- package/dist/assets/{calendar-rules-DdxPmBZJ.js → calendar-rules-jys-Ya5M.js} +1 -1
- package/dist/assets/{calendar-week-toolbar-Cu8V6zv1.js → calendar-week-toolbar-DWTObcj1.js} +1 -1
- package/dist/assets/{charts-Cdtn55ol.js → charts-YpkKrjkZ.js} +1 -1
- package/dist/assets/{companion-sync-lab-page-CJI5jf8W.js → companion-sync-lab-page-COYI00E2.js} +1 -1
- package/dist/assets/{daily-metrics-dashboard-CXESx7bU.js → daily-metrics-dashboard-CLoHakVX.js} +1 -1
- package/dist/assets/{define-workbench-box-Dbl9W7oE.js → define-workbench-box-DkTWtzNA.js} +1 -1
- package/dist/assets/{entity-link-multiselect-DZ_jAjs4.js → entity-link-multiselect-HmmmJO5A.js} +1 -1
- package/dist/assets/{entity-note-count-link-FOK_qhcC.js → entity-note-count-link-BDLj5ezr.js} +1 -1
- package/dist/assets/{entity-notes-surface-Dq9dFKjD.js → entity-notes-surface-Csbm1myW.js} +1 -1
- package/dist/assets/{execution-board-D9hkXKC2.js → execution-board-C7wYWJE4.js} +1 -1
- package/dist/assets/{faceted-token-search-BeShxjkc.js → faceted-token-search-B2XWEl8j.js} +1 -1
- package/dist/assets/{flagship-signal-deck-DZx_HEH9.js → flagship-signal-deck-DnNN_VE1.js} +1 -1
- package/dist/assets/{floating-action-menu-CFrgvQJi.js → floating-action-menu-D2Lk9TOc.js} +1 -1
- package/dist/assets/{forms-DhEGHkFR.js → forms-DznAv9hZ.js} +1 -1
- package/dist/assets/{generic-node-view-C1kLClIm.js → generic-node-view-C_WhZXoj.js} +1 -1
- package/dist/assets/goal-detail-page-B395rAnv.js +1 -0
- package/dist/assets/{goal-dialog-BlZHh3dw.js → goal-dialog-DiEV3MyU.js} +1 -1
- package/dist/assets/goals-page-BNwaz0yD.js +1 -0
- package/dist/assets/{graph-U1J6VkbG.js → graph-BUSFLDnl.js} +1 -1
- package/dist/assets/{habits-page-DHxZSThT.js → habits-page-BkfbiwMJ.js} +1 -1
- package/dist/assets/{health-boxes-BZjIqiiG.js → health-boxes-BlA33CqS.js} +1 -1
- package/dist/assets/index-C0CztQTU.js +2 -0
- package/dist/assets/index-CKnJCN1y.css +1 -0
- package/dist/assets/{inline-note-fields-DpmCMAJf.js → inline-note-fields-CbA0QOnc.js} +1 -1
- package/dist/assets/{insight-flow-dialog-DNIe0sts.js → insight-flow-dialog-DdxIE6oo.js} +1 -1
- package/dist/assets/{insights-page-D_N_MWGu.js → insights-page-C0q_J9Hz.js} +1 -1
- package/dist/assets/{kanban-boxes-DTDG5UEJ.js → kanban-boxes-BynqbGHC.js} +1 -1
- package/dist/assets/{kanban-page-DEvIY5IW.js → kanban-page-DyiaHH0e.js} +1 -1
- package/dist/assets/{knowledge-graph-page-CvXSnnG5.js → knowledge-graph-page-Cn9VkUur.js} +1 -1
- package/dist/assets/{life-force-page-CgvUrqQb.js → life-force-page-DQPEIj23.js} +1 -1
- package/dist/assets/{life-force-workspace-BNeMbRHf.js → life-force-workspace-Db7XThH2.js} +1 -1
- package/dist/assets/{maps-Dk9tZqTA.js → maps-CpdpZmGM.js} +1 -1
- package/dist/assets/{metric-tile-DAhX60rg.js → metric-tile-sDt_l_O7.js} +1 -1
- package/dist/assets/{motion-DeJZhOSA.js → motion-eRlWWQT8.js} +1 -1
- package/dist/assets/{movement-boxes-BOqU18NH.js → movement-boxes-birc_cd8.js} +1 -1
- package/dist/assets/{movement-page-DCDeUynh.js → movement-page-BQllmJBm.js} +1 -1
- package/dist/assets/{note-markdown-Cxj84-0j.js → note-markdown-Dpve4W0R.js} +1 -1
- package/dist/assets/{note-tags-input-CP0-EPpE.js → note-tags-input-Hvi_ifLe.js} +1 -1
- package/dist/assets/{notes-boxes-C7WPT7mf.js → notes-boxes-J-MuDr8u.js} +1 -1
- package/dist/assets/{notes-page-Dll8PIks.js → notes-page-uR_LafDv.js} +1 -1
- package/dist/assets/{open-in-graph-button-BHl16hJP.js → open-in-graph-button-JgYTH-IQ.js} +1 -1
- package/dist/assets/{orbit-map-De0qpMpY.js → orbit-map-BpNCTagm.js} +1 -1
- package/dist/assets/overview-page-DQB4q_vg.js +1 -0
- package/dist/assets/{page-hero-DYmFM6-q.js → page-hero-ED69y6m0.js} +1 -1
- package/dist/assets/pill-cluster-DbPrs1Y4.js +1 -0
- package/dist/assets/{preference-entity-handoff-button-1XXtBsUF.js → preference-entity-handoff-button-NkwkWqGv.js} +1 -1
- package/dist/assets/{preferences-page-OwfPIQwe.js → preferences-page-BFUVjsHA.js} +1 -1
- package/dist/assets/{project-collections-DfmkBk9d.js → project-collections-DHXN2w-P.js} +1 -1
- package/dist/assets/{project-detail-page-BC_MNaca.js → project-detail-page-nE0M0UmN.js} +1 -1
- package/dist/assets/{project-dialog-BuZdXECa.js → project-dialog-CDkUuAgl.js} +1 -1
- package/dist/assets/{project-management-hierarchy-page-AhEHe60K.js → project-management-hierarchy-page-CID81NpW.js} +1 -1
- package/dist/assets/{project-management-section-nav-CnaseOqL.js → project-management-section-nav-BjFavt6d.js} +1 -1
- package/dist/assets/{projects-boxes-D0zM8PfY.js → projects-boxes-DzGqWlhE.js} +1 -1
- package/dist/assets/projects-page-DpFKm_CM.js +1 -0
- package/dist/assets/{psyche-behaviors-page-CPurgDg6.js → psyche-behaviors-page-CEQ2EByW.js} +1 -1
- package/dist/assets/{psyche-flashcards-page-DnUSe-bb.js → psyche-flashcards-page-D-g1DOS7.js} +1 -1
- package/dist/assets/{psyche-goal-map-page-uWocO7kZ.js → psyche-goal-map-page-DbWVOpVH.js} +1 -1
- package/dist/assets/{psyche-graph-BDszV3UN.js → psyche-graph-1FHrdH3f.js} +1 -1
- package/dist/assets/{psyche-metrics-page-CIJLJTPy.js → psyche-metrics-page-B3736p8_.js} +1 -1
- package/dist/assets/{psyche-mode-guide-page-uC8L4WvH.js → psyche-mode-guide-page-CjsMqDsi.js} +1 -1
- package/dist/assets/{psyche-modes-page-CtBeRA_3.js → psyche-modes-page-B2qzppBs.js} +1 -1
- package/dist/assets/{psyche-page-Ds3QDsin.js → psyche-page-BEPP2B13.js} +1 -1
- package/dist/assets/{psyche-patterns-page-Cvq5WshW.js → psyche-patterns-page-CWeNeX2P.js} +2 -2
- package/dist/assets/{psyche-questionnaire-builder-page-Cg5Upe6z.js → psyche-questionnaire-builder-page-QFg9LkM0.js} +1 -1
- package/dist/assets/{psyche-questionnaire-detail-page-D4jEnNoh.js → psyche-questionnaire-detail-page-D67EJ1D5.js} +1 -1
- package/dist/assets/psyche-questionnaire-run-detail-page-C1KsEy8T.js +1 -0
- package/dist/assets/{psyche-questionnaire-run-page-Yg_VG2vq.js → psyche-questionnaire-run-page-CB3rSTAX.js} +1 -1
- package/dist/assets/{psyche-questionnaires-page-BqeOJRj7.js → psyche-questionnaires-page-wU3bZws7.js} +1 -1
- package/dist/assets/{psyche-report-detail-page-BtcMQ7mk.js → psyche-report-detail-page-DI3jE820.js} +3 -3
- package/dist/assets/{psyche-reports-page-tagvW0To.js → psyche-reports-page-aUbgZ_12.js} +1 -1
- package/dist/assets/{psyche-schemas-CvRSkI_u.js → psyche-schemas-B00gm5HO.js} +1 -1
- package/dist/assets/{psyche-schemas-beliefs-page-4NL3415v.js → psyche-schemas-beliefs-page-C_PMXwjL.js} +2 -2
- package/dist/assets/{psyche-screen-time-page-Bc5AwZHQ.js → psyche-screen-time-page-CMIgDG-3.js} +1 -1
- package/dist/assets/{psyche-self-observation-page-CUrUYbQ_.js → psyche-self-observation-page-DC3orZgf.js} +1 -1
- package/dist/assets/{psyche-values-page-BshT2sXE.js → psyche-values-page-CPdKfTdl.js} +2 -2
- package/dist/assets/{question-flow-dialog-CPyXCqA-.js → question-flow-dialog-B4B3BI8e.js} +2 -2
- package/dist/assets/{report-chain-fields-C0UMLpze.js → report-chain-fields-D-XNut8V.js} +1 -1
- package/dist/assets/rewards-page-D8w07BIZ.js +1 -0
- package/dist/assets/{scheduling-rules-editor-DiA6KkQ4.js → scheduling-rules-editor-Cn6t-RRn.js} +1 -1
- package/dist/assets/{schema-badge-DURw2eYH.js → schema-badge-Dsk9AoYd.js} +1 -1
- package/dist/assets/{schemas-D_z2C8l1.js → schemas-3GS34K1i.js} +1 -1
- package/dist/assets/{select-menu-BUB8__Nx.js → select-menu-BDeaaa4m.js} +1 -1
- package/dist/assets/{settings-agents-page-Kk98Whcf.js → settings-agents-page-CkS4s4kN.js} +2 -2
- package/dist/assets/settings-bin-page-BHlW0n-a.js +1 -0
- package/dist/assets/{settings-calendar-page-CdhlUnUW.js → settings-calendar-page-BAmKOPeT.js} +3 -3
- package/dist/assets/{settings-data-page-BvvuZNbb.js → settings-data-page-C-VrzHGq.js} +1 -1
- package/dist/assets/{settings-logs-page-CrzkXxtZ.js → settings-logs-page-CnVuzJ7d.js} +1 -1
- package/dist/assets/{settings-mobile-page-Dl582NK6.js → settings-mobile-page-0SWGg6CE.js} +1 -1
- package/dist/assets/settings-models-page-BjVixsws.js +1 -0
- package/dist/assets/{settings-page-DqnlOCgo.js → settings-page-DVZ58c3R.js} +1 -1
- package/dist/assets/settings-rewards-page-Df0ONVFq.js +1 -0
- package/dist/assets/{settings-section-nav-C1NcWveT.js → settings-section-nav-Btjx5m2u.js} +1 -1
- package/dist/assets/settings-users-page-Cl0YuOOI.js +1 -0
- package/dist/assets/{settings-wiki-page-CkpnUkiZ.js → settings-wiki-page-K8KBzeYx.js} +1 -1
- package/dist/assets/{sleep-page-DrS1zs3B.js → sleep-page-BFj8hcTf.js} +1 -1
- package/dist/assets/{sports-page-EVnB_zjB.js → sports-page-7yta1r8s.js} +1 -1
- package/dist/assets/{state-DWw8Jay_.js → state-CkEUXgqt.js} +1 -1
- package/dist/assets/{strategies-page-COhyv_SH.js → strategies-page-BQoWnPtN.js} +1 -1
- package/dist/assets/strategy-detail-page-D9DTQoyy.js +1 -0
- package/dist/assets/strategy-dialog-z9w2UB3s.js +1 -0
- package/dist/assets/{surface-Dg5fauKP.js → surface-BL_bDiZ5.js} +1 -1
- package/dist/assets/{table-CWVROEBP.js → table--SK_dk4S.js} +1 -1
- package/dist/assets/{task-detail-page-3IeMYIXl.js → task-detail-page-RcbvVzXn.js} +1 -1
- package/dist/assets/{task-dialog-B7ZT4KE5.js → task-dialog-ri1qEzPp.js} +4 -4
- package/dist/assets/timebox-planning-dialog-DoeeGwCm.js +1 -0
- package/dist/assets/{today-boxes-BbUNpb16.js → today-boxes-CTw0D5JP.js} +1 -1
- package/dist/assets/today-page-5-qRLbBt.js +1 -0
- package/dist/assets/{training-load-page-DTYbu9f0.js → training-load-page-DrGnOtnH.js} +1 -1
- package/dist/assets/{ui-CdEDMtXF.js → ui-CDt36qNz.js} +1 -1
- package/dist/assets/{use-anchored-overlay-position-Cracjgo6.js → use-anchored-overlay-position-C2kg0Ay0.js} +1 -1
- package/dist/assets/{use-psyche-focus-target-DvRgu-94.js → use-psyche-focus-target-p2l8W-Af.js} +1 -1
- package/dist/assets/{user-badge-B8hYK6NU.js → user-badge-BWoSrGA-.js} +1 -1
- package/dist/assets/{user-select-field-akGHK-2t.js → user-select-field-DbB9v7Lf.js} +1 -1
- package/dist/assets/{utility-widgets-D4KsKxLT.js → utility-widgets-fodvUR7I.js} +2 -2
- package/dist/assets/{vendor-y_uz1Wft.js → vendor-Dgw7UY7q.js} +1 -1
- package/dist/assets/{vitals-page-Cjcxh-kO.js → vitals-page-f8QdPdpp.js} +1 -1
- package/dist/assets/{weekly-review-page-CR57efzH.js → weekly-review-page-D0wPiQgO.js} +1 -1
- package/dist/assets/{weight-loss-page-Bk7YkB7b.js → weight-loss-page-BT9dPxYi.js} +1 -1
- package/dist/assets/{wiki-article-markdown-um6gpmGQ.js → wiki-article-markdown-Hyu5JwrY.js} +1 -1
- package/dist/assets/{wiki-editor-page-DdP5hvjZ.js → wiki-editor-page-ujqNw8ua.js} +1 -1
- package/dist/assets/{wiki-ingest-history-page-DSTndduq.js → wiki-ingest-history-page-BwoDT00-.js} +1 -1
- package/dist/assets/{wiki-ingest-modal-PNW3CJ-o.js → wiki-ingest-modal-cvnNma0M.js} +1 -1
- package/dist/assets/{wiki-page-CsJlPyQ6.js → wiki-page-jHyJ7EgO.js} +1 -1
- package/dist/assets/{workbench-flow-page-DFtIKgNe.js → workbench-flow-page-DJD5sXMF.js} +1 -1
- package/dist/assets/{workbench-page-DEpKjMEv.js → workbench-page-Ci0xh6rG.js} +1 -1
- package/dist/assets/{workout-detail-page-BwfEhxA_.js → workout-detail-page-DA30ubtE.js} +2 -2
- package/dist/index.html +8 -8
- package/dist/openclaw/tools.js +1 -1
- package/dist/server/apps/api/src/app.js +26 -8
- package/dist/server/apps/api/src/openapi.js +103 -24
- package/dist/server/apps/api/src/services/artifacts.js +138 -68
- package/dist/server/apps/web/src/lib/api.js +3 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/forge-openclaw/SKILL.md +7 -5
- package/skills/forge-openclaw/entity_conversation_playbooks.md +5 -3
- package/dist/assets/artifacts-page-Bqjp0L-L.js +0 -2
- package/dist/assets/goal-detail-page-BhMrnVQs.js +0 -1
- package/dist/assets/goals-page-CesC8IkZ.js +0 -1
- package/dist/assets/index-CHbe1sy1.css +0 -1
- package/dist/assets/index-Dj8q65se.js +0 -2
- package/dist/assets/overview-page-C1RX7dcq.js +0 -1
- package/dist/assets/pill-cluster-ClkmFVFT.js +0 -1
- package/dist/assets/projects-page-ltrWfLrA.js +0 -1
- package/dist/assets/psyche-questionnaire-run-detail-page-CWoZEY31.js +0 -1
- package/dist/assets/rewards-page-D9BzsNPW.js +0 -1
- package/dist/assets/settings-bin-page-BnJ-mgy2.js +0 -1
- package/dist/assets/settings-models-page-COoBw28S.js +0 -1
- package/dist/assets/settings-rewards-page-Cw5QSTjy.js +0 -1
- package/dist/assets/settings-users-page-0opvepcM.js +0 -1
- package/dist/assets/strategy-detail-page-BaCVkvIu.js +0 -1
- package/dist/assets/strategy-dialog-DvlPo9WV.js +0 -1
- package/dist/assets/timebox-planning-dialog-DoZzpEBp.js +0 -1
- package/dist/assets/today-page-adKXN2g1.js +0 -1
|
@@ -5639,7 +5639,13 @@ export function buildOpenApiDocument() {
|
|
|
5639
5639
|
},
|
|
5640
5640
|
sourceKind: {
|
|
5641
5641
|
type: "string",
|
|
5642
|
-
enum: [
|
|
5642
|
+
enum: [
|
|
5643
|
+
"upload",
|
|
5644
|
+
"agent_upload",
|
|
5645
|
+
"wiki_ingest",
|
|
5646
|
+
"external_reference",
|
|
5647
|
+
"manual"
|
|
5648
|
+
]
|
|
5643
5649
|
},
|
|
5644
5650
|
sourceLabel: { type: "string" },
|
|
5645
5651
|
uploadedByUserId: nullable({ type: "string" }),
|
|
@@ -5650,7 +5656,10 @@ export function buildOpenApiDocument() {
|
|
|
5650
5656
|
enum: ["active", "quarantined", "blocked", "archived", "metadata_only"]
|
|
5651
5657
|
},
|
|
5652
5658
|
dangerScore: { type: "integer", minimum: 0, maximum: 100 },
|
|
5653
|
-
dangerLevel: {
|
|
5659
|
+
dangerLevel: {
|
|
5660
|
+
type: "string",
|
|
5661
|
+
enum: ["low", "moderate", "high", "blocked"]
|
|
5662
|
+
},
|
|
5654
5663
|
downloadPolicy: { type: "string", enum: ["human_only", "disabled"] },
|
|
5655
5664
|
scanResults: artifactScanResult,
|
|
5656
5665
|
enrichmentResults: { type: "object", additionalProperties: true },
|
|
@@ -5660,6 +5669,17 @@ export function buildOpenApiDocument() {
|
|
|
5660
5669
|
updatedAt: { type: "string", format: "date-time" }
|
|
5661
5670
|
}
|
|
5662
5671
|
};
|
|
5672
|
+
const artifactListResponse = {
|
|
5673
|
+
type: "object",
|
|
5674
|
+
required: ["artifacts", "total", "limit", "offset", "hasMore"],
|
|
5675
|
+
properties: {
|
|
5676
|
+
artifacts: arrayOf({ $ref: "#/components/schemas/Artifact" }),
|
|
5677
|
+
total: { type: "integer", minimum: 0 },
|
|
5678
|
+
limit: { type: "integer", minimum: 1, maximum: 500 },
|
|
5679
|
+
offset: { type: "integer", minimum: 0 },
|
|
5680
|
+
hasMore: { type: "boolean" }
|
|
5681
|
+
}
|
|
5682
|
+
};
|
|
5663
5683
|
const artifactUploadInput = {
|
|
5664
5684
|
type: "object",
|
|
5665
5685
|
required: ["originalFileName", "contentBase64"],
|
|
@@ -5675,7 +5695,13 @@ export function buildOpenApiDocument() {
|
|
|
5675
5695
|
},
|
|
5676
5696
|
sourceKind: {
|
|
5677
5697
|
type: "string",
|
|
5678
|
-
enum: [
|
|
5698
|
+
enum: [
|
|
5699
|
+
"upload",
|
|
5700
|
+
"agent_upload",
|
|
5701
|
+
"wiki_ingest",
|
|
5702
|
+
"external_reference",
|
|
5703
|
+
"manual"
|
|
5704
|
+
]
|
|
5679
5705
|
},
|
|
5680
5706
|
sourceLabel: { type: "string" },
|
|
5681
5707
|
uploadedByUserId: nullable({ type: "string" }),
|
|
@@ -5758,7 +5784,15 @@ export function buildOpenApiDocument() {
|
|
|
5758
5784
|
};
|
|
5759
5785
|
const artifactAuditEvent = {
|
|
5760
5786
|
type: "object",
|
|
5761
|
-
required: [
|
|
5787
|
+
required: [
|
|
5788
|
+
"id",
|
|
5789
|
+
"artifactId",
|
|
5790
|
+
"eventType",
|
|
5791
|
+
"actor",
|
|
5792
|
+
"source",
|
|
5793
|
+
"metadata",
|
|
5794
|
+
"createdAt"
|
|
5795
|
+
],
|
|
5762
5796
|
properties: {
|
|
5763
5797
|
id: { type: "string" },
|
|
5764
5798
|
artifactId: { type: "string" },
|
|
@@ -5880,6 +5914,7 @@ export function buildOpenApiDocument() {
|
|
|
5880
5914
|
ArtifactScanFinding: artifactScanFinding,
|
|
5881
5915
|
ArtifactScanResult: artifactScanResult,
|
|
5882
5916
|
Artifact: artifact,
|
|
5917
|
+
ArtifactListResponse: artifactListResponse,
|
|
5883
5918
|
ArtifactUploadInput: artifactUploadInput,
|
|
5884
5919
|
ArtifactMetadataPatchInput: artifactMetadataPatchInput,
|
|
5885
5920
|
ArtifactTrustPatchInput: artifactTrustPatchInput,
|
|
@@ -5933,13 +5968,22 @@ export function buildOpenApiDocument() {
|
|
|
5933
5968
|
in: "query",
|
|
5934
5969
|
schema: {
|
|
5935
5970
|
type: "string",
|
|
5936
|
-
enum: [
|
|
5971
|
+
enum: [
|
|
5972
|
+
"active",
|
|
5973
|
+
"quarantined",
|
|
5974
|
+
"blocked",
|
|
5975
|
+
"archived",
|
|
5976
|
+
"metadata_only"
|
|
5977
|
+
]
|
|
5937
5978
|
}
|
|
5938
5979
|
},
|
|
5939
5980
|
{
|
|
5940
5981
|
name: "dangerLevel",
|
|
5941
5982
|
in: "query",
|
|
5942
|
-
schema: {
|
|
5983
|
+
schema: {
|
|
5984
|
+
type: "string",
|
|
5985
|
+
enum: ["low", "moderate", "high", "blocked"]
|
|
5986
|
+
}
|
|
5943
5987
|
},
|
|
5944
5988
|
{
|
|
5945
5989
|
name: "formatFamily",
|
|
@@ -5957,16 +6001,25 @@ export function buildOpenApiDocument() {
|
|
|
5957
6001
|
]
|
|
5958
6002
|
}
|
|
5959
6003
|
},
|
|
5960
|
-
{
|
|
6004
|
+
{
|
|
6005
|
+
name: "linkedEntityType",
|
|
6006
|
+
in: "query",
|
|
6007
|
+
schema: { type: "string" }
|
|
6008
|
+
},
|
|
5961
6009
|
{ name: "linkedEntityId", in: "query", schema: { type: "string" } },
|
|
5962
|
-
{
|
|
6010
|
+
{
|
|
6011
|
+
name: "limit",
|
|
6012
|
+
in: "query",
|
|
6013
|
+
schema: { type: "integer", minimum: 1, maximum: 500 }
|
|
6014
|
+
},
|
|
6015
|
+
{
|
|
6016
|
+
name: "offset",
|
|
6017
|
+
in: "query",
|
|
6018
|
+
schema: { type: "integer", minimum: 0 }
|
|
6019
|
+
}
|
|
5963
6020
|
],
|
|
5964
6021
|
responses: {
|
|
5965
|
-
"200": jsonResponse({
|
|
5966
|
-
type: "object",
|
|
5967
|
-
required: ["artifacts"],
|
|
5968
|
-
properties: { artifacts: arrayOf({ $ref: "#/components/schemas/Artifact" }) }
|
|
5969
|
-
}, "Artifact list"),
|
|
6022
|
+
"200": jsonResponse({ $ref: "#/components/schemas/ArtifactListResponse" }, "Artifact list"),
|
|
5970
6023
|
default: { $ref: "#/components/responses/Error" }
|
|
5971
6024
|
}
|
|
5972
6025
|
},
|
|
@@ -5985,7 +6038,9 @@ export function buildOpenApiDocument() {
|
|
|
5985
6038
|
"201": jsonResponse({
|
|
5986
6039
|
type: "object",
|
|
5987
6040
|
required: ["artifact"],
|
|
5988
|
-
properties: {
|
|
6041
|
+
properties: {
|
|
6042
|
+
artifact: { $ref: "#/components/schemas/Artifact" }
|
|
6043
|
+
}
|
|
5989
6044
|
}, "Created artifact"),
|
|
5990
6045
|
default: { $ref: "#/components/responses/Error" }
|
|
5991
6046
|
}
|
|
@@ -6006,7 +6061,9 @@ export function buildOpenApiDocument() {
|
|
|
6006
6061
|
"200": jsonResponse({
|
|
6007
6062
|
type: "object",
|
|
6008
6063
|
required: ["artifact"],
|
|
6009
|
-
properties: {
|
|
6064
|
+
properties: {
|
|
6065
|
+
artifact: { $ref: "#/components/schemas/Artifact" }
|
|
6066
|
+
}
|
|
6010
6067
|
}, "Artifact metadata"),
|
|
6011
6068
|
default: { $ref: "#/components/responses/Error" }
|
|
6012
6069
|
}
|
|
@@ -6017,7 +6074,9 @@ export function buildOpenApiDocument() {
|
|
|
6017
6074
|
required: true,
|
|
6018
6075
|
content: {
|
|
6019
6076
|
"application/json": {
|
|
6020
|
-
schema: {
|
|
6077
|
+
schema: {
|
|
6078
|
+
$ref: "#/components/schemas/ArtifactMetadataPatchInput"
|
|
6079
|
+
}
|
|
6021
6080
|
}
|
|
6022
6081
|
}
|
|
6023
6082
|
},
|
|
@@ -6025,7 +6084,9 @@ export function buildOpenApiDocument() {
|
|
|
6025
6084
|
"200": jsonResponse({
|
|
6026
6085
|
type: "object",
|
|
6027
6086
|
required: ["artifact"],
|
|
6028
|
-
properties: {
|
|
6087
|
+
properties: {
|
|
6088
|
+
artifact: { $ref: "#/components/schemas/Artifact" }
|
|
6089
|
+
}
|
|
6029
6090
|
}, "Updated artifact"),
|
|
6030
6091
|
default: { $ref: "#/components/responses/Error" }
|
|
6031
6092
|
}
|
|
@@ -6071,7 +6132,9 @@ export function buildOpenApiDocument() {
|
|
|
6071
6132
|
"200": jsonResponse({
|
|
6072
6133
|
type: "object",
|
|
6073
6134
|
required: ["artifact"],
|
|
6074
|
-
properties: {
|
|
6135
|
+
properties: {
|
|
6136
|
+
artifact: { $ref: "#/components/schemas/Artifact" }
|
|
6137
|
+
}
|
|
6075
6138
|
}, "Rescanned artifact"),
|
|
6076
6139
|
default: { $ref: "#/components/responses/Error" }
|
|
6077
6140
|
}
|
|
@@ -6101,7 +6164,9 @@ export function buildOpenApiDocument() {
|
|
|
6101
6164
|
"200": jsonResponse({
|
|
6102
6165
|
type: "object",
|
|
6103
6166
|
required: ["artifact"],
|
|
6104
|
-
properties: {
|
|
6167
|
+
properties: {
|
|
6168
|
+
artifact: { $ref: "#/components/schemas/Artifact" }
|
|
6169
|
+
}
|
|
6105
6170
|
}, "Enriched artifact"),
|
|
6106
6171
|
default: { $ref: "#/components/responses/Error" }
|
|
6107
6172
|
}
|
|
@@ -6127,7 +6192,9 @@ export function buildOpenApiDocument() {
|
|
|
6127
6192
|
type: "object",
|
|
6128
6193
|
required: ["links"],
|
|
6129
6194
|
properties: {
|
|
6130
|
-
links: arrayOf({
|
|
6195
|
+
links: arrayOf({
|
|
6196
|
+
$ref: "#/components/schemas/EntityLinkInput"
|
|
6197
|
+
})
|
|
6131
6198
|
}
|
|
6132
6199
|
}
|
|
6133
6200
|
}
|
|
@@ -6137,7 +6204,9 @@ export function buildOpenApiDocument() {
|
|
|
6137
6204
|
"200": jsonResponse({
|
|
6138
6205
|
type: "object",
|
|
6139
6206
|
required: ["artifact"],
|
|
6140
|
-
properties: {
|
|
6207
|
+
properties: {
|
|
6208
|
+
artifact: { $ref: "#/components/schemas/Artifact" }
|
|
6209
|
+
}
|
|
6141
6210
|
}, "Relinked artifact"),
|
|
6142
6211
|
default: { $ref: "#/components/responses/Error" }
|
|
6143
6212
|
}
|
|
@@ -6166,7 +6235,9 @@ export function buildOpenApiDocument() {
|
|
|
6166
6235
|
"200": jsonResponse({
|
|
6167
6236
|
type: "object",
|
|
6168
6237
|
required: ["artifact"],
|
|
6169
|
-
properties: {
|
|
6238
|
+
properties: {
|
|
6239
|
+
artifact: { $ref: "#/components/schemas/Artifact" }
|
|
6240
|
+
}
|
|
6170
6241
|
}, "Trust-updated artifact"),
|
|
6171
6242
|
default: { $ref: "#/components/responses/Error" }
|
|
6172
6243
|
}
|
|
@@ -6187,7 +6258,11 @@ export function buildOpenApiDocument() {
|
|
|
6187
6258
|
"200": jsonResponse({
|
|
6188
6259
|
type: "object",
|
|
6189
6260
|
required: ["versions"],
|
|
6190
|
-
properties: {
|
|
6261
|
+
properties: {
|
|
6262
|
+
versions: arrayOf({
|
|
6263
|
+
$ref: "#/components/schemas/ArtifactVersion"
|
|
6264
|
+
})
|
|
6265
|
+
}
|
|
6191
6266
|
}, "Artifact versions"),
|
|
6192
6267
|
default: { $ref: "#/components/responses/Error" }
|
|
6193
6268
|
}
|
|
@@ -6208,7 +6283,11 @@ export function buildOpenApiDocument() {
|
|
|
6208
6283
|
"200": jsonResponse({
|
|
6209
6284
|
type: "object",
|
|
6210
6285
|
required: ["events"],
|
|
6211
|
-
properties: {
|
|
6286
|
+
properties: {
|
|
6287
|
+
events: arrayOf({
|
|
6288
|
+
$ref: "#/components/schemas/ArtifactAuditEvent"
|
|
6289
|
+
})
|
|
6290
|
+
}
|
|
6212
6291
|
}, "Artifact audit events"),
|
|
6213
6292
|
default: { $ref: "#/components/responses/Error" }
|
|
6214
6293
|
}
|
|
@@ -5,7 +5,7 @@ import path from "node:path";
|
|
|
5
5
|
import AdmZip from "adm-zip";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { getDatabase, resolveDataDir, runInTransaction } from "../db.js";
|
|
8
|
-
import {
|
|
8
|
+
import { isEntityDeleted } from "../repositories/deleted-entities.js";
|
|
9
9
|
import { listEntityLinksForSources, replaceEntityLinksForSource } from "../repositories/entity-links.js";
|
|
10
10
|
import { recordEventLog } from "../repositories/event-log.js";
|
|
11
11
|
import { listWikiLlmProfiles } from "../repositories/wiki-memory.js";
|
|
@@ -64,10 +64,7 @@ export const artifactDangerLevelSchema = z.enum([
|
|
|
64
64
|
"high",
|
|
65
65
|
"blocked"
|
|
66
66
|
]);
|
|
67
|
-
export const artifactDownloadPolicySchema = z.enum([
|
|
68
|
-
"human_only",
|
|
69
|
-
"disabled"
|
|
70
|
-
]);
|
|
67
|
+
export const artifactDownloadPolicySchema = z.enum(["human_only", "disabled"]);
|
|
71
68
|
export const artifactFormatFamilySchema = z.enum([
|
|
72
69
|
"spreadsheet",
|
|
73
70
|
"document",
|
|
@@ -141,7 +138,8 @@ export const artifactListQuerySchema = z.object({
|
|
|
141
138
|
formatFamily: artifactFormatFamilySchema.optional(),
|
|
142
139
|
linkedEntityType: z.string().trim().optional(),
|
|
143
140
|
linkedEntityId: z.string().trim().optional(),
|
|
144
|
-
limit: z.coerce.number().int().min(1).max(500).optional().default(100)
|
|
141
|
+
limit: z.coerce.number().int().min(1).max(500).optional().default(100),
|
|
142
|
+
offset: z.coerce.number().int().min(0).optional().default(0)
|
|
145
143
|
});
|
|
146
144
|
export const artifactTrustPatchSchema = z.object({
|
|
147
145
|
artifactState: artifactStateSchema,
|
|
@@ -181,10 +179,16 @@ function normalizeNullableText(value) {
|
|
|
181
179
|
return text && text.length > 0 ? text : null;
|
|
182
180
|
}
|
|
183
181
|
function sanitizeFileName(fileName) {
|
|
184
|
-
return path
|
|
182
|
+
return path
|
|
183
|
+
.basename(fileName)
|
|
184
|
+
.replace(/[^\w.\- ()[\]]+/g, "_")
|
|
185
|
+
.slice(0, 180);
|
|
185
186
|
}
|
|
186
187
|
function extensionFromFileName(fileName) {
|
|
187
|
-
return path
|
|
188
|
+
return path
|
|
189
|
+
.extname(sanitizeFileName(fileName))
|
|
190
|
+
.replace(/^\./, "")
|
|
191
|
+
.toLowerCase();
|
|
188
192
|
}
|
|
189
193
|
function formatFamilyForExtension(extension) {
|
|
190
194
|
return extensionToFormatFamily[extension] ?? null;
|
|
@@ -305,11 +309,21 @@ function severityScore(severity) {
|
|
|
305
309
|
function computeDanger(findings) {
|
|
306
310
|
const score = Math.min(100, findings.reduce((max, finding) => Math.max(max, severityScore(finding.severity)), 0) +
|
|
307
311
|
Math.max(0, findings.length - 1) * 4);
|
|
308
|
-
const level = score >= 90
|
|
312
|
+
const level = score >= 90
|
|
313
|
+
? "blocked"
|
|
314
|
+
: score >= 70
|
|
315
|
+
? "high"
|
|
316
|
+
: score >= 35
|
|
317
|
+
? "moderate"
|
|
318
|
+
: "low";
|
|
309
319
|
return { score, level };
|
|
310
320
|
}
|
|
311
321
|
function safeUtf8(buffer, limit = MAX_TEXT_EXTRACTION_CHARS) {
|
|
312
|
-
return buffer
|
|
322
|
+
return buffer
|
|
323
|
+
.subarray(0, limit)
|
|
324
|
+
.toString("utf8")
|
|
325
|
+
.replace(/\u0000/g, "")
|
|
326
|
+
.trim();
|
|
313
327
|
}
|
|
314
328
|
function stripXml(xml) {
|
|
315
329
|
return xml
|
|
@@ -321,7 +335,9 @@ function stripXml(xml) {
|
|
|
321
335
|
.trim();
|
|
322
336
|
}
|
|
323
337
|
function zipEntryText(zip, name) {
|
|
324
|
-
const entry = zip
|
|
338
|
+
const entry = zip
|
|
339
|
+
.getEntries()
|
|
340
|
+
.find((candidate) => candidate.entryName === name);
|
|
325
341
|
return entry ? entry.getData().toString("utf8") : "";
|
|
326
342
|
}
|
|
327
343
|
function extractOfficeText(zip, extension) {
|
|
@@ -344,7 +360,10 @@ function extractOfficeText(zip, extension) {
|
|
|
344
360
|
.slice(0, 5)
|
|
345
361
|
.map((entry) => stripXml(entry.getData().toString("utf8")))
|
|
346
362
|
.join("\n");
|
|
347
|
-
return [sharedStrings, sheetText]
|
|
363
|
+
return [sharedStrings, sheetText]
|
|
364
|
+
.filter(Boolean)
|
|
365
|
+
.join("\n")
|
|
366
|
+
.slice(0, MAX_TEXT_EXTRACTION_CHARS);
|
|
348
367
|
}
|
|
349
368
|
return "";
|
|
350
369
|
}
|
|
@@ -359,7 +378,8 @@ function scanOfficeZip(buffer, extension, findings) {
|
|
|
359
378
|
if (entries.length > MAX_ZIP_ENTRY_COUNT) {
|
|
360
379
|
addFinding(findings, "blocked", "zip_entry_limit", "The archive has too many entries for safe static inspection.");
|
|
361
380
|
}
|
|
362
|
-
if (totalUncompressed > MAX_ZIP_UNCOMPRESSED_BYTES ||
|
|
381
|
+
if (totalUncompressed > MAX_ZIP_UNCOMPRESSED_BYTES ||
|
|
382
|
+
ratio > MAX_ZIP_RATIO) {
|
|
363
383
|
addFinding(findings, "blocked", "zip_bomb_indicator", "The archive has unsafe compressed-to-uncompressed size characteristics.");
|
|
364
384
|
}
|
|
365
385
|
if (entries.some((entry) => entry.entryName.endsWith("EncryptedPackage"))) {
|
|
@@ -400,7 +420,9 @@ function scanOfficeZip(buffer, extension, findings) {
|
|
|
400
420
|
return extractedTextSample;
|
|
401
421
|
}
|
|
402
422
|
function scanPdf(buffer, findings) {
|
|
403
|
-
const text = buffer
|
|
423
|
+
const text = buffer
|
|
424
|
+
.subarray(0, Math.min(buffer.byteLength, 2_000_000))
|
|
425
|
+
.toString("latin1");
|
|
404
426
|
if (/\/JavaScript|\/JS\b/i.test(text)) {
|
|
405
427
|
addFinding(findings, "high", "pdf_javascript", "The PDF contains JavaScript actions.");
|
|
406
428
|
}
|
|
@@ -436,17 +458,21 @@ export function scanArtifactBytes(input) {
|
|
|
436
458
|
const detectedMimeType = detectMimeType(input.buffer, detectedExtension);
|
|
437
459
|
const formatFamily = formatFamilyForExtension(detectedExtension);
|
|
438
460
|
const findings = [];
|
|
439
|
-
if (!formatFamily ||
|
|
461
|
+
if (!formatFamily ||
|
|
462
|
+
!ALLOWED_EXTENSIONS.includes(detectedExtension)) {
|
|
440
463
|
addFinding(findings, "blocked", "unsupported_extension", `Files with extension .${detectedExtension || "unknown"} are not allowed.`);
|
|
441
464
|
}
|
|
442
465
|
if (input.buffer.byteLength > MAX_ARTIFACT_BYTES) {
|
|
443
466
|
addFinding(findings, "blocked", "size_limit_exceeded", "The file exceeds Forge's artifact size limit.");
|
|
444
467
|
}
|
|
445
|
-
if (input.declaredMimeType?.trim() &&
|
|
468
|
+
if (input.declaredMimeType?.trim() &&
|
|
469
|
+
input.declaredMimeType !== detectedMimeType) {
|
|
446
470
|
addFinding(findings, "low", "mime_mismatch", "The declared MIME type differs from static file detection.");
|
|
447
471
|
}
|
|
448
472
|
let extractedTextSample = "";
|
|
449
|
-
if (formatFamily === "document" ||
|
|
473
|
+
if (formatFamily === "document" ||
|
|
474
|
+
formatFamily === "presentation" ||
|
|
475
|
+
formatFamily === "spreadsheet") {
|
|
450
476
|
if (["docx", "pptx", "xlsx", "xlsm"].includes(detectedExtension)) {
|
|
451
477
|
extractedTextSample = scanOfficeZip(input.buffer, detectedExtension, findings);
|
|
452
478
|
}
|
|
@@ -467,7 +493,11 @@ export function scanArtifactBytes(input) {
|
|
|
467
493
|
addFinding(findings, "info", "static_scan_clean", "Static inspection found no configured danger signal.");
|
|
468
494
|
}
|
|
469
495
|
const danger = computeDanger(findings);
|
|
470
|
-
const artifactState = danger.level === "blocked"
|
|
496
|
+
const artifactState = danger.level === "blocked"
|
|
497
|
+
? "blocked"
|
|
498
|
+
: danger.level === "high"
|
|
499
|
+
? "quarantined"
|
|
500
|
+
: "active";
|
|
471
501
|
return {
|
|
472
502
|
detectedExtension,
|
|
473
503
|
detectedMimeType,
|
|
@@ -532,31 +562,66 @@ function mapArtifact(row, links = []) {
|
|
|
532
562
|
updatedAt: row.updated_at
|
|
533
563
|
};
|
|
534
564
|
}
|
|
535
|
-
|
|
536
|
-
return getDatabase()
|
|
537
|
-
.prepare(`SELECT id, title, short_description, description, original_file_name,
|
|
565
|
+
const ARTIFACT_SELECT_COLUMNS = `id, title, short_description, description, original_file_name,
|
|
538
566
|
storage_key, storage_path, content_sha256, byte_size,
|
|
539
567
|
detected_extension, declared_mime_type, detected_mime_type,
|
|
540
568
|
format_family, source_kind, source_label, uploaded_by_user_id,
|
|
541
569
|
uploaded_by_agent_id, acting_for_user_id, artifact_state,
|
|
542
570
|
danger_score, danger_level, download_policy, scan_results_json,
|
|
543
|
-
enrichment_results_json, metadata_json, created_at, updated_at
|
|
571
|
+
enrichment_results_json, metadata_json, created_at, updated_at`;
|
|
572
|
+
function getArtifactRow(id) {
|
|
573
|
+
return getDatabase()
|
|
574
|
+
.prepare(`SELECT ${ARTIFACT_SELECT_COLUMNS}
|
|
544
575
|
FROM artifacts
|
|
545
576
|
WHERE id = ?`)
|
|
546
577
|
.get(id);
|
|
547
578
|
}
|
|
548
|
-
function
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
.
|
|
579
|
+
function buildArtifactListWhere(parsed) {
|
|
580
|
+
const clauses = [
|
|
581
|
+
`NOT EXISTS (
|
|
582
|
+
SELECT 1
|
|
583
|
+
FROM deleted_entities
|
|
584
|
+
WHERE deleted_entities.entity_type = 'artifact'
|
|
585
|
+
AND deleted_entities.entity_id = artifacts.id
|
|
586
|
+
)`
|
|
587
|
+
];
|
|
588
|
+
const params = [];
|
|
589
|
+
if (parsed.artifactState) {
|
|
590
|
+
clauses.push("artifacts.artifact_state = ?");
|
|
591
|
+
params.push(parsed.artifactState);
|
|
592
|
+
}
|
|
593
|
+
if (parsed.dangerLevel) {
|
|
594
|
+
clauses.push("artifacts.danger_level = ?");
|
|
595
|
+
params.push(parsed.dangerLevel);
|
|
596
|
+
}
|
|
597
|
+
if (parsed.formatFamily) {
|
|
598
|
+
clauses.push("artifacts.format_family = ?");
|
|
599
|
+
params.push(parsed.formatFamily);
|
|
600
|
+
}
|
|
601
|
+
if (parsed.query) {
|
|
602
|
+
const needle = `%${parsed.query.toLowerCase()}%`;
|
|
603
|
+
clauses.push(`(
|
|
604
|
+
LOWER(COALESCE(artifacts.title, '')) LIKE ?
|
|
605
|
+
OR LOWER(COALESCE(artifacts.short_description, '')) LIKE ?
|
|
606
|
+
OR LOWER(COALESCE(artifacts.description, '')) LIKE ?
|
|
607
|
+
OR LOWER(COALESCE(artifacts.original_file_name, '')) LIKE ?
|
|
608
|
+
OR LOWER(COALESCE(artifacts.source_label, '')) LIKE ?
|
|
609
|
+
OR LOWER(COALESCE(artifacts.metadata_json, '')) LIKE ?
|
|
610
|
+
)`);
|
|
611
|
+
params.push(needle, needle, needle, needle, needle, needle);
|
|
612
|
+
}
|
|
613
|
+
if (parsed.linkedEntityType && parsed.linkedEntityId) {
|
|
614
|
+
clauses.push(`EXISTS (
|
|
615
|
+
SELECT 1
|
|
616
|
+
FROM entity_links artifact_link_filter
|
|
617
|
+
WHERE artifact_link_filter.source_entity_type = 'artifact'
|
|
618
|
+
AND artifact_link_filter.source_entity_id = artifacts.id
|
|
619
|
+
AND artifact_link_filter.target_entity_type = ?
|
|
620
|
+
AND artifact_link_filter.target_entity_id = ?
|
|
621
|
+
)`);
|
|
622
|
+
params.push(parsed.linkedEntityType, parsed.linkedEntityId);
|
|
623
|
+
}
|
|
624
|
+
return { sql: clauses.join(" AND "), params };
|
|
560
625
|
}
|
|
561
626
|
function toEventMetadata(metadata) {
|
|
562
627
|
const normalized = {};
|
|
@@ -612,7 +677,10 @@ function insertArtifactVersion(input) {
|
|
|
612
677
|
}
|
|
613
678
|
function deriveFallbackTitle(originalFileName) {
|
|
614
679
|
const sanitized = sanitizeFileName(originalFileName);
|
|
615
|
-
return sanitized
|
|
680
|
+
return (sanitized
|
|
681
|
+
.replace(/\.[^.]+$/, "")
|
|
682
|
+
.replace(/[_-]+/g, " ")
|
|
683
|
+
.trim() || "Artifact");
|
|
616
684
|
}
|
|
617
685
|
export async function createArtifactFromUpload(input, context, services = {}) {
|
|
618
686
|
const parsed = artifactUploadSchema.parse(input);
|
|
@@ -628,7 +696,8 @@ export async function createArtifactFromUpload(input, context, services = {}) {
|
|
|
628
696
|
const blob = await ensureBlobStored(buffer, scan.detectedMimeType);
|
|
629
697
|
const id = artifactId();
|
|
630
698
|
const createdAt = nowIso();
|
|
631
|
-
const sourceKind = parsed.sourceKind ??
|
|
699
|
+
const sourceKind = parsed.sourceKind ??
|
|
700
|
+
(context.source === "agent" ? "agent_upload" : "upload");
|
|
632
701
|
const uploadedByAgentId = parsed.uploadedByAgentId ?? context.token?.agentId ?? null;
|
|
633
702
|
const metadata = {
|
|
634
703
|
...parsed.metadata,
|
|
@@ -690,38 +759,37 @@ export async function createArtifactFromUpload(input, context, services = {}) {
|
|
|
690
759
|
export function createArtifactMetadata() {
|
|
691
760
|
throw new Error("Use POST /api/v1/artifacts for artifact creation. Batch CRUD may search, link, update metadata, delete, and restore artifact records, but it must not create file artifacts.");
|
|
692
761
|
}
|
|
693
|
-
export function
|
|
762
|
+
export function listArtifactsPage(input = {}) {
|
|
694
763
|
const parsed = artifactListQuerySchema.parse(input);
|
|
695
|
-
const
|
|
764
|
+
const where = buildArtifactListWhere(parsed);
|
|
765
|
+
const totalRow = getDatabase()
|
|
766
|
+
.prepare(`SELECT COUNT(*) AS total FROM artifacts WHERE ${where.sql}`)
|
|
767
|
+
.get(...where.params);
|
|
768
|
+
const rows = getDatabase()
|
|
769
|
+
.prepare(`SELECT ${ARTIFACT_SELECT_COLUMNS}
|
|
770
|
+
FROM artifacts
|
|
771
|
+
WHERE ${where.sql}
|
|
772
|
+
ORDER BY updated_at DESC, id ASC
|
|
773
|
+
LIMIT ? OFFSET ?`)
|
|
774
|
+
.all(...where.params, parsed.limit, parsed.offset);
|
|
696
775
|
const linksByArtifactId = new Map();
|
|
697
776
|
for (const linkRow of listEntityLinksForSources("artifact", rows.map((row) => row.id))) {
|
|
698
777
|
const current = linksByArtifactId.get(linkRow.sourceEntityId) ?? [];
|
|
699
778
|
current.push(mapLink(linkRow));
|
|
700
779
|
linksByArtifactId.set(linkRow.sourceEntityId, current);
|
|
701
780
|
}
|
|
702
|
-
const
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
.
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
sourceLabel: artifact.sourceLabel,
|
|
715
|
-
metadata: artifact.metadata
|
|
716
|
-
})
|
|
717
|
-
.toLowerCase()
|
|
718
|
-
.includes(query)
|
|
719
|
-
: true)
|
|
720
|
-
.filter((artifact) => parsed.linkedEntityType && parsed.linkedEntityId
|
|
721
|
-
? artifact.links.some((link) => link.targetEntityType === parsed.linkedEntityType &&
|
|
722
|
-
link.targetEntityId === parsed.linkedEntityId)
|
|
723
|
-
: true)
|
|
724
|
-
.slice(0, parsed.limit);
|
|
781
|
+
const artifacts = rows.map((row) => mapArtifact(row, linksByArtifactId.get(row.id) ?? []));
|
|
782
|
+
const total = totalRow?.total ?? 0;
|
|
783
|
+
return {
|
|
784
|
+
artifacts,
|
|
785
|
+
total,
|
|
786
|
+
limit: parsed.limit,
|
|
787
|
+
offset: parsed.offset,
|
|
788
|
+
hasMore: parsed.offset + artifacts.length < total
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
export function listArtifacts(input = {}) {
|
|
792
|
+
return listArtifactsPage(input).artifacts;
|
|
725
793
|
}
|
|
726
794
|
export function getArtifactById(id) {
|
|
727
795
|
if (isEntityDeleted("artifact", id)) {
|
|
@@ -743,12 +811,13 @@ export function updateArtifactMetadata(id, input, context) {
|
|
|
743
811
|
const nextMetadata = parsed.metadata
|
|
744
812
|
? { ...existing.metadata, ...parsed.metadata }
|
|
745
813
|
: existing.metadata;
|
|
746
|
-
const nextLinks = parsed.links ??
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
814
|
+
const nextLinks = parsed.links ??
|
|
815
|
+
existing.links.map((link) => ({
|
|
816
|
+
entityType: link.targetEntityType,
|
|
817
|
+
entityId: link.targetEntityId,
|
|
818
|
+
anchorKey: link.anchorKey ?? "",
|
|
819
|
+
relationship: link.relationship
|
|
820
|
+
}));
|
|
752
821
|
runInTransaction(() => {
|
|
753
822
|
getDatabase()
|
|
754
823
|
.prepare(`UPDATE artifacts
|
|
@@ -799,7 +868,8 @@ export async function readArtifactDownload(id) {
|
|
|
799
868
|
if (!artifact) {
|
|
800
869
|
return null;
|
|
801
870
|
}
|
|
802
|
-
if (artifact.downloadPolicy !== "human_only" ||
|
|
871
|
+
if (artifact.downloadPolicy !== "human_only" ||
|
|
872
|
+
artifact.artifactState === "blocked") {
|
|
803
873
|
throw new Error("This artifact is not downloadable in its current state.");
|
|
804
874
|
}
|
|
805
875
|
const storagePath = resolveStoragePath(artifact.storageKey);
|
|
@@ -911,6 +911,9 @@ export async function listArtifacts(options = {}) {
|
|
|
911
911
|
if (options.limit) {
|
|
912
912
|
search.set("limit", String(options.limit));
|
|
913
913
|
}
|
|
914
|
+
if (typeof options.offset === "number") {
|
|
915
|
+
search.set("offset", String(options.offset));
|
|
916
|
+
}
|
|
914
917
|
const suffix = search.size > 0 ? `?${search.toString()}` : "";
|
|
915
918
|
return request(`/api/v1/artifacts${suffix}`);
|
|
916
919
|
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "forge-openclaw-plugin",
|
|
3
3
|
"name": "Forge",
|
|
4
4
|
"description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
|
|
5
|
-
"version": "0.3.
|
|
5
|
+
"version": "0.3.19",
|
|
6
6
|
"activation": {
|
|
7
7
|
"onStartup": true,
|
|
8
8
|
"onCapabilities": [
|
package/package.json
CHANGED