@inneranimalmedia/agentsam-sdk 2.6.10 → 2.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/TRADEMARKS.md +22 -0
- package/apps/README.md +3 -0
- package/apps/cad-creator/LICENSE +21 -0
- package/apps/cad-creator/README.md +4 -1
- package/apps/cad-creator/shared/cad/package.json +1 -1
- package/apps/client-cms-editor/LICENSE +21 -0
- package/apps/client-cms-editor/README.md +3 -0
- package/apps/client-cms-editor/backend/package.json +2 -2
- package/apps/client-cms-editor/frontend/package.json +3 -3
- package/apps/client-cms-editor/package-lock.json +43 -43
- package/apps/client-cms-editor/package.json +3 -3
- package/apps/client-cms-editor/reference/harvest/HARVEST_RECEIPT.json +1 -1
- package/apps/client-cms-editor/reference/harvest/README.md +1 -1
- package/apps/client-cms-editor/reference/harvest/plans/ARCHIVE-INTAKE.md +1 -1
- package/apps/client-cms-editor/reference/harvest/plans/HARVEST-INDEX.md +1 -1
- package/apps/client-cms-editor/reference/harvest/plans/TOOLING-LAB.md +1 -1
- package/apps/client-cms-editor/shared/cms/package.json +1 -1
- package/docs/MINI.md +4 -2
- package/docs/REPO_FILE_MAP.txt +0 -1
- package/docs/SOURCE_ARCHITECTURE.md +1 -1
- package/docs/architecture/DUAL_ANALYTICS_PRODUCT.md +140 -0
- package/docs/content-studio/REVISION_GATE_2026-09-27.md +1 -1
- package/docs/engineering/go-portability/01-product-project-deployment-authority.md +69 -0
- package/docs/engineering/provider-internal-renames/01-lane-initialization.md +20 -0
- package/docs/engineering/provider-internal-renames/01a-runtime-environment-contract.md +115 -0
- package/docs/engineering/provider-internal-renames/02-cfoa.md +57 -0
- package/docs/engineering/provider-internal-renames/03-gclioa.md +32 -0
- package/docs/engineering/provider-internal-renames/04-goaude.md +50 -0
- package/docs/engineering/provider-internal-renames/05-gdrv.md +33 -0
- package/docs/engineering/provider-internal-renames/06-verification.md +103 -0
- package/docs/engineering/provider-internal-renames/README.md +77 -0
- package/docs/engineering/provider-internal-renames/runtime-environment-contract.json +220 -0
- package/docs/engineering/test-diagnostics/go-cli-test-hang-20261003.md +49 -0
- package/docs/engineering/test-diagnostics/go-skip-deploy-docker-fix.md +90 -0
- package/docs/knowledge-service-verification.md +3 -3
- package/docs/plans/AGENTSAM-SUSPEND-QUEUE-KNOWLEDGE-RDP-2026-10-03.md +870 -0
- package/docs/plans/LOCAL-STUDIO-GRADUATION-2026-09-26.md +9 -9
- package/docs/plans/MACHINE-FIRST-APPS-TUI-2026-09-24.md +11 -11
- package/docs/plans/RECONCILIATION-2026-09-19.md +6 -6
- package/docs/plans/SAM_WORK_PROTOCOL.md +667 -0
- package/docs/plans/TOMORROW-EXTENSIVE-TODO-2026-09-26.md +2 -2
- package/docs/plans/UNIVERSAL-INGEST-MACHINE-FIRST-2026-09-24.md +3 -3
- package/examples/hyperspace-demo/src/main.tsx +227 -110
- package/migrations/d1/0020_agentsam_receipt_catalog.sql +35 -0
- package/migrations/runtime/0006_agent_run_suspend_activity.sql +53 -0
- package/migrations/runtime/0007_queue_control.sql +40 -0
- package/migrations/runtime/0008_agent_run_dependencies.sql +24 -0
- package/migrations/runtime/0008_analytics_legacy_bootstrap.sql +43 -0
- package/migrations/runtime/0009_analytics_authority.sql +108 -0
- package/package.json +26 -11
- package/packages/agentsam-brand/README.md +3 -0
- package/packages/agentsam-brand/package.json +2 -2
- package/packages/agentsam-contracts/dist/adapter.d.ts +22 -0
- package/packages/agentsam-contracts/dist/adapter.js +0 -0
- package/packages/agentsam-contracts/dist/agent.d.ts +66 -0
- package/packages/agentsam-contracts/dist/agent.js +15 -0
- package/packages/agentsam-contracts/dist/artifacts.d.ts +70 -0
- package/packages/agentsam-contracts/dist/artifacts.js +0 -0
- package/packages/agentsam-contracts/dist/authority.d.ts +21 -0
- package/packages/agentsam-contracts/dist/authority.js +0 -0
- package/packages/agentsam-contracts/dist/context.d.ts +14 -0
- package/packages/agentsam-contracts/dist/context.js +0 -0
- package/packages/agentsam-contracts/dist/errors.d.ts +121 -0
- package/packages/agentsam-contracts/dist/errors.js +5 -0
- package/packages/agentsam-contracts/dist/events.d.ts +53 -0
- package/packages/agentsam-contracts/dist/events.js +0 -0
- package/packages/agentsam-contracts/dist/execution.d.ts +38 -0
- package/packages/agentsam-contracts/dist/execution.js +0 -0
- package/packages/agentsam-contracts/dist/hooks.d.ts +31 -0
- package/packages/agentsam-contracts/dist/hooks.js +0 -0
- package/packages/agentsam-contracts/dist/identity.d.ts +15 -0
- package/packages/agentsam-contracts/dist/identity.js +0 -0
- package/packages/agentsam-contracts/dist/index.d.ts +16 -0
- package/packages/agentsam-contracts/dist/index.js +164 -0
- package/packages/agentsam-contracts/dist/models.d.ts +9 -0
- package/packages/agentsam-contracts/dist/models.js +0 -0
- package/packages/agentsam-contracts/dist/providers.d.ts +27 -0
- package/packages/agentsam-contracts/dist/providers.js +0 -0
- package/packages/agentsam-contracts/dist/repository.d.ts +56 -0
- package/packages/agentsam-contracts/dist/repository.js +15 -0
- package/packages/agentsam-contracts/dist/run.d.ts +113 -0
- package/packages/agentsam-contracts/dist/run.js +132 -0
- package/packages/agentsam-contracts/dist/tools.d.ts +82 -0
- package/packages/agentsam-contracts/dist/tools.js +0 -0
- package/packages/agentsam-contracts/dist/widgets.d.ts +38 -0
- package/packages/agentsam-contracts/dist/widgets.js +0 -0
- package/packages/agentsam-contracts/package.json +9 -1
- package/packages/agentsam-contracts/scripts/build.mjs +1 -1
- package/packages/agentsam-contracts/src/agent.ts +78 -3
- package/packages/agentsam-contracts/src/index.ts +2 -0
- package/packages/agentsam-contracts/src/run.ts +320 -0
- package/packages/agentsam-contracts/src/widgets.ts +58 -0
- package/packages/agentsam-contracts/test/contracts.test.mjs +1 -1
- package/packages/agentsam-contracts/test/run-contract.test.mjs +94 -0
- package/packages/agentsam-errors/package.json +1 -1
- package/packages/agentsam-goap/README.md +3 -0
- package/packages/agentsam-goap/package.json +2 -2
- package/packages/agentsam-hooks/package.json +2 -2
- package/packages/agentsam-hooks/src/adapters/agents.js +48 -22
- package/packages/agentsam-hooks/src/index.d.ts +16 -0
- package/packages/agentsam-knowledge/package.json +1 -1
- package/packages/agentsam-knowledge/src/backends/index.js +1 -1
- package/packages/agentsam-merch/README.md +62 -0
- package/packages/agentsam-merch/bin/agentsam-merch.mjs +16 -0
- package/packages/agentsam-merch/package.json +65 -0
- package/packages/agentsam-merch/profiles/completeful/dtg-back-large.json +42 -0
- package/packages/agentsam-merch/profiles/completeful/laser-engraving.json +39 -0
- package/packages/agentsam-merch/profiles/generic/embroidery-digitization.json +22 -0
- package/packages/agentsam-merch/schemas/collection-candidate.schema.json +66 -0
- package/packages/agentsam-merch/schemas/manufacturing-profile.schema.json +221 -0
- package/packages/agentsam-merch/src/adapters-completeful.js +50 -0
- package/packages/agentsam-merch/src/cli.js +93 -0
- package/packages/agentsam-merch/src/collection-lab.js +60 -0
- package/packages/agentsam-merch/src/compatibility.js +501 -0
- package/packages/agentsam-merch/src/derivatives.js +112 -0
- package/packages/agentsam-merch/src/index.d.ts +316 -0
- package/packages/agentsam-merch/src/index.js +46 -0
- package/packages/agentsam-merch/src/node/index.d.ts +58 -0
- package/packages/agentsam-merch/src/node/index.js +6 -0
- package/packages/agentsam-merch/src/node/raster.js +142 -0
- package/packages/agentsam-merch/src/node/vector.js +239 -0
- package/packages/agentsam-merch/src/product-concepts.js +118 -0
- package/packages/agentsam-merch/src/profile-registry.js +104 -0
- package/packages/agentsam-merch/src/profile.js +158 -0
- package/packages/agentsam-merch/src/transforms.js +215 -0
- package/packages/agentsam-merch/test/merch.test.mjs +332 -0
- package/packages/agentsam-merch/test/node-transforms.test.mjs +149 -0
- package/packages/agentsam-nav/dist/browser.global.js +71 -34
- package/packages/agentsam-nav/dist/browser.js +3179 -781
- package/packages/agentsam-nav/dist/index.js +3171 -773
- package/packages/agentsam-nav/package.json +1 -1
- package/packages/agentsam-queue-control/README.md +4 -1
- package/packages/agentsam-queue-control/package.json +4 -3
- package/packages/agentsam-queue-control/schemas/job-envelope.schema.json +111 -11
- package/packages/agentsam-queue-control/src/adapters/cloudflare.js +34 -6
- package/packages/agentsam-queue-control/src/adapters/memory.js +11 -2
- package/packages/agentsam-queue-control/src/adapters/sqlite.js +259 -0
- package/packages/agentsam-queue-control/src/contracts.js +207 -3
- package/packages/agentsam-queue-control/src/control-plane.js +62 -2
- package/packages/agentsam-queue-control/src/index.js +1 -0
- package/packages/agentsam-queue-control/test/queue-control.test.mjs +310 -0
- package/packages/agentsam-queue-control/test/sqlite-adapter.test.mjs +91 -0
- package/packages/agentsam-rapid-rust/README.md +3 -0
- package/packages/agentsam-repository/README.md +3 -0
- package/packages/agentsam-repository/package.json +1 -1
- package/packages/agentsam-vault/package.json +1 -1
- package/packages/agentsam-workbench/README.md +43 -0
- package/packages/agentsam-workbench/package.json +13 -3
- package/packages/agentsam-workbench/src/agent/AgentConversationSurface.tsx +108 -0
- package/packages/agentsam-workbench/src/agent/AgentPanel.tsx +25 -8
- package/packages/agentsam-workbench/src/agent/AgentRuntimeField.tsx +152 -0
- package/packages/agentsam-workbench/src/agent/Composer.tsx +10 -1
- package/packages/agentsam-workbench/src/agent/RunMode.ts +26 -0
- package/packages/agentsam-workbench/src/agent/Thread.tsx +18 -3
- package/packages/agentsam-workbench/src/agent/index.ts +3 -0
- package/packages/agentsam-workbench/src/index.ts +4 -0
- package/packages/agentsam-workbench/src/manufacturing/PreflightIndicator.tsx +203 -0
- package/packages/agentsam-workbench/src/manufacturing/index.ts +2 -0
- package/packages/agentsam-workbench/src/manufacturing/loading.ts +147 -0
- package/packages/agentsam-workbench/src/widgets/BuiltinWidget.tsx +22 -0
- package/packages/agentsam-workbench/src/widgets/CountdownWidget.tsx +68 -0
- package/packages/agentsam-workbench/src/widgets/WidgetFrame.tsx +56 -0
- package/packages/agentsam-workbench/src/widgets/countdown.ts +25 -0
- package/packages/agentsam-workbench/src/widgets/index.ts +6 -0
- package/packages/agentsam-workbench/src/widgets/registry.ts +13 -0
- package/packages/agentsam-workbench/src/widgets/useCountdown.ts +128 -0
- package/packages/agentsam-workbench/src/widgets/widgets.css +102 -0
- package/packages/connectors/{cloudflare → cfoa}/package.json +3 -3
- package/packages/heuristic-theme/package.json +1 -1
- package/packages/identity/README.md +3 -0
- package/packages/identity/backend/README.md +3 -0
- package/packages/identity/package.json +1 -1
- package/packages/identity/src/frontend/auth-portal/README.md +3 -0
- package/packages/identity/src/index.js +1 -1
- package/packages/identity/src/oauth/README.md +4 -1
- package/packages/identity/src/oauth/credentials.js +1 -1
- package/packages/identity/src/server/worker-router.js +1 -1
- package/packages/identity/tests/google-desktop-identity-login.test.mjs +1 -1
- package/packages/identity/tests/lane1-packed-consumer.test.mjs +1 -1
- package/packages/identity/tests/oauth-presets-accounts-ssot.test.mjs +1 -1
- package/packages/providers/completeful/package.json +1 -1
- package/packages/theme-church-site/package.json +1 -1
- package/packages/theme-companions-site/package.json +1 -1
- package/packages/theme-floors-site/package.json +1 -1
- package/packages/theme-fuelnfree-site/package.json +1 -1
- package/packages/theme-handyman-site/package.json +1 -1
- package/packages/theme-insurance-site/package.json +1 -1
- package/packages/theme-scenes/package.json +1 -1
- package/packages/theme-shinshu-site/package.json +1 -1
- package/packages/work-graph/package.json +1 -1
- package/protocol/models/README.md +3 -0
- package/protocol/receipts/agentsam.receipt.v1.json +95 -0
- package/protocol/theme-refinery/receipts/products-registry-batch-20260924.json +6 -6
- package/protocol/theme-refinery/receipts/theme-harvest-20260924.json +6 -6
- package/skills/README.md +3 -0
- package/src/acp/agent-executor.js +106 -0
- package/src/acp/client.js +316 -0
- package/src/acp/dependencies.js +426 -0
- package/src/acp/http.js +207 -0
- package/src/acp/index.js +22 -0
- package/src/acp/runs.js +125 -0
- package/src/acp/runtime-selection.js +180 -0
- package/src/cli/command-catalog.js +3 -0
- package/src/cli.js +24 -0
- package/src/commands/cloudflare-login.js +1 -1
- package/src/commands/cloudflare.js +2 -2
- package/src/commands/connections.js +1 -1
- package/src/commands/go.js +76 -6
- package/src/commands/merch.js +5 -0
- package/src/commands/mini.js +1 -1
- package/src/commands/receipts.js +140 -0
- package/src/commands/run.js +253 -0
- package/src/go/container.js +1 -1
- package/src/go/contract.js +61 -18
- package/src/go/discover.js +0 -4
- package/src/go/index.js +13 -1
- package/src/go/probe.js +109 -0
- package/src/go/{cloudflare.js → providers/cloudflare.js} +36 -136
- package/src/go/verify.js +1 -1
- package/src/indexing/ingest/inventory.js +1 -1
- package/src/lib/deploy/local-studio.js +2 -2
- package/src/lib/mini/scaffold.js +1 -1
- package/src/lib/whoami-capabilities.js +1 -1
- package/src/local/runtime-store.js +8 -0
- package/src/mcp/cloudflare-bundles.js +1 -1
- package/src/plugins/index.js +1 -0
- package/src/plugins/registry.js +59 -6
- package/src/receipts/contract.js +68 -0
- package/src/receipts/index.js +20 -0
- package/src/receipts/prune.js +64 -0
- package/src/receipts/sinks.js +285 -0
- package/templates/mini/gadget/app.js +15 -40
- package/templates/mini/gadget/index.html +7 -7
- package/templates/mini/shared/style.css +1 -1
- package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +0 -670
- /package/packages/connectors/{cloudflare → cfoa}/OAUTH_STORAGE_AUDIT.md +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/api-client.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/capabilities.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/credential.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/brand-protection.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/keyless.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/pages.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/scanner.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/snippets.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/tag-gateway.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/tags.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/token-validation.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/vectorize.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/workflows.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/index.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/oauth-persist.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/owner.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/permission-options.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/routes.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/scope-catalog.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/vault.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/tests/capabilities.test.mjs +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/tests/connector.test.mjs +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/tests/oauth-persist.test.mjs +0 -0
- /package/packages/identity/src/oauth/{google-desktop-exchange.js → goaude.js} +0 -0
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import { parseWranglerVersionId } from '
|
|
4
|
+
import { parseWranglerVersionId } from '../../lib/deploy/health.js';
|
|
5
5
|
import {
|
|
6
6
|
writeDeploymentReceipt,
|
|
7
7
|
writeDeploymentValidationReceipt,
|
|
8
8
|
writeProductRegistryLocal,
|
|
9
9
|
writeProductValidationLocal,
|
|
10
10
|
buildProductRow,
|
|
11
|
-
} from '
|
|
12
|
-
import { applyInnerAnimalMediaOfficialGoProductRegistry } from '
|
|
13
|
-
import { SDK_ROOT } from '
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
} from '../receipts.js';
|
|
12
|
+
import { applyInnerAnimalMediaOfficialGoProductRegistry } from '../official-registry.js';
|
|
13
|
+
import { SDK_ROOT } from '../discover.js';
|
|
14
|
+
import { resolveWranglerBin } from '../contract.js';
|
|
15
|
+
import { probeGoDeploymentWithRetry } from '../probe.js';
|
|
16
16
|
|
|
17
17
|
function resolveWranglerInvocation(productRoot) {
|
|
18
|
-
|
|
19
|
-
if (fs.existsSync(js)) return { command: process.execPath, args: [js] };
|
|
20
|
-
const bin = path.join(productRoot, 'node_modules', '.bin', 'wrangler');
|
|
21
|
-
if (fs.existsSync(bin)) return { command: bin, args: [] };
|
|
22
|
-
return { command: 'npx', args: ['--yes', 'wrangler'] };
|
|
18
|
+
return resolveWranglerBin(productRoot);
|
|
23
19
|
}
|
|
24
20
|
|
|
25
21
|
function runWrangler(wrangler, args, {
|
|
@@ -56,8 +52,11 @@ function publicAccount(account) {
|
|
|
56
52
|
};
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
export function resolveConfiguredDeploymentUrl(
|
|
60
|
-
|
|
55
|
+
export function resolveConfiguredDeploymentUrl(
|
|
56
|
+
productRoot,
|
|
57
|
+
configName = 'wrangler.jsonc',
|
|
58
|
+
) {
|
|
59
|
+
const configPath = path.join(productRoot, configName);
|
|
61
60
|
if (!fs.existsSync(configPath)) return null;
|
|
62
61
|
|
|
63
62
|
try {
|
|
@@ -189,8 +188,9 @@ function deploymentArgs({
|
|
|
189
188
|
dryRun = false,
|
|
190
189
|
source = null,
|
|
191
190
|
builtAt = null,
|
|
191
|
+
configName = 'wrangler.jsonc',
|
|
192
192
|
} = {}) {
|
|
193
|
-
const args = ['deploy', '-c',
|
|
193
|
+
const args = ['deploy', '-c', configName];
|
|
194
194
|
if (source?.identity) args.push('--var', 'AGENTSAM_BUILD_SOURCE:' + source.identity);
|
|
195
195
|
if (source?.commit) args.push('--var', 'AGENTSAM_BUILD_COMMIT:' + source.commit);
|
|
196
196
|
if (builtAt) args.push('--var', 'AGENTSAM_BUILT_AT:' + builtAt);
|
|
@@ -225,8 +225,16 @@ export async function deployGoCloudflare({
|
|
|
225
225
|
spawn = spawnSync,
|
|
226
226
|
fetchImpl = globalThis.fetch,
|
|
227
227
|
} = {}) {
|
|
228
|
-
const
|
|
229
|
-
|
|
228
|
+
const configName = officialRelease
|
|
229
|
+
? 'wrangler.inneranimalmedia.jsonc'
|
|
230
|
+
: 'wrangler.jsonc';
|
|
231
|
+
|
|
232
|
+
const wranglerConfig = path.join(productRoot, configName);
|
|
233
|
+
if (!fs.existsSync(wranglerConfig)) {
|
|
234
|
+
const err = new Error('wrangler_config_missing: ' + wranglerConfig);
|
|
235
|
+
err.code = 'wrangler_config_missing';
|
|
236
|
+
throw err;
|
|
237
|
+
}
|
|
230
238
|
|
|
231
239
|
let cfIdentity = cloudflareIdentity;
|
|
232
240
|
if (!skipDeploy) {
|
|
@@ -247,15 +255,6 @@ export async function deployGoCloudflare({
|
|
|
247
255
|
accountId = cfIdentity.account.id;
|
|
248
256
|
}
|
|
249
257
|
|
|
250
|
-
const docker = spawn('docker', ['info'], { encoding: 'utf8' });
|
|
251
|
-
const dockerOk = docker.status === 0;
|
|
252
|
-
if (!dockerOk && !skipDeploy) {
|
|
253
|
-
const err = new Error('docker_unavailable');
|
|
254
|
-
err.detail = (docker.stderr || docker.stdout || '').trim().slice(0, 400);
|
|
255
|
-
err.hint = 'Cloudflare Containers require a local container engine for image build.';
|
|
256
|
-
throw err;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
258
|
const wrangler = resolveWranglerInvocation(productRoot);
|
|
260
259
|
let deployOutput = '';
|
|
261
260
|
let deployed = false;
|
|
@@ -267,7 +266,12 @@ export async function deployGoCloudflare({
|
|
|
267
266
|
} else if (dryRun) {
|
|
268
267
|
const res = runWrangler(
|
|
269
268
|
wrangler,
|
|
270
|
-
deploymentArgs({
|
|
269
|
+
deploymentArgs({
|
|
270
|
+
dryRun: true,
|
|
271
|
+
source,
|
|
272
|
+
builtAt,
|
|
273
|
+
configName,
|
|
274
|
+
}),
|
|
271
275
|
{ productRoot, spawn, accountId },
|
|
272
276
|
);
|
|
273
277
|
deployOutput = res.output;
|
|
@@ -280,7 +284,11 @@ export async function deployGoCloudflare({
|
|
|
280
284
|
} else {
|
|
281
285
|
const res = runWrangler(
|
|
282
286
|
wrangler,
|
|
283
|
-
deploymentArgs({
|
|
287
|
+
deploymentArgs({
|
|
288
|
+
source,
|
|
289
|
+
builtAt,
|
|
290
|
+
configName,
|
|
291
|
+
}),
|
|
284
292
|
{ productRoot, spawn, accountId },
|
|
285
293
|
);
|
|
286
294
|
deployOutput = res.output;
|
|
@@ -347,7 +355,7 @@ export async function deployGoCloudflare({
|
|
|
347
355
|
|
|
348
356
|
const url = deployed
|
|
349
357
|
? (
|
|
350
|
-
resolveConfiguredDeploymentUrl(productRoot)
|
|
358
|
+
resolveConfiguredDeploymentUrl(productRoot, configName)
|
|
351
359
|
|| extractWorkersDevUrl(deployOutput)
|
|
352
360
|
|| guessWorkersDevUrl(product)
|
|
353
361
|
)
|
|
@@ -483,7 +491,6 @@ export async function deployGoCloudflare({
|
|
|
483
491
|
productPath,
|
|
484
492
|
productRow,
|
|
485
493
|
registry,
|
|
486
|
-
dockerOk,
|
|
487
494
|
cloudflare: cfIdentity,
|
|
488
495
|
deployOutput,
|
|
489
496
|
};
|
|
@@ -499,110 +506,3 @@ export function guessWorkersDevUrl(product) {
|
|
|
499
506
|
return account ? 'https://' + product + '.' + account + '.workers.dev' : null;
|
|
500
507
|
}
|
|
501
508
|
|
|
502
|
-
export async function probeGoDeployment(origin, {
|
|
503
|
-
fetchImpl = globalThis.fetch,
|
|
504
|
-
expectedSource = null,
|
|
505
|
-
expectedSourceCommit = null,
|
|
506
|
-
expectedTarget = null,
|
|
507
|
-
edge = true,
|
|
508
|
-
} = {}) {
|
|
509
|
-
const base = String(origin).replace(/\/+$/, '');
|
|
510
|
-
const results = {};
|
|
511
|
-
const checks = {};
|
|
512
|
-
const probedAt = new Date().toISOString();
|
|
513
|
-
|
|
514
|
-
async function request(key, pathname, init = {}) {
|
|
515
|
-
try {
|
|
516
|
-
const res = await fetchImpl(base + pathname, init);
|
|
517
|
-
let body = null;
|
|
518
|
-
try { body = await res.json(); } catch {}
|
|
519
|
-
results[key] = {
|
|
520
|
-
path: pathname,
|
|
521
|
-
status: res.status,
|
|
522
|
-
ok: res.status >= 200 && res.status < 300,
|
|
523
|
-
body,
|
|
524
|
-
};
|
|
525
|
-
return results[key];
|
|
526
|
-
} catch (error) {
|
|
527
|
-
results[key] = { path: pathname, status: 0, ok: false, error: error.message };
|
|
528
|
-
return results[key];
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
if (edge) {
|
|
533
|
-
await request('edge_root', '/', { headers: { Accept: 'application/json' } });
|
|
534
|
-
await request('edge_health', '/edge/health', { headers: { Accept: 'application/json' } });
|
|
535
|
-
}
|
|
536
|
-
await request('health', '/health', { headers: { Accept: 'application/json' } });
|
|
537
|
-
await request('runtime', '/v1/runtime', { headers: { Accept: 'application/json' } });
|
|
538
|
-
await request('capabilities', '/v1/capabilities', { headers: { Accept: 'application/json' } });
|
|
539
|
-
await request('hash', '/v1/hash', {
|
|
540
|
-
method: 'POST',
|
|
541
|
-
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
|
|
542
|
-
body: JSON.stringify({ input: 'agentsam', algorithm: 'sha256' }),
|
|
543
|
-
});
|
|
544
|
-
await request('inspect', '/v1/inspect', {
|
|
545
|
-
method: 'POST',
|
|
546
|
-
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
|
|
547
|
-
body: JSON.stringify({ files: [{ path: 'demo.css', content: '.button { color: #2563eb; }' }] }),
|
|
548
|
-
});
|
|
549
|
-
await request('malformed', '/v1/inspect', {
|
|
550
|
-
method: 'POST',
|
|
551
|
-
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
|
|
552
|
-
body: JSON.stringify({ not_files: true }),
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
const health = results.health?.body;
|
|
556
|
-
const runtime = results.runtime?.body;
|
|
557
|
-
const caps = results.capabilities?.body;
|
|
558
|
-
const malformed = results.malformed?.body;
|
|
559
|
-
|
|
560
|
-
if (edge) {
|
|
561
|
-
checks.edge_root = results.edge_root?.status === 200 && results.edge_root?.body?.edge === 'worker';
|
|
562
|
-
checks.edge_health = results.edge_health?.status === 200 && results.edge_health?.body?.edge === 'worker';
|
|
563
|
-
checks.edge_source = expectedSource
|
|
564
|
-
? results.edge_root?.body?.source === expectedSource
|
|
565
|
-
: true;
|
|
566
|
-
}
|
|
567
|
-
checks.health = results.health?.status === 200
|
|
568
|
-
&& health?.ok === true
|
|
569
|
-
&& health?.runtime === 'go'
|
|
570
|
-
&& (!expectedTarget || health?.target === expectedTarget);
|
|
571
|
-
checks.source_identity = expectedSource ? health?.build?.source === expectedSource : true;
|
|
572
|
-
checks.source_commit = expectedSourceCommit ? health?.build?.commit === expectedSourceCommit : true;
|
|
573
|
-
checks.runtime = results.runtime?.status === 200
|
|
574
|
-
&& runtime?.schema === 'agentsam.go-runtime.v1'
|
|
575
|
-
&& runtime?.os === 'linux';
|
|
576
|
-
checks.capabilities = results.capabilities?.status === 200
|
|
577
|
-
&& caps?.schema === 'agentsam.go-capabilities.v1'
|
|
578
|
-
&& ['hash', 'inspect', 'runtime', 'capabilities'].every((name) => caps?.capabilities?.includes(name));
|
|
579
|
-
checks.hash = results.hash?.status === 200 && results.hash?.body?.hash === EXPECTED_HASH;
|
|
580
|
-
checks.inspect = results.inspect?.status === 200
|
|
581
|
-
&& results.inspect?.body?.findings?.some((finding) => finding.kind === 'hardcoded_color' && finding.value === '#2563eb');
|
|
582
|
-
checks.error_envelope = results.malformed?.status === 400
|
|
583
|
-
&& malformed?.ok === false
|
|
584
|
-
&& malformed?.schema_version === 1
|
|
585
|
-
&& malformed?.reason === 'input_invalid'
|
|
586
|
-
&& malformed?.code === 'INVALID_ARGUMENT';
|
|
587
|
-
|
|
588
|
-
results.deterministic_hash = { ok: checks.hash };
|
|
589
|
-
results.deterministic_inspect = { ok: checks.inspect };
|
|
590
|
-
results.malformed_rejected = { ok: checks.error_envelope };
|
|
591
|
-
const ok = Object.values(checks).every(Boolean);
|
|
592
|
-
return { origin: base, ok, checks, results, probed_at: probedAt };
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
export async function probeGoDeploymentWithRetry(origin, {
|
|
596
|
-
attempts = 12,
|
|
597
|
-
delayMs = 2500,
|
|
598
|
-
...options
|
|
599
|
-
} = {}) {
|
|
600
|
-
let latest = null;
|
|
601
|
-
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
602
|
-
latest = await probeGoDeployment(origin, options);
|
|
603
|
-
latest.attempt = attempt;
|
|
604
|
-
if (latest.ok) return latest;
|
|
605
|
-
if (attempt < attempts) await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
606
|
-
}
|
|
607
|
-
return latest || { origin, ok: false, checks: {}, results: {}, probed_at: new Date().toISOString() };
|
|
608
|
-
}
|
package/src/go/verify.js
CHANGED
|
@@ -57,7 +57,7 @@ const CATEGORY_TOOLING = new Set([
|
|
|
57
57
|
/** Generated / historical — review before including. */
|
|
58
58
|
const CATEGORY_GENERATED = new Set([
|
|
59
59
|
'generated', 'fixtures', 'snapshots', 'artifacts',
|
|
60
|
-
'site', 'sites', 'templates', 'level-1',
|
|
60
|
+
'site', 'sites', 'templates', 'level-1',
|
|
61
61
|
]);
|
|
62
62
|
|
|
63
63
|
/** AgentSam / config control plane — review. */
|
|
@@ -12,7 +12,7 @@ export const DEPLOY_INPUT_GLOBS = Object.freeze([
|
|
|
12
12
|
'apps/local-studio',
|
|
13
13
|
'packages/agentsam-contracts',
|
|
14
14
|
'packages/agentsam-workbench',
|
|
15
|
-
'packages/connectors/
|
|
15
|
+
'packages/connectors/cfoa',
|
|
16
16
|
]);
|
|
17
17
|
|
|
18
18
|
export function findRepoRoot(start = process.cwd()) {
|
|
@@ -176,7 +176,7 @@ export async function runLocalStudioDeploy({
|
|
|
176
176
|
target.wranglerConfig,
|
|
177
177
|
path.join(target.appRoot, '.env.cloudflare.example'),
|
|
178
178
|
path.join(target.appRoot, 'backend/worker/index.js'),
|
|
179
|
-
path.join(target.repoRoot, 'packages/connectors/
|
|
179
|
+
path.join(target.repoRoot, 'packages/connectors/cfoa/src/index.js'),
|
|
180
180
|
]);
|
|
181
181
|
}
|
|
182
182
|
if (plan.skip) {
|
package/src/lib/mini/scaffold.js
CHANGED
|
@@ -4,7 +4,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
4
4
|
|
|
5
5
|
const templateRoot = fileURLToPath(new URL('../../../templates/mini/', import.meta.url));
|
|
6
6
|
export const MINI_TEMPLATES = Object.freeze({
|
|
7
|
-
gadget: 'A
|
|
7
|
+
gadget: 'A blank interactive widget canvas',
|
|
8
8
|
page: 'A small editable landing page',
|
|
9
9
|
data: 'A searchable JSON viewer',
|
|
10
10
|
});
|
|
@@ -9,7 +9,7 @@ import { listProviderCredentialStatus } from './provider-credentials.js';
|
|
|
9
9
|
import {
|
|
10
10
|
listCloudflareFeaturePacks,
|
|
11
11
|
scopesForFeaturePacks,
|
|
12
|
-
} from '../../packages/connectors/
|
|
12
|
+
} from '../../packages/connectors/cfoa/src/index.js';
|
|
13
13
|
import { projectTerminalCapability } from './terminal-scopes.js';
|
|
14
14
|
|
|
15
15
|
function clean(value) {
|
|
@@ -5,6 +5,7 @@ import { applyRuntimeMigrations } from './migrations.js';
|
|
|
5
5
|
import { findCliProjectRoot } from '../lib/cli-preferences.js';
|
|
6
6
|
import { getLocalDatabasePath, tryReadProjectConfig } from '../lib/project-config.js';
|
|
7
7
|
import { createHookStore } from '../../packages/agentsam-hooks/src/store.js';
|
|
8
|
+
import { reconcileParentAfterChildTerminal } from '../acp/dependencies.js';
|
|
8
9
|
|
|
9
10
|
function clean(value) { return value == null ? '' : String(value).trim(); }
|
|
10
11
|
function hash(value) { return createHash('sha256').update(String(value || '')).digest('hex'); }
|
|
@@ -115,6 +116,13 @@ export async function finishRuntimeRun(value = {}) {
|
|
|
115
116
|
Number.isFinite(Number(value.latency_ms)) ? Math.max(0, Math.round(Number(value.latency_ms))) : null,
|
|
116
117
|
value.id,
|
|
117
118
|
).run();
|
|
119
|
+
|
|
120
|
+
await reconcileParentAfterChildTerminal(db, {
|
|
121
|
+
runId: value.id,
|
|
122
|
+
status: clean(value.status) || 'completed',
|
|
123
|
+
errorCode: clean(value.error_code) || null,
|
|
124
|
+
errorMessage: clean(value.error_message) || null,
|
|
125
|
+
});
|
|
118
126
|
});
|
|
119
127
|
}
|
|
120
128
|
|
package/src/plugins/index.js
CHANGED
package/src/plugins/registry.js
CHANGED
|
@@ -42,9 +42,11 @@ export async function installPlugin(db, options = {}) {
|
|
|
42
42
|
provider_key=?, plugin_kind=?, category=?, display_name=?, short_name=?, description=?, mention_aliases_json=?,
|
|
43
43
|
endpoint_url=?, transport=?, auth_type=?, secret_ref=?, oauth_connect_url=?, capabilities_json=?, tool_lanes_json=?,
|
|
44
44
|
resource_scope_json=?, config_json=?, metadata_json=?, icon_url=?, icon_dark_url=?, icon_alt=?, icon_fit=?,
|
|
45
|
-
composer_visible=?, settings_visible=?, sort_priority=?, health_strategy=?,
|
|
45
|
+
composer_visible=?, settings_visible=?, sort_priority=?, health_strategy=?,
|
|
46
|
+
is_enabled=CASE WHEN ? THEN is_enabled ELSE 1 END,
|
|
47
|
+
updated_at=unixepoch()
|
|
46
48
|
WHERE id=?
|
|
47
|
-
`, [...values, pluginId]);
|
|
49
|
+
`, [...values, options.preserveEnabled === true ? 1 : 0, pluginId]);
|
|
48
50
|
} else {
|
|
49
51
|
await runMutation(db, `
|
|
50
52
|
INSERT INTO agentsam_plugins (
|
|
@@ -122,11 +124,13 @@ export async function installPlugin(db, options = {}) {
|
|
|
122
124
|
export async function listPlugins(db, options = {}) {
|
|
123
125
|
const accountId = clean(options.accountId);
|
|
124
126
|
const environment = clean(options.environment || 'production');
|
|
127
|
+
const includeDisabled = options.includeDisabled === true;
|
|
125
128
|
const result = await db.prepare(`
|
|
126
129
|
SELECT * FROM agentsam_plugins
|
|
127
|
-
WHERE account_id = ? AND environment = ?
|
|
130
|
+
WHERE account_id = ? AND environment = ?
|
|
131
|
+
AND (? = 1 OR is_enabled = 1)
|
|
128
132
|
ORDER BY sort_priority, display_name
|
|
129
|
-
`).bind(accountId, environment).all();
|
|
133
|
+
`).bind(accountId, environment, includeDisabled ? 1 : 0).all();
|
|
130
134
|
return (result?.results || []).map((row) => ({
|
|
131
135
|
...row,
|
|
132
136
|
mention_aliases: json(row.mention_aliases_json, []), capabilities: json(row.capabilities_json, []),
|
|
@@ -137,18 +141,67 @@ export async function listPlugins(db, options = {}) {
|
|
|
137
141
|
|
|
138
142
|
export async function listPluginTools(db, options = {}) {
|
|
139
143
|
const accountId = clean(options.accountId);
|
|
144
|
+
const includeDisabledPlugins = options.includeDisabledPlugins === true;
|
|
140
145
|
const result = await db.prepare(`
|
|
141
146
|
SELECT t.* FROM agentsam_tools t
|
|
142
147
|
JOIN agentsam_plugins p ON p.id = t.plugin_id
|
|
143
|
-
WHERE t.account_id = ? AND t.is_active = 1
|
|
148
|
+
WHERE t.account_id = ? AND t.is_active = 1
|
|
149
|
+
AND (? = 1 OR p.is_enabled = 1)
|
|
144
150
|
ORDER BY t.connector_priority, t.sort_priority, t.tool_name
|
|
145
|
-
`).bind(accountId).all();
|
|
151
|
+
`).bind(accountId, includeDisabledPlugins ? 1 : 0).all();
|
|
146
152
|
return (result?.results || []).map((row) => ({
|
|
147
153
|
...row, input_schema: json(row.input_schema, {}), output_schema: json(row.output_schema, null),
|
|
148
154
|
handler_config: json(row.handler_config, {}), intent_tags: json(row.intent_tags, []),
|
|
149
155
|
}));
|
|
150
156
|
}
|
|
151
157
|
|
|
158
|
+
|
|
159
|
+
export async function updatePluginPreferences(db, options = {}) {
|
|
160
|
+
if (!db?.prepare) throw new TypeError('D1-compatible database binding required');
|
|
161
|
+
const accountId = clean(options.accountId);
|
|
162
|
+
const pluginId = clean(options.pluginId);
|
|
163
|
+
if (!accountId) throw new Error('plugin_account_id_required');
|
|
164
|
+
if (!pluginId) throw new Error('plugin_id_required');
|
|
165
|
+
|
|
166
|
+
const fields = [];
|
|
167
|
+
const values = [];
|
|
168
|
+
if (typeof options.enabled === 'boolean') {
|
|
169
|
+
fields.push('is_enabled=?');
|
|
170
|
+
values.push(options.enabled ? 1 : 0);
|
|
171
|
+
}
|
|
172
|
+
if (typeof options.composerVisible === 'boolean') {
|
|
173
|
+
fields.push('composer_visible=?');
|
|
174
|
+
values.push(options.composerVisible ? 1 : 0);
|
|
175
|
+
}
|
|
176
|
+
if (typeof options.settingsVisible === 'boolean') {
|
|
177
|
+
fields.push('settings_visible=?');
|
|
178
|
+
values.push(options.settingsVisible ? 1 : 0);
|
|
179
|
+
}
|
|
180
|
+
if (!fields.length) throw new Error('plugin_preferences_empty');
|
|
181
|
+
|
|
182
|
+
await runMutation(db, `
|
|
183
|
+
UPDATE agentsam_plugins
|
|
184
|
+
SET ${fields.join(', ')}, updated_at=unixepoch()
|
|
185
|
+
WHERE id=? AND account_id=?
|
|
186
|
+
`, [...values, pluginId, accountId]);
|
|
187
|
+
|
|
188
|
+
const row = await db.prepare(`
|
|
189
|
+
SELECT * FROM agentsam_plugins
|
|
190
|
+
WHERE id=? AND account_id=?
|
|
191
|
+
LIMIT 1
|
|
192
|
+
`).bind(pluginId, accountId).first();
|
|
193
|
+
if (!row) throw new Error('plugin_not_found');
|
|
194
|
+
return {
|
|
195
|
+
...row,
|
|
196
|
+
mention_aliases: json(row.mention_aliases_json, []),
|
|
197
|
+
capabilities: json(row.capabilities_json, []),
|
|
198
|
+
tool_lanes: json(row.tool_lanes_json, []),
|
|
199
|
+
resource_scope: json(row.resource_scope_json, {}),
|
|
200
|
+
config: json(row.config_json, {}),
|
|
201
|
+
metadata: json(row.metadata_json, {}),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
152
205
|
export async function recordPluginHealthCheck(db, value = {}) {
|
|
153
206
|
const startedAt = Number(value.startedAt || Math.floor(Date.now() / 1000));
|
|
154
207
|
const completedAt = Number(value.completedAt || Math.floor(Date.now() / 1000));
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const RECEIPT_ENVELOPE_SCHEMA = "agentsam.receipt.v1";
|
|
2
|
+
export const SCHEMA_BASE_URL = "https://schemas.inneranimalmedia.com";
|
|
3
|
+
export const SCHEMAS_BUCKET_NAME = "inneranimalmedia-schemas";
|
|
4
|
+
export const RECEIPT_SCHEMA_URL =
|
|
5
|
+
`${SCHEMA_BASE_URL}/agentsam/schemas/agentsam.receipt.v1.json`;
|
|
6
|
+
export const RECEIPT_R2_PREFIX = "agentsam/runtime/receipts/v1";
|
|
7
|
+
export const BLOB_R2_PREFIX = "agentsam/runtime/blobs/sha256";
|
|
8
|
+
|
|
9
|
+
export function validateReceiptEnvelope(receipt) {
|
|
10
|
+
const errors = [];
|
|
11
|
+
if (!receipt || typeof receipt !== "object") {
|
|
12
|
+
return { ok: false, errors: ["receipt must be an object"] };
|
|
13
|
+
}
|
|
14
|
+
if (receipt.schema !== RECEIPT_ENVELOPE_SCHEMA) {
|
|
15
|
+
errors.push(`schema must be ${RECEIPT_ENVELOPE_SCHEMA}`);
|
|
16
|
+
}
|
|
17
|
+
if (!receipt.receipt_id) errors.push("receipt_id is required");
|
|
18
|
+
if (!receipt.kind) errors.push("kind is required");
|
|
19
|
+
if (!["passed", "failed", "skipped"].includes(receipt.status)) {
|
|
20
|
+
errors.push("status must be passed, failed, or skipped");
|
|
21
|
+
}
|
|
22
|
+
if (
|
|
23
|
+
!["ephemeral_success", "failure_bundle", "release_proof"].includes(
|
|
24
|
+
receipt.retention_class,
|
|
25
|
+
)
|
|
26
|
+
) {
|
|
27
|
+
errors.push("retention_class is invalid");
|
|
28
|
+
}
|
|
29
|
+
if (!receipt.identity?.account_id) {
|
|
30
|
+
errors.push("identity.account_id is required");
|
|
31
|
+
}
|
|
32
|
+
if (!Number.isFinite(Number(receipt.metrics?.created_at_unix))) {
|
|
33
|
+
errors.push("metrics.created_at_unix is required");
|
|
34
|
+
}
|
|
35
|
+
for (const artifact of receipt.evidence?.artifacts || []) {
|
|
36
|
+
if (
|
|
37
|
+
artifact.r2_key &&
|
|
38
|
+
!String(artifact.r2_key).startsWith(`${BLOB_R2_PREFIX}/`)
|
|
39
|
+
) {
|
|
40
|
+
errors.push(
|
|
41
|
+
`artifact r2_key must start with ${BLOB_R2_PREFIX}/`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return Object.freeze({ ok: errors.length === 0, errors: Object.freeze(errors) });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function receiptDatePrefix(receipt) {
|
|
49
|
+
const unix = Number(receipt?.metrics?.created_at_unix);
|
|
50
|
+
if (!Number.isFinite(unix) || unix < 0) {
|
|
51
|
+
throw new TypeError("receipt.metrics.created_at_unix is required");
|
|
52
|
+
}
|
|
53
|
+
return new Date(unix * 1000).toISOString().slice(0, 10).replace(/-/g, "/");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function receiptR2Key(receipt) {
|
|
57
|
+
return `${RECEIPT_R2_PREFIX}/${receiptDatePrefix(receipt)}/${receipt.receipt_id}.json`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function retentionExpiresAt(receipt, nowUnix = Math.floor(Date.now() / 1000)) {
|
|
61
|
+
if (receipt.retention_class === "ephemeral_success") {
|
|
62
|
+
return nowUnix + 7 * 86400;
|
|
63
|
+
}
|
|
64
|
+
if (receipt.retention_class === "failure_bundle") {
|
|
65
|
+
return nowUnix + 60 * 86400;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export {
|
|
2
|
+
BLOB_R2_PREFIX,
|
|
3
|
+
RECEIPT_ENVELOPE_SCHEMA,
|
|
4
|
+
RECEIPT_R2_PREFIX,
|
|
5
|
+
RECEIPT_SCHEMA_URL,
|
|
6
|
+
SCHEMA_BASE_URL,
|
|
7
|
+
SCHEMAS_BUCKET_NAME,
|
|
8
|
+
receiptDatePrefix,
|
|
9
|
+
receiptR2Key,
|
|
10
|
+
retentionExpiresAt,
|
|
11
|
+
validateReceiptEnvelope,
|
|
12
|
+
} from "./contract.js";
|
|
13
|
+
export {
|
|
14
|
+
CompositeReceiptSink,
|
|
15
|
+
D1ReceiptCatalog,
|
|
16
|
+
LocalReceiptSink,
|
|
17
|
+
R2ReceiptSink,
|
|
18
|
+
ReceiptCatalogReader,
|
|
19
|
+
} from "./sinks.js";
|
|
20
|
+
export { pruneLocalWorkspaces } from "./prune.js";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { readdir, rm, stat } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
async function directorySize(root) {
|
|
6
|
+
let total = 0;
|
|
7
|
+
const entries = await readdir(root, { withFileTypes: true }).catch(() => []);
|
|
8
|
+
for (const entry of entries) {
|
|
9
|
+
const full = path.join(root, entry.name);
|
|
10
|
+
if (entry.isDirectory()) total += await directorySize(full);
|
|
11
|
+
else if (entry.isFile()) total += (await stat(full)).size;
|
|
12
|
+
}
|
|
13
|
+
return total;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function pruneLocalWorkspaces({
|
|
17
|
+
maxTmpGb = 1,
|
|
18
|
+
tmpDir = os.tmpdir(),
|
|
19
|
+
prefix = "agentsam-",
|
|
20
|
+
dryRun = false,
|
|
21
|
+
detailLimit = 100,
|
|
22
|
+
} = {}) {
|
|
23
|
+
const maxBytes = Math.max(0, Number(maxTmpGb)) * 1024 * 1024 * 1024;
|
|
24
|
+
const entries = await readdir(tmpDir, { withFileTypes: true });
|
|
25
|
+
const targets = [];
|
|
26
|
+
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
if (!entry.isDirectory() || !entry.name.startsWith(prefix)) continue;
|
|
29
|
+
const fullPath = path.join(tmpDir, entry.name);
|
|
30
|
+
const info = await stat(fullPath);
|
|
31
|
+
const byteSize = await directorySize(fullPath);
|
|
32
|
+
targets.push({ path: fullPath, mtime: info.mtimeMs, byteSize });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
targets.sort((a, b) => a.mtime - b.mtime);
|
|
36
|
+
let remainingBytes = targets.reduce((sum, target) => sum + target.byteSize, 0);
|
|
37
|
+
const purged = [];
|
|
38
|
+
|
|
39
|
+
for (const target of targets) {
|
|
40
|
+
if (remainingBytes <= maxBytes) break;
|
|
41
|
+
if (!dryRun) {
|
|
42
|
+
await rm(target.path, { recursive: true, force: true });
|
|
43
|
+
}
|
|
44
|
+
remainingBytes -= target.byteSize;
|
|
45
|
+
purged.push(target);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const boundedDetailLimit = Math.max(0, Math.min(1000, Number(detailLimit) || 0));
|
|
49
|
+
const purgeDetails = purged
|
|
50
|
+
.slice(0, boundedDetailLimit)
|
|
51
|
+
.map((item) => Object.freeze({ ...item }));
|
|
52
|
+
|
|
53
|
+
return Object.freeze({
|
|
54
|
+
maxBytes,
|
|
55
|
+
scannedCount: targets.length,
|
|
56
|
+
purgedCount: purged.length,
|
|
57
|
+
purgedBytes: purged.reduce((sum, item) => sum + item.byteSize, 0),
|
|
58
|
+
remainingBytes: Math.max(0, remainingBytes),
|
|
59
|
+
dryRun,
|
|
60
|
+
purged: Object.freeze(purgeDetails),
|
|
61
|
+
purgedDetailLimit: boundedDetailLimit,
|
|
62
|
+
purgedDetailsTruncated: purged.length > purgeDetails.length,
|
|
63
|
+
});
|
|
64
|
+
}
|