@granular-software/sdk 0.4.52 → 0.4.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -25348,6 +25348,55 @@ var Granular = class _Granular {
25348
25348
  throw error2;
25349
25349
  }
25350
25350
  }
25351
+ /**
25352
+ * Resolve one exact environment only when Granular confirms that it belongs
25353
+ * to the given external user in the requested sandbox (and, optionally,
25354
+ * tag). This is deliberately read-only: callers use it to keep an already
25355
+ * opened delegated workspace stable while a newer active environment is
25356
+ * being prepared in the background.
25357
+ */
25358
+ async getEnvironmentForUser(options) {
25359
+ const sandboxId = options.sandboxId.trim();
25360
+ const userId = options.userId.trim();
25361
+ const environmentId = options.environmentId.trim();
25362
+ const tagName = options.tag?.trim();
25363
+ if (!sandboxId || !userId || !environmentId) {
25364
+ throw new Error(
25365
+ "getEnvironmentForUser() requires sandboxId, userId, and environmentId."
25366
+ );
25367
+ }
25368
+ const subjects = await this.request(
25369
+ `/control/subjects?identityId=${encodeURIComponent(userId)}`
25370
+ );
25371
+ const subject = (subjects.items || []).find(
25372
+ (item) => item.identityId === userId || item.userId === userId
25373
+ );
25374
+ const subjectId = subject?.subjectId || subject?.granularId;
25375
+ if (!subjectId) return null;
25376
+ let environment;
25377
+ try {
25378
+ environment = await this.environments.get(environmentId);
25379
+ } catch (error2) {
25380
+ const message = error2 instanceof Error ? error2.message : String(error2);
25381
+ if (message.includes("404") || message.includes("not found")) {
25382
+ return null;
25383
+ }
25384
+ throw error2;
25385
+ }
25386
+ if (environment.sandboxId !== sandboxId || environment.subjectId !== subjectId) {
25387
+ return null;
25388
+ }
25389
+ if (tagName) {
25390
+ const tags = await this.request(`/control/sandboxes/${encodeURIComponent(sandboxId)}/tags`);
25391
+ const tag2 = (tags.items || []).find(
25392
+ (candidate) => candidate?.name === tagName
25393
+ );
25394
+ if (!tag2 || environment.tagId !== tag2.tagId) {
25395
+ return null;
25396
+ }
25397
+ }
25398
+ return this.bindEnvironmentHandle(environment);
25399
+ }
25351
25400
  /**
25352
25401
  * Register one reviewed, pre-existing environment as the active workspace
25353
25402
  * for an external user. This is for a controlled migration only: it does
@@ -963,6 +963,19 @@ declare class Granular {
963
963
  userId: string;
964
964
  slot?: string;
965
965
  }): Promise<Environment | null>;
966
+ /**
967
+ * Resolve one exact environment only when Granular confirms that it belongs
968
+ * to the given external user in the requested sandbox (and, optionally,
969
+ * tag). This is deliberately read-only: callers use it to keep an already
970
+ * opened delegated workspace stable while a newer active environment is
971
+ * being prepared in the background.
972
+ */
973
+ getEnvironmentForUser(options: {
974
+ sandboxId: string;
975
+ userId: string;
976
+ environmentId: string;
977
+ tag?: string;
978
+ }): Promise<Environment | null>;
966
979
  /**
967
980
  * Register one reviewed, pre-existing environment as the active workspace
968
981
  * for an external user. This is for a controlled migration only: it does
@@ -963,6 +963,19 @@ declare class Granular {
963
963
  userId: string;
964
964
  slot?: string;
965
965
  }): Promise<Environment | null>;
966
+ /**
967
+ * Resolve one exact environment only when Granular confirms that it belongs
968
+ * to the given external user in the requested sandbox (and, optionally,
969
+ * tag). This is deliberately read-only: callers use it to keep an already
970
+ * opened delegated workspace stable while a newer active environment is
971
+ * being prepared in the background.
972
+ */
973
+ getEnvironmentForUser(options: {
974
+ sandboxId: string;
975
+ userId: string;
976
+ environmentId: string;
977
+ tag?: string;
978
+ }): Promise<Environment | null>;
966
979
  /**
967
980
  * Register one reviewed, pre-existing environment as the active workspace
968
981
  * for an external user. This is for a controlled migration only: it does
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { E as Environment, a as EnvironmentSession, G as Granular, O as OntologyHandle, S as Session, W as WSClient } from './client-B2OyGOHE.mjs';
1
+ export { E as Environment, a as EnvironmentSession, G as Granular, O as OntologyHandle, S as Session, W as WSClient } from './client-CfTDojJF.mjs';
2
2
  import { E as EndpointMode, T as ToolWithHandler, a as EffectHandlerContext, M as ManifestEffectMetamodelSpec, R as ResolvedEffectBehaviors, S as SessionHeapEntry, b as SessionHeapList, c as SessionHeapSnapshot, P as Prompt, d as SessionTranscriptEntry } from './spend-DpRRCrAr.mjs';
3
3
  export { cN as APIError, A as AccessTokenProvider, J as AdoptEnvironmentOptions, bg as ArtifactApprovalDecisionInput, bh as ArtifactApprovalDecisionResult, be as ArtifactApprovalTask, bf as ArtifactApprovalTaskListOptions, bd as ArtifactApprovalTaskStatus, aa as Assignment, ab as AssignmentListResponse, al as Build, an as BuildListResponse, ac as BuildPolicy, ak as BuildStatus, C as ConditionIR, K as ConnectOptions, aV as ConversationActionSuggestion, aZ as ConversationAppendResult, aW as ConversationMessageAction, aY as ConversationMessageInput, aX as ConversationMessagePart, aP as ConversationMessageShowRefs, Q as ConversationSessionInfo, W as ConversationSessionListOptions, V as ConversationSessionListStatus, aQ as ConversationTableCell, aR as ConversationTableColumn, aU as ConversationTableProjection, aT as ConversationTableRow, aS as ConversationTableRowReference, ag as CreateEnvironmentData, a8 as CreatePermissionProfileData, a4 as CreateSandboxData, L as CreateSessionOptions, bV as DefineRelationshipOptions, cO as DeleteResponse, D as DomainState, aE as EffectHandler, aB as EffectInfo, av as EffectInvocationMetadata, au as EffectInvocationMode, aw as EffectSchema, az as EffectVersionSelector, ax as EffectWithHandler, aD as EffectsChangedEvent, af as EnvironmentData, aM as EnvironmentFeedbackRecord, ci as EnvironmentImporter, ch as EnvironmentImporterImportOptions, ah as EnvironmentListResponse, cb as EnvironmentRecordImportSummary, cg as EnvironmentSetupImporterClaim, ce as EnvironmentSetupLifecycleStatus, cf as EnvironmentSetupSummary, cc as EnvironmentSetupTriggerReason, b$ as EnvironmentStateMachineProxy, bZ as EnvironmentStateObservationInput, c0 as EnvironmentStateProxy, bY as EnvironmentStateTarget, b_ as EnvironmentStateUpdateInput, z as GranularAuth, y as GranularOptions, a1 as GranularQuotaPolicy, a2 as GranularQuotaProgress, G as GranularSpendContext, cM as GraphQLResult, aF as InstanceEffectHandler, I as InstanceToolHandler, aO as Job, aK as JobFeedbackInput, aJ as JobFeedbackMetadata, aL as JobFeedbackRecord, aH as JobFeedbackSentiment, aI as JobFeedbackToolCall, aG as JobStatus, aN as JobSubmitResult, ai as Manifest, cB as ManifestApprovalRequiredSpec, cL as ManifestContent, cC as ManifestCreatesSpec, cz as ManifestDryRunSpec, cF as ManifestEffectDeclaration, cE as ManifestEffectSchema, cl as ManifestEnumRuleSpec, cH as ManifestEventStreamDef, cG as ManifestEventTypeDef, cm as ManifestFilterBySpec, cJ as ManifestImport, aj as ManifestListResponse, cI as ManifestOperation, cy as ManifestPostConditionSpec, cj as ManifestPropertySpec, cD as ManifestRelationshipDef, cA as ManifestReverseSpec, cx as ManifestStateMachineSpec, co as ManifestStateMachineStateSpec, cw as ManifestStateMachineTransitionSpec, cq as ManifestStateTransitionActionSpec, cr as ManifestStateTransitionAssigneeSpec, cv as ManifestStateTransitionExpectedOutcomeSpec, cp as ManifestStateTransitionInputBinding, cu as ManifestStateTransitionPermissionSpec, cs as ManifestStateTransitionRelatedStateRequirementSpec, ct as ManifestStateTransitionRequirementsSpec, ck as ManifestValidationOperator, cn as ManifestValidationRuleSpec, cK as ManifestVolume, bp as ManualActionListOptions, bn as ManualActionOccurrence, bo as ManualActionRecordResult, bl as ManualActionRelatedRecord, bj as ManualActionSource, bi as ManualActionStatus, bq as ManualActionSuggestion, br as ManualActionSuggestionOptions, bk as ManualActionTarget, bJ as MarkUserEnvironmentReadOptions, x as MatchedPolicy, bT as ModelRef, N as NormalizedOpenAIUsage, i as OPENAI_MODEL_PRICING_USD_PER_MILLION, O as OpenAIModelPricing, h as OpenAITokenSpend, l as OpenAIUsageSpendEvent, H as OpenEnvironmentOptions, a7 as PermissionProfile, a9 as PermissionProfileListResponse, a6 as PermissionRules, u as PolicyOperator, v as PolicyOrigin, s as PolicyPredicateSource, w as PolicyRuleIR, q as PolicySource, ay as PublishEffectsResult, f as PublishToolsResult, a0 as QuotaLineItemFilter, Z as QuotaPeriod, Y as QuotaScopeType, _ as QuotaStatus, bN as RPCRequest, bQ as RPCRequestFromServer, bO as RPCResponse, ca as RecordImport, c9 as RecordImportItem, c7 as RecordImportItemStatus, c5 as RecordImportOptions, c8 as RecordImportStats, c6 as RecordImportStatus, c4 as RecordImportWriteMode, bm as RecordManualActionInput, bz as RecordMentionInput, bW as RecordObjectOptions, c1 as RecordObjectResult, bX as RecordObjectStateValue, c2 as RecordObjectsChunkInfo, c3 as RecordObjectsOptions, m as RecordOpenAIUsageSpendOptions, o as RecordOpenAIUsageSpendResult, by as RecordSearchOptions, bx as RecordSearchResult, B as RecordUserOptions, bU as RelationshipInfo, at as ResolvedEffectApprovalRequired, ar as ResolvedEffectDryRun, aq as ResolvedEffectPostCondition, as as ResolvedEffectReverse, cd as RunEnvironmentImporterOptions, a3 as Sandbox, a5 as SandboxListResponse, ap as SemanticVersionDiff, ao as SemanticVersionDiffEntry, bc as SessionArtifactApprovalOptions, b6 as SessionArtifactAutonomyPolicy, bb as SessionArtifactExecutionOptions, ba as SessionArtifactExecutionResult, b5 as SessionArtifactKind, b8 as SessionArtifactListOptions, b7 as SessionArtifactRecord, b4 as SessionArtifactStatus, b9 as SessionArtifactValidationResult, bB as SessionCollectionListOptions, bD as SessionCollectionListResult, a_ as SessionConversationMessage, bA as SessionDocumentResult, b1 as SessionFileKind, b3 as SessionFileRecord, b0 as SessionFileSource, b2 as SessionFileStatus, bs as SessionFileUploadOptions, bu as SessionHeapFieldType, bv as SessionHeapFieldValue, bw as SessionHeapVariable, bC as SessionJobListOptions, bt as SessionJobRecord, a$ as SessionTimelineEvent, X as SpendLineItemType, $ as SpendSummary, cP as StreamEvent, cR as StreamStats, cQ as StreamSubscription, F as Subject, bP as SyncMessage, g as ToolHandler, aA as ToolInfo, bR as ToolInvokeParams, bS as ToolResultParams, e as ToolSchema, aC as ToolsChangedEvent, U as User, bF as UserEnvironmentMessagePreview, bE as UserEnvironmentPrompt, bG as UserEnvironmentSessionState, bH as UserEnvironmentState, bI as UserEnvironmentStateOptions, am as Version, ae as VersionTag, ad as VersionTracking, bM as WSClientOptions, bK as WSDisconnectInfo, bL as WSReconnectErrorInfo, p as buildOpenAISpendEventId, k as calculateOpenAITokenSpend, j as getOpenAIModelPricing, n as normalizeOpenAIUsage, r as recordOpenAIUsageSpend, t as toGranularHttpBase } from './spend-DpRRCrAr.mjs';
4
4
  export { BuildGranularAgentSystemPromptInput, GeneratedJobCodeIssue, GranularAgentExecutionCheckpoint, GranularAgentHeapSummaryOptions, GranularAgentManualActionMemorySuggestion, GranularAgentPromptCapabilities, GranularAgentReferentFocus, GranularAgentSessionContext, GranularAgentToolInfo, GranularAgentWorkflowFocus, GranularReasoningTraceChunkResult, GranularReasoningTraceOptions, HarnessContinuationDecision, HarnessControllerBudgets, HarnessProjectionOptions, HarnessPromptLike, HarnessRenderedContinuation, HarnessRenderedPrompt, HarnessTemplate, HarnessTemplateManifest, HarnessTemplateSelectionOptions, HarnessTemplateStatus, HarnessVerifierSnapshot, HarnessVerifierSnapshotInput, ReviewGeneratedJobCodeOptions, buildContinuationInstruction, buildContinuationInstructionFromTemplate, buildGranularAgentCheckpointBlock, buildGranularAgentDomainBlock, buildGranularAgentFileBlock, buildGranularAgentHeapBlock, buildGranularAgentLoopBlock, buildGranularAgentManualActionBlock, buildGranularAgentManualActionMemorySummary, buildGranularAgentReferentBlock, buildGranularAgentRuntimeImportsBlock, buildGranularAgentSessionBlock, buildGranularAgentSystemPrompt, buildGranularAgentSystemPromptFromTemplate, buildGranularAgentToolBlock, buildGranularAgentWorkflowBlock, consumeGranularReasoningOnlyChunk, consumeGranularReasoningTraceChunk, createHarnessVerifierSnapshot, evaluateContinuation, getCurrentClosureId, getDefaultHarnessTemplateId, getExclusivePromptTarget, hasOpenPrompt, hashHarnessTemplateValue, listHarnessTemplates, projectConversationReferentFocus, projectConversationReferentSummary, projectHeapSummary, projectLoopSummary, projectSessionFileSummary, projectWorkflowFocus, projectWorkflowSummary, renderContinuationInstructionFromTemplate, renderGranularAgentSystemPromptFromTemplate, resolveHarnessTemplate, reviewGeneratedJobCode, stripGranularReasoningTrace, validateHarnessTemplateManifest } from './agent-harness.mjs';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { E as Environment, a as EnvironmentSession, G as Granular, O as OntologyHandle, S as Session, W as WSClient } from './client-BMfjRJTs.js';
1
+ export { E as Environment, a as EnvironmentSession, G as Granular, O as OntologyHandle, S as Session, W as WSClient } from './client-DcRzwuGp.js';
2
2
  import { E as EndpointMode, T as ToolWithHandler, a as EffectHandlerContext, M as ManifestEffectMetamodelSpec, R as ResolvedEffectBehaviors, S as SessionHeapEntry, b as SessionHeapList, c as SessionHeapSnapshot, P as Prompt, d as SessionTranscriptEntry } from './spend-DpRRCrAr.js';
3
3
  export { cN as APIError, A as AccessTokenProvider, J as AdoptEnvironmentOptions, bg as ArtifactApprovalDecisionInput, bh as ArtifactApprovalDecisionResult, be as ArtifactApprovalTask, bf as ArtifactApprovalTaskListOptions, bd as ArtifactApprovalTaskStatus, aa as Assignment, ab as AssignmentListResponse, al as Build, an as BuildListResponse, ac as BuildPolicy, ak as BuildStatus, C as ConditionIR, K as ConnectOptions, aV as ConversationActionSuggestion, aZ as ConversationAppendResult, aW as ConversationMessageAction, aY as ConversationMessageInput, aX as ConversationMessagePart, aP as ConversationMessageShowRefs, Q as ConversationSessionInfo, W as ConversationSessionListOptions, V as ConversationSessionListStatus, aQ as ConversationTableCell, aR as ConversationTableColumn, aU as ConversationTableProjection, aT as ConversationTableRow, aS as ConversationTableRowReference, ag as CreateEnvironmentData, a8 as CreatePermissionProfileData, a4 as CreateSandboxData, L as CreateSessionOptions, bV as DefineRelationshipOptions, cO as DeleteResponse, D as DomainState, aE as EffectHandler, aB as EffectInfo, av as EffectInvocationMetadata, au as EffectInvocationMode, aw as EffectSchema, az as EffectVersionSelector, ax as EffectWithHandler, aD as EffectsChangedEvent, af as EnvironmentData, aM as EnvironmentFeedbackRecord, ci as EnvironmentImporter, ch as EnvironmentImporterImportOptions, ah as EnvironmentListResponse, cb as EnvironmentRecordImportSummary, cg as EnvironmentSetupImporterClaim, ce as EnvironmentSetupLifecycleStatus, cf as EnvironmentSetupSummary, cc as EnvironmentSetupTriggerReason, b$ as EnvironmentStateMachineProxy, bZ as EnvironmentStateObservationInput, c0 as EnvironmentStateProxy, bY as EnvironmentStateTarget, b_ as EnvironmentStateUpdateInput, z as GranularAuth, y as GranularOptions, a1 as GranularQuotaPolicy, a2 as GranularQuotaProgress, G as GranularSpendContext, cM as GraphQLResult, aF as InstanceEffectHandler, I as InstanceToolHandler, aO as Job, aK as JobFeedbackInput, aJ as JobFeedbackMetadata, aL as JobFeedbackRecord, aH as JobFeedbackSentiment, aI as JobFeedbackToolCall, aG as JobStatus, aN as JobSubmitResult, ai as Manifest, cB as ManifestApprovalRequiredSpec, cL as ManifestContent, cC as ManifestCreatesSpec, cz as ManifestDryRunSpec, cF as ManifestEffectDeclaration, cE as ManifestEffectSchema, cl as ManifestEnumRuleSpec, cH as ManifestEventStreamDef, cG as ManifestEventTypeDef, cm as ManifestFilterBySpec, cJ as ManifestImport, aj as ManifestListResponse, cI as ManifestOperation, cy as ManifestPostConditionSpec, cj as ManifestPropertySpec, cD as ManifestRelationshipDef, cA as ManifestReverseSpec, cx as ManifestStateMachineSpec, co as ManifestStateMachineStateSpec, cw as ManifestStateMachineTransitionSpec, cq as ManifestStateTransitionActionSpec, cr as ManifestStateTransitionAssigneeSpec, cv as ManifestStateTransitionExpectedOutcomeSpec, cp as ManifestStateTransitionInputBinding, cu as ManifestStateTransitionPermissionSpec, cs as ManifestStateTransitionRelatedStateRequirementSpec, ct as ManifestStateTransitionRequirementsSpec, ck as ManifestValidationOperator, cn as ManifestValidationRuleSpec, cK as ManifestVolume, bp as ManualActionListOptions, bn as ManualActionOccurrence, bo as ManualActionRecordResult, bl as ManualActionRelatedRecord, bj as ManualActionSource, bi as ManualActionStatus, bq as ManualActionSuggestion, br as ManualActionSuggestionOptions, bk as ManualActionTarget, bJ as MarkUserEnvironmentReadOptions, x as MatchedPolicy, bT as ModelRef, N as NormalizedOpenAIUsage, i as OPENAI_MODEL_PRICING_USD_PER_MILLION, O as OpenAIModelPricing, h as OpenAITokenSpend, l as OpenAIUsageSpendEvent, H as OpenEnvironmentOptions, a7 as PermissionProfile, a9 as PermissionProfileListResponse, a6 as PermissionRules, u as PolicyOperator, v as PolicyOrigin, s as PolicyPredicateSource, w as PolicyRuleIR, q as PolicySource, ay as PublishEffectsResult, f as PublishToolsResult, a0 as QuotaLineItemFilter, Z as QuotaPeriod, Y as QuotaScopeType, _ as QuotaStatus, bN as RPCRequest, bQ as RPCRequestFromServer, bO as RPCResponse, ca as RecordImport, c9 as RecordImportItem, c7 as RecordImportItemStatus, c5 as RecordImportOptions, c8 as RecordImportStats, c6 as RecordImportStatus, c4 as RecordImportWriteMode, bm as RecordManualActionInput, bz as RecordMentionInput, bW as RecordObjectOptions, c1 as RecordObjectResult, bX as RecordObjectStateValue, c2 as RecordObjectsChunkInfo, c3 as RecordObjectsOptions, m as RecordOpenAIUsageSpendOptions, o as RecordOpenAIUsageSpendResult, by as RecordSearchOptions, bx as RecordSearchResult, B as RecordUserOptions, bU as RelationshipInfo, at as ResolvedEffectApprovalRequired, ar as ResolvedEffectDryRun, aq as ResolvedEffectPostCondition, as as ResolvedEffectReverse, cd as RunEnvironmentImporterOptions, a3 as Sandbox, a5 as SandboxListResponse, ap as SemanticVersionDiff, ao as SemanticVersionDiffEntry, bc as SessionArtifactApprovalOptions, b6 as SessionArtifactAutonomyPolicy, bb as SessionArtifactExecutionOptions, ba as SessionArtifactExecutionResult, b5 as SessionArtifactKind, b8 as SessionArtifactListOptions, b7 as SessionArtifactRecord, b4 as SessionArtifactStatus, b9 as SessionArtifactValidationResult, bB as SessionCollectionListOptions, bD as SessionCollectionListResult, a_ as SessionConversationMessage, bA as SessionDocumentResult, b1 as SessionFileKind, b3 as SessionFileRecord, b0 as SessionFileSource, b2 as SessionFileStatus, bs as SessionFileUploadOptions, bu as SessionHeapFieldType, bv as SessionHeapFieldValue, bw as SessionHeapVariable, bC as SessionJobListOptions, bt as SessionJobRecord, a$ as SessionTimelineEvent, X as SpendLineItemType, $ as SpendSummary, cP as StreamEvent, cR as StreamStats, cQ as StreamSubscription, F as Subject, bP as SyncMessage, g as ToolHandler, aA as ToolInfo, bR as ToolInvokeParams, bS as ToolResultParams, e as ToolSchema, aC as ToolsChangedEvent, U as User, bF as UserEnvironmentMessagePreview, bE as UserEnvironmentPrompt, bG as UserEnvironmentSessionState, bH as UserEnvironmentState, bI as UserEnvironmentStateOptions, am as Version, ae as VersionTag, ad as VersionTracking, bM as WSClientOptions, bK as WSDisconnectInfo, bL as WSReconnectErrorInfo, p as buildOpenAISpendEventId, k as calculateOpenAITokenSpend, j as getOpenAIModelPricing, n as normalizeOpenAIUsage, r as recordOpenAIUsageSpend, t as toGranularHttpBase } from './spend-DpRRCrAr.js';
4
4
  export { BuildGranularAgentSystemPromptInput, GeneratedJobCodeIssue, GranularAgentExecutionCheckpoint, GranularAgentHeapSummaryOptions, GranularAgentManualActionMemorySuggestion, GranularAgentPromptCapabilities, GranularAgentReferentFocus, GranularAgentSessionContext, GranularAgentToolInfo, GranularAgentWorkflowFocus, GranularReasoningTraceChunkResult, GranularReasoningTraceOptions, HarnessContinuationDecision, HarnessControllerBudgets, HarnessProjectionOptions, HarnessPromptLike, HarnessRenderedContinuation, HarnessRenderedPrompt, HarnessTemplate, HarnessTemplateManifest, HarnessTemplateSelectionOptions, HarnessTemplateStatus, HarnessVerifierSnapshot, HarnessVerifierSnapshotInput, ReviewGeneratedJobCodeOptions, buildContinuationInstruction, buildContinuationInstructionFromTemplate, buildGranularAgentCheckpointBlock, buildGranularAgentDomainBlock, buildGranularAgentFileBlock, buildGranularAgentHeapBlock, buildGranularAgentLoopBlock, buildGranularAgentManualActionBlock, buildGranularAgentManualActionMemorySummary, buildGranularAgentReferentBlock, buildGranularAgentRuntimeImportsBlock, buildGranularAgentSessionBlock, buildGranularAgentSystemPrompt, buildGranularAgentSystemPromptFromTemplate, buildGranularAgentToolBlock, buildGranularAgentWorkflowBlock, consumeGranularReasoningOnlyChunk, consumeGranularReasoningTraceChunk, createHarnessVerifierSnapshot, evaluateContinuation, getCurrentClosureId, getDefaultHarnessTemplateId, getExclusivePromptTarget, hasOpenPrompt, hashHarnessTemplateValue, listHarnessTemplates, projectConversationReferentFocus, projectConversationReferentSummary, projectHeapSummary, projectLoopSummary, projectSessionFileSummary, projectWorkflowFocus, projectWorkflowSummary, renderContinuationInstructionFromTemplate, renderGranularAgentSystemPromptFromTemplate, resolveHarnessTemplate, reviewGeneratedJobCode, stripGranularReasoningTrace, validateHarnessTemplateManifest } from './agent-harness.js';
package/dist/index.js CHANGED
@@ -16447,6 +16447,55 @@ var Granular = class _Granular {
16447
16447
  throw error;
16448
16448
  }
16449
16449
  }
16450
+ /**
16451
+ * Resolve one exact environment only when Granular confirms that it belongs
16452
+ * to the given external user in the requested sandbox (and, optionally,
16453
+ * tag). This is deliberately read-only: callers use it to keep an already
16454
+ * opened delegated workspace stable while a newer active environment is
16455
+ * being prepared in the background.
16456
+ */
16457
+ async getEnvironmentForUser(options) {
16458
+ const sandboxId = options.sandboxId.trim();
16459
+ const userId = options.userId.trim();
16460
+ const environmentId = options.environmentId.trim();
16461
+ const tagName = options.tag?.trim();
16462
+ if (!sandboxId || !userId || !environmentId) {
16463
+ throw new Error(
16464
+ "getEnvironmentForUser() requires sandboxId, userId, and environmentId."
16465
+ );
16466
+ }
16467
+ const subjects = await this.request(
16468
+ `/control/subjects?identityId=${encodeURIComponent(userId)}`
16469
+ );
16470
+ const subject = (subjects.items || []).find(
16471
+ (item) => item.identityId === userId || item.userId === userId
16472
+ );
16473
+ const subjectId = subject?.subjectId || subject?.granularId;
16474
+ if (!subjectId) return null;
16475
+ let environment;
16476
+ try {
16477
+ environment = await this.environments.get(environmentId);
16478
+ } catch (error) {
16479
+ const message = error instanceof Error ? error.message : String(error);
16480
+ if (message.includes("404") || message.includes("not found")) {
16481
+ return null;
16482
+ }
16483
+ throw error;
16484
+ }
16485
+ if (environment.sandboxId !== sandboxId || environment.subjectId !== subjectId) {
16486
+ return null;
16487
+ }
16488
+ if (tagName) {
16489
+ const tags = await this.request(`/control/sandboxes/${encodeURIComponent(sandboxId)}/tags`);
16490
+ const tag = (tags.items || []).find(
16491
+ (candidate) => candidate?.name === tagName
16492
+ );
16493
+ if (!tag || environment.tagId !== tag.tagId) {
16494
+ return null;
16495
+ }
16496
+ }
16497
+ return this.bindEnvironmentHandle(environment);
16498
+ }
16450
16499
  /**
16451
16500
  * Register one reviewed, pre-existing environment as the active workspace
16452
16501
  * for an external user. This is for a controlled migration only: it does