@arnilo/prism-tools 0.0.0-stage → 0.13.1
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 +418 -0
- package/LICENSE +21 -0
- package/README.md +44 -2
- package/browser/README.md +98 -0
- package/browser/skills/browser-automation/SKILL.md +14 -0
- package/browser/src/actions/cdp.ts +131 -0
- package/browser/src/actions/dialog.ts +25 -0
- package/browser/src/actions/download_release.ts +22 -0
- package/browser/src/actions/index.ts +37 -0
- package/browser/src/actions/locator.ts +70 -0
- package/browser/src/actions/navigate.ts +23 -0
- package/browser/src/actions/screenshot.ts +27 -0
- package/browser/src/actions/scroll.ts +24 -0
- package/browser/src/actions/select_page.ts +21 -0
- package/browser/src/actions/types.ts +114 -0
- package/browser/src/actions/upload.ts +44 -0
- package/browser/src/actions/wait.ts +45 -0
- package/browser/src/browser.ts +197 -0
- package/browser/src/cdp.ts +178 -0
- package/browser/src/checkpoint.ts +189 -0
- package/browser/src/config.ts +72 -0
- package/browser/src/downloads.ts +253 -0
- package/browser/src/errors.ts +31 -0
- package/browser/src/evaluate.ts +101 -0
- package/browser/src/index.ts +129 -0
- package/browser/src/limits.ts +271 -0
- package/browser/src/manager.ts +730 -0
- package/browser/src/network.ts +263 -0
- package/browser/src/observe.ts +178 -0
- package/browser/src/policy.ts +133 -0
- package/browser/src/screenshot.ts +107 -0
- package/browser/src/shared-sandbox.ts +53 -0
- package/browser/src/snapshot.ts +99 -0
- package/browser/src/targets.ts +165 -0
- package/browser/src/tools.ts +480 -0
- package/browser/src/types.ts +316 -0
- package/browser/src/uploads.ts +174 -0
- package/coding/README.md +337 -0
- package/coding/src/agent/acp-operations.ts +146 -0
- package/coding/src/agent/artifacts.ts +38 -0
- package/coding/src/agent/ask-user-decision.ts +623 -0
- package/coding/src/agent/atomic-write.ts +23 -0
- package/coding/src/agent/bounded-file.ts +21 -0
- package/coding/src/agent/checks.ts +301 -0
- package/coding/src/agent/coding-checkpoint.ts +828 -0
- package/coding/src/agent/delete.ts +237 -0
- package/coding/src/agent/diagnostics-tool.ts +163 -0
- package/coding/src/agent/diagnostics.ts +262 -0
- package/coding/src/agent/edit-diff.ts +382 -0
- package/coding/src/agent/edit.ts +322 -0
- package/coding/src/agent/effects.ts +102 -0
- package/coding/src/agent/env.ts +28 -0
- package/coding/src/agent/execution-policy.ts +89 -0
- package/coding/src/agent/file-mutation-queue.ts +72 -0
- package/coding/src/agent/forge/github.ts +603 -0
- package/coding/src/agent/forge/index.ts +16 -0
- package/coding/src/agent/forge/types.ts +185 -0
- package/coding/src/agent/git-aware-repository.ts +305 -0
- package/coding/src/agent/git-exec.ts +326 -0
- package/coding/src/agent/git-status.ts +177 -0
- package/coding/src/agent/git-tools.ts +360 -0
- package/coding/src/agent/git.ts +1074 -0
- package/coding/src/agent/glob-match.ts +146 -0
- package/coding/src/agent/glob.ts +182 -0
- package/coding/src/agent/goal-verify.ts +385 -0
- package/coding/src/agent/grep-worker.ts +74 -0
- package/coding/src/agent/grep.ts +459 -0
- package/coding/src/agent/identity.ts +48 -0
- package/coding/src/agent/index.ts +676 -0
- package/coding/src/agent/language/client.ts +429 -0
- package/coding/src/agent/language/framing.ts +190 -0
- package/coding/src/agent/language/index.ts +23 -0
- package/coding/src/agent/language/intelligence.ts +682 -0
- package/coding/src/agent/language/types.ts +187 -0
- package/coding/src/agent/lifecycle-events.ts +121 -0
- package/coding/src/agent/lifecycle.ts +166 -0
- package/coding/src/agent/limits.ts +214 -0
- package/coding/src/agent/move.ts +178 -0
- package/coding/src/agent/mutation-path.ts +52 -0
- package/coding/src/agent/output-accumulator.ts +304 -0
- package/coding/src/agent/path-utils.ts +120 -0
- package/coding/src/agent/process/index.ts +58 -0
- package/coding/src/agent/process/recovery.ts +508 -0
- package/coding/src/agent/process/sessions-host.ts +222 -0
- package/coding/src/agent/process/sessions-monitor.ts +141 -0
- package/coding/src/agent/process/sessions-recovery.ts +241 -0
- package/coding/src/agent/process/sessions-spawn.ts +613 -0
- package/coding/src/agent/process/sessions-teardown.ts +281 -0
- package/coding/src/agent/process/sessions.ts +30 -0
- package/coding/src/agent/process/types.ts +358 -0
- package/coding/src/agent/read-path-set.ts +126 -0
- package/coding/src/agent/read.ts +713 -0
- package/coding/src/agent/repository/glob.ts +147 -0
- package/coding/src/agent/repository/indexed-search.ts +480 -0
- package/coding/src/agent/repository/list.ts +131 -0
- package/coding/src/agent/repository/operations.ts +22 -0
- package/coding/src/agent/repository/path.ts +98 -0
- package/coding/src/agent/repository/search.ts +277 -0
- package/coding/src/agent/repository/types.ts +243 -0
- package/coding/src/agent/repository/walk.ts +126 -0
- package/coding/src/agent/repository.ts +12 -0
- package/coding/src/agent/shell-background.ts +264 -0
- package/coding/src/agent/shell-output.ts +75 -0
- package/coding/src/agent/shell.ts +526 -0
- package/coding/src/agent/todo.ts +399 -0
- package/coding/src/agent/truncate.ts +251 -0
- package/coding/src/agent/write.ts +170 -0
- package/coding/src/ask-user-host.ts +48 -0
- package/coding/src/config.ts +278 -0
- package/coding/src/hard-deny.ts +97 -0
- package/coding/src/index.ts +318 -0
- package/coding/src/principal-guard.ts +84 -0
- package/coding/src/sandbox.ts +92 -0
- package/coding/src/security/approval.ts +144 -0
- package/coding/src/security/command-rules.ts +57 -0
- package/coding/src/security/docker-cli.ts +222 -0
- package/coding/src/security/docker-sandbox.ts +1205 -0
- package/coding/src/security/e2b-sandbox.ts +853 -0
- package/coding/src/security/egress/dns-pin.ts +88 -0
- package/coding/src/security/egress/index.ts +32 -0
- package/coding/src/security/egress/limits.ts +57 -0
- package/coding/src/security/egress/policy.ts +137 -0
- package/coding/src/security/egress/proxy.ts +599 -0
- package/coding/src/security/egress/types.ts +30 -0
- package/coding/src/security/index.ts +199 -0
- package/coding/src/security/native-sandbox.ts +639 -0
- package/coding/src/security/path-containment.ts +55 -0
- package/coding/src/security/sandbox-coding-operations.ts +392 -0
- package/coding/src/security/sandbox-fs-operations.ts +644 -0
- package/coding/src/security/sandbox-limits.ts +147 -0
- package/coding/src/security/sandbox-tar.ts +308 -0
- package/coding/src/security/sandbox.ts +179 -0
- package/coding/src/security/semaphore.ts +55 -0
- package/coding/src/targets.ts +110 -0
- package/coding/src/workspace/diff.ts +78 -0
- package/coding/src/workspace/errors.ts +29 -0
- package/coding/src/workspace/index.ts +5 -0
- package/coding/src/workspace/merge.ts +151 -0
- package/coding/src/workspace/routing.ts +76 -0
- package/coding/src/workspace/service.ts +584 -0
- package/computer-use/README.md +105 -0
- package/computer-use/skills/computer-use-linux/SKILL.md +17 -0
- package/computer-use/src/classify.ts +53 -0
- package/computer-use/src/command.ts +29 -0
- package/computer-use/src/config.ts +69 -0
- package/computer-use/src/create.ts +170 -0
- package/computer-use/src/devices.ts +247 -0
- package/computer-use/src/env.ts +28 -0
- package/computer-use/src/index.ts +157 -0
- package/computer-use/src/skill.ts +21 -0
- package/openapi/README.md +97 -0
- package/openapi/src/compile.ts +386 -0
- package/openapi/src/config.ts +73 -0
- package/openapi/src/errors.ts +16 -0
- package/openapi/src/execute.ts +241 -0
- package/openapi/src/index.ts +124 -0
- package/openapi/src/limits.ts +63 -0
- package/openapi/src/specs.ts +86 -0
- package/openapi/src/tools.ts +60 -0
- package/openapi/src/types.ts +61 -0
- package/package.json +171 -4
- package/research/README.md +72 -0
- package/research/skills/research-report/SKILL.md +12 -0
- package/research/skills/research-scoping/SKILL.md +10 -0
- package/research/skills/research-synthesis/SKILL.md +10 -0
- package/research/skills/source-triage/SKILL.md +10 -0
- package/research/src/check.ts +71 -0
- package/research/src/config.ts +41 -0
- package/research/src/index.ts +147 -0
- package/research/src/ledger.ts +157 -0
- package/research/src/urls.ts +21 -0
- package/web/README.md +287 -0
- package/web/skills/web-research/SKILL.md +17 -0
- package/web/src/brave.ts +66 -0
- package/web/src/cache.ts +151 -0
- package/web/src/config.ts +210 -0
- package/web/src/controls.ts +128 -0
- package/web/src/domains.ts +114 -0
- package/web/src/exa.ts +60 -0
- package/web/src/firecrawl.ts +160 -0
- package/web/src/index.ts +387 -0
- package/web/src/kagi.ts +73 -0
- package/web/src/limits.ts +55 -0
- package/web/src/native/convert.ts +84 -0
- package/web/src/native/fetch.ts +226 -0
- package/web/src/normalize.ts +131 -0
- package/web/src/obscura/cdp.ts +201 -0
- package/web/src/obscura/classify.ts +35 -0
- package/web/src/obscura/cli.ts +254 -0
- package/web/src/obscura/errors.ts +8 -0
- package/web/src/obscura/index.ts +59 -0
- package/web/src/obscura/limits.ts +92 -0
- package/web/src/obscura/mcp.ts +104 -0
- package/web/src/obscura/playwright.ts +133 -0
- package/web/src/obscura/process.ts +235 -0
- package/web/src/obscura/search-profile.ts +73 -0
- package/web/src/obscura/types.ts +48 -0
- package/web/src/obscura/web.ts +419 -0
- package/web/src/prompt-fetch.ts +88 -0
- package/web/src/render.ts +75 -0
- package/web/src/searxng.ts +78 -0
- package/web/src/slice.ts +139 -0
- package/web/src/tavily.ts +77 -0
- package/web/src/tools.ts +182 -0
- package/web/src/transport.ts +310 -0
- package/web/src/types.ts +199 -0
- package/work/README.md +77 -0
- package/work/THIRD_PARTY_NOTICES +24 -0
- package/work/docling/ocr.py +150 -0
- package/work/sandbox/Dockerfile +36 -0
- package/work/sandbox/soffice.sh +12 -0
- package/work/src/command.ts +29 -0
- package/work/src/config.ts +138 -0
- package/work/src/connectors/cli.ts +343 -0
- package/work/src/connectors/drafts.ts +647 -0
- package/work/src/connectors/errors.ts +8 -0
- package/work/src/connectors/file-bytes.ts +149 -0
- package/work/src/connectors/google-workspace-http.ts +399 -0
- package/work/src/connectors/google-workspace.ts +465 -0
- package/work/src/connectors/gws-tools.ts +378 -0
- package/work/src/connectors/http.ts +123 -0
- package/work/src/connectors/idempotency.ts +235 -0
- package/work/src/connectors/identity.ts +34 -0
- package/work/src/connectors/index.ts +93 -0
- package/work/src/connectors/limits.ts +50 -0
- package/work/src/connectors/m365-tools.ts +308 -0
- package/work/src/connectors/microsoft365-http.ts +428 -0
- package/work/src/connectors/microsoft365.ts +402 -0
- package/work/src/connectors/normalize.ts +120 -0
- package/work/src/connectors/tool-helpers.ts +398 -0
- package/work/src/connectors/tools.ts +42 -0
- package/work/src/connectors/types.ts +399 -0
- package/work/src/diagrams/canonicalize.ts +166 -0
- package/work/src/diagrams/caps.ts +52 -0
- package/work/src/diagrams/embed.ts +340 -0
- package/work/src/diagrams/errors.ts +76 -0
- package/work/src/diagrams/index.ts +81 -0
- package/work/src/diagrams/messages.ts +150 -0
- package/work/src/diagrams/origin.ts +52 -0
- package/work/src/diagrams/telemetry.ts +34 -0
- package/work/src/diagrams/xml.ts +267 -0
- package/work/src/document-extraction/index.ts +563 -0
- package/work/src/document-reader/ambient.d.ts +2 -0
- package/work/src/document-reader/errors.ts +7 -0
- package/work/src/document-reader/index.ts +181 -0
- package/work/src/document-reader/mistral-ocr.ts +318 -0
- package/work/src/document-reader/parsers.ts +171 -0
- package/work/src/documents/caps.ts +135 -0
- package/work/src/documents/diff.ts +269 -0
- package/work/src/documents/errors.ts +44 -0
- package/work/src/documents/fidelity.ts +98 -0
- package/work/src/documents/generate.ts +96 -0
- package/work/src/documents/hash.ts +8 -0
- package/work/src/documents/index.ts +14 -0
- package/work/src/documents/model-schema.ts +639 -0
- package/work/src/documents/parse.ts +252 -0
- package/work/src/documents/patch-history.ts +81 -0
- package/work/src/documents/patch.ts +476 -0
- package/work/src/documents/preview-html.ts +245 -0
- package/work/src/documents/preview.ts +227 -0
- package/work/src/documents/telemetry.ts +36 -0
- package/work/src/documents/translate/docx.ts +292 -0
- package/work/src/documents/translate/pptx.ts +304 -0
- package/work/src/documents/translate/xlsx.ts +137 -0
- package/work/src/documents/types.ts +188 -0
- package/work/src/index.ts +311 -0
- package/work/src/runtime/worker-pool-entry.ts +102 -0
- package/work/src/runtime/worker-pool.ts +267 -0
- package/work/src/sandbox/composition.ts +212 -0
- package/work/src/sandbox/image.ts +6 -0
- package/work/src/sandbox/index.ts +14 -0
- package/work/src/sheets/caps.ts +68 -0
- package/work/src/sheets/csv.ts +351 -0
- package/work/src/sheets/decimal.ts +388 -0
- package/work/src/sheets/errors.ts +52 -0
- package/work/src/sheets/index.ts +62 -0
- package/work/src/sheets/inference.ts +378 -0
- package/work/src/sheets/telemetry.ts +34 -0
- package/work/src/sheets/types.ts +162 -0
- package/work/src/sheets/xlsx.ts +388 -0
- package/work/src/skills/index.ts +8 -0
- package/work/src/skills/load.ts +43 -0
- package/work/src/tools/filesystem.ts +21 -0
- package/work/src/tools/index.ts +1 -0
- package/work/src/tools/local-filesystem.ts +33 -0
- package/work/src/tools/office.ts +311 -0
- package/work/vendor/hermes-agent/LICENSE +21 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/LICENSE +21 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/SKILL.md +196 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_comments.py +289 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_common.py +94 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_create.py +177 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_edit.py +250 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_read.py +149 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_revisions.py +147 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_template.py +70 -0
- package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_validate.py +156 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/LICENSE +21 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/SKILL.md +125 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/_raster.py +76 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/extract_marker.py +88 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/extract_pymupdf.py +101 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_create.py +130 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_fill_form.py +97 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_form_layout.py +168 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_make_form.py +145 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_merge.py +50 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_meta.py +115 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_page_image.py +99 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_read.py +153 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_secure.py +71 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_split.py +84 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_stamp.py +143 -0
- package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_watermark.py +51 -0
- package/work/vendor/hermes-agent/skills/productivity/powerpoint/LICENSE +21 -0
- package/work/vendor/hermes-agent/skills/productivity/powerpoint/SKILL.md +220 -0
- package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_create.py +214 -0
- package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_edit.py +436 -0
- package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_from_template.py +88 -0
- package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_read.py +131 -0
- package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_render.py +93 -0
- package/work/vendor/hermes-agent/skills/productivity/xlsx/LICENSE +21 -0
- package/work/vendor/hermes-agent/skills/productivity/xlsx/SKILL.md +196 -0
- package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/csv_to_xlsx.py +104 -0
- package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_create.py +259 -0
- package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_edit.py +263 -0
- package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_read.py +160 -0
- package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_recalc.py +111 -0
- package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_restructure.py +337 -0
- package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_to_csv.py +69 -0
- package/work/vendor-lock.json +11 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ColumnOptions,
|
|
3
|
+
generateWorkbookSync,
|
|
4
|
+
parseWorkbookSync as ooParseWorkbook,
|
|
5
|
+
type WorkbookOptions,
|
|
6
|
+
type WorksheetOptions,
|
|
7
|
+
} from "@office-open/xlsx";
|
|
8
|
+
import type { CellValue, SheetData, SheetModel } from "../types.js";
|
|
9
|
+
|
|
10
|
+
/** Draft-07 DecimalCellValue pattern; requires a fractional part so years/ids stay strings. */
|
|
11
|
+
const CANONICAL_DECIMAL = /^-?(?:0|[1-9]\d*)\.\d+$/;
|
|
12
|
+
|
|
13
|
+
function mapCellValue(cell: CellValue) {
|
|
14
|
+
if (cell === null || cell === undefined) {
|
|
15
|
+
return { value: "" };
|
|
16
|
+
}
|
|
17
|
+
if (typeof cell === "string" || typeof cell === "number" || typeof cell === "boolean") {
|
|
18
|
+
return { value: cell };
|
|
19
|
+
}
|
|
20
|
+
if ("type" in cell) {
|
|
21
|
+
if (cell.type === "decimal") {
|
|
22
|
+
return { value: cell.value };
|
|
23
|
+
}
|
|
24
|
+
if (cell.type === "date" || cell.type === "datetime") {
|
|
25
|
+
return { value: cell.value };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if ("formula" in cell) {
|
|
29
|
+
const rawFormula = cell.formula.startsWith("=") ? cell.formula.slice(1) : cell.formula;
|
|
30
|
+
return {
|
|
31
|
+
formula: rawFormula,
|
|
32
|
+
value: cell.cachedValue !== undefined && cell.cachedValue !== null ? cell.cachedValue : undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return { value: "" };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function sheetDataToWorksheet(data: SheetData): WorksheetOptions {
|
|
39
|
+
const rows = data.cells.map((row) => ({
|
|
40
|
+
cells: row.map(mapCellValue),
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
const columns: ColumnOptions[] | undefined = data.columnWidths
|
|
44
|
+
? data.columnWidths.map((cw) => ({
|
|
45
|
+
min: cw.column + 1,
|
|
46
|
+
max: cw.column + 1,
|
|
47
|
+
width: cw.width,
|
|
48
|
+
}))
|
|
49
|
+
: undefined;
|
|
50
|
+
|
|
51
|
+
const freezePanes = data.frozenPanes
|
|
52
|
+
? {
|
|
53
|
+
row: data.frozenPanes.rows,
|
|
54
|
+
col: data.frozenPanes.columns,
|
|
55
|
+
}
|
|
56
|
+
: undefined;
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
name: data.name,
|
|
60
|
+
columns,
|
|
61
|
+
freezePanes,
|
|
62
|
+
rows,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function sheetModelToXlsxOptions(model: SheetModel): WorkbookOptions {
|
|
67
|
+
return {
|
|
68
|
+
worksheets: model.sheets.map(sheetDataToWorksheet),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function generateXlsxBytes(model: SheetModel): Uint8Array {
|
|
73
|
+
const options = sheetModelToXlsxOptions(model);
|
|
74
|
+
const result = generateWorkbookSync(options);
|
|
75
|
+
return new Uint8Array(result);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function parseXlsxBytes(bytes: Uint8Array): SheetModel {
|
|
79
|
+
const parsed = ooParseWorkbook(bytes);
|
|
80
|
+
const worksheets = parsed.worksheets ?? [];
|
|
81
|
+
const sheets: SheetData[] = [];
|
|
82
|
+
|
|
83
|
+
for (const ws of worksheets) {
|
|
84
|
+
const name = ws.name ?? "Sheet1";
|
|
85
|
+
const cells: CellValue[][] = [];
|
|
86
|
+
|
|
87
|
+
for (const row of ws.rows ?? []) {
|
|
88
|
+
const rowCells: CellValue[] = [];
|
|
89
|
+
for (const c of row.cells ?? []) {
|
|
90
|
+
if (c.formula && typeof c.formula === "object" && "formula" in c.formula && typeof c.formula.formula === "string") {
|
|
91
|
+
const raw = c.formula.formula;
|
|
92
|
+
const formulaStr = raw.startsWith("=") ? raw : `=${raw}`;
|
|
93
|
+
rowCells.push({
|
|
94
|
+
formula: formulaStr,
|
|
95
|
+
cachedValue: c.value !== undefined ? (c.value as string | number | boolean | null) : null,
|
|
96
|
+
});
|
|
97
|
+
} else if (typeof c.value === "number") {
|
|
98
|
+
rowCells.push(c.value);
|
|
99
|
+
} else if (typeof c.value === "string") {
|
|
100
|
+
rowCells.push(CANONICAL_DECIMAL.test(c.value) ? { type: "decimal", value: c.value } : c.value);
|
|
101
|
+
} else if (typeof c.value === "boolean") {
|
|
102
|
+
rowCells.push(c.value);
|
|
103
|
+
} else if (c.value === null || c.value === undefined) {
|
|
104
|
+
rowCells.push(null);
|
|
105
|
+
} else {
|
|
106
|
+
rowCells.push(String(c.value));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
cells.push(rowCells);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const columnWidths = ws.columns?.map((cw, i) => ({
|
|
113
|
+
column: cw.min !== undefined ? cw.min - 1 : i,
|
|
114
|
+
width: cw.width ?? 10,
|
|
115
|
+
}));
|
|
116
|
+
|
|
117
|
+
const frozenPanes = ws.freezePanes
|
|
118
|
+
? {
|
|
119
|
+
rows: ws.freezePanes.row,
|
|
120
|
+
columns: ws.freezePanes.col,
|
|
121
|
+
}
|
|
122
|
+
: undefined;
|
|
123
|
+
|
|
124
|
+
sheets.push({
|
|
125
|
+
name,
|
|
126
|
+
cells,
|
|
127
|
+
columnWidths,
|
|
128
|
+
frozenPanes,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
kind: "sheet",
|
|
134
|
+
modelVersion: 1,
|
|
135
|
+
sheets,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Prism Document Model types.
|
|
3
|
+
*
|
|
4
|
+
* All models are plain JSON-serializable structures with zero required class
|
|
5
|
+
* instantiation. Discriminated union on `kind` ("doc" | "sheet" | "deck") with
|
|
6
|
+
* stamped `modelVersion`.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export type DocumentKind = "doc" | "sheet" | "deck";
|
|
10
|
+
|
|
11
|
+
// --- Document Runs & Inline Elements ---
|
|
12
|
+
|
|
13
|
+
export interface DocRun {
|
|
14
|
+
readonly text: string;
|
|
15
|
+
readonly bold?: boolean;
|
|
16
|
+
readonly italic?: boolean;
|
|
17
|
+
readonly underline?: boolean;
|
|
18
|
+
readonly strikethrough?: boolean;
|
|
19
|
+
readonly code?: boolean;
|
|
20
|
+
readonly link?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ListItem {
|
|
24
|
+
readonly text: string;
|
|
25
|
+
readonly runs?: readonly DocRun[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// --- Cell Values (Document Tables & Sheets) ---
|
|
29
|
+
|
|
30
|
+
export interface DecimalCellValue {
|
|
31
|
+
readonly type: "decimal";
|
|
32
|
+
/** Canonical decimal string (e.g. "1234.56", "-0.05", "42"). */
|
|
33
|
+
readonly value: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface DateCellValue {
|
|
37
|
+
readonly type: "date";
|
|
38
|
+
/** ISO-8601 date string (YYYY-MM-DD). */
|
|
39
|
+
readonly value: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface DateTimeCellValue {
|
|
43
|
+
readonly type: "datetime";
|
|
44
|
+
/** ISO-8601 datetime string (e.g. "2026-08-31T18:00:00Z"). */
|
|
45
|
+
readonly value: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface FormulaCellValue {
|
|
49
|
+
/** Formula expression starting with "=" (read-only, not evaluated by Prism). */
|
|
50
|
+
readonly formula: string;
|
|
51
|
+
/** Optional pre-computed or cached value. */
|
|
52
|
+
readonly cachedValue?: string | number | boolean | null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type CellValue = string | number | boolean | DecimalCellValue | DateCellValue | DateTimeCellValue | FormulaCellValue | null;
|
|
56
|
+
|
|
57
|
+
// --- Chart Data ---
|
|
58
|
+
|
|
59
|
+
export type ChartType = "bar" | "line" | "pie" | "scatter";
|
|
60
|
+
|
|
61
|
+
export interface ChartSeries {
|
|
62
|
+
readonly name: string;
|
|
63
|
+
readonly values: readonly number[];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ChartData {
|
|
67
|
+
readonly categories: readonly string[];
|
|
68
|
+
readonly series: readonly ChartSeries[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// --- Document Blocks (DocModel) ---
|
|
72
|
+
|
|
73
|
+
export interface HeadingBlock {
|
|
74
|
+
readonly type: "heading";
|
|
75
|
+
readonly level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
76
|
+
readonly text: string;
|
|
77
|
+
readonly id?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface ParagraphBlock {
|
|
81
|
+
readonly type: "paragraph";
|
|
82
|
+
readonly text?: string;
|
|
83
|
+
readonly runs?: readonly DocRun[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface ListBlock {
|
|
87
|
+
readonly type: "list";
|
|
88
|
+
readonly ordered?: boolean;
|
|
89
|
+
readonly items: readonly (string | ListItem)[];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface TableBlock {
|
|
93
|
+
readonly type: "table";
|
|
94
|
+
readonly rows: number;
|
|
95
|
+
readonly columns: number;
|
|
96
|
+
readonly headers?: readonly string[];
|
|
97
|
+
readonly cells: readonly (readonly CellValue[])[];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface ImageBlock {
|
|
101
|
+
readonly type: "image";
|
|
102
|
+
/** Base64-encoded image data or empty when referencing via `ref`. */
|
|
103
|
+
readonly data?: string;
|
|
104
|
+
readonly mimeType?: string;
|
|
105
|
+
readonly alt?: string;
|
|
106
|
+
readonly width?: number;
|
|
107
|
+
readonly height?: number;
|
|
108
|
+
/** Host-supplied opaque asset reference. */
|
|
109
|
+
readonly ref?: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface PageBreakBlock {
|
|
113
|
+
readonly type: "page-break";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface ChartBlock {
|
|
117
|
+
readonly type: "chart";
|
|
118
|
+
readonly chartType: ChartType;
|
|
119
|
+
readonly title?: string;
|
|
120
|
+
readonly data: ChartData;
|
|
121
|
+
readonly alt?: string;
|
|
122
|
+
readonly width?: number;
|
|
123
|
+
readonly height?: number;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export type DocBlock = HeadingBlock | ParagraphBlock | ListBlock | TableBlock | ImageBlock | PageBreakBlock | ChartBlock;
|
|
127
|
+
|
|
128
|
+
// --- Sheet Model Elements ---
|
|
129
|
+
|
|
130
|
+
export interface ColumnWidth {
|
|
131
|
+
readonly column: number;
|
|
132
|
+
readonly width: number;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface FrozenPanes {
|
|
136
|
+
readonly rows?: number;
|
|
137
|
+
readonly columns?: number;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface SheetData {
|
|
141
|
+
readonly name: string;
|
|
142
|
+
readonly cells: readonly (readonly CellValue[])[];
|
|
143
|
+
readonly columnWidths?: readonly ColumnWidth[];
|
|
144
|
+
readonly frozenPanes?: FrozenPanes;
|
|
145
|
+
readonly numberFormats?: Readonly<Record<string, string>>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// --- Presentation Slide Elements ---
|
|
149
|
+
|
|
150
|
+
export type SlideLayout = "title" | "title-and-content" | "section-header" | "two-column" | "blank";
|
|
151
|
+
|
|
152
|
+
export interface SlideData {
|
|
153
|
+
readonly layout: SlideLayout;
|
|
154
|
+
readonly title?: string;
|
|
155
|
+
readonly subtitle?: string;
|
|
156
|
+
readonly bullets?: readonly (string | ListItem)[];
|
|
157
|
+
readonly notes?: string;
|
|
158
|
+
readonly image?: ImageBlock;
|
|
159
|
+
readonly chart?: ChartBlock;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// --- Top-Level Document Models ---
|
|
163
|
+
|
|
164
|
+
export interface DocModel {
|
|
165
|
+
readonly kind: "doc";
|
|
166
|
+
readonly modelVersion: number;
|
|
167
|
+
readonly title?: string;
|
|
168
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
169
|
+
readonly blocks: readonly DocBlock[];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface SheetModel {
|
|
173
|
+
readonly kind: "sheet";
|
|
174
|
+
readonly modelVersion: number;
|
|
175
|
+
readonly title?: string;
|
|
176
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
177
|
+
readonly sheets: readonly SheetData[];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export interface DeckModel {
|
|
181
|
+
readonly kind: "deck";
|
|
182
|
+
readonly modelVersion: number;
|
|
183
|
+
readonly title?: string;
|
|
184
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
185
|
+
readonly slides: readonly SlideData[];
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export type DocumentModel = DocModel | SheetModel | DeckModel;
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@arnilo/prism-tools/work` — the first-party work tools as a package.
|
|
3
|
+
*
|
|
4
|
+
* The default export registers the `office_*` document tools, `work_exec` inside the host-injected
|
|
5
|
+
* `work.sandbox` service, and the `m365_*` / `gws_*` connector tools when a ref-only credential
|
|
6
|
+
* resolves. The bounded document reader is provided as the `work.reader` service, and the vendored
|
|
7
|
+
* Hermes productivity skills are added from `vendor/`. A missing optional parser, an unresolved
|
|
8
|
+
* connector credential, or a missing sandbox writes a `warn` status note and registers less.
|
|
9
|
+
*
|
|
10
|
+
* The document, spreadsheet, diagram, reader, extraction, connector, sandbox, skill, and tool
|
|
11
|
+
* libraries stay importable as subpaths (`@arnilo/prism-tools/work/documents`, `/sheets`,
|
|
12
|
+
* `/connectors`, …) because the family shares type names (`validateByteCap`, `CellValue`) that a
|
|
13
|
+
* single flat barrel cannot re-export unambiguously. The 0.12 factory names stay exported.
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import toolsWork from "@arnilo/prism-tools/work";
|
|
17
|
+
* import { createAgent } from "@arnilo/prism";
|
|
18
|
+
*
|
|
19
|
+
* const agent = await createAgent({
|
|
20
|
+
* model,
|
|
21
|
+
* packages: [toolsWork({ root: process.cwd(), connectors: { microsoft365: { credential: "keyring:m365", configDir, identity } } })],
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { isAbsolute } from "node:path";
|
|
27
|
+
import { definePackage, type JsonObject, type PackageAPI, type PackageInstance, type Secret, type ToolDefinition } from "@arnilo/prism";
|
|
28
|
+
import manifest from "../../package.json" with { type: "json" };
|
|
29
|
+
import { resolveCommand } from "./command.js";
|
|
30
|
+
import { type ToolsWorkConfig, toolsWorkConfigSchema } from "./config.js";
|
|
31
|
+
import { createGoogleWorkspaceCliAdapter } from "./connectors/google-workspace.js";
|
|
32
|
+
import { type AgentIdentity } from "./connectors/identity.js";
|
|
33
|
+
import { createMicrosoft365CliAdapter } from "./connectors/microsoft365.js";
|
|
34
|
+
import { createWorkTools } from "./connectors/tools.js";
|
|
35
|
+
import type {
|
|
36
|
+
GoogleWorkspaceAdapter,
|
|
37
|
+
GoogleWorkspaceOp,
|
|
38
|
+
Microsoft365Adapter,
|
|
39
|
+
Microsoft365Op,
|
|
40
|
+
WorkTokenProvider,
|
|
41
|
+
WorkToolsOptions,
|
|
42
|
+
} from "./connectors/types.js";
|
|
43
|
+
import {
|
|
44
|
+
createDocumentReader,
|
|
45
|
+
createDocxParser,
|
|
46
|
+
createOoxmlParser,
|
|
47
|
+
createPdfParser,
|
|
48
|
+
type DocumentParser,
|
|
49
|
+
type DocumentReader,
|
|
50
|
+
} from "./document-reader/index.js";
|
|
51
|
+
import { createMistralOcrParser } from "./document-reader/mistral-ocr.js";
|
|
52
|
+
import { closeWorkerPool } from "./runtime/worker-pool.js";
|
|
53
|
+
import { createWorkComposition, type WorkSandbox } from "./sandbox/composition.js";
|
|
54
|
+
import { loadWorkSkills } from "./skills/index.js";
|
|
55
|
+
import { createLocalWorkFilesystem } from "./tools/local-filesystem.js";
|
|
56
|
+
import { createOfficeTools } from "./tools/office.js";
|
|
57
|
+
|
|
58
|
+
export type {
|
|
59
|
+
ToolsWorkConfig,
|
|
60
|
+
ToolsWorkConnectorConfig,
|
|
61
|
+
ToolsWorkConnectorsConfig,
|
|
62
|
+
ToolsWorkOfficeConfig,
|
|
63
|
+
ToolsWorkReaderConfig,
|
|
64
|
+
} from "./config.js";
|
|
65
|
+
export { toolsWorkConfigSchema } from "./config.js";
|
|
66
|
+
export { createWorkTools, WORK_MUTATING_TOOL_NAMES } from "./connectors/tools.js";
|
|
67
|
+
export { createDocumentReader, type DocumentReader } from "./document-reader/index.js";
|
|
68
|
+
// A curated flat surface; the group libraries stay behind their subpaths (see the file doc comment).
|
|
69
|
+
export { createWorkComposition, type WorkComposition, type WorkSandbox } from "./sandbox/composition.js";
|
|
70
|
+
export { loadWorkSkills, type WorkSkillName } from "./skills/index.js";
|
|
71
|
+
export { createLocalWorkFilesystem } from "./tools/local-filesystem.js";
|
|
72
|
+
export { createOfficeTools, type OfficeToolsOptions } from "./tools/office.js";
|
|
73
|
+
|
|
74
|
+
const READER_FORMATS = ["pdf", "docx", "xlsx", "pptx"] as const;
|
|
75
|
+
|
|
76
|
+
function identityFrom(json: JsonObject): AgentIdentity {
|
|
77
|
+
return { ...json, verified: true } as unknown as AgentIdentity;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The token provider for a connector credential. A JSON object value is treated as the env map to
|
|
82
|
+
* inject; any other value becomes the provider's default access-token variable. The value is never
|
|
83
|
+
* logged, returned, or placed in argv.
|
|
84
|
+
*/
|
|
85
|
+
function tokenProviderFrom(provider: "microsoft365" | "google-workspace", secret: Secret): WorkTokenProvider {
|
|
86
|
+
const fallback = provider === "microsoft365" ? "M365_ACCESSTOKEN" : "GOOGLE_ACCESS_TOKEN";
|
|
87
|
+
return {
|
|
88
|
+
tokenEnv: () => {
|
|
89
|
+
try {
|
|
90
|
+
const parsed: unknown = JSON.parse(secret.value);
|
|
91
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
92
|
+
const out: Record<string, string> = {};
|
|
93
|
+
for (const [key, value] of Object.entries(parsed)) if (typeof value === "string") out[key] = value;
|
|
94
|
+
if (Object.keys(out).length > 0) return out;
|
|
95
|
+
}
|
|
96
|
+
} catch {
|
|
97
|
+
// Not JSON: fall through to the provider's default variable.
|
|
98
|
+
}
|
|
99
|
+
return { [fallback]: secret.value };
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Build the reader service. A missing optional peer drops only its formats, with one note. */
|
|
105
|
+
async function buildReader(prism: PackageAPI<ToolsWorkConfig>): Promise<DocumentReader | undefined> {
|
|
106
|
+
const config = prism.config.reader;
|
|
107
|
+
if (config === undefined) return undefined;
|
|
108
|
+
const formats = new Set(config.formats ?? READER_FORMATS);
|
|
109
|
+
const parsers: DocumentParser[] = [];
|
|
110
|
+
const dropped: string[] = [];
|
|
111
|
+
|
|
112
|
+
if (formats.has("pdf")) {
|
|
113
|
+
if (config.ocr) {
|
|
114
|
+
const secret = await prism.credentials.resolve(config.ocr.apiKey);
|
|
115
|
+
if (secret) {
|
|
116
|
+
parsers.push(
|
|
117
|
+
createMistralOcrParser({
|
|
118
|
+
apiKey: secret.value,
|
|
119
|
+
...(config.ocr.baseUrl ? { baseUrl: config.ocr.baseUrl } : {}),
|
|
120
|
+
...(config.ocr.model ? { model: config.ocr.model } : {}),
|
|
121
|
+
}),
|
|
122
|
+
);
|
|
123
|
+
} else {
|
|
124
|
+
dropped.push("pdf (ocr credential unresolved)");
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
try {
|
|
128
|
+
parsers.push(await createPdfParser());
|
|
129
|
+
} catch {
|
|
130
|
+
dropped.push("pdf (pdf-parse)");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (formats.has("docx")) {
|
|
135
|
+
try {
|
|
136
|
+
parsers.push(await createDocxParser());
|
|
137
|
+
} catch {
|
|
138
|
+
dropped.push("docx (mammoth)");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (const [format, kind, part] of [
|
|
142
|
+
["xlsx", "sheet", "xl/workbook.xml"],
|
|
143
|
+
["pptx", "deck", "ppt/presentation.xml"],
|
|
144
|
+
] as const) {
|
|
145
|
+
if (!formats.has(format)) continue;
|
|
146
|
+
try {
|
|
147
|
+
await import("./documents/parse.js");
|
|
148
|
+
parsers.push(createOoxmlParser(format, kind, part));
|
|
149
|
+
} catch {
|
|
150
|
+
dropped.push(`${format} (install @office-open/docx, @office-open/pptx, @office-open/xlsx, @office-open/xml and ajv)`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (dropped.length > 0) {
|
|
155
|
+
prism.status.note("warn", `work: dropped reader formats: ${dropped.join(", ")}`);
|
|
156
|
+
}
|
|
157
|
+
if (parsers.length === 0) return undefined;
|
|
158
|
+
return await createDocumentReader({
|
|
159
|
+
parsers,
|
|
160
|
+
...(config.maxBytes !== undefined ? { maxBytes: config.maxBytes } : {}),
|
|
161
|
+
...(config.maxPages !== undefined ? { maxPages: config.maxPages } : {}),
|
|
162
|
+
...(config.maxTextBytes !== undefined ? { maxTextBytes: config.maxTextBytes } : {}),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Build the connector adapters. A provider registers only when its credential resolves. */
|
|
167
|
+
async function buildConnectors(prism: PackageAPI<ToolsWorkConfig>): Promise<WorkToolsOptions | undefined> {
|
|
168
|
+
const config = prism.config.connectors;
|
|
169
|
+
if (config === undefined) return undefined;
|
|
170
|
+
|
|
171
|
+
let microsoft365: Microsoft365Adapter | undefined;
|
|
172
|
+
let googleWorkspace: GoogleWorkspaceAdapter | undefined;
|
|
173
|
+
|
|
174
|
+
const m365 = config.microsoft365;
|
|
175
|
+
if (m365) {
|
|
176
|
+
const secret = await prism.credentials.resolve(m365.credential);
|
|
177
|
+
if (!secret) {
|
|
178
|
+
prism.status.note("warn", "work: microsoft365 credential did not resolve; registering no microsoft365 tools");
|
|
179
|
+
} else if (!m365.configDir || !m365.identity) {
|
|
180
|
+
prism.status.note("warn", "work: microsoft365 needs configDir and identity; registering no microsoft365 tools");
|
|
181
|
+
} else {
|
|
182
|
+
const binary = resolveCommand(m365.binary ?? "m365");
|
|
183
|
+
if (!binary) {
|
|
184
|
+
prism.status.note(
|
|
185
|
+
"warn",
|
|
186
|
+
`work: microsoft365 binary "${m365.binary ?? "m365"}" not found on PATH; registering no microsoft365 tools`,
|
|
187
|
+
);
|
|
188
|
+
} else {
|
|
189
|
+
microsoft365 = createMicrosoft365CliAdapter({
|
|
190
|
+
binary,
|
|
191
|
+
configDir: m365.configDir,
|
|
192
|
+
identity: identityFrom(m365.identity),
|
|
193
|
+
...(m365.allowedOps ? { allowedOps: m365.allowedOps as readonly Microsoft365Op[] } : {}),
|
|
194
|
+
tokenProvider: tokenProviderFrom("microsoft365", secret),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const google = config.google;
|
|
201
|
+
if (google) {
|
|
202
|
+
const secret = await prism.credentials.resolve(google.credential);
|
|
203
|
+
if (!secret) {
|
|
204
|
+
prism.status.note("warn", "work: google credential did not resolve; registering no google tools");
|
|
205
|
+
} else if (!google.configDir || !google.identity) {
|
|
206
|
+
prism.status.note("warn", "work: google needs configDir and identity; registering no google tools");
|
|
207
|
+
} else {
|
|
208
|
+
const binary = resolveCommand(google.binary ?? "gws");
|
|
209
|
+
if (!binary) {
|
|
210
|
+
prism.status.note("warn", `work: google binary "${google.binary ?? "gws"}" not found on PATH; registering no google tools`);
|
|
211
|
+
} else {
|
|
212
|
+
googleWorkspace = createGoogleWorkspaceCliAdapter({
|
|
213
|
+
binary,
|
|
214
|
+
configDir: google.configDir,
|
|
215
|
+
identity: identityFrom(google.identity),
|
|
216
|
+
...(google.allowedOps ? { allowedOps: google.allowedOps as readonly GoogleWorkspaceOp[] } : {}),
|
|
217
|
+
tokenProvider: tokenProviderFrom("google-workspace", secret),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (!microsoft365 && !googleWorkspace) return undefined;
|
|
224
|
+
return {
|
|
225
|
+
...(microsoft365 ? { microsoft365 } : {}),
|
|
226
|
+
...(googleWorkspace ? { googleWorkspace } : {}),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const definition = definePackage<ToolsWorkConfig>({
|
|
231
|
+
name: "@arnilo/prism-tools/work",
|
|
232
|
+
version: manifest.version,
|
|
233
|
+
description:
|
|
234
|
+
"Office document, spreadsheet, diagram, connector, and bounded reader tools with declared effects, ref-only credentials, and an injected work sandbox.",
|
|
235
|
+
requires: { api: 1 },
|
|
236
|
+
capabilities: ["credentials"],
|
|
237
|
+
config: toolsWorkConfigSchema,
|
|
238
|
+
setup: async (prism) => {
|
|
239
|
+
const root = prism.config.root;
|
|
240
|
+
if (typeof root !== "string" || root.length === 0) {
|
|
241
|
+
throw new Error("prism-tools-work: config needs root (the absolute workspace root the file tools operate in)");
|
|
242
|
+
}
|
|
243
|
+
if (!isAbsolute(root)) {
|
|
244
|
+
throw new Error("prism-tools-work: root must be an absolute path");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const filesystem = createLocalWorkFilesystem(root);
|
|
248
|
+
const officeConfig = prism.config.office;
|
|
249
|
+
const officeOptions = {
|
|
250
|
+
filesystem,
|
|
251
|
+
...(officeConfig?.maxBytes !== undefined ? { caps: { maxBytes: officeConfig.maxBytes } } : {}),
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const reader = await buildReader(prism);
|
|
255
|
+
if (reader) prism.services.provide("work.reader", reader);
|
|
256
|
+
|
|
257
|
+
const connectors = await buildConnectors(prism);
|
|
258
|
+
let officeEnabled = officeConfig?.enabled !== false;
|
|
259
|
+
const officePeers = ["@office-open/docx", "@office-open/pptx", "@office-open/xlsx", "@office-open/xml", "ajv", "fast-xml-parser"];
|
|
260
|
+
const missingPeers = officePeers.filter((peer) => {
|
|
261
|
+
try {
|
|
262
|
+
import.meta.resolve(peer);
|
|
263
|
+
return false;
|
|
264
|
+
} catch {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
if (missingPeers.length > 0) {
|
|
269
|
+
prism.status.note(
|
|
270
|
+
"warn",
|
|
271
|
+
`work: optional peers missing: ${missingPeers.join(", ")}; install them to enable Office tools and OOXML reading`,
|
|
272
|
+
);
|
|
273
|
+
officeEnabled = false;
|
|
274
|
+
}
|
|
275
|
+
const workEnabled = prism.config.work?.enabled !== false;
|
|
276
|
+
const sandbox = prism.services.consume<WorkSandbox>("work.sandbox");
|
|
277
|
+
|
|
278
|
+
const tools: ToolDefinition[] = [];
|
|
279
|
+
if (sandbox && workEnabled) {
|
|
280
|
+
const composed = createWorkComposition({
|
|
281
|
+
sandbox,
|
|
282
|
+
...(officeEnabled ? { office: officeOptions } : {}),
|
|
283
|
+
...(connectors ? { connectors } : {}),
|
|
284
|
+
...(reader ? { reader } : {}),
|
|
285
|
+
filesystem,
|
|
286
|
+
...(prism.config.env ? { env: prism.config.env } : {}),
|
|
287
|
+
});
|
|
288
|
+
tools.push(...composed.tools.filter((tool) => officeEnabled || !tool.name.startsWith("office_")));
|
|
289
|
+
} else {
|
|
290
|
+
if (officeEnabled) tools.push(...createOfficeTools(officeOptions));
|
|
291
|
+
if (connectors) tools.push(...createWorkTools({ ...connectors, filesystem }));
|
|
292
|
+
if (workEnabled && !sandbox) {
|
|
293
|
+
prism.status.note("warn", "work: work_exec needs the host work.sandbox service; registering office and connector tools only");
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
for (const tool of tools) prism.tools.register(tool);
|
|
298
|
+
|
|
299
|
+
for (const skill of loadWorkSkills()) prism.skills.register(skill);
|
|
300
|
+
|
|
301
|
+
prism.onDispose(() => closeWorkerPool());
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
/** The package definition. Pass config through `packageConfig` or use {@link toolsWork}. */
|
|
306
|
+
export default definition;
|
|
307
|
+
|
|
308
|
+
/** The package with config baked in, for `packages: [toolsWork({ root })]`. */
|
|
309
|
+
export function toolsWork(config: ToolsWorkConfig): PackageInstance {
|
|
310
|
+
return definition(config);
|
|
311
|
+
}
|