opensteer 0.9.6 → 0.9.8

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.
Files changed (35) hide show
  1. package/README.md +2 -2
  2. package/dist/{chunk-3I3A5OLB.js → chunk-BPGXP3RF.js} +257 -24
  3. package/dist/chunk-BPGXP3RF.js.map +1 -0
  4. package/dist/{chunk-3XBQRZZC.js → chunk-EXXRLPLI.js} +158 -46
  5. package/dist/chunk-EXXRLPLI.js.map +1 -0
  6. package/dist/{chunk-T5P2QGZ3.js → chunk-GKYBP3KD.js} +154 -13
  7. package/dist/chunk-GKYBP3KD.js.map +1 -0
  8. package/dist/{chunk-BVRIPCWA.js → chunk-LFWP5RXF.js} +500 -513
  9. package/dist/chunk-LFWP5RXF.js.map +1 -0
  10. package/dist/{chunk-L4NF74KI.js → chunk-SOJEWKSW.js} +5 -5
  11. package/dist/{chunk-L4NF74KI.js.map → chunk-SOJEWKSW.js.map} +1 -1
  12. package/dist/cli/bin.cjs +1230 -660
  13. package/dist/cli/bin.cjs.map +1 -1
  14. package/dist/cli/bin.js +166 -72
  15. package/dist/cli/bin.js.map +1 -1
  16. package/dist/index.cjs +793 -565
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +36 -51
  19. package/dist/index.d.ts +36 -51
  20. package/dist/index.js +4 -4
  21. package/dist/local-view/public/assets/app.js +10 -1
  22. package/dist/local-view/serve-entry.cjs +1022 -591
  23. package/dist/local-view/serve-entry.cjs.map +1 -1
  24. package/dist/local-view/serve-entry.js +2 -2
  25. package/dist/opensteer-XLPY343Y.js +6 -0
  26. package/dist/{opensteer-UGA6YBRN.js.map → opensteer-XLPY343Y.js.map} +1 -1
  27. package/dist/{session-control-U3L5H2ZI.js → session-control-FVKKD45R.js} +4 -4
  28. package/dist/{session-control-U3L5H2ZI.js.map → session-control-FVKKD45R.js.map} +1 -1
  29. package/package.json +5 -5
  30. package/skills/recorder/SKILL.md +2 -2
  31. package/dist/chunk-3I3A5OLB.js.map +0 -1
  32. package/dist/chunk-3XBQRZZC.js.map +0 -1
  33. package/dist/chunk-BVRIPCWA.js.map +0 -1
  34. package/dist/chunk-T5P2QGZ3.js.map +0 -1
  35. package/dist/opensteer-UGA6YBRN.js +0 -6
@@ -1,4 +1,4 @@
1
- import { filePathToUri, resolveStoragePath, encodePathSegment, ensureDirectory, pathExists, readJsonFile, writeJsonFileAtomic, normalizeTimestamp, withFilesystemLock, resolveLocalViewPreferencesPath, resolveLocalViewServiceLockDir, readLocalViewServiceState, isLocalViewServiceStateLive, clearLocalViewServiceState, getLocalViewServiceStateLiveness, clearPersistedSessionRecord, writePersistedSessionRecord, isProcessRunning, readPersistedLocalBrowserSessionRecord, buildLocalViewSessionId, selectAttachBrowserCandidate, resolveChromeExecutablePath, readDevToolsActivePort, inspectCdpEndpoint, normalizeNonEmptyString, toCanonicalJsonValue, canonicalJsonString, sha256Hex, joinStoragePath, writeBufferIfMissing, writeJsonFileExclusive, isAlreadyExistsError, readBinaryFile, listJsonFiles, expandHome, createLocalViewSessionManifest, writeLocalViewSessionManifest, deleteLocalViewSessionManifest, CURRENT_PROCESS_OWNER, getProcessLiveness, processOwnersEqual, parseProcessOwner } from './chunk-T5P2QGZ3.js';
1
+ import { filePathToUri, resolveStoragePath, encodePathSegment, ensureDirectory, pathExists, readJsonFile, writeJsonFileAtomic, normalizeTimestamp, withFilesystemLock, resolveLocalViewPreferencesPath, resolveLocalViewServiceLockDir, readLocalViewServiceState, isLocalViewServiceStateLive, clearLocalViewServiceState, getLocalViewServiceStateLiveness, clearPersistedSessionRecord, writePersistedSessionRecord, isAttachedLocalBrowserSessionReachable, isProcessRunning, readPersistedLocalBrowserSessionRecord, getPersistedLocalBrowserSessionOwnership, buildLocalViewSessionId, inspectCdpEndpoint, selectAttachBrowserCandidate, resolveChromeExecutablePath, readDevToolsActivePort, normalizeNonEmptyString, toCanonicalJsonValue, canonicalJsonString, sha256Hex, joinStoragePath, writeBufferIfMissing, writeJsonFileExclusive, isAlreadyExistsError, readBinaryFile, listJsonFiles, expandHome, createLocalViewSessionManifest, writeLocalViewSessionManifest, deleteLocalViewSessionManifest, CURRENT_PROCESS_OWNER, getProcessLiveness, processOwnersEqual, parseProcessOwner } from './chunk-GKYBP3KD.js';
2
2
  import path7, { join, resolve, dirname, relative } from 'path';
3
3
  import { randomBytes, randomUUID } from 'crypto';
4
4
  import { spawn } from 'child_process';
@@ -692,6 +692,9 @@ var FilesystemSessionSink = class {
692
692
  this.store = store;
693
693
  this.sessionId = sessionId;
694
694
  }
695
+ configure(input) {
696
+ return this.store.configureSession(this.sessionId, input);
697
+ }
695
698
  append(input) {
696
699
  return this.store.appendEvent(this.sessionId, input);
697
700
  }
@@ -722,40 +725,14 @@ var FilesystemObservationStoreImpl = class {
722
725
  const sessionId = normalizeNonEmptyString("sessionId", input.sessionId);
723
726
  const openedAt = normalizeTimestamp("openedAt", input.openedAt ?? Date.now());
724
727
  const config = normalizeObservabilityConfig(input.config);
725
- const redactor = createObservationRedactor(config);
726
- this.redactors.set(sessionId, redactor);
727
- const redactedLabels = redactor.redactLabels(config.labels);
728
- const redactedTraceContext = redactor.redactTraceContext(config.traceContext);
729
- await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
730
- const existing = await this.reconcileSessionManifest(sessionId);
731
- if (existing === void 0) {
732
- await ensureDirectory(this.sessionEventsDirectory(sessionId));
733
- await ensureDirectory(this.sessionArtifactsDirectory(sessionId));
734
- const session = {
735
- sessionId,
736
- profile: config.profile,
737
- ...redactedLabels === void 0 ? {} : { labels: redactedLabels },
738
- ...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
739
- openedAt,
740
- updatedAt: openedAt,
741
- currentSequence: 0,
742
- eventCount: 0,
743
- artifactCount: 0
744
- };
745
- await writeJsonFileExclusive(this.sessionManifestPath(sessionId), session);
746
- return;
747
- }
748
- const patched = {
749
- ...existing,
750
- profile: config.profile,
751
- ...redactedLabels === void 0 ? {} : { labels: redactedLabels },
752
- ...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
753
- updatedAt: Math.max(existing.updatedAt, openedAt)
754
- };
755
- await writeJsonFileAtomic(this.sessionManifestPath(sessionId), patched);
756
- });
728
+ await this.applySessionConfiguration(sessionId, config, openedAt);
757
729
  return new FilesystemSessionSink(this, sessionId);
758
730
  }
731
+ async configureSession(sessionId, input) {
732
+ const updatedAt = normalizeTimestamp("updatedAt", input.updatedAt ?? Date.now());
733
+ const config = normalizeObservabilityConfig(input.config);
734
+ await this.applySessionConfiguration(sessionId, config, updatedAt);
735
+ }
759
736
  async getSession(sessionId) {
760
737
  const manifestPath = this.sessionManifestPath(sessionId);
761
738
  if (!await pathExists(manifestPath)) {
@@ -976,6 +953,40 @@ var FilesystemObservationStoreImpl = class {
976
953
  sessionLockPath(sessionId) {
977
954
  return path7.join(this.sessionDirectory(sessionId), ".lock");
978
955
  }
956
+ async applySessionConfiguration(sessionId, config, timestamp) {
957
+ const redactor = createObservationRedactor(config);
958
+ this.redactors.set(sessionId, redactor);
959
+ const redactedLabels = redactor.redactLabels(config.labels);
960
+ const redactedTraceContext = redactor.redactTraceContext(config.traceContext);
961
+ await withFilesystemLock(this.sessionLockPath(sessionId), async () => {
962
+ const existing = await this.reconcileSessionManifest(sessionId);
963
+ if (existing === void 0) {
964
+ await ensureDirectory(this.sessionEventsDirectory(sessionId));
965
+ await ensureDirectory(this.sessionArtifactsDirectory(sessionId));
966
+ const session = {
967
+ sessionId,
968
+ profile: config.profile,
969
+ ...redactedLabels === void 0 ? {} : { labels: redactedLabels },
970
+ ...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
971
+ openedAt: timestamp,
972
+ updatedAt: timestamp,
973
+ currentSequence: 0,
974
+ eventCount: 0,
975
+ artifactCount: 0
976
+ };
977
+ await writeJsonFileExclusive(this.sessionManifestPath(sessionId), session);
978
+ return;
979
+ }
980
+ const patched = {
981
+ ...existing,
982
+ profile: config.profile,
983
+ ...redactedLabels === void 0 ? {} : { labels: redactedLabels },
984
+ ...redactedTraceContext === void 0 ? {} : { traceContext: redactedTraceContext },
985
+ updatedAt: Math.max(existing.updatedAt, timestamp)
986
+ };
987
+ await writeJsonFileAtomic(this.sessionManifestPath(sessionId), patched);
988
+ });
989
+ }
979
990
  async reconcileSessionManifest(sessionId) {
980
991
  const session = await this.getSession(sessionId);
981
992
  if (session === void 0) {
@@ -3473,7 +3484,7 @@ var OpensteerBrowserManager = class {
3473
3484
  }
3474
3485
  const liveRecord = await this.readLivePersistentBrowser(await this.ensureWorkspaceStore());
3475
3486
  return {
3476
- mode: this.mode,
3487
+ mode: liveRecord?.ownership === "attached" ? "attach" : this.mode,
3477
3488
  engine: liveRecord?.engine ?? this.engineName,
3478
3489
  ...this.workspace === void 0 ? {} : { workspace: this.workspace },
3479
3490
  live: liveRecord !== void 0
@@ -3601,6 +3612,7 @@ var OpensteerBrowserManager = class {
3601
3612
  });
3602
3613
  const liveRecord = {
3603
3614
  mode: "persistent",
3615
+ ownership: "owned",
3604
3616
  engine: "abp",
3605
3617
  baseUrl: launched.baseUrl,
3606
3618
  remoteDebuggingUrl: launched.remoteDebuggingUrl,
@@ -3687,11 +3699,78 @@ var OpensteerBrowserManager = class {
3687
3699
  }
3688
3700
  async createAttachEngine() {
3689
3701
  const endpoint = await resolveAttachEndpoint(this.browserOptions);
3690
- return this.createAttachedEngine({
3691
- endpoint,
3692
- ...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
3693
- freshTab: this.browserOptions?.freshTab ?? true,
3694
- onDispose: async () => void 0
3702
+ if (this.workspace === void 0) {
3703
+ return this.createAttachedEngine({
3704
+ endpoint,
3705
+ ...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
3706
+ freshTab: this.browserOptions?.freshTab ?? true,
3707
+ onDispose: async () => void 0
3708
+ });
3709
+ }
3710
+ const workspace = await this.ensureWorkspaceStore();
3711
+ return workspace.lock(async () => {
3712
+ const live = await this.readLivePersistentBrowser(workspace);
3713
+ if (live) {
3714
+ if (live.engine !== "playwright") {
3715
+ throw new Error(
3716
+ `workspace "${this.workspace}" already has a live ${live.engine} browser. Close it before attaching a Playwright browser.`
3717
+ );
3718
+ }
3719
+ if (live.ownership !== "attached") {
3720
+ throw new Error(
3721
+ `workspace "${this.workspace}" already has a live Opensteer-owned browser. Close it before attaching another browser.`
3722
+ );
3723
+ }
3724
+ if (live.endpoint === void 0) {
3725
+ throw new Error("workspace live browser record is missing a DevTools endpoint.");
3726
+ }
3727
+ if (live.endpoint !== endpoint) {
3728
+ throw new Error(
3729
+ `workspace "${this.workspace}" is already attached to a different browser endpoint. Close it before reattaching.`
3730
+ );
3731
+ }
3732
+ await bestEffortRegisterLocalViewSession({
3733
+ rootPath: workspace.rootPath,
3734
+ ...this.workspace === void 0 ? {} : { workspace: this.workspace },
3735
+ live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
3736
+ ownership: "attached"
3737
+ });
3738
+ return this.createAttachedEngine({
3739
+ endpoint: live.endpoint,
3740
+ ...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
3741
+ freshTab: this.browserOptions?.freshTab ?? true,
3742
+ onDispose: async () => void 0
3743
+ });
3744
+ }
3745
+ const liveRecord = {
3746
+ mode: "persistent",
3747
+ ownership: "attached",
3748
+ engine: "playwright",
3749
+ endpoint,
3750
+ pid: 0,
3751
+ startedAt: Date.now(),
3752
+ userDataDir: workspace.browserUserDataDir
3753
+ };
3754
+ await this.writeLivePersistentBrowser(workspace, liveRecord);
3755
+ const persistedLiveRecord = toPersistedLocalBrowserSessionRecord(this.workspace, liveRecord);
3756
+ await bestEffortRegisterLocalViewSession({
3757
+ rootPath: workspace.rootPath,
3758
+ ...this.workspace === void 0 ? {} : { workspace: this.workspace },
3759
+ live: persistedLiveRecord,
3760
+ ownership: "attached"
3761
+ });
3762
+ try {
3763
+ return await this.createAttachedEngine({
3764
+ endpoint,
3765
+ ...this.browserOptions?.headers === void 0 ? {} : { headers: this.browserOptions.headers },
3766
+ freshTab: this.browserOptions?.freshTab ?? true,
3767
+ onDispose: async () => void 0
3768
+ });
3769
+ } catch (error) {
3770
+ await this.unregisterLocalViewSessionForRecord(workspace.rootPath, persistedLiveRecord);
3771
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
3772
+ throw error;
3773
+ }
3695
3774
  });
3696
3775
  }
3697
3776
  async createPersistentEngine() {
@@ -3711,7 +3790,7 @@ var OpensteerBrowserManager = class {
3711
3790
  rootPath: workspace.rootPath,
3712
3791
  ...this.workspace === void 0 ? {} : { workspace: this.workspace },
3713
3792
  live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
3714
- ownership: "owned"
3793
+ ownership: live.ownership
3715
3794
  });
3716
3795
  return this.createAttachedEngine({
3717
3796
  endpoint: live.endpoint,
@@ -3727,6 +3806,7 @@ var OpensteerBrowserManager = class {
3727
3806
  });
3728
3807
  const liveRecord = {
3729
3808
  mode: "persistent",
3809
+ ownership: "owned",
3730
3810
  engine: "playwright",
3731
3811
  endpoint: launched.endpoint,
3732
3812
  pid: launched.pid,
@@ -3856,7 +3936,20 @@ var OpensteerBrowserManager = class {
3856
3936
  if (live === void 0) {
3857
3937
  return void 0;
3858
3938
  }
3939
+ if (live.ownership === "attached") {
3940
+ const attachedRecord = toPersistedLocalBrowserSessionRecord(this.workspace, live);
3941
+ if (!await isAttachedLocalBrowserSessionReachable(attachedRecord)) {
3942
+ await this.unregisterLocalViewSessionForRecord(workspace.rootPath, attachedRecord);
3943
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
3944
+ return void 0;
3945
+ }
3946
+ return live;
3947
+ }
3859
3948
  if (!isProcessRunning(live.pid)) {
3949
+ await this.unregisterLocalViewSessionForRecord(
3950
+ workspace.rootPath,
3951
+ toPersistedLocalBrowserSessionRecord(this.workspace, live)
3952
+ );
3860
3953
  await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
3861
3954
  return void 0;
3862
3955
  }
@@ -3904,6 +3997,10 @@ var OpensteerBrowserManager = class {
3904
3997
  workspace.rootPath,
3905
3998
  toPersistedLocalBrowserSessionRecord(this.workspace, live)
3906
3999
  );
4000
+ if (live.ownership === "attached") {
4001
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
4002
+ return;
4003
+ }
3907
4004
  if (live.engine === "playwright") {
3908
4005
  if (live.endpoint !== void 0) {
3909
4006
  await requestBrowserClose(live.endpoint).catch(() => void 0);
@@ -3932,10 +4029,18 @@ var OpensteerBrowserManager = class {
3932
4029
  }
3933
4030
  async unregisterLocalViewSessionForRecord(rootPath, record) {
3934
4031
  await bestEffortUnregisterLocalViewSession(
3935
- buildLocalViewSessionId({
4032
+ getPersistedLocalBrowserSessionOwnership(record) === "attached" ? buildLocalViewSessionId({
4033
+ rootPath,
4034
+ startedAt: record.startedAt,
4035
+ ownership: "attached",
4036
+ ...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
4037
+ ...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
4038
+ ...record.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: record.remoteDebuggingUrl }
4039
+ }) : buildLocalViewSessionId({
3936
4040
  rootPath,
3937
- pid: record.pid,
3938
- startedAt: record.startedAt
4041
+ startedAt: record.startedAt,
4042
+ ownership: "owned",
4043
+ pid: record.pid
3939
4044
  })
3940
4045
  );
3941
4046
  }
@@ -3970,6 +4075,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
3970
4075
  version: 1,
3971
4076
  provider: "local",
3972
4077
  ...workspace === void 0 ? {} : { workspace },
4078
+ ownership: live.ownership,
3973
4079
  engine: live.engine,
3974
4080
  ...live.endpoint === void 0 ? {} : { endpoint: live.endpoint },
3975
4081
  ...live.baseUrl === void 0 ? {} : { baseUrl: live.baseUrl },
@@ -3985,6 +4091,7 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
3985
4091
  function toWorkspaceLiveBrowserRecord(record) {
3986
4092
  return {
3987
4093
  mode: "persistent",
4094
+ ownership: getPersistedLocalBrowserSessionOwnership(record),
3988
4095
  engine: record.engine,
3989
4096
  ...record.endpoint === void 0 ? {} : { endpoint: record.endpoint },
3990
4097
  ...record.baseUrl === void 0 ? {} : { baseUrl: record.baseUrl },
@@ -4011,7 +4118,12 @@ function isAttachBrowserOptions(browser) {
4011
4118
  async function resolveAttachEndpoint(browser) {
4012
4119
  const endpoint = browser?.endpoint?.trim();
4013
4120
  if (endpoint && endpoint.length > 0) {
4014
- return endpoint;
4121
+ const inspected = await inspectCdpEndpoint({
4122
+ endpoint,
4123
+ ...browser?.headers === void 0 ? {} : { headers: browser.headers },
4124
+ timeoutMs: DEFAULT_TIMEOUT_MS
4125
+ });
4126
+ return inspected.endpoint;
4015
4127
  }
4016
4128
  const selection = await selectAttachBrowserCandidate({
4017
4129
  timeoutMs: DEFAULT_TIMEOUT_MS
@@ -4358,5 +4470,5 @@ async function sleep2(ms) {
4358
4470
  }
4359
4471
 
4360
4472
  export { DEFAULT_OPENSTEER_ENGINE, JSON_SCHEMA_DRAFT_2020_12, OPENSTEER_ENGINE_NAMES, OPENSTEER_FILESYSTEM_WORKSPACE_LAYOUT, OPENSTEER_FILESYSTEM_WORKSPACE_VERSION, OpensteerBrowserManager, OpensteerProtocolError, arraySchema, assertSupportedEngineOptions, buildLocalViewSessionUrl, createArtifactStore, createFilesystemOpensteerWorkspace, createObservationStore, createOpensteerError, defineSchema, ensureLocalViewServiceRunning, enumSchema, integerSchema, isOpensteerProtocolError, literalSchema, manifestToExternalBinaryLocation, normalizeObservabilityConfig, normalizeObservationContext, normalizeOpensteerEngineName, normalizeWorkspaceId, numberSchema, objectSchema, oneOfSchema, opensteerCapabilitySetSchema, opensteerErrorCodes, opensteerErrorSchema, recordSchema, resolveFilesystemWorkspacePath, resolveOpensteerEngineName, setLocalViewMode, stopLocalViewService, stringSchema, toOpensteerError };
4361
- //# sourceMappingURL=chunk-3XBQRZZC.js.map
4362
- //# sourceMappingURL=chunk-3XBQRZZC.js.map
4473
+ //# sourceMappingURL=chunk-EXXRLPLI.js.map
4474
+ //# sourceMappingURL=chunk-EXXRLPLI.js.map