@crewx/sdk 0.9.0-rc.18 → 0.9.0-rc.180
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 +1 -1
- package/dist/account/auth-client.d.ts +61 -0
- package/dist/account/auth-json-v2.d.ts +1 -0
- package/dist/account/auth-json.d.ts +30 -0
- package/dist/account/config.d.ts +37 -0
- package/dist/account/env-bootstrap.d.ts +11 -0
- package/dist/account/errors.d.ts +24 -0
- package/dist/account/index.d.ts +12 -0
- package/dist/account/index.js +2 -0
- package/dist/account/session-manager.d.ts +47 -0
- package/dist/activity-log/builder.d.ts +59 -6
- package/dist/agent/agent-list-view.d.ts +19 -0
- package/dist/agent-interceptor/chain.d.ts +25 -0
- package/dist/agent-interceptor/index.d.ts +6 -0
- package/dist/agent-interceptor/model-runner.d.ts +19 -0
- package/dist/agent-interceptor/program-runner.d.ts +13 -0
- package/dist/agent-interceptor/protocol.d.ts +68 -0
- package/dist/agent-interceptor/run-stop.d.ts +3 -0
- package/dist/agent-interceptor/schema.d.ts +267 -0
- package/dist/agent-interceptor/types.d.ts +88 -0
- package/dist/app/app-files/args.d.ts +12 -0
- package/dist/app/app-files/errors.d.ts +6 -0
- package/dist/app/app-files/index.d.ts +34 -0
- package/dist/app/app-files/lock.d.ts +26 -0
- package/dist/app/app-files/root.d.ts +22 -0
- package/dist/app/app-files/store.d.ts +47 -0
- package/dist/app/app-files/write.child.d.ts +1 -0
- package/dist/app/app.d.ts +167 -0
- package/dist/app/backend-env.d.ts +3 -0
- package/dist/app/content-media-types.d.ts +2 -0
- package/dist/app/context.d.ts +2 -0
- package/dist/app/entry.d.ts +9 -0
- package/dist/app/frame.d.ts +55 -0
- package/dist/app/index.d.ts +20 -0
- package/dist/app/index.js +13 -0
- package/dist/app/job-bridge.child.d.ts +1 -0
- package/dist/app/job-bridge.d.ts +67 -0
- package/dist/app/job-bridge.drain.child.d.ts +1 -0
- package/dist/app/job-bridge.example.d.ts +11 -0
- package/dist/app/job-contract.d.ts +40 -0
- package/dist/app/job-wire.d.ts +149 -0
- package/dist/app/protocol.d.ts +9 -0
- package/dist/app/runtime.d.ts +23 -0
- package/dist/app/schedule-contract.d.ts +59 -0
- package/dist/app/tool-mode.d.ts +3 -0
- package/dist/app-artifact-policy/check.d.ts +2 -0
- package/dist/app-artifact-policy/contract.d.ts +54 -0
- package/dist/app-artifact-policy/helper.d.ts +15 -0
- package/dist/app-artifact-policy/index.d.ts +3 -0
- package/dist/app-artifact-policy/index.js +18 -0
- package/dist/app-artifact-policy/paths.d.ts +24 -0
- package/dist/app-artifact-policy/scan.d.ts +47 -0
- package/dist/app-ui/index.d.ts +83 -0
- package/dist/app-ui/index.js +1 -0
- package/dist/boxing/box.types.d.ts +4 -0
- package/dist/config/canonicalize-agent-options.d.ts +18 -0
- package/dist/config/default-agent-models.d.ts +11 -0
- package/dist/config/global-settings.d.ts +33 -0
- package/dist/config/migrate-grok-mode.d.ts +6 -0
- package/dist/config/model-compat.d.ts +31 -0
- package/dist/config/models.generated.d.ts +37 -0
- package/dist/config/models.remote.d.ts +1 -0
- package/dist/config/overdrive.d.ts +7 -0
- package/dist/config/pricing.d.ts +6 -3
- package/dist/config/pricing.generated.d.ts +4 -0
- package/dist/config/pricing.types.d.ts +4 -0
- package/dist/config/timeout.config.d.ts +4 -0
- package/dist/config/wi-boards.d.ts +19 -0
- package/dist/context-budget/continuity.d.ts +63 -0
- package/dist/context-budget/index.d.ts +142 -0
- package/dist/conversation/index.d.ts +1 -1
- package/dist/conversation/sqlite-provider.d.ts +6 -3
- package/dist/conversation/to-template-messages.d.ts +9 -0
- package/dist/conversation/types.d.ts +58 -1
- package/dist/desktop/command-runner.d.ts +4 -0
- package/dist/desktop/default-adapters.d.ts +4 -0
- package/dist/desktop/global-install.d.ts +19 -0
- package/dist/desktop/index.d.ts +3 -0
- package/dist/desktop/index.js +3 -0
- package/dist/desktop/install.d.ts +5 -0
- package/dist/desktop/lnk.d.ts +22 -0
- package/dist/desktop/manifest.d.ts +21 -0
- package/dist/desktop/types.d.ts +67 -0
- package/dist/desktop/version.d.ts +1 -0
- package/dist/desktop/windows-paths.d.ts +21 -0
- package/dist/desktop/wrapper.d.ts +18 -0
- package/dist/esm/account/index.js +2 -0
- package/dist/esm/app/index.js +13 -0
- package/dist/esm/app-artifact-policy/index.js +18 -0
- package/dist/esm/desktop/index.js +3 -0
- package/dist/esm/index.js +1304 -224
- package/dist/esm/node/index.js +2 -0
- package/dist/esm/plugins/index.js +531 -214
- package/dist/esm/process/index.js +1 -0
- package/dist/esm/publish/index.js +2 -0
- package/dist/esm/repository/index.js +777 -207
- package/dist/esm/skills/index.js +2 -0
- package/dist/esm/testing/index.js +1 -1
- package/dist/events/types.d.ts +28 -0
- package/dist/facade/Crewx.d.ts +70 -5
- package/dist/facade/task-ticket.d.ts +14 -0
- package/dist/highlight/thread-highlight-prompt.d.ts +2 -0
- package/dist/highlight/thread-highlighter.d.ts +326 -0
- package/dist/index.browser.d.ts +25 -1
- package/dist/index.browser.js +6 -2
- package/dist/index.d.ts +164 -17
- package/dist/index.js +1304 -224
- package/dist/internal/console-decoder.d.ts +38 -0
- package/dist/internal/windows-spawn.d.ts +10 -0
- package/dist/layout/types.d.ts +18 -1
- package/dist/lifecycle/process-lease.d.ts +80 -0
- package/dist/lifecycle/process-owner.d.ts +20 -0
- package/dist/lifecycle/task-heartbeat.d.ts +41 -0
- package/dist/lifecycle/task-stop.d.ts +108 -0
- package/dist/lifecycle/update-admission.d.ts +45 -0
- package/dist/local-server/base-url.d.ts +18 -0
- package/dist/local-server/index.d.ts +8 -0
- package/dist/local-server/opencode.d.ts +8 -0
- package/dist/local-server/probe.d.ts +3 -0
- package/dist/local-server/runtime.d.ts +26 -0
- package/dist/local-server/types.d.ts +43 -0
- package/dist/mcp-app/agent-access.d.ts +26 -0
- package/dist/mcp-app/app-handoff.d.ts +109 -0
- package/dist/mcp-app/app-icon-read.d.ts +7 -0
- package/dist/mcp-app/app-job-bridge.d.ts +30 -0
- package/dist/mcp-app/app-job-bridge.example.d.ts +36 -0
- package/dist/mcp-app/app-job.d.ts +168 -0
- package/dist/mcp-app/app-schedule.d.ts +85 -0
- package/dist/mcp-app/apps-context.d.ts +32 -0
- package/dist/mcp-app/bundle-provenance.d.ts +3 -0
- package/dist/mcp-app/candidate-registration.d.ts +4 -0
- package/dist/mcp-app/card-handler.d.ts +7 -0
- package/dist/mcp-app/catalog.d.ts +7 -0
- package/dist/mcp-app/content-channel.d.ts +86 -0
- package/dist/mcp-app/content-declarations.d.ts +31 -0
- package/dist/mcp-app/dev-checks.d.ts +31 -0
- package/dist/mcp-app/diagnostic-reason.d.ts +3 -0
- package/dist/mcp-app/discovery.d.ts +164 -0
- package/dist/mcp-app/errors.d.ts +7 -0
- package/dist/mcp-app/index.d.ts +45 -0
- package/dist/mcp-app/installed-app-ref.d.ts +25 -0
- package/dist/mcp-app/model-context.d.ts +29 -0
- package/dist/mcp-app/node-app-discovery-fs.d.ts +23 -0
- package/dist/mcp-app/product-bundle-assets.d.ts +27 -0
- package/dist/mcp-app/product-bundle-loader.d.ts +53 -0
- package/dist/mcp-app/projection.d.ts +14 -0
- package/dist/mcp-app/prompt-cards.d.ts +28 -0
- package/dist/mcp-app/registry.d.ts +28 -0
- package/dist/mcp-app/skill-backend.d.ts +141 -0
- package/dist/mcp-app/state-set.d.ts +9 -0
- package/dist/mcp-app/types.d.ts +501 -0
- package/dist/mcp-app/workspace-app-assets.d.ts +42 -0
- package/dist/mcp-app/workspace-app-scan-cache.d.ts +27 -0
- package/dist/mcp-app/workspace-snapshot.d.ts +80 -0
- package/dist/migrations/0011_far_black_tarantula.sql +1 -0
- package/dist/migrations/0012_blue_turbo.sql +23 -0
- package/dist/migrations/0013_hesitant_adam_destine.sql +15 -0
- package/dist/migrations/0014_organic_mongu.sql +73 -0
- package/dist/migrations/0015_panoramic_gorilla_man.sql +71 -0
- package/dist/migrations/0016_fuzzy_hemingway.sql +14 -0
- package/dist/migrations/0017_project_stage_sdk_migration.sql +29 -0
- package/dist/migrations/0018_bored_jackal.sql +33 -0
- package/dist/migrations/0019_backfill_task_thread_ids.sql +74 -0
- package/dist/migrations/0020_useful_iron_lad.sql +55 -0
- package/dist/migrations/0021_dashing_peter_quill.sql +51 -0
- package/dist/migrations/0022_wandering_bucky.sql +1 -0
- package/dist/migrations/0023_red_payback.sql +1 -0
- package/dist/migrations/0024_storage_metadata.sql +262 -0
- package/dist/migrations/0025_task_heartbeat.sql +8 -0
- package/dist/migrations/0025_thread_app_instance_ledger.sql +2 -0
- package/dist/migrations/0026_mcp_action_source.sql +47 -0
- package/dist/migrations/0027_task_stop_scope_cleanup.sql +5 -0
- package/dist/migrations/0027_ui_instance_active_unique.sql +2 -0
- package/dist/migrations/0029_nice_rhino.sql +1 -0
- package/dist/migrations/0031_petite_arclight.sql +6 -0
- package/dist/migrations/0032_ui_instance_opened_by.sql +1 -0
- package/dist/migrations/0033_thread_creator_boundary_guard.sql +38 -0
- package/dist/migrations/0034_keen_fallen_one.sql +36 -0
- package/dist/migrations/0035_request_log_daily.sql +11 -0
- package/dist/migrations/0036_ui_definition_archive.sql +8 -0
- package/dist/migrations/0037_ui_instance_agent_open_request.sql +1 -0
- package/dist/migrations/0038_task_rating.sql +3 -0
- package/dist/migrations/0039_aspiring_purifiers.sql +9 -0
- package/dist/migrations/0040_task_provider_inputs.sql +53 -0
- package/dist/migrations/0041_tranquil_vivisector.sql +54 -0
- package/dist/migrations/0042_breezy_blue_shield.sql +31 -0
- package/dist/migrations/0043_nervous_darkstar.sql +1 -0
- package/dist/migrations/0044_military_galactus.sql +8 -0
- package/dist/migrations/0045_task_pid_started_at.sql +1 -0
- package/dist/migrations/0046_acoustic_karnak.sql +49 -0
- package/dist/migrations/0047_doc_sync_connect_requests.sql +18 -0
- package/dist/migrations/meta/0011_snapshot.json +1342 -0
- package/dist/migrations/meta/0012_snapshot.json +1494 -0
- package/dist/migrations/meta/0013_snapshot.json +1592 -0
- package/dist/migrations/meta/0014_snapshot.json +1975 -0
- package/dist/migrations/meta/0015_snapshot.json +2315 -0
- package/dist/migrations/meta/0016_snapshot.json +2419 -0
- package/dist/migrations/meta/0017_snapshot.json +2419 -0
- package/dist/migrations/meta/0018_snapshot.json +2570 -0
- package/dist/migrations/meta/0020_snapshot.json +2895 -0
- package/dist/migrations/meta/0021_snapshot.json +3031 -0
- package/dist/migrations/meta/0022_snapshot.json +3039 -0
- package/dist/migrations/meta/0023_snapshot.json +3047 -0
- package/dist/migrations/meta/0029_snapshot.json +3206 -0
- package/dist/migrations/meta/0031_snapshot.json +3251 -0
- package/dist/migrations/meta/0034_snapshot.json +3473 -0
- package/dist/migrations/meta/0035_snapshot.json +3547 -0
- package/dist/migrations/meta/0036_snapshot.json +3591 -0
- package/dist/migrations/meta/0037_snapshot.json +3598 -0
- package/dist/migrations/meta/0038_snapshot.json +3626 -0
- package/dist/migrations/meta/0039_snapshot.json +3684 -0
- package/dist/migrations/meta/0040_snapshot.json +3759 -0
- package/dist/migrations/meta/0041_snapshot.json +4156 -0
- package/dist/migrations/meta/0042_snapshot.json +4383 -0
- package/dist/migrations/meta/0043_snapshot.json +4390 -0
- package/dist/migrations/meta/0044_snapshot.json +4435 -0
- package/dist/migrations/meta/0045_snapshot.json +4442 -0
- package/dist/migrations/meta/0046_snapshot.json +4733 -0
- package/dist/migrations/meta/0047_snapshot.json +4832 -0
- package/dist/migrations/meta/_journal.json +259 -0
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +2 -0
- package/dist/paths.d.ts +1 -0
- package/dist/plugin/types.d.ts +1 -0
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/index.js +531 -214
- package/dist/plugins/sqlite-tracing.d.ts +46 -0
- package/dist/process/index.d.ts +2 -0
- package/dist/process/index.js +1 -0
- package/dist/process/process-control.d.ts +74 -0
- package/dist/prompt/tag-names.d.ts +22 -0
- package/dist/provider/acp/connection.d.ts +6 -0
- package/dist/provider/acp/meta.d.ts +11 -0
- package/dist/provider/bridge.d.ts +12 -2
- package/dist/provider/classify-task-error.d.ts +2 -0
- package/dist/provider/claude-agent-env.d.ts +1 -0
- package/dist/provider/cli/adapter.types.d.ts +23 -2
- package/dist/provider/cli/adapters/agent-call.util.d.ts +1 -1
- package/dist/provider/cli/adapters/cli-knob.util.d.ts +7 -0
- package/dist/provider/cli/adapters/codex-item.d.ts +1 -0
- package/dist/provider/cli/adapters/event-timestamp.util.d.ts +1 -0
- package/dist/provider/cli/adapters/grok.d.ts +2 -0
- package/dist/provider/cli/adapters/index.d.ts +5 -0
- package/dist/provider/cli/index.d.ts +3 -2
- package/dist/provider/cli/meta.d.ts +5 -0
- package/dist/provider/cli/protocol-envelope.d.ts +3 -0
- package/dist/provider/errors.d.ts +5 -1
- package/dist/provider/idle-watchdog.d.ts +19 -0
- package/dist/provider/models.d.ts +17 -12
- package/dist/provider/order.d.ts +1 -1
- package/dist/provider/parse-usage.d.ts +6 -0
- package/dist/provider/provider-selection.d.ts +8 -0
- package/dist/provider/redact-technical-message.d.ts +1 -0
- package/dist/provider/task-error.types.d.ts +17 -0
- package/dist/provider-account/accounts.d.ts +15 -0
- package/dist/provider-account/index.d.ts +5 -0
- package/dist/provider-account/registry.d.ts +30 -0
- package/dist/provider-account/types.d.ts +40 -0
- package/dist/publish/constants.d.ts +6 -0
- package/dist/publish/errors.d.ts +7 -0
- package/dist/publish/index.d.ts +55 -0
- package/dist/publish/index.js +2 -0
- package/dist/publish/manifest.d.ts +47 -0
- package/dist/publish/marketplace-api.constants.d.ts +1 -0
- package/dist/publish/pack.d.ts +6 -0
- package/dist/publish/scan.d.ts +10 -0
- package/dist/publish/secrets.d.ts +6 -0
- package/dist/publish/upload.d.ts +19 -0
- package/dist/remote/execution-profile.d.ts +9 -0
- package/dist/remote/index.d.ts +1 -0
- package/dist/remote/types.d.ts +28 -0
- package/dist/repository/agent-send-history.repository.d.ts +23 -0
- package/dist/repository/agent-suggestion.repository.d.ts +34 -0
- package/dist/repository/base-sqlite-repository.d.ts +1 -0
- package/dist/repository/common-code.repository.d.ts +45 -0
- package/dist/repository/db.d.ts +13 -1
- package/dist/repository/index.d.ts +62 -6
- package/dist/repository/index.js +777 -207
- package/dist/repository/logs-db.d.ts +12 -0
- package/dist/repository/notification.repository.d.ts +58 -0
- package/dist/repository/project.repository.d.ts +90 -0
- package/dist/repository/public-task-answer.d.ts +24 -0
- package/dist/repository/request-log-mover.d.ts +70 -0
- package/dist/repository/request-log.repository.d.ts +7 -3
- package/dist/repository/run-columns.d.ts +10 -0
- package/dist/repository/run-history.repository.d.ts +112 -0
- package/dist/repository/schedule-run.repository.d.ts +103 -0
- package/dist/repository/sidebar-tab.repository.d.ts +86 -0
- package/dist/repository/storage-metadata.repository.d.ts +64 -0
- package/dist/repository/task-log-migration.d.ts +74 -0
- package/dist/repository/task-log.repository.d.ts +47 -0
- package/dist/repository/task-status.d.ts +21 -0
- package/dist/repository/task.repository.d.ts +318 -8
- package/dist/repository/thread-history.repository.d.ts +193 -0
- package/dist/repository/thread-origin-verdict.d.ts +27 -0
- package/dist/repository/thread-title.types.d.ts +29 -0
- package/dist/repository/thread.repository.d.ts +134 -5
- package/dist/repository/usage-backfill.d.ts +62 -0
- package/dist/repository/usage-from-logs.d.ts +21 -0
- package/dist/repository/workflow-anchor-kinds.d.ts +4 -0
- package/dist/repository/workspace.repository.d.ts +3 -0
- package/dist/schema/agent-send-history.d.ts +85 -0
- package/dist/schema/agent-suggestions.d.ts +199 -0
- package/dist/schema/common-codes.d.ts +216 -0
- package/dist/schema/doc-sync-connect-requests.d.ts +140 -0
- package/dist/schema/doc-sync-links.d.ts +481 -0
- package/dist/schema/index.d.ts +20 -0
- package/dist/schema/notifications.d.ts +303 -0
- package/dist/schema/projects.d.ts +610 -0
- package/dist/schema/request-log-daily.d.ts +151 -0
- package/dist/schema/run-column-backfill.d.ts +81 -0
- package/dist/schema/schedule-runs.d.ts +451 -0
- package/dist/schema/sidebar-tabs.d.ts +466 -0
- package/dist/schema/storage-metadata.d.ts +181 -0
- package/dist/schema/task-log-events.d.ts +119 -0
- package/dist/schema/task-provider-inputs.d.ts +100 -0
- package/dist/schema/tasks.d.ts +1172 -1
- package/dist/schema/thread-creator-unverified.d.ts +45 -0
- package/dist/schema/thread-history.d.ts +734 -0
- package/dist/schema/threads.d.ts +59 -0
- package/dist/schema/ui-action-receipts.d.ts +358 -0
- package/dist/schema/ui-definition-archive.d.ts +63 -0
- package/dist/schema/ui-instance-repins.d.ts +222 -0
- package/dist/schema/ui-instances.d.ts +324 -0
- package/dist/schema/workspaces.d.ts +17 -0
- package/dist/skills/index.d.ts +15 -0
- package/dist/skills/index.js +2 -0
- package/dist/skills/types.d.ts +18 -0
- package/dist/task-log/anchor-child-tasks.d.ts +7 -0
- package/dist/task-log/delegation-trailer.d.ts +34 -0
- package/dist/template/engine.d.ts +2 -2
- package/dist/template/helpers/exec.browser.d.ts +4 -3
- package/dist/template/helpers/exec.d.ts +4 -3
- package/dist/template/helpers/format-conversation.d.ts +1 -0
- package/dist/template/types.d.ts +20 -0
- package/dist/testing/index.js +1 -1
- package/dist/types/index.d.ts +1611 -3
- package/dist/types/task-log.types.d.ts +6 -1
- package/dist/ui-card/index.d.ts +2 -0
- package/dist/ui-card/legacy-card-parser.d.ts +11 -0
- package/dist/ui-instance/definition.d.ts +6 -0
- package/dist/ui-instance/errors.d.ts +18 -0
- package/dist/ui-instance/index.d.ts +11 -0
- package/dist/ui-instance/json.d.ts +19 -0
- package/dist/ui-instance/lineage.d.ts +24 -0
- package/dist/ui-instance/runtime.d.ts +19 -0
- package/dist/ui-instance/store.d.ts +213 -0
- package/dist/ui-instance/types.d.ts +344 -0
- package/dist/ui-plugin/app-icon.d.ts +50 -0
- package/dist/ui-plugin/app-manifest.d.ts +64 -0
- package/dist/ui-plugin/csp.d.ts +28 -0
- package/dist/ui-plugin/index.d.ts +8 -0
- package/dist/ui-plugin/limits.d.ts +27 -0
- package/dist/ui-plugin/manifest.d.ts +3 -0
- package/dist/ui-plugin/types.d.ts +220 -0
- package/dist/ui-plugin/validator.d.ts +18 -0
- package/dist/utils/crewx-executable.d.ts +76 -0
- package/dist/utils/crewx-home.d.ts +1 -0
- package/dist/utils/env-defaults.d.ts +3 -0
- package/dist/utils/id.d.ts +1 -1
- package/dist/utils/local-identity.d.ts +2 -0
- package/dist/utils/runner-env.d.ts +3 -0
- package/dist/utils/timestamp.d.ts +1 -0
- package/dist/utils/workspace.d.ts +1 -0
- package/dist/wi/create.d.ts +48 -0
- package/dist/wi/select.d.ts +20 -0
- package/package.json +68 -3
- package/templates/agents/default.yaml +303 -128
- package/templates/documents/crewx-manual.md +138 -138
- package/templates/documents/crewx-quick-guide.md +8 -7
- package/templates/workflows/wi-default-flow.yaml +65 -0
- package/templates/workflows/wi-plan-flow.yaml +140 -0
|
@@ -1,16 +1,56 @@
|
|
|
1
|
+
import type { ThreadCreationOptions } from '../repository/thread.repository';
|
|
2
|
+
export type { ThreadCreationOptions } from '../repository/thread.repository';
|
|
1
3
|
export interface ConversationMessage {
|
|
2
4
|
id: string;
|
|
3
5
|
userId?: string;
|
|
4
6
|
text: string;
|
|
5
7
|
isAssistant: boolean;
|
|
6
8
|
timestamp: number;
|
|
9
|
+
taskId?: string;
|
|
7
10
|
metadata?: Record<string, unknown>;
|
|
8
11
|
}
|
|
9
12
|
export type Platform = 'cli' | 'web' | 'api' | 'mcp' | `channel/${string}`;
|
|
13
|
+
export interface ConversationHighlight {
|
|
14
|
+
id: string;
|
|
15
|
+
text: string;
|
|
16
|
+
kind?: string;
|
|
17
|
+
source?: string;
|
|
18
|
+
coversFromTaskId?: string;
|
|
19
|
+
coversToTaskId?: string;
|
|
20
|
+
covers_from_task_id?: string;
|
|
21
|
+
covers_to_task_id?: string;
|
|
22
|
+
createdAt?: number | string;
|
|
23
|
+
created_at?: number | string;
|
|
24
|
+
}
|
|
25
|
+
export interface SemanticContinuityContext {
|
|
26
|
+
highlights: ConversationHighlight[];
|
|
27
|
+
truncatedHighlights?: number;
|
|
28
|
+
omittedTurns: {
|
|
29
|
+
count: number;
|
|
30
|
+
represented: number;
|
|
31
|
+
unrepresented: number;
|
|
32
|
+
taskIds: string[];
|
|
33
|
+
};
|
|
34
|
+
rendered?: string;
|
|
35
|
+
omittedRendered: string;
|
|
36
|
+
}
|
|
37
|
+
export type ConversationSemanticContinuityContext = SemanticContinuityContext;
|
|
38
|
+
export interface ConversationThreadStateValue {
|
|
39
|
+
code: string;
|
|
40
|
+
name: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ConversationThreadState {
|
|
43
|
+
title?: string;
|
|
44
|
+
priority?: ConversationThreadStateValue;
|
|
45
|
+
state?: ConversationThreadStateValue;
|
|
46
|
+
rendered?: string;
|
|
47
|
+
}
|
|
48
|
+
export type ThreadStateContext = ConversationThreadState;
|
|
10
49
|
export interface ConversationThread {
|
|
11
50
|
threadId: string;
|
|
12
51
|
platform: Platform;
|
|
13
52
|
messages: ConversationMessage[];
|
|
53
|
+
highlights?: ConversationHighlight[];
|
|
14
54
|
metadata?: {
|
|
15
55
|
title?: string;
|
|
16
56
|
firstMessage?: string;
|
|
@@ -19,27 +59,44 @@ export interface ConversationThread {
|
|
|
19
59
|
updatedAt?: number;
|
|
20
60
|
};
|
|
21
61
|
}
|
|
62
|
+
export interface TemplateAppCard {
|
|
63
|
+
readonly instanceId: string;
|
|
64
|
+
readonly anchorTaskId: string;
|
|
65
|
+
readonly status: 'running' | 'waiting' | 'done' | 'failed' | 'expired';
|
|
66
|
+
readonly result?: 'saved' | 'deferred' | 'cancelled';
|
|
67
|
+
readonly agentId?: string;
|
|
68
|
+
readonly xml: string;
|
|
69
|
+
readonly replacesSlot?: boolean;
|
|
70
|
+
}
|
|
22
71
|
export interface TemplateMessage {
|
|
72
|
+
id?: string;
|
|
23
73
|
text: string;
|
|
24
74
|
isAssistant: boolean;
|
|
75
|
+
taskId?: string;
|
|
25
76
|
timestamp?: number;
|
|
26
77
|
metadata?: Record<string, unknown>;
|
|
78
|
+
activity_log?: string;
|
|
27
79
|
files?: Array<{
|
|
28
80
|
name: string;
|
|
29
81
|
size?: number;
|
|
30
82
|
localPath?: string;
|
|
31
83
|
}>;
|
|
84
|
+
appCard?: TemplateAppCard;
|
|
32
85
|
}
|
|
33
86
|
export interface FetchHistoryOptions {
|
|
34
87
|
limit?: number;
|
|
35
88
|
maxContextLength?: number;
|
|
89
|
+
includeHighlights?: boolean;
|
|
36
90
|
currentTraceId?: string;
|
|
91
|
+
agentId?: string;
|
|
37
92
|
}
|
|
38
93
|
export interface IConversationHistoryProvider {
|
|
39
|
-
ensureThread(threadId: string, platform: Platform, workspaceId?: string): Promise<{
|
|
94
|
+
ensureThread(threadId: string, platform: Platform, workspaceId?: string, creator?: ThreadCreationOptions): Promise<{
|
|
40
95
|
created: boolean;
|
|
41
96
|
}>;
|
|
42
97
|
fetchHistory(threadId: string, options?: FetchHistoryOptions): Promise<ConversationThread>;
|
|
98
|
+
fetchThreadState?(threadId: string): Promise<ConversationThreadState | undefined>;
|
|
99
|
+
fetchHighlights?(threadId: string): Promise<ConversationHighlight[] | undefined>;
|
|
43
100
|
saveUserMessage(threadId: string, text: string, userId?: string, metadata?: Record<string, unknown>): Promise<{
|
|
44
101
|
id: string;
|
|
45
102
|
firstMessage: boolean;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CommandRunner, GlobalCrewxInfo, ShortcutProgressEvent } from './types';
|
|
2
|
+
export interface DetectGlobalCrewxOptions {
|
|
3
|
+
env: NodeJS.ProcessEnv;
|
|
4
|
+
cwd: string;
|
|
5
|
+
run: CommandRunner;
|
|
6
|
+
}
|
|
7
|
+
export declare function detectGlobalCrewx(opts: DetectGlobalCrewxOptions): Promise<GlobalCrewxInfo>;
|
|
8
|
+
export interface EnsureGlobalCrewxOptions {
|
|
9
|
+
env: NodeJS.ProcessEnv;
|
|
10
|
+
cwd: string;
|
|
11
|
+
run: CommandRunner;
|
|
12
|
+
targetVersion: string;
|
|
13
|
+
currentInfo?: GlobalCrewxInfo;
|
|
14
|
+
installRoot?: string;
|
|
15
|
+
onProgress?: (event: ShortcutProgressEvent) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function ensureGlobalCrewx(opts: EnsureGlobalCrewxOptions): Promise<{
|
|
18
|
+
info: GlobalCrewxInfo;
|
|
19
|
+
}>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { getShortcutStatus, installShortcut, uninstallShortcut, dismissShortcutNotice, } from './install';
|
|
2
|
+
export { killProcessTree } from './command-runner';
|
|
3
|
+
export { ShortcutError, type ShortcutState, type DesktopSource, type GlobalCrewxInfo, type ShortcutStatus, type ShortcutInstallResult, type ShortcutProgressPhase, type ShortcutProgressEvent, type ShortcutEnvOptions, type InstallShortcutOptions, type ShortcutErrorCode, type CommandResult, type CommandRunner, type CommandRunOptions, type ShortcutFsLike, } from './types';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
'use strict';var m=require('path'),crypto=require('crypto'),fs=require('fs'),os=require('os'),child_process=require('child_process'),string_decoder=require('string_decoder'),module$1=require('module');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var m__namespace=/*#__PURE__*/_interopNamespace(m);var F=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var p=class extends Error{code;constructor(t,n){super(`${t}: ${n}`),this.code=t,this.name="ShortcutError";}};var q={existsSync:e=>fs.existsSync(e),readFileSync:e=>fs.readFileSync(e,"utf8"),readBinaryFileSync:e=>new Uint8Array(fs.readFileSync(e)),writeFileSync:(e,t)=>fs.writeFileSync(e,t,"utf8"),mkdirSync:e=>{fs.mkdirSync(e,{recursive:true});},unlinkSync:e=>{fs.unlinkSync(e);}},Y=os.homedir;function O(e){return typeof e!="string"?void 0:e.trim()||void 0}function L(e){return O(e)?.toLowerCase()??""}function _(e){try{return fs.statSync(e).isFile()}catch{return false}}function Je(e,t){if(e===t)return true;let n=m__namespace.default.relative(e,t);return n!==""&&!n.startsWith("..")&&!m__namespace.default.isAbsolute(n)}function je(e,t){if(m__namespace.default.basename(e)!==".bin")return false;let n=m__namespace.default.dirname(e);if(m__namespace.default.basename(n)!=="node_modules")return false;let r=m__namespace.default.dirname(n);return Je(r,t)}function Q(e,t={}){if(e.includes("/")||e.includes("\\")||m__namespace.default.isAbsolute(e))return e;let n=t.platform??process.platform,r=t.env??process.env,o=m__namespace.default.resolve(t.cwd??process.cwd()),c=(t.resolution??"global_first")==="global_first",s=r.PATH??r.Path??process.env.PATH??process.env.Path??"",i=n==="win32"?";":":",a=s.split(i).map(l=>l.trim()).filter(Boolean),u=m__namespace.default.extname(e).length>0,d=r.PATHEXT??r.Pathext??process.env.PATHEXT??process.env.Pathext??".EXE;.CMD;.BAT;.COM",f=n==="win32"?u?[""]:d.split(";").map(l=>l.trim()).filter(Boolean).map(l=>l.startsWith(".")?l:`.${l}`):[""];for(let l of a){let P=m__namespace.default.resolve(o,l);if(!(c&&je(P,o)))for(let h of f){let y=L(h),w=h.toUpperCase();for(let g of [h,y,w]){let C=m__namespace.default.join(P,`${e}${g}`);if(_(C))return C}}}return e}function ze(e){if(!_(e))return null;try{let t=fs.readFileSync(e,"utf8"),n=m__namespace.default.dirname(e),r=[];for(let i of t.matchAll(/"([^"\r\n]*)"/g)){let d=(i[1]??"").match(/%~?dp0%?\s*[\\/]*(.*)$/i)?.[1]?.trim();if(!d)continue;let f=d.replace(/[\\/]+/g,m__namespace.default.sep).replace(/^[\\/]+/,""),l=m__namespace.default.resolve(n,f);_(l)&&r.push(l);}let o=[],c=new Map;for(let i of t.matchAll(/SET\s+"(\w+)=%~?dp0%?[\\/]?([^"]+)"/gi)){let a=i[1].toUpperCase(),u=i[2].trim().replace(/[\\/]+/g,m__namespace.default.sep).replace(/^[\\/]+/,"");c.set(a,m__namespace.default.resolve(n,u));}for(let i of t.split(/\r?\n/))if(i.includes("%*"))for(let a of i.matchAll(/"%(\w+)%"/g)){let u=c.get(a[1].toUpperCase());u&&_(u)&&o.push(u);}let s=i=>i.find(a=>{let u=L(m__namespace.default.basename(a));return u!=="node.exe"&&u!=="node"})??null;return s(o)??s(r)}catch{return null}}function qe(e,t){if(typeof t=="string")return O(t)||null;if(!t||typeof t!="object")return null;if(e){let n=t[e],r=typeof n=="string"?O(n):void 0;if(r)return r}for(let n of Object.values(t)){let r=typeof n=="string"?O(n):void 0;if(r)return r}return null}function Ye(e,t){if(!t)return null;let n=m__namespace.default.dirname(e),r=[m__namespace.default.resolve(n,"..",t),m__namespace.default.resolve(n,"node_modules",t)];for(let o of r){let c=m__namespace.default.join(o,"package.json");if(_(c))try{let s=JSON.parse(fs.readFileSync(c,"utf8")),i=qe(t,s.bin);if(!i)continue;let a=m__namespace.default.resolve(o,i);if(_(a))return a}catch{}}return null}function Qe(e){let t=e.platform??process.platform,n=e.env??process.env,r=e.execPath??process.execPath,o=e.cwd,c=e.resolution;if(t!=="win32")return {command:Q(e.command,{cwd:o,env:n,platform:t,resolution:c}),leadingArgv:[],resolution:"direct"};let s=Q(e.command,{cwd:o,env:n,platform:t,resolution:c}),i=L(m__namespace.default.extname(s));if(i===".js"||i===".cjs"||i===".mjs")return {command:r,leadingArgv:[s],resolution:"node-entrypoint",windowsHide:true};if(i===".cmd"||i===".bat"){let a=ze(s)??Ye(s,e.packageName);return a?L(m__namespace.default.extname(a))===".exe"?{command:a,leadingArgv:[],resolution:"exe-entrypoint",windowsHide:true}:{command:r,leadingArgv:[a],resolution:"node-entrypoint",windowsHide:true}:{command:s,leadingArgv:[],resolution:"unresolved-wrapper"}}return {command:s,leadingArgv:[],resolution:"direct",windowsHide:true}}function Ze(e){if(e.candidate.resolution!=="unresolved-wrapper")return {command:e.candidate.command,leadingArgv:e.candidate.leadingArgv,resolution:e.candidate.resolution,windowsHide:e.candidate.windowsHide};throw new Error(`${m__namespace.default.basename(e.candidate.command)} wrapper resolved, but no executable/Node entrypoint could be resolved without shell execution.`)}function ee(e){let t=Qe(e);return Ze({candidate:t})}function te(e,t){return {command:e.command,argv:[...e.leadingArgv,...t],resolution:e.resolution,shell:e.shell,windowsHide:e.windowsHide}}var D="\uFFFD",B=8,re=1e3,tt=new Map([[437,"ibm437"],[720,"ibm720"],[737,"ibm737"],[775,"ibm775"],[850,"ibm850"],[852,"ibm852"],[855,"ibm855"],[857,"ibm857"],[858,"ibm858"],[862,"ibm862"],[864,"ibm864"],[932,"shift_jis"],[936,"gb18030"],[949,"euc-kr"],[950,"big5"],[866,"ibm866"],[869,"ibm869"],[1250,"windows-1250"],[1251,"windows-1251"],[1252,"windows-1252"],[1253,"windows-1253"],[1254,"windows-1254"],[1255,"windows-1255"],[1256,"windows-1256"],[1257,"windows-1257"],[1258,"windows-1258"]]),T;function U(e){let t=0;for(let n of e)n===D&&(t+=1);return t}function $(e,t){return U(t)<U(e)?t:e}function nt(e){let t=e.match(/(?:^|[^0-9])([0-9]{1,5})(?![0-9])/);if(!t)return null;let n=Number(t[1]);return Number.isInteger(n)&&n>0&&n<=65535?n:null}function rt(e){if(e!==65001)return tt.get(e)}function ot(e){let t=rt(e);if(!t)return null;try{return new TextDecoder(t)}catch{return null}}function st(){return new Promise(e=>{let t=false,n,r=o=>{t||(t=true,n&&clearTimeout(n),e(o));};n=setTimeout(()=>r(null),re),n.unref();try{child_process.execFile("chcp.com",[],{encoding:"ascii",timeout:re,windowsHide:!0},(c,s)=>{if(c){r(null);return}r(nt(String(s)));}).once("error",()=>r(null));}catch{r(null);}})}function ie(){return process.platform!=="win32"?Promise.resolve(null):(T||(T=st(),T.then(e=>{},()=>{})),T)}function it(){process.platform==="win32"&&ie();}function se(e,t){if(t.length>=B)return t.subarray(t.length-B);let n=B-t.length,r=e.length>n?e.subarray(e.length-n):e;return Buffer.concat([r,t])}var b=class{platform;detectCodePage;utf8Decoder=new string_decoder.StringDecoder("utf8");codePage;fallbackDecoder;replayTail=Buffer.alloc(0);pendingUtf8="";pendingFallback="";pendingBytes=Buffer.alloc(0);queue=Promise.resolve();ended=false;constructor(t={}){this.platform=t.platform??process.platform,this.detectCodePage=t.detectCodePage??ie,this.codePage=t.codePage;}write(t){let n=Buffer.from(t);return this.enqueue(()=>this.decodeChunk(n))}end(){return this.enqueue(()=>this.finish())}enqueue(t){let n=this.queue.then(t);return this.queue=n.then(()=>{},()=>{}),n}clearPendingCandidate(){this.pendingUtf8="",this.pendingFallback="",this.pendingBytes=Buffer.alloc(0);}async resolveCodePage(){if(this.codePage!==void 0)return this.codePage;try{this.codePage=await this.detectCodePage();}catch{this.codePage=null;}return this.codePage}async getFallbackDecoder(){if(this.fallbackDecoder!==void 0)return this.fallbackDecoder;let t=await this.resolveCodePage();return this.fallbackDecoder=t===null?null:ot(t),this.fallbackDecoder}async decodeChunk(t){if(this.ended)return "";let n=this.utf8Decoder.write(t),r=n.includes(D);if(r&&(this.utf8Decoder=new string_decoder.StringDecoder("utf8")),this.platform!=="win32")return n;if(this.fallbackDecoder){let a=this.fallbackDecoder.decode(t,{stream:true}),u=se(this.pendingBytes,t);if(r){let d=this.pendingUtf8+n,f=this.pendingFallback+a;return this.clearPendingCandidate(),$(d,f)}if(U(a)>0){let d=this.pendingUtf8+n;return this.clearPendingCandidate(),this.fallbackDecoder=void 0,this.replayTail=u,d}if(this.pendingUtf8||this.pendingFallback){if(this.pendingUtf8+=n,this.pendingFallback+=a,this.pendingBytes=u,n.length===0||a.length===0)return "";let d=this.pendingUtf8;return this.clearPendingCandidate(),d}return n.length===0&&a.length>0?(this.pendingUtf8=n,this.pendingFallback=a,this.pendingBytes=u,""):n}let o=this.replayTail;if(this.fallbackDecoder===void 0&&(this.replayTail=se(this.replayTail,t)),!r)return n;let c=this.fallbackDecoder===void 0,s=await this.getFallbackDecoder();if(!s)return this.replayTail=Buffer.alloc(0),n;c&&o.length>0&&s.decode(o,{stream:true}),this.replayTail=Buffer.alloc(0);let i=s.decode(t,{stream:true});return $(n,i)}async finish(){if(this.ended)return "";this.ended=true;let t=this.utf8Decoder.end();if(this.platform!=="win32")return t;if(this.fallbackDecoder===void 0&&t.includes(D)){let c=await this.getFallbackDecoder();c&&this.replayTail.length>0&&(c.decode(this.replayTail,{stream:true}),this.replayTail=Buffer.alloc(0));}let n=this.pendingUtf8+t,r=this.fallbackDecoder?.decode()??"",o=this.pendingFallback+r;return this.clearPendingCandidate(),n.includes(D)?$(n,o):n}};it();var ae=3e3;var ct=2e3,ut=25,lt=100;function le(e){return e instanceof Error?e:e===void 0?void 0:new Error(String(e))}function ce(e){return typeof e=="object"&&e!==null&&"code"in e?String(e.code):void 0}function dt(e){return Number.isSafeInteger(e)&&e>0}function ft(e,t){return new Promise(n=>{let r;try{r=child_process.spawn(e,t,{windowsHide:!0});}catch(u){n({status:null,stdout:"",stderr:"",error:le(u)});return}let o="",c="",s=false,i,a=setTimeout(()=>{try{r.kill();}catch{}i({status:null,stdout:o,stderr:c,error:new Error(`Command timed out after ${ae}ms`)});},ae);i=u=>{s||(s=true,clearTimeout(a),n(u));},r.stdout?.setEncoding("utf8"),r.stderr?.setEncoding("utf8"),r.stdout?.on("data",u=>{o+=String(u);}),r.stderr?.on("data",u=>{c+=String(u);}),r.once("error",u=>{i({status:null,stdout:o,stderr:c,error:u});}),r.once("close",u=>{i({status:u,stdout:o,stderr:c});});})}async function mt(e,t,n){return n.runCommandAsync?n.runCommandAsync(e,t):n.runCommand?n.runCommand(e,t):ft(e,t)}function pt(e){return new Promise(t=>{setTimeout(t,Math.max(0,e));})}function ht(){return new Promise(e=>{setImmediate(e);})}function A(e,t=process.kill){try{return t(e,0),"alive"}catch(n){return ce(n)==="ESRCH"?"not_found":ce(n)==="EPERM"?"alive":"unknown"}}function wt(e,t){let n=A(-e,t),r=A(e,t);return n==="alive"||r==="alive"?"alive":n==="unknown"||r==="unknown"?"unknown":"not_found"}async function de(e,t,n,r){let o=Math.max(0,n),c=Math.max(1,r.pollIntervalMs??ut),s=Date.now()+o,i,a=o===0,u=r.sleep?Promise.resolve().then(()=>r.sleep(o)).then(()=>{},()=>{}):new Promise(d=>{i=setTimeout(d,o);});u.then(()=>{a=true;});try{for(await ht();;){let d=wt(e,t);if(d==="not_found")return d;let f=s-Date.now();if(a||f<=0)return d;await Promise.race([u,pt(Math.min(c,f))]);}}finally{i!==void 0&&clearTimeout(i);}}async function ue(e,t,n,r,o){let c=await de(e,t,o.hardConfirmMs??lt,{...o,sleep:void 0});return c==="not_found"?n?{status:"not_found",pid:e,method:r}:{status:"terminated",pid:e,method:r}:c==="alive"?{status:"failed",pid:e,method:r,error:"Process is still running after termination attempt"}:{status:"failed",pid:e,method:r,error:"Unable to verify process termination"}}async function fe(e,t={}){let n=t.platform??process.platform,r=n==="win32"?"taskkill":"process-group",o=l=>({status:"failed",pid:e,method:r,error:l});if(!dt(e))return o("Invalid process ID");let c=t.kill??process.kill,s=A(e,c);if(s==="not_found")return {status:"not_found",pid:e,method:r};if(s!=="alive")return o("Unable to determine whether the process is alive");if(n==="win32"){let l;try{l=await mt("taskkill",["/PID",String(e),"/T","/F"],t);}catch(h){l={status:null,stdout:"",stderr:"",error:le(h)};}let P=A(e,c);return P==="not_found"?l.status===0&&!l.error?{status:"terminated",pid:e,method:r}:{status:"not_found",pid:e,method:r}:o(P==="alive"?"Process is still running after termination attempt":"Unable to verify process termination")}let i,a=t.signal??"SIGKILL";try{c(-e,a);}catch(l){i=l;}if(a==="SIGKILL")return ue(e,c,i,r,t);if(await de(e,c,t.graceMs??ct,t)==="not_found")return i?{status:"not_found",pid:e,method:r}:{status:"terminated",pid:e,method:r};let d;try{c(-e,"SIGKILL");}catch(l){d=l;}let f=await ue(e,c,d,r,t);return f.status==="terminated"?f:f.status==="not_found"?i?f:{status:"terminated",pid:e,method:r}:o(f.error??"Process termination failed")}var gt=["CREWX_ASSIGNED_TASK_ID","CREWX_DETACHED_RUNNER"];function Pt(e,t){let n={};for(let[r,o]of Object.entries(e))o!==void 0&&(t.includes(r)||(n[r]=o));return n}function me(e){return Pt(e,gt)}var pe=3e4;function he(e){if(typeof e.pid!="number"){try{e.kill();}catch{}return}fe(e.pid,{signal:"SIGKILL"}).then(t=>{if(t.status==="failed")try{e.kill("SIGKILL");}catch{}},()=>{try{e.kill("SIGKILL");}catch{}});}var we=(e,t,n={})=>new Promise((r,o)=>{let c=me(n.env??process.env),s=process.platform,i;try{let g=ee({command:e,platform:s,env:c,cwd:n.cwd,allowShellFallback:!1});i=te(g,t);}catch(g){o(g instanceof Error?g:new Error(String(g)));return}let a=child_process.spawn(i.command,i.argv,{cwd:n.cwd,env:c,shell:i.shell,windowsHide:i.windowsHide??true,detached:s!=="win32"}),u="",d="",f=false,l=new b({platform:s}),P=new b({platform:s}),h=Promise.resolve(),y=Promise.resolve(),w=setTimeout(()=>{f||(f=true,he(a),o(new Error(`Command timed out after ${n.timeoutMs??pe}ms: ${e} ${t.join(" ")}`)));},n.timeoutMs??pe);a.stdout?.on("data",g=>{h=h.then(async()=>{u+=await l.write(g);});}),a.stderr?.on("data",g=>{y=y.then(async()=>{d+=await P.write(g);});}),a.on("error",g=>{f||(f=true,clearTimeout(w),o(g));}),a.on("close",g=>{f||(async()=>{await Promise.all([h,y]);let[C,Be]=await Promise.all([l.end(),P.end()]);f||(u+=C,d+=Be,f=true,clearTimeout(w),r({code:g??0,stdout:u,stderr:d}));})().catch(C=>{f||(f=true,clearTimeout(w),o(C instanceof Error?C:new Error(String(C))));});});});function Ct(){try{return (typeof F=="function"?F:module$1.createRequire(__filename)).resolve("@crewx/sdk/package.json")}catch{return null}}function Rt(){let e=[Ct(),m.join(__dirname,"../../package.json"),m.join(__dirname,"../../../package.json")].filter(t=>!!t);for(let t of e)try{let n=JSON.parse(fs.readFileSync(t,"utf8"));if(n.name==="@crewx/sdk"&&n.version)return n.version}catch{}return "0.0.0"}var Pe=Rt();var E=m__namespace.win32;function H(e){return E.join(e,".crewx")}function Ee(e){return E.join(H(e),"shortcut.json")}function ye(e){return E.join(H(e),"launcher.json")}function Ce(e){return E.join(H(e),"bin","crewx-launcher.cmd")}function Re(e){return E.join(e,"CrewX.lnk")}function V(e,t){return E.normalize(e).toLowerCase()===E.normalize(t).toLowerCase()}var vt="[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [Environment]::GetFolderPath('DesktopDirectory')";async function ve(e){try{let n=await e.run("powershell",["-NoProfile","-NonInteractive","-Command",vt],{env:e.env}),r=n.stdout.trim();if(n.code===0&&r)return {dir:r,source:"known-folder"}}catch{}let t=e.env.USERPROFILE||e.env.Userprofile||e.homedir();return t?{dir:E.join(t,"Desktop"),source:"fallback"}:null}function X(e,t){let n=E.resolve(t,"node_modules",".bin").toLowerCase();return e.split(";").filter(r=>r?E.resolve(r).toLowerCase()!==n:true).join(";")}function _e(e){return e?/\\Program Files( \(x86\))?\\/i.test(e)&&/crewx/i.test(e):false}function _t(e,t){let n=a=>{let[u,...d]=a.split("-"),f=d.join("-")||void 0;return {parts:(u??"").split(".").map(P=>Number.parseInt(P,10)||0),pre:f}},r=n(e),o=n(t),c=Math.max(r.parts.length,o.parts.length);for(let a=0;a<c;a++){let u=r.parts[a]??0,d=o.parts[a]??0;if(u!==d)return u<d?-1:1}if(r.pre===o.pre)return 0;if(!r.pre&&o.pre)return 1;if(r.pre&&!o.pre)return -1;let s=Number.parseInt(r.pre.match(/(\d+)$/)?.[1]??"",10),i=Number.parseInt(o.pre.match(/(\d+)$/)?.[1]??"",10);return !Number.isNaN(s)&&!Number.isNaN(i)&&s!==i?s<i?-1:1:r.pre<o.pre?-1:r.pre>o.pre?1:0}function k(e,t){return _t(e,t)<0}var ke=m__namespace.win32,Ne=1;function xe(e,t){if(!e.existsSync(t))return null;try{let n=JSON.parse(e.readFileSync(t));return {schema:n.schema??Ne,shortcutPath:n.shortcutPath,version:n.version,iconHash:typeof n.iconHash=="string"?n.iconHash:void 0,owned:!!n.owned,declined:!!n.declined,desktopSource:n.desktopSource,updatedAt:n.updatedAt}}catch{return null}}function W(e,t,n){let r={schema:Ne,...n,updatedAt:new Date().toISOString()};e.mkdirSync(ke.dirname(t)),e.writeFileSync(t,JSON.stringify(r,null,2));}function M(e,t){if(!e.existsSync(t))return null;try{let n=JSON.parse(e.readFileSync(t));return {schema:n.schema??0,binPath:n.binPath,updatedAt:n.updatedAt}}catch{return null}}function Ie(e,t,n){e.mkdirSync(ke.dirname(t)),e.writeFileSync(t,JSON.stringify(n,null,2));}var bt=m__namespace.win32,N=1;function kt(e){return e.replace(/%/g,"%%")}function Nt(e){return ["@echo off","setlocal DisableDelayedExpansion","chcp 65001 >nul","",'set "CREWX_WORKDIR=%USERPROFILE%\\crewx"','if not exist "%CREWX_WORKDIR%" mkdir "%CREWX_WORKDIR%" >nul 2>nul','cd /d "%CREWX_WORKDIR%"',"",'set "CREWX_PORT_EFFECTIVE=%CREWX_PORT%"','if "%CREWX_PORT_EFFECTIVE%"=="" set "CREWX_PORT_EFFECTIVE=8150"','set "CREWX_HEALTH_URL=http://127.0.0.1:%CREWX_PORT_EFFECTIVE%/api/v1/health"','set "CREWX_ORIGIN_URL=http://127.0.0.1:%CREWX_PORT_EFFECTIVE%/"',"",e.bakedBinPath?`set "CREWX_FALLBACK_BIN=${kt(e.bakedBinPath)}"`:'set "CREWX_FALLBACK_BIN="','set "CREWX_RESOLVED_BIN=%CREWX_BIN%"','if "%CREWX_RESOLVED_BIN%"=="" set "CREWX_RESOLVED_BIN=%CREWX_FALLBACK_BIN%"','if "%CREWX_RESOLVED_BIN%"=="" (',` for /f "delims=" %%I in ('where crewx 2^>nul') do (`,' if not defined CREWX_RESOLVED_BIN set "CREWX_RESOLVED_BIN=%%I"'," )",")","",'powershell -NoProfile -NonInteractive -Command "try { $r = Invoke-WebRequest -Uri $env:CREWX_HEALTH_URL -TimeoutSec 1 -UseBasicParsing; if ($r.StatusCode -eq 200) { exit 0 } else { exit 1 } } catch { exit 1 }"',"if %ERRORLEVEL% EQU 0 (",' start "" "%CREWX_ORIGIN_URL%"'," exit /b 0",")","",'if "%CREWX_RESOLVED_BIN%"=="" ('," echo CrewX executable not found. Please reinstall the desktop shortcut."," pause"," exit /b 1",")","",'start "CrewX" /min "%CREWX_RESOLVED_BIN%"',""].join(`\r
|
|
2
|
+
`)}function Le(e){let t=M(e.fs,e.launcherManifestPath),n=!!t&&t.schema>=N&&e.fs.existsSync(e.wrapperPath),r=n&&!t.binPath&&!!e.bakedBinPath;if(n&&!r)return {wrapperPath:e.wrapperPath,wrote:false,schema:t.schema};let c=Nt({bakedBinPath:e.bakedBinPath});try{e.fs.mkdirSync(bt.dirname(e.wrapperPath)),e.fs.writeFileSync(e.wrapperPath,c),Ie(e.fs,e.launcherManifestPath,{schema:N,binPath:e.bakedBinPath,updatedAt:new Date().toISOString()});}catch(s){throw s instanceof p?s:new p("WRITE_DENIED",`Could not write launcher wrapper: ${s instanceof Error?s.message:String(s)}`)}return {wrapperPath:e.wrapperPath,wrote:true,schema:N}}var xt=["$ws = New-Object -ComObject WScript.Shell","$sc = $ws.CreateShortcut($env:CREWX_LNK_PATH)","$sc.TargetPath = $env:CREWX_LNK_TARGET","if ($env:CREWX_LNK_WORKDIR) { $sc.WorkingDirectory = $env:CREWX_LNK_WORKDIR }","$sc.WindowStyle = 7","if ($env:CREWX_LNK_ICON) { $sc.IconLocation = $env:CREWX_LNK_ICON }","$sc.Save()"].join("; "),It=["[Console]::OutputEncoding = [System.Text.Encoding]::UTF8","$ws = New-Object -ComObject WScript.Shell","$sc = $ws.CreateShortcut($env:CREWX_LNK_PATH)","[PSCustomObject]@{ TargetPath = $sc.TargetPath; WorkingDirectory = $sc.WorkingDirectory; IconLocation = $sc.IconLocation } | ConvertTo-Json -Compress"].join("; ");async function Te(e){let t={...e.env,CREWX_LNK_PATH:e.shortcutPath,CREWX_LNK_TARGET:e.targetPath,CREWX_LNK_WORKDIR:e.workingDirectory??"",CREWX_LNK_ICON:e.iconPath??""},n;try{n=await e.run("powershell",["-NoProfile","-NonInteractive","-Command",xt],{env:t});}catch(r){throw new p("POWERSHELL_UNAVAILABLE",`Could not run PowerShell: ${r instanceof Error?r.message:String(r)}`)}if(n.code!==0)throw new p("POWERSHELL_UNAVAILABLE",`Failed to create desktop shortcut: ${n.stderr||n.stdout}`)}function De(e){let t=e.trim(),n=t.lastIndexOf(",");return n!==-1&&/^-?\d+$/.test(t.slice(n+1).trim())&&(t=t.slice(0,n).trim()),t.length>=2&&t.startsWith('"')&&t.endsWith('"')&&(t=t.slice(1,-1).trim()),t}async function Ae(e){try{let t={...e.env,CREWX_LNK_PATH:e.shortcutPath},n=await e.run("powershell",["-NoProfile","-NonInteractive","-Command",It],{env:t});if(n.code!==0||!n.stdout.trim())return null;let r=JSON.parse(n.stdout.trim());return {targetPath:r.TargetPath??"",workingDirectory:r.WorkingDirectory??"",iconLocation:r.IconLocation??""}}catch{return null}}var J=m__namespace.win32;async function x(e){let t=X(e.env.PATH??e.env.Path??"",e.cwd),n={...e.env,PATH:t,Path:t},r;try{r=await e.run("npm",["list","-g","crewx","--depth=0","--json"],{env:n});}catch{return {installed:false}}let o;try{o=JSON.parse(r.stdout||"{}");}catch{return {installed:false}}let c=o.dependencies?.crewx;if(!c?.version)return {installed:false};let s;try{let a=await e.run("npm",["prefix","-g"],{env:n});a.code===0&&(s=a.stdout.trim()||void 0);}catch{}let i=s?J.join(s,"crewx.cmd"):void 0;return {installed:true,version:c.version,binPath:i,prefix:s}}var Ot=/EACCES|EPERM|EROFS/,Lt=/ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network|registry/i,Tt=/^\d+\.\d+\.\d+/;function Dt(e){return !!e&&e!=="0.0.0"&&Tt.test(e)}var K=10*6e4;async function Me(e){if(!Dt(e.targetVersion))throw new p("GLOBAL_INSTALL_FAILED",`RUNNING_VERSION_UNKNOWN: cannot reliably determine the running crewx version to install (got ${JSON.stringify(e.targetVersion)}); refusing to fall back to crewx@latest`);if(e.currentInfo?.installed&&e.currentInfo.version&&!k(e.currentInfo.version,e.targetVersion))return {info:e.currentInfo};let t=X(e.env.PATH??e.env.Path??"",e.cwd),n={...e.env,PATH:t,Path:t},r=`crewx@${e.targetVersion}`;e.onProgress?.({phase:"global-install",message:`Installing crewx globally (npm install -g ${r})`});let o;try{o=await e.run("npm",["install","-g",r,"--no-audit","--no-fund"],{env:n,timeoutMs:K});}catch(s){throw new p("NPM_UNAVAILABLE",`Could not run npm: ${s instanceof Error?s.message:String(s)}`)}if(o.code===0)return {info:await x({env:n,cwd:e.cwd,run:e.run})};let c=`${o.stdout}
|
|
3
|
+
${o.stderr}`;if(Ot.test(c)){e.onProgress?.({phase:"global-install",message:"Permission denied \u2014 retrying with a user-scoped npm prefix"});let s=e.env.LOCALAPPDATA||J.join(e.env.USERPROFILE??"","AppData","Local"),i={...n,npm_config_prefix:J.join(s,"crewx","npm")},a;try{a=await e.run("npm",["install","-g",r,"--no-audit","--no-fund"],{env:i,timeoutMs:K});}catch(u){throw new p("NPM_PERMISSION_DENIED",`Retry with user-scoped prefix failed: ${u instanceof Error?u.message:String(u)}`)}if(a.code===0)return {info:await x({env:i,cwd:e.cwd,run:e.run})};throw new p("NPM_PERMISSION_DENIED",`npm install -g failed after user-scoped prefix retry: ${a.stderr||a.stdout}`)}if(Lt.test(c)){if(!e.installRoot)throw new p("OFFLINE_NO_SOURCE","The npm registry is unreachable and no local installRoot was provided for an offline install");e.onProgress?.({phase:"global-install",message:`Registry unreachable \u2014 installing offline from ${e.installRoot}`});let s;try{s=await e.run("npm",["install","-g",e.installRoot,"--offline","--no-audit","--no-fund"],{env:n,timeoutMs:K});}catch(i){throw new p("GLOBAL_INSTALL_FAILED",`Offline install failed: ${i instanceof Error?i.message:String(i)}`)}if(s.code===0)return {info:await x({env:n,cwd:e.cwd,run:e.run})};throw new p("GLOBAL_INSTALL_FAILED",`Offline install failed: ${s.stderr||s.stdout}`)}throw new p("GLOBAL_INSTALL_FAILED",c.trim()||`npm install -g ${r} failed`)}function Wt(e){return e.run??we}function Mt(e){return e.fs??q}async function G(e){let t=e.platform??process.platform,n=e.env??process.env,r=e.homedir??Y,o=Wt(e),c=Mt(e),s=e.runningVersion??Pe,i=e.cwd??process.cwd(),a=r(),u=Ee(a),d=ye(a),f=Ce(a),l=null;t==="win32"&&(l=await ve({env:n,homedir:r,run:o}));let P=l?Re(l.dir):null;return {platform:t,env:n,homedir:r,run:o,fs:c,runningVersion:s,cwd:i,installRoot:e.installRoot,shortcutManifestPath:u,launcherManifestPath:d,wrapperPath:f,desktop:l,shortcutPath:P}}function Ge(e){return e?m__namespace.win32.normalize(e).toLowerCase().endsWith(`${m__namespace.win32.sep}bin${m__namespace.win32.sep}crewx.ico`):false}function j(e,t){let n=e.readBinaryFileSync;if(n)try{return crypto.createHash("sha256").update(n(t)).digest("hex")}catch{return}}async function Gt(e){try{await e.run("ie4uinit.exe",["-show"],{env:e.env});}catch{}}async function R(e){if(e.platform!=="win32")return {supported:false,state:"unsupported",globalCrewx:null,runningVersion:e.runningVersion,errors:[],manifest:null,iconStale:false};let t=[];e.desktop||t.push("NO_DESKTOP_DIR: could not resolve the Windows Desktop directory");let n=xe(e.fs,e.shortcutManifestPath),r=M(e.fs,e.launcherManifestPath),o=await x({env:e.env,cwd:e.cwd,run:e.run}),c=e.shortcutPath?e.fs.existsSync(e.shortcutPath):false,s,i=false,a,u;if(!c)s=n?.declined?"declined":"not-installed";else {let d=!!n?.owned&&!!e.shortcutPath&&n.shortcutPath===e.shortcutPath,f=false,l=e.shortcutPath?await Ae({run:e.run,env:e.env,shortcutPath:e.shortcutPath}):null;if(d||(l&&V(l.targetPath,e.wrapperPath)?d=true:l&&_e(l.targetPath)&&(f=true)),f)s="foreign",t.push("NSIS_PRESENT: an NSIS-installed CrewX shortcut was detected");else if(!d)s="foreign";else if(n?.version&&k(e.runningVersion,n.version))s="superseded",t.push(`SUPERSEDED: running version ${e.runningVersion} is older than the installed shortcut's version ${n.version}; refusing to modify it`);else {let P=!r||r.schema<N||!e.fs.existsSync(e.wrapperPath);if(l){let h=De(l.iconLocation);if(!(!!h&&e.fs.existsSync(h)))i=true;else {a=h;let w=Fe(o,e.fs);w?V(h,w)?(u=j(e.fs,h),i=!u||n?.iconHash!==u):i=true:Ge(h)?(u=j(e.fs,h),i=!u||n?.iconHash!==u):i=true;}}s=P||i?"stale":"installed";}}return {supported:true,state:s,shortcutPath:e.shortcutPath??void 0,desktopDir:e.desktop?.dir,desktopSource:e.desktop?.source,wrapperPath:e.wrapperPath,wrapperSchema:r?.schema,globalCrewx:o.installed?o:{installed:false},runningVersion:e.runningVersion,errors:t,manifest:n,iconStale:i,iconPath:a,iconHash:u}}function Fe(e,t){if(!e?.installed||!e.prefix)return;let n=m__namespace.win32.join(e.prefix,"node_modules","crewx","bin","crewx.ico");return t.existsSync(n)?n:void 0}function v(e){let{manifest:t,iconStale:n,iconPath:r,iconHash:o,...c}=e;return c}async function Ft(e={}){let t=await G(e),n=await R(t);return v(n)}async function Bt(e={}){let t=await G(e);e.onProgress?.({phase:"detect",message:"Checking current shortcut status"});let n=await R(t),r=v(n);if(!r.supported)return {...r,changed:false,installedGlobal:false};if(r.state==="superseded")return {...r,changed:false,installedGlobal:false};if(r.state==="foreign"){if(n.errors.some(w=>w.startsWith("NSIS_PRESENT")))throw new p("NSIS_PRESENT",`An NSIS-installed CrewX shortcut was detected at ${r.shortcutPath}`);if(!e.force)throw new p("FOREIGN_SHORTCUT",`An existing shortcut at ${r.shortcutPath} is not managed by CrewX`)}if(!t.desktop||!t.shortcutPath)throw new p("NO_DESKTOP_DIR","Could not resolve the Windows Desktop directory");let o=false,c=false,s=r.globalCrewx,i=[],a=n.manifest?.iconHash,u=false;if(!!s?.installed&&!!s.version&&k(s.version,t.runningVersion)||!s?.installed&&r.state!=="installed"){let w=await Me({env:t.env,cwd:t.cwd,run:t.run,targetVersion:t.runningVersion,currentInfo:s??void 0,installRoot:t.installRoot,onProgress:e.onProgress});s=w.info,c=w.info.installed,o=true,c||i.push(`GLOBAL_INSTALL_UNCONFIRMED: npm install -g crewx@${t.runningVersion} exited successfully but a follow-up check could not confirm the global install`);}if(e.onProgress?.({phase:"wrapper",message:"Ensuring launcher wrapper"}),Le({fs:t.fs,wrapperPath:t.wrapperPath,launcherManifestPath:t.launcherManifestPath,bakedBinPath:s?.binPath}).wrote&&(o=true),!((r.state==="installed"||r.state==="stale")&&!n.iconStale)){let w=Fe(s,t.fs)??(n.iconPath&&Ge(n.iconPath)&&t.fs.existsSync(n.iconPath)?n.iconPath:void 0);if(n.iconStale&&!w)throw new p("ICON_UNAVAILABLE",`Could not locate the global CrewX icon (bin\\crewx.ico) to repair the desktop shortcut at ${t.shortcutPath}; the existing shortcut was left untouched`);e.onProgress?.({phase:"lnk",message:"Creating desktop shortcut"}),await Te({run:t.run,env:t.env,shortcutPath:t.shortcutPath,targetPath:t.wrapperPath,iconPath:w}),o=true,u=n.iconStale;let g=w?j(t.fs,w):void 0;g&&(a=g);}o&&W(t.fs,t.shortcutManifestPath,{shortcutPath:t.shortcutPath,version:t.runningVersion,owned:true,declined:false,desktopSource:t.desktop.source,iconHash:a}),u&&await Gt(t);let h=await R(t),y=v(h);return {...y,errors:[...y.errors,...i],changed:o,installedGlobal:c}}async function $t(e={}){let t=await G(e),n=await R(t),r=v(n);if(!r.supported)return r;if((r.state==="installed"||r.state==="stale")&&t.shortcutPath)try{t.fs.unlinkSync(t.shortcutPath);}catch{}W(t.fs,t.shortcutManifestPath,{shortcutPath:void 0,version:n.manifest?.version,owned:false,declined:true,desktopSource:void 0,iconHash:void 0});let o=await R(t);return v(o)}async function Ut(e={}){let t=await G(e),n=await R(t),r=v(n);if(!r.supported)return r;W(t.fs,t.shortcutManifestPath,{shortcutPath:n.manifest?.shortcutPath,version:n.manifest?.version,owned:n.manifest?.owned??false,declined:true,desktopSource:n.manifest?.desktopSource,iconHash:n.manifest?.iconHash});let o=await R(t);return v(o)}exports.ShortcutError=p;exports.dismissShortcutNotice=Ut;exports.getShortcutStatus=Ft;exports.installShortcut=Bt;exports.killProcessTree=he;exports.uninstallShortcut=$t;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type InstallShortcutOptions, type ShortcutEnvOptions, type ShortcutInstallResult, type ShortcutStatus } from './types';
|
|
2
|
+
export declare function getShortcutStatus(options?: ShortcutEnvOptions): Promise<ShortcutStatus>;
|
|
3
|
+
export declare function installShortcut(options?: InstallShortcutOptions): Promise<ShortcutInstallResult>;
|
|
4
|
+
export declare function uninstallShortcut(options?: ShortcutEnvOptions): Promise<ShortcutStatus>;
|
|
5
|
+
export declare function dismissShortcutNotice(options?: ShortcutEnvOptions): Promise<ShortcutStatus>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CommandRunner } from './types';
|
|
2
|
+
export interface WriteLnkOptions {
|
|
3
|
+
run: CommandRunner;
|
|
4
|
+
env: NodeJS.ProcessEnv;
|
|
5
|
+
shortcutPath: string;
|
|
6
|
+
targetPath: string;
|
|
7
|
+
workingDirectory?: string;
|
|
8
|
+
iconPath?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function writeLnk(opts: WriteLnkOptions): Promise<void>;
|
|
11
|
+
export interface LnkInfo {
|
|
12
|
+
targetPath: string;
|
|
13
|
+
workingDirectory: string;
|
|
14
|
+
iconLocation: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ReadLnkOptions {
|
|
17
|
+
run: CommandRunner;
|
|
18
|
+
env: NodeJS.ProcessEnv;
|
|
19
|
+
shortcutPath: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function normalizeIconLocation(raw: string): string;
|
|
22
|
+
export declare function readLnkTarget(opts: ReadLnkOptions): Promise<LnkInfo | null>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { DesktopSource, ShortcutFsLike } from './types';
|
|
2
|
+
export declare const MANIFEST_SCHEMA_VERSION = 1;
|
|
3
|
+
export interface ShortcutManifest {
|
|
4
|
+
schema: number;
|
|
5
|
+
shortcutPath?: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
iconHash?: string;
|
|
8
|
+
owned: boolean;
|
|
9
|
+
declined: boolean;
|
|
10
|
+
desktopSource?: DesktopSource;
|
|
11
|
+
updatedAt?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface LauncherManifest {
|
|
14
|
+
schema: number;
|
|
15
|
+
binPath?: string;
|
|
16
|
+
updatedAt?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function readShortcutManifest(fs: ShortcutFsLike, manifestPath: string): ShortcutManifest | null;
|
|
19
|
+
export declare function writeShortcutManifest(fs: ShortcutFsLike, manifestPath: string, data: Omit<ShortcutManifest, 'schema' | 'updatedAt'>): void;
|
|
20
|
+
export declare function readLauncherManifest(fs: ShortcutFsLike, manifestPath: string): LauncherManifest | null;
|
|
21
|
+
export declare function writeLauncherManifest(fs: ShortcutFsLike, manifestPath: string, data: LauncherManifest): void;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type ShortcutState = 'unsupported' | 'not-installed' | 'installed' | 'stale' | 'foreign' | 'superseded' | 'declined';
|
|
2
|
+
export type DesktopSource = 'known-folder' | 'fallback';
|
|
3
|
+
export interface GlobalCrewxInfo {
|
|
4
|
+
installed: boolean;
|
|
5
|
+
version?: string;
|
|
6
|
+
binPath?: string;
|
|
7
|
+
prefix?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ShortcutStatus {
|
|
10
|
+
supported: boolean;
|
|
11
|
+
state: ShortcutState;
|
|
12
|
+
shortcutPath?: string;
|
|
13
|
+
desktopDir?: string;
|
|
14
|
+
desktopSource?: DesktopSource;
|
|
15
|
+
wrapperPath?: string;
|
|
16
|
+
wrapperSchema?: number;
|
|
17
|
+
globalCrewx: GlobalCrewxInfo | null;
|
|
18
|
+
runningVersion: string;
|
|
19
|
+
errors: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface ShortcutInstallResult extends ShortcutStatus {
|
|
22
|
+
changed: boolean;
|
|
23
|
+
installedGlobal: boolean;
|
|
24
|
+
}
|
|
25
|
+
export type ShortcutProgressPhase = 'detect' | 'global-install' | 'wrapper' | 'lnk';
|
|
26
|
+
export interface ShortcutProgressEvent {
|
|
27
|
+
phase: ShortcutProgressPhase;
|
|
28
|
+
message: string;
|
|
29
|
+
}
|
|
30
|
+
export interface CommandResult {
|
|
31
|
+
code: number;
|
|
32
|
+
stdout: string;
|
|
33
|
+
stderr: string;
|
|
34
|
+
}
|
|
35
|
+
export interface CommandRunOptions {
|
|
36
|
+
env?: NodeJS.ProcessEnv;
|
|
37
|
+
cwd?: string;
|
|
38
|
+
timeoutMs?: number;
|
|
39
|
+
}
|
|
40
|
+
export type CommandRunner = (command: string, args: string[], opts?: CommandRunOptions) => Promise<CommandResult>;
|
|
41
|
+
export interface ShortcutFsLike {
|
|
42
|
+
existsSync(path: string): boolean;
|
|
43
|
+
readFileSync(path: string): string;
|
|
44
|
+
readBinaryFileSync?: (path: string) => Uint8Array;
|
|
45
|
+
writeFileSync(path: string, data: string): void;
|
|
46
|
+
mkdirSync(path: string): void;
|
|
47
|
+
unlinkSync(path: string): void;
|
|
48
|
+
}
|
|
49
|
+
export interface ShortcutEnvOptions {
|
|
50
|
+
platform?: NodeJS.Platform;
|
|
51
|
+
env?: NodeJS.ProcessEnv;
|
|
52
|
+
homedir?: () => string;
|
|
53
|
+
run?: CommandRunner;
|
|
54
|
+
fs?: ShortcutFsLike;
|
|
55
|
+
runningVersion?: string;
|
|
56
|
+
cwd?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface InstallShortcutOptions extends ShortcutEnvOptions {
|
|
59
|
+
force?: boolean;
|
|
60
|
+
onProgress?: (event: ShortcutProgressEvent) => void;
|
|
61
|
+
installRoot?: string;
|
|
62
|
+
}
|
|
63
|
+
export type ShortcutErrorCode = 'NOT_WINDOWS' | 'NO_DESKTOP_DIR' | 'NPM_UNAVAILABLE' | 'NPM_PERMISSION_DENIED' | 'OFFLINE_NO_SOURCE' | 'GLOBAL_INSTALL_FAILED' | 'POWERSHELL_UNAVAILABLE' | 'WRITE_DENIED' | 'FOREIGN_SHORTCUT' | 'NSIS_PRESENT' | 'ICON_UNAVAILABLE';
|
|
64
|
+
export declare class ShortcutError extends Error {
|
|
65
|
+
readonly code: ShortcutErrorCode;
|
|
66
|
+
constructor(code: ShortcutErrorCode, message: string);
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SDK_VERSION: string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CommandRunner, DesktopSource } from './types';
|
|
2
|
+
export declare function crewxHomeDir(homedir: string): string;
|
|
3
|
+
export declare function shortcutManifestPath(homedir: string): string;
|
|
4
|
+
export declare function launcherManifestPath(homedir: string): string;
|
|
5
|
+
export declare function wrapperPath(homedir: string): string;
|
|
6
|
+
export declare function shortcutLnkPath(desktopDir: string): string;
|
|
7
|
+
export declare function samePath(a: string, b: string): boolean;
|
|
8
|
+
export interface ResolveDesktopDirOptions {
|
|
9
|
+
env: NodeJS.ProcessEnv;
|
|
10
|
+
homedir: () => string;
|
|
11
|
+
run: CommandRunner;
|
|
12
|
+
}
|
|
13
|
+
export interface ResolvedDesktopDir {
|
|
14
|
+
dir: string;
|
|
15
|
+
source: DesktopSource;
|
|
16
|
+
}
|
|
17
|
+
export declare function resolveDesktopDir(opts: ResolveDesktopDirOptions): Promise<ResolvedDesktopDir | null>;
|
|
18
|
+
export declare function filterWorkspaceLocalBin(pathValue: string, cwd: string): string;
|
|
19
|
+
export declare function looksLikeNsisInstall(targetPath: string): boolean;
|
|
20
|
+
export declare function compareVersions(a: string, b: string): -1 | 0 | 1;
|
|
21
|
+
export declare function isOlderVersion(a: string, b: string): boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ShortcutFsLike } from './types';
|
|
2
|
+
export declare const WRAPPER_SCHEMA_VERSION = 1;
|
|
3
|
+
export interface BuildWrapperScriptOptions {
|
|
4
|
+
bakedBinPath?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function buildWrapperScript(opts: BuildWrapperScriptOptions): string;
|
|
7
|
+
export interface EnsureWrapperOptions {
|
|
8
|
+
fs: ShortcutFsLike;
|
|
9
|
+
wrapperPath: string;
|
|
10
|
+
launcherManifestPath: string;
|
|
11
|
+
bakedBinPath?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface EnsureWrapperResult {
|
|
14
|
+
wrapperPath: string;
|
|
15
|
+
wrote: boolean;
|
|
16
|
+
schema: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function ensureWrapper(opts: EnsureWrapperOptions): EnsureWrapperResult;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {parse}from'dotenv';import*as Y from'fs';import {readFileSync,existsSync,mkdirSync,writeFileSync,chmodSync,renameSync,unlinkSync}from'fs';import*as C from'path';import {join,dirname}from'path';import*as z from'os';import {randomUUID}from'crypto';var s=class extends Error{code;kind;status;constructor(e,n,r,o){super(o??`Account authentication request failed (${e})`),this.name="AccountAuthError",this.code=e,this.kind=n,this.status=r;}};var l=class extends Error{code="LOGIN_REQUIRED";constructor(){super("Login required \u2014 please log in again"),this.name="LoginRequiredError";}},f=class extends Error{code;constructor(e,n){super(n),this.name="SessionManagerError",this.code=e;}},p=class extends Error{code;constructor(e,n="auth.json is invalid \u2014 please log in again"){super(n),this.name="AuthJsonValidationError",this.code=e;}},i=class extends s{constructor(e){let n=e.startsWith("ACCOUNT_BASE_URL")?"CREWX_ACCOUNT_BASE_URL":e.startsWith("ACCOUNT_ISSUER")?"CREWX_ACCOUNT_ISSUER":e==="ACCOUNT_TARGET_INVALID"?"CREWX_TARGET":e==="ACCOUNT_TARGET_MIXED"?"CREWX_ACCOUNT_BASE_URL/CREWX_MARKETPLACE_URL":e==="MARKETPLACE_DISABLED"?"CREWX_MARKETPLACE_DISABLED":"CREWX_MARKETPLACE_URL",r=e==="ACCOUNT_TARGET_MIXED"?`${n} must not mix loopback and public hosts \u2014 choose one account target`:e==="MARKETPLACE_DISABLED"?`${n} disables Marketplace access`:`${n} is missing or invalid \u2014 configure it and try again`;super(e,"configuration",void 0,r),this.name="AccountConfigurationError";}};var O="CREWX_ACCOUNT_BASE_URL",I="CREWX_ACCOUNT_ISSUER",x="CREWX_MARKETPLACE_URL",L="CREWX_TARGET",X="CREWX_MARKETPLACE_DISABLED",R=Object.freeze({accountBaseUrl:"https://app.sowonai.com",marketplaceUrl:"https://market.sowonai.com"}),k=Object.freeze({accountBaseUrl:"http://127.0.0.1:3030",marketplaceUrl:"http://127.0.0.1:4000"}),D=Object.freeze(["https://app.sowonai.com/auth/v1","https://auth.sowonai.com/auth/v1"]);function P(t,e,n=false){let r=t?.trim();if(!r)throw new i(e);try{let o=new URL(r);if(o.protocol!=="http:"&&o.protocol!=="https:"||o.username.length>0||o.password.length>0||o.hostname.length===0||o.search.length>0||o.hash.length>0||n&&o.pathname!=="/")throw new Error("invalid URL")}catch{throw new i(e)}return r.replace(/\/+$/,"")}function q(t){let e=t?.trim();if(!e)throw new i("ACCOUNT_ISSUER_INVALID");try{let n=new URL(e);if(n.protocol!=="http:"&&n.protocol!=="https:"||n.username.length>0||n.password.length>0||n.hostname.length===0||n.search.length>0||n.hash.length>0)throw new Error("invalid issuer")}catch{throw new i("ACCOUNT_ISSUER_INVALID")}return e}function b(t){let e=t[L];if(e===void 0)return "production";let n=e.trim();if(n==="local"||n==="production")return n;throw new i("ACCOUNT_TARGET_INVALID")}function F(t){let e=t[X]?.trim().toLowerCase();return e==="1"||e==="true"}function V(t){return t==="local"?k:R}function J(t=process.env){let e=b(t),n=t[O];return n!==void 0?P(n,"ACCOUNT_BASE_URL_INVALID",true):V(e).accountBaseUrl}function de(t=process.env){let e=b(t);if(F(t))throw new i("MARKETPLACE_DISABLED");let n=t[x];return n!==void 0?P(n,"MARKETPLACE_URL_INVALID"):V(e).marketplaceUrl}function U(t=process.env){let e=t[I];return e===void 0?D:[q(e)]}function Ae(t=process.env){return U(t)[0]}function W(t,e,n,r=false){if(t===void 0)return e;try{return P(t,n,r)}catch{return t.trim()}}function _e(t){let e=t[I];if(e===void 0)return D;try{return [q(e)]}catch{return [e.trim()]}}function j(t){if(t===null)return false;try{let e=new URL(t).hostname.toLowerCase();return e==="127.0.0.1"||e==="localhost"||e==="[::1]"||e==="::1"}catch{return false}}function ge(t,e){return e!==null&&t===R.accountBaseUrl&&e===R.marketplaceUrl?"production":e!==null&&t===k.accountBaseUrl&&e===k.marketplaceUrl?"local":"custom"}function $(t=process.env){let e,n=true;try{e=b(t);}catch{e="production",n=false;}let r=V(e),o=t[L]!==void 0&&n,c=t[O],T=t[x],u=F(t),d=W(c,r.accountBaseUrl,"ACCOUNT_BASE_URL_INVALID",true),y=u?null:W(T,r.marketplaceUrl,"MARKETPLACE_URL_INVALID");return {accountBaseUrl:d,marketplaceUrl:y,issuers:_e(t),profile:ge(d,y),sources:{accountBaseUrl:c===void 0?o?"profile":"default":"env",marketplaceUrl:u?"disabled":T===void 0?o?"profile":"default":"env",issuer:t[I]===void 0?"default":"env"},mixed:y!==null&&j(d)!==j(y),marketplaceDisabled:u}}function Ee(t=process.env){if($(t).mixed)throw new i("ACCOUNT_TARGET_MIXED")}function M(t,e){return `${t.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`}function v(){if(process.env.CREWX_HOME){let t=C.resolve(process.env.CREWX_HOME);try{return Y.realpathSync(t)}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return t;throw e}}return process.platform!=="win32"&&process.env.XDG_CONFIG_HOME?C.join(process.env.XDG_CONFIG_HOME,"crewx"):C.join(z.homedir(),".crewx")}var te="CREWX_TASK_TICKET_SECRET";function ne(t={}){let e=t.workspaceDir??process.env.CREWX_WORKSPACE??process.cwd(),n=t.homeDir??v();return {workspace:join(e,".env"),home:join(n,".env")}}function me(t){try{return new Set(Object.keys(parse(readFileSync(t))))}catch(e){if(e?.code==="ENOENT")return new Set;throw e}}function Te(t){try{return parse(readFileSync(t))}catch(e){if(e?.code==="ENOENT")return {};throw e}}function Ce(t={}){let e=ne(t);for(let n of [e.workspace,e.home]){let r=Te(n);for(let[o,c]of Object.entries(r))o===te||process.env[o]!==void 0||(process.env[o]=c);}}var ie="auth.json",H=2,se=["version","sub","email","access_token","refresh_token","expires_at","updated_at"];function h(t="auth.json is invalid \u2014 please log in again"){throw new p("AUTH_JSON_INVALID",t)}function ve(){throw new p("AUTH_JSON_LEGACY","auth.json uses an unsupported legacy format \u2014 please log in again")}function Ne(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Oe(t){try{return E(t),!0}catch{return false}}function E(t){if(!Ne(t))return h();if(t.version===1)return ve();if(t.version!==H)return h();let e=Object.keys(t);if(e.length!==se.length||e.some(r=>!se.includes(r))||typeof t.sub!="string"||t.sub.length===0||typeof t.email!="string"||t.email.length===0||typeof t.access_token!="string"||t.access_token.length===0||typeof t.refresh_token!="string"||t.refresh_token.length===0)return h();let n=t.expires_at;return typeof n!="number"||!Number.isSafeInteger(n)||n<0||typeof t.updated_at!="string"||t.updated_at.length===0||Number.isNaN(Date.parse(t.updated_at))?h():{version:H,sub:t.sub,email:t.email,access_token:t.access_token,refresh_token:t.refresh_token,expires_at:n,updated_at:t.updated_at}}function ce(t){let e;try{e=JSON.parse(t);}catch{return h()}return E(e)}function ae(t){return t??join(v(),ie)}var A=class{configuredPath;constructor(e={}){this.configuredPath=typeof e=="string"?e:e.filePath;}path(){return ae(this.configuredPath)}read(){let e=this.path();if(!existsSync(e))return null;try{return ce(readFileSync(e,"utf8"))}catch(n){throw n instanceof p?n:new p("AUTH_JSON_INVALID")}}write(e){let n=E(e),r=this.path(),o=dirname(r);mkdirSync(o,{recursive:true,mode:448});let c=`${r}.tmp.${process.pid}.${randomUUID()}`;try{writeFileSync(c,JSON.stringify(n,null,2),{encoding:"utf8",mode:384}),chmodSync(c,384),renameSync(c,r),chmodSync(r,384);}catch{try{existsSync(c)&&unlinkSync(c);}catch{}throw new Error("Could not persist auth.json securely")}}clear(){let e=this.path();try{existsSync(e)&&unlinkSync(e);}catch{throw new Error("Could not clear auth.json")}}};function xe(t){let e=new A({filePath:t}).read();if(!e)throw new l;return e}function Le(t,e){new A({filePath:e}).write(t);}function De(t){new A({filePath:t}).clear();}var pe="/auth/v1/oauth/device/code",he="/auth/v1/oauth/token",le="/auth/v1/oauth/revoke",N="crewx-cli",m="urn:ietf:params:oauth:grant-type:device_code";function a(t){return typeof t=="string"&&t.trim().length>0}function w(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}function Pe(t){let e=w(t),n=e?.error??e?.code;if(typeof n=="string")return n.toLowerCase();let r=w(n),o=r?.code??r?.error;return typeof o=="string"?o.toLowerCase():void 0}function be(t){let e=w(t);if(!e||!a(e.device_code)||!a(e.user_code)||!a(e.verification_uri))throw new s("AUTH_RESPONSE_INVALID","protocol");let n=e.expires_in,r=e.interval;if(typeof n!="number"||!Number.isSafeInteger(n)||n<=0)throw new s("AUTH_RESPONSE_INVALID","protocol");if(e.verification_uri_complete!==void 0&&!a(e.verification_uri_complete))throw new s("AUTH_RESPONSE_INVALID","protocol");if(r!==void 0&&(typeof r!="number"||!Number.isSafeInteger(r)||r<0))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={device_code:e.device_code,user_code:e.user_code,verification_uri:e.verification_uri,expires_in:n};return e.verification_uri_complete!==void 0&&(o.verification_uri_complete=e.verification_uri_complete),r!==void 0&&(o.interval=r),o}function Ve(t){let e=w(t),n=w(e?.account),r=e?.expires_in;if(!e||!a(e.access_token)||!a(e.refresh_token)||typeof r!="number"||!Number.isSafeInteger(r)||r<=0||!n||!a(n.sub)||!a(n.email))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={access_token:e.access_token,refresh_token:e.refresh_token,expires_in:r,account:{sub:n.sub,email:n.email}};return typeof e.token_type=="string"&&e.token_type.length>0&&(o.token_type=e.token_type),typeof e.scope=="string"&&e.scope.length>0&&(o.scope=e.scope),o}var S=class{configuredBaseUrl;fetchImpl;timeoutMs;constructor(e={}){let n=typeof e=="string"?{baseUrl:e}:e;this.configuredBaseUrl=n.baseUrl===void 0?void 0:Je(n.baseUrl),this.fetchImpl=n.fetch??n.fetchImpl,this.timeoutMs=n.timeoutMs??1e4;}baseUrl(){return this.configuredBaseUrl!==void 0?this.configuredBaseUrl:J()}signal(e){if(!(e<=0||typeof AbortSignal>"u"||typeof AbortSignal.timeout!="function"))return AbortSignal.timeout(e)}async request(e,n,r,o={}){let c=M(this.baseUrl(),e),T=this.fetchImpl??globalThis.fetch;if(typeof T!="function")throw new s("AUTH_NETWORK_ERROR","network");let u;try{u=await T(c,{...n,signal:n.signal??this.signal(o.timeoutMs??this.timeoutMs)});}catch{throw new s("AUTH_NETWORK_ERROR","network")}if(o.parseBody===false){if(!u.ok)throw ue(u.status,null,r);return}let d=null;try{d=await u.json();}catch{d=null;}if(!u.ok)throw ue(u.status,d,r);return d}async requestDeviceCode(){let e=new URLSearchParams;e.set("client_id",N);let n=await this.request(pe,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:e.toString()});return be(n)}async requestToken(e){Me(e);let n=new URLSearchParams;n.set("grant_type",e.grant_type),n.set("client_id",N),e.grant_type===m?n.set("device_code",e.device_code):n.set("refresh_token",e.refresh_token);let r=await this.request(he,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},e);return Ve(r)}async exchangeDeviceCode(e){return this.requestToken({grant_type:m,device_code:e})}async refreshToken(e){return this.requestToken({grant_type:"refresh_token",refresh_token:e})}async deviceCode(){return this.requestDeviceCode()}async getDeviceCode(){return this.requestDeviceCode()}async token(e){return this.requestToken(e)}async getToken(e){return this.requestToken(e)}async refresh(e){return this.refreshToken(e)}async refreshAccessToken(e){return this.refreshToken(e)}async revokeToken(e){if(!a(e))throw new s("AUTH_INPUT_INVALID","protocol");let n=new URLSearchParams;n.set("token",e),n.set("token_type_hint","refresh_token"),n.set("client_id",N),await this.request(le,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},void 0,{parseBody:false,timeoutMs:3e3});}async revoke(e){return this.revokeToken(e)}};function Je(t){if(typeof t!="string"||!t.trim())throw new i("ACCOUNT_BASE_URL_INVALID");try{let e=new URL(t.trim());if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username.length>0||e.password.length>0||e.hostname.length===0||e.pathname!=="/"||e.search.length>0||e.hash.length>0)throw new Error("invalid URL")}catch{throw new i("ACCOUNT_BASE_URL_INVALID")}return t.trim().replace(/\/+$/,"")}function Me(t){if(!t||t.grant_type!==m&&t.grant_type!=="refresh_token"||t.grant_type===m&&!a(t.device_code)||t.grant_type==="refresh_token"&&!a(t.refresh_token))throw new s("AUTH_INPUT_INVALID","protocol")}function ue(t,e,n){let r=Pe(e);if(t>=500)return new s("AUTH_SERVER_ERROR","server",t);if(n?.grant_type==="refresh_token"&&(r==="invalid_grant"||t===401))return new s("INVALID_REFRESH_TOKEN","invalid_refresh",t);if(n?.grant_type===m){if(r==="authorization_pending")return new s("AUTHORIZATION_PENDING","pending",t);if(r==="slow_down")return new s("SLOW_DOWN","pending",t);if(r==="access_denied")return new s("ACCESS_DENIED","denied",t);if(r==="expired_token")return new s("EXPIRED_TOKEN","expired",t)}return new s("AUTH_HTTP_ERROR","http",t)}var G=class{client;store;refreshSkewSeconds;now;nowSecondsOverride;refreshPromise=null;constructor(e={},n){let r=He(e)?e:void 0,o=r?{}:e;this.client=r??o.client??o.authClient??new S,this.store=o.store??o.storage??n??new A,this.refreshSkewSeconds=o.refreshSkewSeconds??60,this.now=o.now??(()=>Date.now()),this.nowSecondsOverride=o.nowSeconds;}getSession(){return this.readSession()}isLoggedIn(){return this.readSession()!==null}async getAccessToken(){let e=this.requireSession();return e.expires_at>this.epochSeconds()+this.refreshSkewSeconds?e.access_token:(await this.refreshSession(e)).access_token}async getValidAccessToken(){return this.getAccessToken()}async getToken(){return this.getAccessToken()}async refresh(){return this.refreshSession(this.requireSession())}async loginWithDeviceCode(e){let n=await this.client.exchangeDeviceCode(e);return this.persistTokenResponse(n)}async login(e){return this.loginWithDeviceCode(e)}async setSession(e){return this.persistTokenResponse(e)}clear(){this.store.clear();}async withAccessToken(e){return e(await this.getAccessToken())}readSession(){try{let e=this.store.read();if(e===null)return null;let n=E(e);return fe(n.access_token,n.sub),n}catch(e){throw e instanceof p?new l:e}}requireSession(){let e=this.readSession();if(!e)throw new l;return e}epochSeconds(){return this.nowSecondsOverride?.()??Math.floor(this.now()/1e3)}refreshSession(e){if(this.refreshPromise)return this.refreshPromise;let n;return n=this.performRefresh(e).finally(()=>{this.refreshPromise===n&&(this.refreshPromise=null);}),this.refreshPromise=n,n}async performRefresh(e){try{let n=await this.client.refreshToken(e.refresh_token);return this.persistTokenResponse(n,e.sub)}catch(n){throw Be(n)?(this.store.clear(),new l):n}}persistTokenResponse(e,n){let r=e?.account;if(!e||typeof e.access_token!="string"||e.access_token.length===0||typeof e.refresh_token!="string"||e.refresh_token.length===0||!Number.isSafeInteger(e.expires_in)||e.expires_in<=0||!r||typeof r.sub!="string"||r.sub.length===0||typeof r.email!="string"||r.email.length===0)throw new f("AUTH_RESPONSE_INVALID","Account token response is malformed");if(n!==void 0&&r.sub!==n)throw new f("ACCOUNT_SUB_MISMATCH","Account subject changed during token refresh \u2014 please log in again");fe(e.access_token,r.sub);let o=E({version:2,sub:r.sub,email:r.email,access_token:e.access_token,refresh_token:e.refresh_token,expires_at:this.epochSeconds()+e.expires_in,updated_at:new Date(this.now()).toISOString()});return this.store.write(o),o}};function Be(t){return t instanceof s?t.kind==="invalid_refresh":typeof t=="object"&&t!==null&&(t.kind==="invalid_refresh"||t.code==="INVALID_REFRESH_TOKEN")}function He(t){return typeof t.exchangeDeviceCode=="function"&&typeof t.refreshToken=="function"}function fe(t,e){let n=U(),r=Ke(t);if(!n.includes(r.iss))throw new f("ACCOUNT_ISSUER_MISMATCH","Access token issuer does not match the configured account issuer \u2014 please log in again");if(r.sub!==e)throw new f("ACCOUNT_SUB_MISMATCH","Access token subject does not match the account session \u2014 please log in again")}function Ke(t){if(typeof t!="string")throw K();let e=t.split(".");if(e.length!==3||e.some(n=>!/^[A-Za-z0-9_-]+$/.test(n)))throw K();try{let n=JSON.parse(Buffer.from(e[1],"base64url").toString("utf8"));if(typeof n!="object"||n===null||Array.isArray(n)||typeof n.iss!="string"||n.iss.length===0||typeof n.sub!="string"||n.sub.length===0)throw new Error("missing identity claims");return {iss:n.iss,sub:n.sub}}catch{throw K()}}function K(){return new f("ACCESS_TOKEN_INVALID","Access token identity could not be verified \u2014 please log in again")}
|
|
2
|
+
export{O as ACCOUNT_BASE_URL_ENV,I as ACCOUNT_ISSUER_ENV,L as ACCOUNT_TARGET_ENV,ie as AUTH_JSON_FILENAME,H as AUTH_JSON_VERSION,s as AccountAuthError,i as AccountConfigurationError,S as AuthClient,s as AuthClientError,s as AuthError,A as AuthJsonStore,p as AuthJsonValidationError,te as CREWX_TASK_TICKET_SECRET_ENV,D as DEFAULT_ACCEPTED_ISSUERS,m as DEVICE_CODE_GRANT_TYPE,pe as DEVICE_CODE_PATH,k as LOCAL_TARGET,l as LoginRequiredError,X as MARKETPLACE_DISABLED_ENV,x as MARKETPLACE_URL_ENV,N as OAUTH_CLIENT_ID,R as PRODUCTION_TARGET,le as REVOKE_PATH,G as SessionManager,f as SessionManagerError,he as TOKEN_PATH,M as appendEndpoint,Ee as assertAccountTargetNotMixed,ae as authJsonPath,De as clearAuthJson,Oe as isAuthJsonV2,Ce as loadCrewxEnvFiles,ce as parseAuthJson,xe as readAuthJson,me as readCrewxEnvFileKeys,U as resolveAcceptedAccountIssuers,J as resolveAccountBaseUrl,Ae as resolveAccountIssuer,$ as resolveAccountTarget,ne as resolveCrewxEnvFilePaths,de as resolveMarketplaceUrl,E as validateAuthJson,Le as writeAuthJson};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {promises,realpath,realpathSync,constants,readSync}from'fs';import {join,dirname,basename,relative,sep,isAbsolute,resolve}from'path';import {promisify,format,inspect}from'util';import {execFile}from'child_process';import {randomUUID,createHash}from'crypto';import {homedir}from'os';import {Socket}from'net';import {Console}from'console';import {Writable}from'stream';var v=["text/plain","application/json"];var z=[5,15,30,60],j=Object.freeze({min:15e3,max:6e5,default:3e5}),It=1,ve="schedule:",Tt="schedule",Ct="exit 78",Sn=["standby","disabled","draining","degraded"],kt=["cron","cron_manual","app_enable"],Jt=/^[A-Z][A-Z0-9_]{0,63}$/u;function Rn(n){return typeof n=="string"&&Jt.test(n)}var wn=["status","everyMinutes","lastStartedAt","lastFinishedAt","lastOutcome","lastErrorCode","nextRunAt","periodic","periodicReason"],Nt=["unset","on","off"],Dt=["available","unavailable"],Le=64,xt=128;function Pn(n){return z.includes(n)}function je(n){return Number.isSafeInteger(n)&&n>=j.min&&n<=j.max}function In(n){return Sn.includes(n)}function Tn(n){if(!Ft(n)||Object.keys(n).length!==wn.length||!wn.every(r=>Object.hasOwn(n,r))||typeof n.status!="string"||!Nt.includes(n.status)||!Pn(n.everyMinutes)||!de(n.lastStartedAt,Le)||!de(n.lastFinishedAt,Le)||!de(n.lastOutcome,xt)||!de(n.nextRunAt,Le)||n.lastErrorCode!==null&&!Rn(n.lastErrorCode)||typeof n.periodic!="string"||!Dt.includes(n.periodic))return;let t=n.periodic;if(!(t==="available"?n.periodicReason!==null:!In(n.periodicReason))&&!(n.nextRunAt!==null&&(n.status!=="on"||t!=="available")))return Object.freeze({status:n.status,everyMinutes:n.everyMinutes,lastStartedAt:n.lastStartedAt,lastFinishedAt:n.lastFinishedAt,lastOutcome:n.lastOutcome,lastErrorCode:n.lastErrorCode,nextRunAt:n.nextRunAt,periodic:t,periodicReason:n.periodicReason})}function de(n,e){return n===null||typeof n=="string"&&n.length>0&&n.length<=e}function Ft(n){if(n===null||typeof n!="object"||Array.isArray(n))return false;let e=Object.getPrototypeOf(n);return e===Object.prototype||e===null}var M=Object.freeze({min:6e4,max:18e5,default:6e5}),Lt=Object.freeze({min:1e3,max:12e4,default:3e4}),vt=1,Cn="crewx/appJobs",kn=1,Me=["starting","running","stopping","finished"],Be=["succeeded","failed","timed_out","cancelled","shutdown","interrupted"],ue=["cancelled","timed_out","shutdown"],Ue=["manual","schedule"],jt=/^[a-z][a-z0-9_]{0,63}$/u,Mt=/^[A-Z][A-Z0-9_]{0,63}$/u,le=["start","status","cancel"],He=["APP_JOB_NOT_DECLARED","APP_JOB_NOT_AUTHORIZED","APP_JOB_SELF_START","APP_JOB_OWNER_INVALID","APP_JOB_DEFINITION_INVALID","APP_JOB_DEFINITION_CHANGED","APP_JOB_DEADLINE_INVALID","APP_JOB_SHUTTING_DOWN","APP_JOB_OWNER_MISMATCH","APP_JOB_STALE_HANDLE","APP_JOB_NOT_ACTIVE","APP_JOB_NOT_GRANTED"],qe="APP_JOB_RUN_REQUIRED";function Ve(n){return Number.isSafeInteger(n)&&n>=M.min&&n<=M.max}function B(n){return typeof n=="string"&&Mt.test(n)}function U(n){return typeof n=="string"&&jt.test(n)}function $(n){return le.includes(n)}function Bt(n){return n?.some(({name:e,version:t})=>e===Cn&&t===kn)===true}var Jn=Symbol;Jn.metadata===void 0&&Object.defineProperty(Symbol,"metadata",{configurable:false,value:Symbol.for("Symbol.metadata")});var Ut=Jn.metadata,K=Symbol.for("crewx.app.tool-metadata"),f=class extends Error{code;detail;outcome;constructor(e,t=null,r){super(e),this.name="AppError",this.code=e,this.detail=t,this.outcome=Ge(r?.outcome);}};function Ge(n){return n==="rejected"?"rejected":"failed"}var Xe=class{static devtools=process.env.CREWX_APP_DEV==="1"?Object.freeze({log:true}):void 0;currentState;stateWasSet=false;answerBody;answerRange;callContext;callSchedule;callJobs;callJobRun;scheduleDirective;workspaceRoot;constructor(e={workspaceRoot:process.cwd()}){this.currentState=e.state??{},this.workspaceRoot=e.workspaceRoot,this.callContext=e.context===void 0?void 0:zt(e.context),this.callSchedule=e.schedule===void 0?void 0:Object.freeze({...e.schedule}),this.callJobs=e.jobs,this.callJobRun=e.jobRun;}get jobs(){return this.callJobs}get jobRun(){return this.callJobRun}get schedule(){return this.callSchedule}requestSchedule(e){if(typeof e!="boolean")throw new TypeError("requestSchedule needs true or false");if(this.callSchedule===void 0)throw new f("SCHEDULE_UNSUPPORTED","this App has no schedule on this Host");let t=this.callContext?.actor;if(t==="schedule")throw new f("SCHEDULE_UNSUPPORTED","a scheduled run cannot change its own schedule",{outcome:"rejected"});if(e&&t!=="user")throw new f("SCHEDULE_ENABLE_DENIED","only the person at the screen can turn a schedule on",{outcome:"rejected"});this.scheduleDirective=Object.freeze({enabled:e});}get didRequestSchedule(){return this.scheduleDirective}get context(){if(this.callContext===void 0)throw new TypeError("this.context is only set when the Host runs the action; pass options.context when you construct the App in a test");return this.callContext}get state(){return this.currentState}get didSetState(){return this.stateWasSet}setState(e){this.currentState=e,this.stateWasSet=true;}get didSetContent(){return this.answerBody!==void 0}get producedContent(){return this.answerBody===void 0?void 0:{body:this.answerBody,...this.answerRange===void 0?{}:{range:this.answerRange}}}setContent(e,t){if(typeof e!="string"&&!(e instanceof Uint8Array))throw new TypeError("setContent needs a string or a Uint8Array");if(t!==void 0&&!Kt(t))throw new TypeError("setContent range must be { startLine, lineCount, totalLines }, three integers of at least 1");this.answerBody=typeof e=="string"?new TextEncoder().encode(e):new Uint8Array(e),this.answerRange=t===void 0?void 0:{startLine:t.startLine,lineCount:t.lineCount,totalLines:t.totalLines};}emptyState(){return {}}validate(e,t,r){}mapError(e){return {code:"EXECUTION_FAILED",detail:null}}errorState(e,t,r){return {...w(r.state)?r.state:{},error:{code:e,detail:t}}}};function Ht(n){return function(e,t){if(t.static||t.private||t.kind!=="method")throw new TypeError("@Tool can decorate public instance methods only");let r=t.metadata;if(!r)throw new TypeError("standard decorator metadata is unavailable");let o=Object.hasOwn(r,K)?r[K]:[];if(o.some(p=>p.methodName===String(t.name)))throw new TypeError(`@Tool is declared more than once for ${String(t.name)}`);let i=n.content===void 0?void 0:Vt(n.name,n.content),s=n.schedule===void 0?void 0:Xt(n);if(s!==void 0&&o.some(p=>p.options.schedule!==void 0))throw new TypeError(`@Tool ${n.name}: an App declares at most one scheduled action`);let a=n.job===void 0?void 0:Gt(n);if(a!==void 0&&o.some(p=>p.options.job!==void 0))throw new TypeError(`@Tool ${n.name}: an App declares at most one job action`);let d=n.jobAccess===void 0?void 0:Wt(n);r[K]=[...o,{methodName:String(t.name),options:Object.freeze({...n,...i===void 0?{}:{content:i},...s===void 0?{}:{schedule:s},...a===void 0?{}:{job:a},...d===void 0?{}:{jobAccess:d}})}];}}function Y(n){let e=n[Ut],t=e&&Object.hasOwn(e,K)?e[K]:[],r=new Map(t.map(i=>[i.methodName,i])),o=Object.getOwnPropertyNames(n.prototype).map(i=>r.get(i)).filter(i=>i!==void 0);if(o.length!==t.length)throw new TypeError("a @Tool method is missing from the App prototype");return o}function Nn(n){return Y(n).some(({options:e})=>e.schedule!==void 0)}function Dn(n){let e=n.definition,t=Y(n),r=new Set;return t.map(({options:o})=>{if(r.has(o.name))throw new TypeError(`duplicate @Tool name: ${o.name}`);return r.add(o.name),{actionId:o.name,...o.dataInputs===void 0?{}:{dataInputs:[...o.dataInputs]},confirmation:o.confirmation??"none",capability:o.capability??"app.read",mutation:o.mutation??true,inputSchema:o.inputSchema,...o.content===void 0?{}:{content:$t(o.content)},...o.schedule===void 0?{}:{schedule:{...o.schedule}},...o.job===void 0?{}:{job:{...o.job}},...o.jobAccess===void 0?{}:{jobAccess:[...o.jobAccess]},resultProjection:o.resultProjection??{allow:[...e.stateProjection.allow]},_meta:{description:o.description}}})}function qt(n,e){if(e.length===0)throw new TypeError("backendCommand must name the skill command");let t=Dn(n).map(({_meta:r,...o})=>({...o,backend:{type:"skill",command:[...e]},_meta:r}));return {...n.definition,actions:t}}function Vt(n,e){let t=i=>{throw new TypeError(`@Tool ${n}: content ${i}`)},r=(i,s,a)=>{if(!w(a))return t(`${i} must be an object`);for(let d of Object.keys(a))if(d==="mediaType"){if(!v.includes(a[d]))return t(`${i}.mediaType must be one of ${v.join(", ")}`)}else if(d===s){if(typeof a[d]!="boolean")return t(`${i}.${d} must be true or false`)}else return t(`${i} has the unknown key "${d}"`);return Object.hasOwn(a,"mediaType")?Object.freeze({...a}):t(`${i}.mediaType is required`)};if(!w(e))return t("must be an object");let o={};for(let i of Object.keys(e))if(i==="in")o[i]=r("in","required",e[i]);else if(i==="out")o[i]=r("out","range",e[i]);else return t(`has the unknown key "${i}"; use "in" and/or "out"`);return Object.keys(o).length===0?t('needs "in" and/or "out"'):Object.freeze(o)}function Xt(n){let e=r=>{throw new TypeError(`@Tool ${n.name}: schedule ${r}`)},t=n.schedule;if(!w(t))return e("must be an object");for(let r of Object.keys(t))if(r!=="everyMinutes"&&r!=="timeoutMs")return e(`has the unknown key "${r}"`);return z.includes(t.everyMinutes)?t.timeoutMs!==void 0&&!je(t.timeoutMs)?e(`timeoutMs must be an integer from ${j.min} to ${j.max}`):n.content!==void 0?e("cannot be combined with content"):n.dataInputs!==void 0?e("cannot be combined with dataInputs"):n.confirmation!==void 0&&n.confirmation!=="none"?e("cannot require a native confirmation"):Object.freeze({everyMinutes:t.everyMinutes,...t.timeoutMs===void 0?{}:{timeoutMs:t.timeoutMs}}):e(`everyMinutes must be one of ${z.join(", ")}`)}function Gt(n){let e=r=>{throw new TypeError(`@Tool ${n.name}: job ${r}`)},t=n.job;if(!w(t))return e("must be an object");for(let r of Object.keys(t))if(r!=="deadlineMs")return e(`has the unknown key "${r}"`);return t.deadlineMs!==void 0&&!Ve(t.deadlineMs)?e(`deadlineMs must be an integer from ${M.min} to ${M.max}`):n.content!==void 0?e("cannot be combined with content"):n.dataInputs!==void 0?e("cannot be combined with dataInputs"):n.confirmation!==void 0&&n.confirmation!=="none"?e("cannot require a native confirmation"):n.schedule!==void 0?e("cannot be the scheduled action too"):n.jobAccess!==void 0?e("cannot also be a control action: a run does not control itself"):Object.freeze({...t.deadlineMs===void 0?{}:{deadlineMs:t.deadlineMs}})}function Wt(n){let e=r=>{throw new TypeError(`@Tool ${n.name}: jobAccess ${r}`)},t=n.jobAccess;return !Array.isArray(t)||t.length===0?e("must list at least one operation"):new Set(t).size!==t.length?e("must not repeat an operation"):t.every($)?n.job!==void 0?e("cannot be set on the job action, which runs the job and cannot control it"):n.content!==void 0?e("cannot be combined with content"):Object.freeze([...t]):e("names an unknown operation")}function zt(n){return Object.freeze({instanceId:n.instanceId,threadId:n.threadId,actor:n.actor,requestId:n.requestId,nowMs:n.nowMs})}function $t(n){let e={};for(let[t,r]of Object.entries(n))e[t]={...r};return e}function Kt(n){return w(n)&&["startLine","lineCount","totalLines"].every(e=>Number.isSafeInteger(n[e])&&n[e]>=1)}function w(n){if(n===null||typeof n!="object"||Array.isArray(n))return false;let e=Object.getPrototypeOf(n);return e===Object.prototype||e===null}var Yt=/^[A-Za-z0-9._:-]{1,128}$/u,Zt=/[\u0000-\u001f\u007f\u2028\u2029]/u,Qt=512;function We(n=process.env){let e=xn(n.CREWX_APP_INSTANCE_ID),t=n.CREWX_APP_REQUEST_ID,r=n.CREWX_APP_ACTOR_KIND,o=n.CREWX_APP_NOW_MS;if(e===void 0||typeof t!="string"||!Yt.test(t)||r!=="user"&&r!=="agent"&&r!=="schedule"||typeof o!="string"||!/^\d{1,16}$/u.test(o))return;let i=Number(o);if(!Number.isSafeInteger(i))return;let s=n.CREWX_THREAD_ID===void 0?null:xn(n.CREWX_THREAD_ID);if(s!==void 0&&!(r==="schedule"&&(s!==null||!e.startsWith(ve))))return Object.freeze({instanceId:e,threadId:s,actor:r,requestId:t,nowMs:i})}function xn(n){if(!(typeof n!="string"||n.length===0||Zt.test(n)))return new TextEncoder().encode(n).byteLength<=Qt?n:void 0}var er="dist/tools.json",nr=1,tr="dist/main.mjs";var Fn=["CREWX_APP_INSTANCE_ID","CREWX_THREAD_ID"];function rr(n){if(!Array.isArray(n)||n.length===0)return false;let e=new Set;for(let t of n){if(!Fn.some(r=>r===t)||e.has(t))return false;e.add(t);}return true}var Ln=["INVALID_REF","FILE_NOT_FOUND","DOCUMENT_CHANGED","TOO_LARGE","IO_ERROR","FILE_BUSY"],l=class extends Error{code;constructor(e){super(e),this.name="AppFilesError",this.code=e;}};var P={textBytes:256*1024,refCodePoints:200,refSegments:3,pageSize:200},H=/^[\p{L}\p{N}][\p{L}\p{N}\p{M}_-]{0,99}$/u,x=()=>{throw new l("INVALID_REF")};function Z(n){let e=n.normalize("NFC");if([...e].length>P.refCodePoints)return;let t=e.split("/");if(t.length>P.refSegments)return;let r=t[t.length-1];return r.endsWith(".md")&&[...t.slice(0,-1),r.slice(0,-3)].every(i=>H.test(i))?e:void 0}function pe(n){return typeof n!="string"?x():Z(n)??x()}function vn(n){if(n==null||n==="")return "";if(typeof n!="string")return x();let e=n.normalize("NFC");if([...e].length>P.refCodePoints)return x();let t=(e.endsWith("/")?e.slice(0,-1):e).split("/");return t.length>P.refSegments-1||!t.every(r=>H.test(r))?x():`${t.join("/")}/`}function jn(n){if(typeof n!="string")return x();if(Buffer.byteLength(n,"utf8")>P.textBytes)throw new l("TOO_LARGE");return n}function Mn(n){return n===null?null:typeof n=="string"&&n.length<=P.refCodePoints?n:x()}var ye=join("locks","files"),ne=12e3,{link:lr,mkdir:pr,open:cr,readFile:Ke,unlink:ee}=promises,fr=5,yr=50,Ar=1e3,mr=2e3,br="/bin/ps",gr={LC_ALL:"C",TZ:"UTC"},hr=100,_r=19,Er=/^[A-Za-z]{3} ([A-Za-z]{3}) +(\d{1,2}) (\d{2}):(\d{2}):(\d{2}) (\d{4})$/,Or=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],wr=promisify(execFile),Bn,ce;function Ye(n=process.env){if(n.CREWX_HOME){let e=resolve(n.CREWX_HOME);try{return realpathSync(e)}catch(t){if(t.code==="ENOENT")return e;throw t}}return process.platform!=="win32"&&n.XDG_CONFIG_HOME?join(n.XDG_CONFIG_HOME,"crewx"):join(homedir(),".crewx")}async function Ae(n){let{lockDir:e,key:t}=n,r=join(e,Sr(t)),o=Date.now()+n.waitMs,i=await qn(e,{token:randomUUID(),pid:process.pid,startedAtMs:await Xn()}),s=new ze;try{let a=fr;for(;;){if(await Vn(i.staged,r))return {path:r,token:i.record.token};let d=await fe(r);if(d!=="vanished"&&!(d!=="unreadable"&&await s.isDead(d)&&await Tr(e,r,d,s))){if(Date.now()>=o)throw new l("FILE_BUSY");await Dr(a),a=Math.min(a*2,yr);}}}finally{await ee(i.staged).catch(()=>{});}}async function me(n){await $e(n.path,n.token);}function Sr(n){return createHash("sha256").update(n,"utf8").digest("hex")}async function qn(n,e){let t=join(n,`.${e.token}.tmp`);try{await pr(n,{recursive:!0}),await Rr(t,JSON.stringify(e));}catch{throw await ee(t).catch(()=>{}),new l("IO_ERROR")}return {record:e,staged:t}}async function Rr(n,e){let t=await cr(n,"wx");try{await t.writeFile(e),await t.sync();}finally{await t.close();}}async function Vn(n,e){try{return await lr(n,e),!0}catch(t){if(t.code==="EEXIST")return false;throw new l("IO_ERROR")}}async function fe(n){let e;try{e=await Ke(n,"utf8");}catch(t){return t.code==="ENOENT"?"vanished":"unreadable"}try{let t=JSON.parse(e);return Pr(t)?t:"unreadable"}catch{return "unreadable"}}function Pr(n){if(typeof n!="object"||n===null||Array.isArray(n))return false;let e=n;return typeof e.token=="string"&&e.token.length>0&&typeof e.pid=="number"&&Number.isSafeInteger(e.pid)&&e.pid>0&&(e.startedAtMs===null||Number.isSafeInteger(e.startedAtMs))}async function Ir(n){try{process.kill(n.pid,0);}catch(t){return t.code==="ESRCH"}if(n.startedAtMs===null)return false;let e=await Gn(n.pid);return e!==null&&e!==n.startedAtMs}var ze=class{constructor(e=Ir,t=Date.now){this.check=e;this.now=t;}check;now;answers=new Map;async isDead(e){let t=this.now(),r=this.answers.get(e.token);if(r!==void 0&&t-r.at<Ar)return r.dead;let o=await this.check(e);return this.answers.set(e.token,{at:t,dead:o}),o}};async function Tr(n,e,t,r){let o=`${e}.reclaim`,i=await qn(n,{token:randomUUID(),pid:process.pid,startedAtMs:await Xn()});try{if(!await Vn(i.staged,o)){let s=await fe(o);return s!=="vanished"&&s!=="unreadable"&&await r.isDead(s)&&await $e(o,s.token),!1}try{let s=await fe(e);return typeof s!="object"||s.token!==t.token?!1:(await ee(e).catch(()=>{}),!0)}finally{await $e(o,i.record.token);}}finally{await ee(i.staged).catch(()=>{});}}async function $e(n,e){let t=await fe(n);typeof t=="object"&&t.token===e&&await ee(n).catch(()=>{});}function Xn(){return (ce===void 0||ce.pid!==process.pid)&&(ce={pid:process.pid,startedAtMs:Gn(process.pid)}),ce.startedAtMs}async function Gn(n){return process.platform==="linux"&&(Bn??=await promises.access("/proc/self/stat").then(()=>true,()=>false),Bn)?Cr(n):Jr(n)}async function Cr(n){try{let e=await Ke(`/proc/${n}/stat`,"utf8"),t=e.slice(e.lastIndexOf(")")+2).split(" "),r=Number(t[_r]),o=await kr();return !Number.isSafeInteger(r)||o===void 0?null:o*1e3+r*1e3/hr}catch{return null}}async function kr(){let n=(await Ke("/proc/stat","utf8")).split(`
|
|
2
|
+
`).find(t=>t.startsWith("btime ")),e=Number(n?.slice(6));return Number.isSafeInteger(e)?e:void 0}async function Jr(n){try{let{stdout:e}=await wr(br,["-o","lstart=","-p",String(n)],{env:gr,encoding:"utf8",timeout:mr});return Nr(e.trim())}catch{return null}}function Nr(n){let e=Er.exec(n);if(e===null)return null;let t=Or.indexOf(e[1]);return t<0?null:Date.UTC(Number(e[6]),t,Number(e[2]),Number(e[3]),Number(e[4]),Number(e[5]))}function Dr(n){return new Promise(e=>setTimeout(e,n))}var Lr=[".git",".crewx","node_modules","apps","skills"],{lstat:vr,readFile:jr}=promises,Mr=4,Br=200,Ur=1024*1024,Wn=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function Hr(n){return ["docs","apps",n]}function zn(n){let e={segments:Hr(n.appId),declared:false};if(n.origin!=="not_installed"||n.source!=="workspace"&&n.source!=="bundled"||n.declared===void 0||n.declared===null)return e;let t=qr(n.declared);return t.ok?n.packageRelativePath!==void 0&&Vr(t.segments,Xr(n.packageRelativePath))?{...e,warning:"FILES_ROOT_FORBIDDEN"}:{segments:t.segments,declared:true}:{...e,warning:t.warning}}async function $n(n){let e={appId:void 0,declared:void 0};try{let t=join(n,"manifest.json"),r=await vr(t);if(!r.isFile()||r.size>Ur)return e;let o=JSON.parse(await jr(t,"utf8"));if(!be(o))return e;let i=o.name,s=typeof i=="string"&&Wn.test(i)?i:void 0,a=o._meta,d=be(a)?a["dev.crewx"]:void 0,p=be(d)?d.files:void 0;return {appId:s,declared:p}}catch{return e}}function qr(n){return !be(n)||Object.keys(n).some(e=>e!=="root")||typeof n.root!="string"?{ok:false,warning:"FILES_ROOT_INVALID"}:Yn(n.root.normalize("NFC"),Kn)}function ge(n){if(n.normalize("NFC")!==n)return;let e=Yn(n,t=>Kn(t)||Wn.test(t));return e.ok?e.segments:void 0}function Kn(n){return H.test(n)}function Yn(n,e){let t={ok:false,warning:"FILES_ROOT_INVALID"},r={ok:false,warning:"FILES_ROOT_FORBIDDEN"};if([...n].length>Br)return t;let o=n.split("/");return o.length>Mr||!o.every(e)?t:o.length===1||Lr.includes(o[0].toLowerCase())?r:{ok:true,segments:o}}function Vr(n,e){let t=Math.min(n.length,e.length);for(let r=0;r<t;r+=1)if(n[r].toLowerCase()!==e[r].toLowerCase())return false;return t>0}function Xr(n){return n.normalize("NFC").split("/").filter(e=>e.length>0)}function be(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}var{lstat:Yr,mkdir:Zr,open:Qr,readdir:eo,rename:no,stat:to,unlink:tt}=promises;function he(n){return `sha256:${createHash("sha256").update(n).digest("hex")}`}function en(n,e){return e===n||e.startsWith(n.endsWith(sep)?n:n+sep)}var _e=class{constructor(e={},t){this.hooks=e;this.lockDir=t.lockDir,this.lockWaitMs=t.lockWaitMs??ne;}hooks;lockDir;lockWaitMs;async list(e,t,r){let o=t===""?[]:t.slice(0,-1).split("/"),i=await Ze(e.workspaceReal,[...e.segments,...o]);if(i.status!=="complete")return {items:[],next:null};let s=await Qn(e),a=await lo(s,i.dir,t);a.sort((y,u)=>et(y.ref,u.ref));let d=r===void 0?a:a.filter(y=>et(y.ref,r)>0),p=d.slice(0,P.pageSize),c=[];for(let y of p){let u=await this.readVerified(s,y.abs);c.push({ref:y.ref,version:he(u.bytes),bytes:u.bytes.length,modifiedAt:u.stat.mtime.toISOString()});}return {items:c,next:d.length>p.length?p[p.length-1].ref:null}}async read(e,t){let r=t.split("/"),o=await Ze(e.workspaceReal,[...e.segments,...r.slice(0,-1)]);if(o.status!=="complete")throw new l("FILE_NOT_FOUND");let i=await Qe(o.dir,r[r.length-1]);if(!i)throw new l("FILE_NOT_FOUND");if(!i.stat.isFile())throw new l("IO_ERROR");let{bytes:s}=await this.readVerified(await Qn(e),i.abs,P.textBytes);return {ref:t,text:Ao(s),version:he(s)}}async write(e,t,r,o){let i=t.split("/"),s=i[i.length-1],a=new Uint8Array(Buffer.from(r,"utf8"));return this.withFileLock(await io(e,t),async()=>{let d=await Ze(e.workspaceReal,[...e.segments,...i.slice(0,-1)]);if(d.status==="blocked")throw new l("IO_ERROR");let p=await Ee(d.dir),c=d.status==="complete"?await Qe(d.dir,s):void 0;if(c&&!c.stat.isFile())throw new l("IO_ERROR");if((c?he((await this.readVerified(p.real,c.abs)).bytes):null)!==o)throw new l("DOCUMENT_CHANGED");let u=await this.createFolders(p,d.status==="missing"?d.missing:[]);await oo(u,s);let b=c?.abs??join(u.path,s);return await this.writeAtomically(u,b,s,a,c?.stat),{ref:t,version:he(a)}})}async readVerified(e,t,r){return await this.hooks.beforeOpen?.(t),ao(e,t,r)}async createFolders(e,t){let r=e;for(let o of t){let i=join(r.path,o);await this.hooks.beforeMkdir?.(i);try{await Zr(i);}catch(s){if(s.code!=="EEXIST")throw new l("IO_ERROR")}r=await uo(r,i);}return r}async writeAtomically(e,t,r,o,i){let s=join(e.path,ro(r)),a;try{await this.hooks.beforeOpen?.(s),a=await rt(s,constants.O_CREAT|constants.O_EXCL|constants.O_WRONLY),await a.writeFile(o),i!==void 0&&await a.chmod(i.mode&4095),await a.sync(),await a.close(),a=void 0,await tn(e),await no(s,t);}catch(d){throw await a?.close().catch(()=>{}),await tt(s).catch(()=>{}),d instanceof l?d:new l("IO_ERROR")}}async withFileLock(e,t){let r=await Ae({lockDir:this.lockDir,key:e,waitMs:this.lockWaitMs});try{return await t()}finally{await me(r);}}};function ro(n){return `.${n}.crewx-${randomUUID()}.tmp`}async function oo(n,e){let t=`.${e}.crewx-`;for(let r of await on(n.path))r.normalize("NFC").startsWith(t)&&r.endsWith(".tmp")&&await tt(join(n.path,r)).catch(()=>{});}async function nn(n){return (await so(n)).normalize("NFC").toLowerCase()}async function io(n,e){return nn(join(n.workspaceReal,...n.segments,...e.split("/")))}async function so(n){let e=[],t=n;for(;;)try{return join(await ot(t),...e.reverse())}catch{let r=dirname(t);if(r===t)throw new l("IO_ERROR");e.push(basename(t)),t=r;}}async function ao(n,e,t){let r=await rt(e,constants.O_RDONLY);try{let o=await r.stat();if(!o.isFile())throw new l("IO_ERROR");if(t!==void 0&&o.size>t)throw new l("TOO_LARGE");let i=yo(await r.readFile());return await co(n,e,o),{bytes:i,stat:o}}finally{await r.close();}}async function Qn(n){let e=await rn(join(n.workspaceReal,...n.segments));if(!en(n.workspaceReal,e))throw new l("INVALID_REF");return e}async function Qe(n,e){let t=(await on(n)).filter(i=>i.normalize("NFC")===e);if(t.length>1)throw new l("IO_ERROR");let r=join(n,t[0]??e),o=await sn(r);if(o){if(o.isSymbolicLink())throw new l("INVALID_REF");return {abs:r,stat:o}}}async function Ze(n,e){let t=n;for(let r=0;r<e.length;r+=1){let o=await Qe(t,e[r]);if(!o)return {status:"missing",dir:t,missing:e.slice(r)};if(!o.stat.isDirectory())return {status:"blocked"};t=o.abs;}return {status:"complete",dir:t}}async function uo(n,e){await tn(n);let t=await Ee(e);if(dirname(t.real)!==n.real)throw new l("INVALID_REF");return t}async function lo(n,e,t){let r=[],o=s=>s===""?0:s.split("/").length-1,i=async(s,a)=>{let d=await po(n,s),p=await on(s);await tn(d);let c=new Set;for(let y of p){let u=y.normalize("NFC");if(c.has(u))throw new l("IO_ERROR");c.add(u);let b=join(s,y),A=await sn(b);if(!(!A||A.isSymbolicLink())){if(A.isDirectory())o(a)<P.refSegments-1&&H.test(u)&&await i(b,`${a}${u}/`);else if(A.isFile()){let m=Z(`${a}${u}`);m!==void 0&&r.push({ref:m,abs:b});}}}};return await i(e,t),r}function et(n,e){return n<e?-1:n>e?1:0}async function Ee(n){let e=await sn(n);if(e?.isSymbolicLink())throw new l("INVALID_REF");if(!e?.isDirectory())throw new l("IO_ERROR");return {path:n,real:await rn(n),dev:e.dev,ino:e.ino}}async function po(n,e){let t=await Ee(e);if(!en(n,t.real))throw new l("INVALID_REF");return t}async function tn(n){let e=await Ee(n.path);if(e.real!==n.real||e.dev!==n.dev||e.ino!==n.ino)throw new l("INVALID_REF")}async function co(n,e,t){let r=await rn(e);if(!en(n,r))throw new l("INVALID_REF");let o=await fo(r);if(o.dev!==t.dev||o.ino!==t.ino)throw new l("INVALID_REF")}async function rt(n,e){try{return await Qr(n,e|constants.O_NOFOLLOW)}catch(t){throw t.code==="ELOOP"?new l("INVALID_REF"):new l("IO_ERROR")}}async function rn(n){try{return await ot(n)}catch{throw new l("IO_ERROR")}}function ot(n){return new Promise((e,t)=>{realpath.native(n,(r,o)=>r?t(r):e(o));})}async function on(n){try{return await eo(n)}catch(e){let t=e.code;if(t==="ENOENT"||t==="ENOTDIR")return [];throw new l("IO_ERROR")}}async function sn(n){try{return await Yr(n)}catch(e){let t=e.code;if(t==="ENOENT"||t==="ENOTDIR")return;throw new l("IO_ERROR")}}async function fo(n){try{return await to(n)}catch{throw new l("IO_ERROR")}}function yo(n){return new Uint8Array(n.buffer,n.byteOffset,n.byteLength)}function Ao(n){try{return new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(n)}catch{throw new l("IO_ERROR")}}var st=promisify(realpath.native),at="CREWX_APP_FILES_ROOT";function Eo(n,e={}){return {async list(t={}){let r=vn(t.prefix),o=t.after===void 0||t.after===null?void 0:pe(t.after),i=await an(n,e);return dn(n,e).list(i,r,o)},async read(t){let r=pe(t),o=await an(n,e);return dn(n,e).read(o,r)},async write(t,r,o){let i=pe(t),s=jn(r),a=Mn(o),d=await an(n,e);return dn(n,e).write(d,i,s,a)}}}async function an(n,e){let t=await Ro(n.workspaceRoot),r=(e.env??process.env)[at]??e.filesRoot;if(r!==void 0)return {workspaceReal:t,segments:Oo(r)};let o=e.packageDir??process.cwd(),i=await $n(o);if(i.appId===void 0)throw new l("IO_ERROR");let s=zn({appId:i.appId,origin:e.origin??"not_installed",source:e.source??"workspace",packageRelativePath:await So(t,o),declared:i.declared});return {workspaceReal:t,segments:s.segments}}function Oo(n){let e=ge(n);if(e===void 0)throw new l("IO_ERROR");return e}function dn(n,e){let t=join(e.crewxHome??Ye(),ye);return new _e({},{lockDir:t,lockWaitMs:wo(n)})}function wo(n){let e;try{e=n.context?.nowMs;}catch{e=void 0;}return typeof e!="number"||!Number.isSafeInteger(e)?ne:Math.max(0,e+ne-Date.now())}async function So(n,e){let t;try{t=await st(e);}catch{return}let r=relative(n,t);if(!(r===""||r===".."||r.startsWith(`..${sep}`)||isAbsolute(r)))return r.split(sep).join("/")}async function Ro(n){try{return await st(n)}catch{throw new l("IO_ERROR")}}var Oe=2,we=2097152;var q=2*1024*1024,Se=2e4;function un(n){return createHash("sha256").update(n).digest("hex")}function Re(n){if(n.byteLength===0)return 0;let e=0;for(let t of n)t===10&&(e+=1);return n[n.byteLength-1]!==10&&(e+=1),e}var To=we+1+q,Co=64*1024,ko=10,Pe={kind:"invalid"};function Jo(n,e){try{let t=[],r=0;for(;;){let s=new Uint8Array(Co),a=readSync(n,s,0,s.length,null);if(a===0)break;if(r+=a,r>e)return;t.push(s.subarray(0,a));}let o=new Uint8Array(r),i=0;for(let s of t)o.set(s,i),i+=s.byteLength;return o}catch{return}}function Ie(n){return No(Jo(n,To))}function No(n){if(n===void 0)return Pe;let e=n.indexOf(ko);if(n.byteLength<=we){let r=jo(Buffer.from(n.buffer,n.byteOffset,n.byteLength).toString("utf8"));if(r.ok&&!(e>=0&&F(r.value)&&r.value.schemaVersion===Oe))return {kind:"v1",value:r.value}}if(e<=0||e>we)return Pe;let t;try{t=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(n.subarray(0,e)));}catch{return Pe}return !F(t)||t.schemaVersion!==Oe?Pe:{kind:"v2",header:t,body:n.subarray(e+1)}}var Do="actionId,content,input,schemaVersion,state",xo="bytes,lines,mediaType,sha256",Fo="mediaType,range",Lo=/^[a-f0-9]{64}$/u,vo=new TextDecoder("utf-8",{fatal:true,ignoreBOM:true});function lt(n,e){let t=d=>({code:d,outcome:"rejected"});if(re(n)!==Do||n.schemaVersion!==Oe||typeof n.actionId!="string"||!F(n.input)||!F(n.state)||!F(n.content)||re(n.content)!=="in,out")return {code:"INPUT_INVALID",outcome:"failed"};let r=n.content,o,i=r.in;if(i===null){if(e.byteLength!==0)return t(e.byteLength>q?"CONTENT_TOO_LARGE":"CONTENT_DIGEST_MISMATCH")}else {if(!F(i)||re(i)!==xo||!dt(i.mediaType)||!ut(i.bytes,q)||!ut(i.lines,Se)||typeof i.sha256!="string"||!Lo.test(i.sha256)||e.byteLength!==i.bytes)return t(e.byteLength>q?"CONTENT_TOO_LARGE":"CONTENT_DIGEST_MISMATCH");if(un(e)!==i.sha256||Re(e)!==i.lines)return t("CONTENT_DIGEST_MISMATCH");let d;try{d=vo.decode(e);}catch{return t("CONTENT_ENCODING_INVALID")}o={mediaType:i.mediaType,text:d};}let s,a=r.out;if(a!==null){if(!F(a)||re(a)!==Fo||!dt(a.mediaType))return t("CONTENT_SOURCE_UNSUPPORTED");let d=a.range;if(d!==null&&!Mo(d))return t("CONTENT_SOURCE_UNSUPPORTED");s={mediaType:a.mediaType,...d===null?{}:{range:{startLine:d.startLine,lineCount:d.lineCount}}};}return {actionId:n.actionId,input:n.input,state:n.state,content:{...o===void 0?{}:{in:o},...s===void 0?{}:{out:s}}}}function pt(n){return Object.hasOwn(n,"code")}function ct(n,e){let t=r=>({code:r,outcome:"rejected"});if(n?.in===void 0){if(e.in!==void 0)return t("CONTENT_SOURCE_UNSUPPORTED")}else if(e.in===void 0){if(n.in.required===true)return t("CONTENT_REQUIRED")}else if(e.in.mediaType!==n.in.mediaType)return t("CONTENT_SOURCE_UNSUPPORTED");if(n?.out===void 0){if(e.out!==void 0)return t("CONTENT_SOURCE_UNSUPPORTED")}else {if(e.out===void 0)return t("CONTENT_REQUIRED");if(e.out.mediaType!==n.out.mediaType||e.out.range!==void 0&&n.out.range!==true)return t("CONTENT_SOURCE_UNSUPPORTED")}}function Te(n,e){let{content:t,...r}=n,o=e===void 0?r:{...r,content:{bytes:e.body.byteLength,lines:Re(e.body),sha256:un(e.body),...e.range===void 0?{}:{range:e.range}}},i=new TextEncoder().encode(`${JSON.stringify(o)}
|
|
3
|
+
`);if(e===void 0)return i;let s=new Uint8Array(i.byteLength+e.body.byteLength);return s.set(i,0),s.set(e.body,i.byteLength),s}function ft(n){if(n.body.byteLength>q||Re(n.body)>Se)return {code:"CONTENT_TOO_LARGE",outcome:"failed"}}function jo(n){try{return {ok:!0,value:JSON.parse(n)}}catch{return {ok:false}}}function re(n){return Object.keys(n).sort().join(",")}function F(n){if(n===null||typeof n!="object"||Array.isArray(n))return false;let e=Object.getPrototypeOf(n);return e===Object.prototype||e===null}function dt(n){return typeof n=="string"&&v.includes(n)}function ut(n,e){return Number.isSafeInteger(n)&&n>=0&&n<=e}function Mo(n){return F(n)&&re(n)==="lineCount,startLine"&&Number.isSafeInteger(n.startLine)&&n.startLine>=1&&Number.isSafeInteger(n.lineCount)&&n.lineCount>=1&&n.lineCount<=Se}var At="CREWX_APP_JOB_CHANNEL",R=1,oe=4096,cn=1e4,fn=5e3,yn=512,ln=Object.freeze({min:3,max:16}),Bo=["APP_JOB_BRIDGE_UNAVAILABLE","APP_JOB_BRIDGE_INVALID","APP_JOB_BRIDGE_TIMEOUT","APP_JOB_BRIDGE_CLOSED"],se=/^[A-Za-z0-9._:-]{1,128}$/u,Uo=64,mt=2147483647,ie=class{#e="";#n=false;push(e){let t=[],r=e;for(;;){let o=r.indexOf(`
|
|
4
|
+
`);if(o===-1)return this.#n||(this.#e+=r,V(this.#e)>oe&&(t.push({kind:"oversized"}),this.#e="",this.#n=true)),t;let i=r.slice(0,o);if(r=r.slice(o+1),this.#n){this.#n=false;continue}let s=this.#e+i;this.#e="",t.push(V(s)>oe?{kind:"oversized"}:{kind:"line",line:s});}}};function Je(n){let e=JSON.stringify(n);if(V(e)>oe)throw new TypeError("App job bridge message is over the line bound");return e}function Ho(n){let e=Ne(n);if(e===void 0||e.v!==R||!bt(e.requestId)||!gt(e.seq))return;let t={v:R,requestId:e.requestId,seq:e.seq};switch(e.op){case "start":return O(e,["v","op","requestId","seq"],[])?{...t,op:"start"}:void 0;case "status":{if(!O(e,["v","op","requestId","seq"],["handle"]))return;if(e.handle===void 0)return {...t,op:"status"};let r=pn(e.handle);return r===void 0?void 0:{...t,op:"status",handle:r}}case "cancel":{if(!O(e,["v","op","requestId","seq","handle"],[]))return;let r=pn(e.handle);return r===void 0?void 0:{...t,op:"cancel",handle:r}}default:return}}function An(n){let e=Ne(n);if(e===void 0||e.v!==R||!bt(e.requestId)||!gt(e.seq))return;let t={v:R,requestId:e.requestId,seq:e.seq};if(e.ok===false)return O(e,["v","requestId","seq","ok","code"],[])&&He.includes(e.code)?{...t,ok:false,code:e.code}:void 0;if(e.ok===true)switch(e.op){case "start":{if(!O(e,["v","requestId","seq","ok","op","outcome","job"],[]))return;let r=Ce(e.job),o=e.outcome;return r===void 0||o!=="started"&&o!=="attached"?void 0:{...t,ok:true,op:"start",outcome:o,job:r}}case "status":{if(!O(e,["v","requestId","seq","ok","op","job"],[]))return;if(e.job===null)return {...t,ok:true,op:"status",job:null};let r=Ce(e.job);return r===void 0?void 0:{...t,ok:true,op:"status",job:r}}case "cancel":{if(!O(e,["v","requestId","seq","ok","op","outcome","job"],[]))return;let r=Ce(e.job);return r===void 0||e.outcome!=="stopping"?void 0:{...t,ok:true,op:"cancel",outcome:"stopping",job:r}}default:return}}function qo(n){let e=Ne(n);if(e===void 0||e.v!==R||typeof e.runId!="string"||!se.test(e.runId)||!xe(e.generation))return;let t={v:R,runId:e.runId,generation:e.generation};switch(e.kind){case "heartbeat":return O(e,["v","kind","runId","generation"],[])?{...t,kind:"heartbeat"}:void 0;case "completed":return O(e,["v","kind","runId","generation"],[])?{...t,kind:"completed"}:void 0;case "progress":{if(!O(e,["v","kind","runId","generation","phase"],["completed","total","resumable"]))return;let{completed:r,total:o,resumable:i}=e;return !U(e.phase)||r!==void 0&&!ke(r)||o!==void 0&&!ke(o)||r!==void 0&&o!==void 0&&r>o||i!==void 0&&typeof i!="boolean"?void 0:{...t,kind:"progress",phase:e.phase,...r===void 0?{}:{completed:r},...o===void 0?{}:{total:o},...i===void 0?{}:{resumable:i}}}case "failed":return O(e,["v","kind","runId","generation","code","recoverable"],[])&&B(e.code)&&typeof e.recoverable=="boolean"?{...t,kind:"failed",code:e.code,recoverable:e.recoverable}:void 0;default:return}}function mn(n){let e=Ne(n);if(!(e===void 0||!O(e,["v","kind","runId","generation","reason"],[])||e.v!==R||e.kind!=="stop"||typeof e.runId!="string"||!se.test(e.runId)||!xe(e.generation)||!ue.includes(e.reason)))return {v:R,kind:"stop",runId:e.runId,generation:e.generation,reason:e.reason}}function bn(n){let e=De(n)?n:void 0;if(!(e===void 0||e.v!==R||!Wo(e.fd))){if(e.role==="control"){let t=e.operations;return !O(e,["v","role","fd","operations"],[])||!Array.isArray(t)||t.length===0||new Set(t).size!==t.length||!t.every($)?void 0:{v:1,role:"control",fd:e.fd,operations:[...t]}}if(e.role==="run")return !O(e,["v","role","fd","runId","generation"],[])||typeof e.runId!="string"||!se.test(e.runId)||!xe(e.generation)?void 0:{v:1,role:"run",fd:e.fd,runId:e.runId,generation:e.generation}}}function gn(n){let e=n[At];if(typeof e!="string"||V(e)>yn)return;let t;try{t=JSON.parse(e);}catch{return}return bn(t)}function Vo(n){let e=bn(JSON.parse(JSON.stringify(n)));if(e===void 0)throw new TypeError("App job channel descriptor is invalid");let t=JSON.stringify(e);if(V(t)>yn)throw new TypeError("App job channel descriptor is over its bound");return Object.freeze({CREWX_APP_JOB_CHANNEL:t})}function Xo(n){return n==="schedule"?"schedule":"manual"}function Go(n){return Ce(n)}function Ce(n){let e=De(n)?n:void 0;if(e===void 0||!O(e,["handle","state","stopReason","trigger","outcome","phase","completed","total","resumable","lastHeartbeatAt","startedAt","finishedAt","errorCode","recoverable"],[]))return;let t=pn(e.handle),r=e.stopReason,o=e.outcome,i=e.phase,s=e.errorCode,a=e.recoverable;if(!(t===void 0||!Me.includes(e.state)||!(r===null||ue.includes(r))||r!==null&&e.state!=="stopping"||!Ue.includes(e.trigger)||!(o===null||Be.includes(o))||!(i===null||U(i))||!(e.completed===null||ke(e.completed))||!(e.total===null||ke(e.total))||typeof e.resumable!="boolean"||!yt(e.lastHeartbeatAt)||!ht(e.startedAt)||!yt(e.finishedAt)||!(s===null||B(s))||!(a===null||typeof a=="boolean")))return {handle:t,state:e.state,stopReason:r,trigger:e.trigger,outcome:o,phase:i,completed:e.completed,total:e.total,resumable:e.resumable,lastHeartbeatAt:e.lastHeartbeatAt,startedAt:e.startedAt,finishedAt:e.finishedAt,errorCode:s,recoverable:a}}function pn(n){if(!(!De(n)||!O(n,["runId","generation"],[]))&&!(typeof n.runId!="string"||!se.test(n.runId)||!xe(n.generation)))return {runId:n.runId,generation:n.generation}}function Ne(n){if(V(n)>oe)return;let e;try{e=JSON.parse(n);}catch{return}return De(e)?e:void 0}function O(n,e,t){let r=new Set([...e,...t]);return Object.keys(n).every(o=>r.has(o))&&e.every(o=>Object.hasOwn(n,o))}function De(n){if(n===null||typeof n!="object"||Array.isArray(n))return false;let e=Object.getPrototypeOf(n);return e===Object.prototype||e===null}function bt(n){return typeof n=="string"&&se.test(n)}function gt(n){return Number.isSafeInteger(n)&&n>=1&&n<=mt}function xe(n){return Number.isSafeInteger(n)&&n>=1&&n<=mt}function Wo(n){return Number.isSafeInteger(n)&&n>=ln.min&&n<=ln.max}function ke(n){return Number.isSafeInteger(n)&&n>=0}function ht(n){return typeof n=="string"&&n.length>0&&n.length<=Uo}function yt(n){return n===null||ht(n)}function V(n){return new TextEncoder().encode(n).byteLength}var Ko=2147483647,X=class{#e;#n;#l;#y=randomUUID();#A=new ie;#o=new Map;#s=new Set;#t;#p=0;#r=false;#c=false;#a=false;#d=null;constructor(e){this.#e=e.channel,this.#n=e.open??Et,this.#l=e.replyTimeoutMs??cn;}jobsFor(e){let t=this.#e;if(t.role!=="control"||e===void 0)return;let r=t.operations,o=le.filter(s=>e.includes(s)&&r.includes(s));if(o.length===0)return;let i=s=>{if(!o.includes(s))throw new f("APP_JOB_NOT_GRANTED",null,{outcome:"rejected"})};return Object.freeze({granted:Object.freeze(o),start:async()=>{i("start");let s=await this.#u("start",{});if(s.ok===false)return {kind:"refused",code:s.code};if(s.op!=="start")throw new f("APP_JOB_BRIDGE_INVALID",null,{outcome:"failed"});return {kind:s.outcome,job:s.job}},status:async s=>{i("status");let a=await this.#u("status",s===void 0?{}:{handle:s});if(a.ok===false)return {kind:"refused",code:a.code};if(a.op!=="status")throw new f("APP_JOB_BRIDGE_INVALID",null,{outcome:"failed"});return {kind:"status",job:a.job}},cancel:async s=>{i("cancel");let a=await this.#u("cancel",{handle:s});if(a.ok===false)return {kind:"refused",code:a.code};if(a.op!=="cancel")throw new f("APP_JOB_BRIDGE_INVALID",null,{outcome:"failed"});return {kind:"stopping",job:a.job}}})}runFor(e){let t=this.#e;if(t.role!=="run"||!e)return;try{this.#f();}catch{return}let r={v:R,runId:t.runId,generation:t.generation},o=()=>this.#d,i=s=>{this.#r||this.#c||this.#t===void 0||this.#t.write(Je({...r,...s}));};return Object.freeze({handle:Object.freeze({runId:t.runId,generation:t.generation}),get stopRequested(){return o()!==null},get stopReason(){return o()},progress:s=>{if(!U(s.phase))throw new TypeError("progress phase must be a lower snake case name");if(s.completed!==void 0&&!_t(s.completed))throw new TypeError("progress completed must be a count");if(s.total!==void 0&&!_t(s.total))throw new TypeError("progress total must be a count");if(s.completed!==void 0&&s.total!==void 0&&s.completed>s.total)throw new TypeError("progress completed cannot exceed total");if(s.resumable!==void 0&&typeof s.resumable!="boolean")throw new TypeError("progress resumable must be boolean");this.#a||i({kind:"progress",phase:s.phase,...s.completed===void 0?{}:{completed:s.completed},...s.total===void 0?{}:{total:s.total},...s.resumable===void 0?{}:{resumable:s.resumable}});},heartbeat:()=>{this.#a||i({kind:"heartbeat"});},complete:()=>{i({kind:"completed"}),this.#a=true;},fail:(s,a)=>{if(!B(s))throw new TypeError("fail code must be an upper snake case code");if(typeof a!="boolean")throw new TypeError("fail recoverable must be boolean");i({kind:"failed",code:s,recoverable:a}),this.#a=true;},onStop:s=>{let a=o();return a!==null?(s(a),()=>{}):(this.#s.add(s),()=>{this.#s.delete(s);})}})}close(){this.#i("APP_JOB_BRIDGE_CLOSED");}async drain(e=fn){if(this.#r)return;this.#c=true;let t=this.#t,r;try{if(t!==void 0){let o;try{o=t.drain();}catch{o=Promise.resolve();}await Promise.race([o.catch(()=>{}),new Promise(i=>{r=setTimeout(i,e);})]);}}finally{clearTimeout(r),this.close();}}#u(e,t){let r=this.#f(),o=this.#p+1;if(o>Ko)throw new f("APP_JOB_BRIDGE_CLOSED",null,{outcome:"failed"});this.#p=o;let i=`${this.#y}.${o}`,s=Je({v:R,op:e,requestId:i,seq:o,...t});return new Promise((a,d)=>{let p=setTimeout(()=>this.#i("APP_JOB_BRIDGE_TIMEOUT"),this.#l);this.#o.set(o,{op:e,requestId:i,resolve:a,reject:d,timer:p}),r.write(s);})}#f(){if(this.#r)throw new f("APP_JOB_BRIDGE_CLOSED",null,{outcome:"failed"});if(this.#t!==void 0)return this.#t;let e;try{e=this.#n(this.#e.fd);}catch{throw new f("APP_JOB_BRIDGE_UNAVAILABLE",null,{outcome:"failed"})}return e.onData(t=>this.#m(t)),e.onEnd(()=>this.#i("APP_JOB_BRIDGE_CLOSED")),this.#t=e,e}#m(e){for(let t of this.#A.push(e)){if(this.#r)return;if(this.#e.role==="run")t.kind==="line"&&this.#g(t.line);else if(t.kind==="oversized"){this.#i("APP_JOB_BRIDGE_INVALID");return}else this.#b(t.line);}}#b(e){let t=An(e),r=t===void 0?void 0:this.#o.get(t.seq);if(t===void 0||r===void 0||r.requestId!==t.requestId||t.ok&&t.op!==r.op){this.#i("APP_JOB_BRIDGE_INVALID");return}clearTimeout(r.timer),this.#o.delete(t.seq),r.resolve(t);}#g(e){let t=this.#e;if(t.role!=="run")return;let r=mn(e);if(!(r===void 0||r.runId!==t.runId||r.generation!==t.generation)&&this.#d===null){this.#d=r.reason;for(let o of [...this.#s])try{o(r.reason);}catch{}}}#i(e){if(this.#r)return;this.#r=true;let t=[...this.#o.values()];this.#o.clear();for(let o of t)clearTimeout(o.timer),o.reject(new f(e,null,{outcome:"failed"}));this.#s.clear();let r=this.#t;this.#t=void 0,r?.close();}};function Et(n){let e=new Socket({fd:n,readable:true,writable:true});return e.setEncoding("utf8"),e.on("error",()=>{}),{write:t=>{e.write(`${t}
|
|
5
|
+
`);},drain:()=>new Promise(t=>{if(e.destroyed){t();return}e.write("",()=>t());}),onData:t=>{e.on("data",t);},onEnd:t=>{e.on("close",t);},close:()=>{e.destroy();}}}function _t(n){return Number.isSafeInteger(n)&&n>=0}var Zo=1;async function Qo(n,e,t=process.env.CREWX_WORKSPACE_ROOT??process.cwd(),r){return (await St(n,e,t,void 0,true,void 0,r)).response}async function St(n,e,t,r,o=true,i,s,a){let d=i!==void 0,p=w(e)?e:void 0,c=p?.input,y=p?.state,u=new n({state:w(y)?y:{},workspaceRoot:t,...s===void 0?{}:{context:s}}),b=w(c)?c:{},A=w(y)?y:u.emptyState(),m={},I=p!==void 0&&Object.hasOwn(p,"schedule"),T;try{let E;if(d){if(p===void 0||I)throw new f("INPUT_INVALID");let S=lt(p,i);if(pt(S))throw new f(S.code,null,{outcome:S.outcome});(({actionId:E,input:b,state:A}=S)),m=S.content;}else {let S=I&&p!==void 0?Tn(p.schedule):void 0;if(!p||Object.keys(p).length!==(I?5:4)||!["schemaVersion","actionId","input","state"].every(Pt=>Object.hasOwn(p,Pt))||p.schemaVersion!==Zo||typeof p.actionId!="string"||!w(c)||!w(y)||I&&S===void 0)throw new f("INPUT_INVALID");E=p.actionId,b=c,A=y,T=S;}let _=Y(n).find(({options:S})=>S.name===E),D=_===void 0?void 0:a?.jobsFor(_.options.jobAccess),C=_===void 0?void 0:a?.runFor(_.options.job!==void 0);if(u=new n({state:A,workspaceRoot:t,...s===void 0?{}:{context:s},...T===void 0?{}:{schedule:T},...D===void 0?{}:{jobs:D},...C===void 0?{}:{jobRun:C}}),await u.validate(E,b,A),!_)throw new f("INPUT_INVALID");if(T!==void 0&&(_.options.content!==void 0||!Nn(n)))throw new f("INPUT_INVALID");let G=u[_.methodName];if(typeof G!="function")throw new f("EXECUTION_FAILED");let L=ct(_.options.content,m);if(L)throw new f(L.code,null,{outcome:L.outcome});if(_.options.job!==void 0&&C===void 0)throw new f(qe,null,{outcome:"rejected"});let ae=Object.freeze({...m.in===void 0?{}:{in:Object.freeze({text:m.in.text})},...m.out===void 0?{}:{out:Object.freeze(m.out.range===void 0?{}:{range:Object.freeze({...m.out.range})})}}),W=()=>G.call(u,b,ae),k=o?await ri(W):await W();if(k!==void 0&&!w(k))throw new f("EXECUTION_FAILED");let J;if(m.out!==void 0){if(J=u.producedContent,J===void 0)throw new f("EXECUTION_FAILED","content.out was requested but setContent was never called");let S=ft(J);if(S)throw new f(S.code,null,{outcome:S.outcome})}else if(u.didSetContent)throw new f("EXECUTION_FAILED","setContent was called but the request asked for no content.out");let On=u.didRequestSchedule;return {response:{...u.didSetState?{state:u.state}:{},...k===void 0?{}:{result:k},...On===void 0?{}:{schedule:{enabled:On.enabled}}},...J===void 0?{}:{answer:J}}}catch(E){let _,D=E,C=E instanceof f?E:void 0;if(C)_={code:C.code,detail:C.detail,outcome:C.outcome};else try{_=u.mapError(E);}catch(J){_={code:"EXECUTION_FAILED",detail:null},D=J;}let G=ii(_?.code),L=G?_.code:"EXECUTION_FAILED",ae=typeof _?.detail=="string"?_.detail:null,W=G?Ge(_.outcome):"failed",k;try{k=u.errorState(L,ae,{input:b,state:A});}catch(J){D=new AggregateError([D,J],"App error handling failed"),k=u.emptyState();}return r?.(L,D,{outcome:W,detail:ae,expected:C!==void 0&&D===C}),{response:{outcome:W,errorCode:L,state:w(k)?k:u.emptyState()}}}}async function ei(n,e={}){let t=ni(e.jobBridge);try{await ti(n,e,t);}finally{await t?.drain();}}function ni(n){if(n===null)return;if(n!==void 0)return new X(n);let e=gn(process.env);return e===void 0?void 0:new X({channel:e})}async function ti(n,e,t){let r=e.output??process.stdout,o,i;if(e.preloadedInput!==void 0)o=e.preloadedInput.value,i=e.preloadedInput.body;else {let u=Ie(e.inputFd??0);u.kind==="v1"?o=u.value:u.kind==="v2"&&(o=u.header,i=u.body);}let s=i!==void 0,a=e.context??We(),d=false,p=(u,b,A)=>{d=true,e.onFailure?.(u,b,A);},c;try{c=await St(n,o,process.env.CREWX_WORKSPACE_ROOT??process.cwd(),p,e.consoleManaged!==!0,i,a,t);}catch(u){p("EXECUTION_FAILED",u),c={response:Ot(e.emptyState)};}oi(c.response)&&!d&&p(c.response.errorCode,void 0,{outcome:c.response.outcome,detail:null,expected:false});let y;try{let u=(e.sanitize??wt)(c.response);y=s?Te(u,c.answer):`${JSON.stringify(u)}
|
|
6
|
+
`;}catch(u){p("EXECUTION_FAILED",u);let b=Ot(e.emptyState);try{let A=(e.sanitize??wt)(b);y=s?Te(A):`${JSON.stringify(A)}
|
|
7
|
+
`;}catch(A){p("EXECUTION_FAILED",A),y=s?Te(b):`${JSON.stringify(b)}
|
|
8
|
+
`;}}r.write(y);}async function ri(n){let e=["log","info","debug"],t=new Map;for(let r of e)t.set(r,console[r]),console[r]=(...o)=>process.stderr.write(`${format(...o)}
|
|
9
|
+
`);try{return await n()}finally{for(let r of e)console[r]=t.get(r);}}function Ot(n={}){return {outcome:"failed",errorCode:"EXECUTION_FAILED",state:{...n,error:{code:"EXECUTION_FAILED",detail:null}}}}function oi(n){return (n.outcome==="failed"||n.outcome==="rejected")&&typeof n.errorCode=="string"}function ii(n){return typeof n=="string"&&/^[A-Z][A-Z0-9_]{0,127}$/u.test(n)}function wt(n){return n}var hn={depth:null,maxArrayLength:null,maxStringLength:null},En=class extends Writable{#e="buffer";#n=[];_write(e,t,r){if(this.#e==="buffer"){this.#n.push(typeof e=="string"?e:Uint8Array.from(e)),r();return}if(this.#e==="discard"){r();return}process.stderr.write(e,r);}flushToStderr(){this.#e="stderr";for(let e of this.#n)process.stderr.write(e);this.#n=[];}discard(){this.#e="discard",this.#n=[];}};async function di(n,e={}){let t=process.stdout,r=t.write.bind(t),o=new En,i=new Console({stdout:o,stderr:o,inspectOptions:{...hn}});globalThis.console=i;let s=false,a="-",d="-",p,c=false,y,u;try{let m=li(e.inputFd??0);a=pi(m.value),d=Fe(process.env.CREWX_APP_REQUEST_ID),p=new Date().toISOString();try{y=await n();}catch(E){c=!0,u=E;}let I=y?.default;if(!c&&I?.devtools?.log===!0?(Object.assign(inspect.defaultOptions,hn),b(p),o.flushToStderr()):o.discard(),c){A("EXECUTION_FAILED",u),_n(r,e,A);return}try{if(typeof y?.runSkillApp!="function")throw new TypeError("App module does not export runSkillApp");let E={sanitize:e.sanitize,emptyState:e.emptyState??ui(I),preloadedInput:m.body===void 0?{value:m.value}:{value:m.value,body:m.body},onFailure:A,consoleManaged:!0,output:{write:r},jobBridge:e.jobBridge};await y.runSkillApp(I,E);}catch(E){A("EXECUTION_FAILED",E),_n(r,e,A);}}catch(m){A("EXECUTION_FAILED",m),_n(r,e,A);}finally{process.exitCode=0;}function b(m){s||(process.stderr.write(`[crewx-app] ${m??new Date().toISOString()} ${Fe(a)} req=${d}
|
|
10
|
+
`),s=true);}function A(m,I,T){b();let E=T?.expected===true&&T.detail?` ${Fe(T.detail)}`:"";process.stderr.write(`[crewx-app] ${T?.outcome??"failed"} ${Fe(m)}${E}
|
|
11
|
+
`),I!==void 0&&T?.expected!==true&&process.stderr.write(`${inspect(I,hn)}
|
|
12
|
+
`);}}function ui(n){if(typeof n=="function")try{let t=new n({workspaceRoot:process.cwd()}).emptyState();return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}catch{return}}function li(n){let e=Ie(n);return e.kind==="v1"?{value:e.value}:e.kind==="v2"?{value:e.header,body:e.body}:{value:void 0}}function pi(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)&&typeof n.actionId=="string"?n.actionId:"-"}function Fe(n){return typeof n!="string"||n.length===0?"-":n.replace(/[\u0000-\u001f\u007f\u2028\u2029]/gu,"_")}function _n(n,e,t){let r={code:"EXECUTION_FAILED",detail:null},i={outcome:"failed",errorCode:"EXECUTION_FAILED",state:e.emptyState!==null&&typeof e.emptyState=="object"&&!Array.isArray(e.emptyState)?{...e.emptyState,error:r}:{error:r}},s=i;try{s=(e.sanitize??ci)(i);}catch(a){t("EXECUTION_FAILED",a);}n(`${JSON.stringify(s)}
|
|
13
|
+
`);}function ci(n){return n}export{Ln as APP_FILES_ERROR_CODES,P as APP_FILES_LIMITS,ye as APP_FILES_LOCK_SUBPATH,at as APP_FILES_ROOT_ENV,yn as APP_JOB_BRIDGE_CHANNEL_MAX_BYTES,fn as APP_JOB_BRIDGE_DRAIN_TIMEOUT_MS,At as APP_JOB_BRIDGE_ENV,Bo as APP_JOB_BRIDGE_ERROR_CODES,ln as APP_JOB_BRIDGE_FD,oe as APP_JOB_BRIDGE_MAX_LINE_BYTES,cn as APP_JOB_BRIDGE_REPLY_TIMEOUT_MS,R as APP_JOB_BRIDGE_VERSION,Cn as APP_JOB_CAPABILITY,kn as APP_JOB_CAPABILITY_VERSION,M as APP_JOB_DEADLINE_MS,vt as APP_JOB_MAX_PER_APP,le as APP_JOB_OPERATIONS,Be as APP_JOB_OUTCOMES,He as APP_JOB_REFUSAL_CODES,qe as APP_JOB_RUN_REQUIRED,Me as APP_JOB_STATES,Lt as APP_JOB_STOP_GRACE_MS,ue as APP_JOB_STOP_REASONS,Ue as APP_JOB_TRIGGERS,Tt as APP_SCHEDULE_ACTOR_KIND,Ct as APP_SCHEDULE_INERT_COMMAND,ve as APP_SCHEDULE_INSTANCE_PREFIX,z as APP_SCHEDULE_INTERVALS_MINUTES,It as APP_SCHEDULE_MAX_PER_APP,Sn as APP_SCHEDULE_PERIODIC_REASONS,j as APP_SCHEDULE_TIMEOUT_MS,er as APP_TOOLS_FILE,nr as APP_TOOLS_SCHEMA_VERSION,tr as APP_TOOL_ENTRY,f as AppError,l as AppFilesError,X as AppJobBridge,ie as AppJobLineReader,Xe as CrewXApp,kt as SCHEDULE_TRIGGERS,Fn as SKILL_BACKEND_ENV_NAMES,Ht as Tool,Ae as acquireFileLock,Eo as appFiles,nn as appFilesLockKeyOf,ge as appFilesRootSegmentsOf,Xo as appJobTriggerForActor,Vo as buildAppJobChannelEnvironment,Je as encodeAppJobLine,Qo as executeAppRequest,qt as generateManifest,Dn as generateToolDeclarations,Y as getToolDeclarations,Bt as hasAppJobCapability,B as isAppJobCode,Ve as isAppJobDeadlineMs,$ as isAppJobOperation,U as isAppJobPhase,Rn as isAppScheduleCode,Pn as isAppScheduleIntervalMinutes,In as isAppSchedulePeriodicReason,je as isAppScheduleTimeoutMs,rr as isSkillBackendEnv,Z as normalizeAppFilesRef,Et as openInheritedAppJobTransport,bn as parseAppJobChannel,An as parseAppJobControlReply,Ho as parseAppJobControlRequest,mn as parseAppJobRunPush,qo as parseAppJobRunReport,Go as parseAppJobView,We as readAppContext,gn as readAppJobChannel,me as releaseFileLock,di as runAppEntry,ei as runSkillApp};
|