@agentxm/workspace-state 0.28.10 → 0.28.12

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.
@@ -31,6 +31,14 @@ export interface UserWorkspaceLayout {
31
31
  readonly owner?: Handle;
32
32
  }
33
33
  export type WorkspaceLayout = ProjectWorkspaceLayout | UserWorkspaceLayout;
34
+ /**
35
+ * The same layout with `owner` established.
36
+ *
37
+ * A layout is resolved once from settings, so a command that records an owner
38
+ * must replace it for the owner to be visible to the resolution that follows
39
+ * in the same run.
40
+ */
41
+ export declare const withLayoutOwner: (layout: WorkspaceLayout, owner: Handle) => WorkspaceLayout;
34
42
  export declare const resolveProjectWorkspaceStatePaths: (path: Path.Path, projectRoot: AbsolutePath) => {
35
43
  settingsPath: string & import("effect/Brand").Brand<"AbsolutePath">;
36
44
  lockPath: string & import("effect/Brand").Brand<"AbsolutePath">;
@@ -27,6 +27,14 @@ const EXTENSION_TYPES = [
27
27
  "knowledge",
28
28
  "pack",
29
29
  ];
30
+ /**
31
+ * The same layout with `owner` established.
32
+ *
33
+ * A layout is resolved once from settings, so a command that records an owner
34
+ * must replace it for the owner to be visible to the resolution that follows
35
+ * in the same run.
36
+ */
37
+ export const withLayoutOwner = (layout, owner) => layout.scope === "project" ? { ...layout, owner } : { ...layout, owner };
30
38
  export const resolveProjectWorkspaceStatePaths = (path, projectRoot) => ({
31
39
  settingsPath: makeAbsolutePath(path, path.join(projectRoot, SETTINGS_FILENAME)),
32
40
  lockPath: makeAbsolutePath(path, path.join(projectRoot, LOCK_FILENAME)),
@@ -277,6 +277,8 @@ export interface WorkspaceMutationsService {
277
277
  readonly records: WorkspaceReadModelRecords;
278
278
  /** Resolve owner: project settings -> user-scope settings -> Option.none(). */
279
279
  readonly getConfiguredOwner: () => Effect.Effect<Option.Option<Handle>, WorkspaceSettingsReadFailure>;
280
+ /** Record the owner in the selected scope's settings. Serialized by semaphore. */
281
+ readonly setOwner: (owner: Handle) => Effect.Effect<void, WorkspaceSettingsMutationFailure>;
280
282
  /** Repository publication default for this exact workspace scope. */
281
283
  readonly getPublishDefaultVisibility: () => Effect.Effect<Option.Option<ExtensionVisibility>, WorkspaceSettingsReadFailure>;
282
284
  /** Resolve minimumReleaseAge: project settings -> user-scope settings -> default. */
@@ -48,7 +48,7 @@ export declare const makeWorkspaceMutations: (options: WorkspaceLayerOptions, ma
48
48
  scope: "project" | "user";
49
49
  path: string & import("effect/Brand").Brand<"AbsolutePath">;
50
50
  baseDir: string & import("effect/Brand").Brand<"AbsolutePath">;
51
- layout: import("./layout.js").ProjectWorkspaceLayout | import("./layout.js").UserWorkspaceLayout;
51
+ readonly layout: import("./layout.js").ProjectWorkspaceLayout | import("./layout.js").UserWorkspaceLayout;
52
52
  runTransaction: import("./service-interface.js").WorkspaceTransactionRunner;
53
53
  acquireTransition: import("./service-interface.js").WorkspaceTransitionAcquirer;
54
54
  getLockfileState: () => Effect.Effect<LockfileState, LockfileValidationError | WorkspaceRootEscape>;
@@ -92,6 +92,7 @@ export declare const makeWorkspaceMutations: (options: WorkspaceLayerOptions, ma
92
92
  rows: (type: "skill" | "mcp-server" | "subagent" | "rule" | "hook" | "knowledge" | "pack") => Effect.Effect<ReadonlyArray<import("./read-model-record-types.ts").ReadModelRecordRow>, WorkspaceStateReadFailure>;
93
93
  };
94
94
  getConfiguredOwner: () => Effect.Effect<Option.Option<string & import("effect/Brand").Brand<"Handle">>, SettingsReadError | WorkspaceRootEscape, never>;
95
+ setOwner: (owner: Handle) => Effect.Effect<void, import("../settings/errors.ts").SettingsWriteError | import("./transaction.ts").WorkspaceSnapshotError | SettingsReadError | WorkspaceRootEscape, never>;
95
96
  getPublishDefaultVisibility: () => Effect.Effect<Option.Option<"public" | "private">, SettingsReadError | WorkspaceRootEscape, never>;
96
97
  getMinimumReleaseAge: () => Effect.Effect<string, SettingsReadError | WorkspaceRootEscape, never>;
97
98
  getMinimumReleaseAgeExclude: () => Effect.Effect<ScopedReleaseAgeExcludePattern[], SettingsReadError | WorkspaceRootEscape, never>;
@@ -38,7 +38,7 @@ import { lockEntryToSourceParams } from "./lock-entry-to-source-params.js";
38
38
  import { makeAbsolutePath } from "@agentxm/extension-model/unstable/path-types";
39
39
  import { resolveKnowledgeDiscoveryConfig } from "../knowledge/discovery-config.js";
40
40
  import { getProjectRuntimeDir, resolveUserHome } from "./paths.js";
41
- import { resolveProjectWorkspaceLayout, resolveProjectWorkspaceStatePaths, resolveUserWorkspaceLayout, } from "./layout.js";
41
+ import { resolveProjectWorkspaceLayout, resolveProjectWorkspaceStatePaths, resolveUserWorkspaceLayout, withLayoutOwner, } from "./layout.js";
42
42
  import * as DateTime from "effect/DateTime";
43
43
  import * as Effect from "effect/Effect";
44
44
  import * as Layer from "effect/Layer";
@@ -127,7 +127,9 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
127
127
  const userSettings = yield* readSettingsCell(userRuntimeDir, "user").pipe(Effect.map(Option.getOrElse(() => createDefaultSettings())));
128
128
  const projectLayout = yield* resolveProjectWorkspaceLayout(options.projectRoot, projectSettings);
129
129
  const userLayout = yield* resolveUserWorkspaceLayout(userHome, userSettings);
130
- const layout = options.scope === "project" ? projectLayout : userLayout;
130
+ // Reassigned by `setOwner`, which is why every reader goes through this
131
+ // binding rather than a captured snapshot.
132
+ let layout = options.scope === "project" ? projectLayout : userLayout;
131
133
  // Built-in sources: parameterized via options, falling back to git forges only
132
134
  const builtInSources = options.builtInSources ?? [
133
135
  { name: "github", type: "github", url: new URL("https://github.com") },
@@ -258,7 +260,9 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
258
260
  scope: options.scope,
259
261
  path: workspaceDir,
260
262
  baseDir,
261
- layout,
263
+ get layout() {
264
+ return layout;
265
+ },
262
266
  runTransaction,
263
267
  acquireTransition,
264
268
  getLockfileState,
@@ -279,6 +283,11 @@ export const makeWorkspaceMutations = (options, makeCapabilities) => Effect.gen(
279
283
  return Option.some(globalSettings.owner);
280
284
  return Option.none();
281
285
  }),
286
+ setOwner: (owner) => withMutex(Effect.gen(function* () {
287
+ const current = yield* readSettingsSafe(workspaceDir);
288
+ yield* writeScopedSettings({ ...current, owner }).pipe(Effect.provide(fsLayer));
289
+ layout = withLayoutOwner(layout, owner);
290
+ })).pipe(Effect.withSpan("WorkspaceMutations.setOwner")),
282
291
  getPublishDefaultVisibility: () => readSettingsSafe(workspaceDir).pipe(Effect.map((settings) => Option.fromUndefinedOr(settings.publish?.defaultVisibility))),
283
292
  getMinimumReleaseAge: Effect.fn("WorkspaceMutations.getMinimumReleaseAge")(function* () {
284
293
  const scopedSettings = yield* readSettingsSafe(workspaceDir);
@@ -230,6 +230,7 @@ export const makeBaseWorkspaceMock = (axmDir = "/tmp/axm", overrides) => {
230
230
  getConfiguredSourceByName: () => Effect.succeed(Option.none()),
231
231
  getRegistrySourceHosts: () => Effect.succeed([]),
232
232
  getConfiguredOwner: () => Effect.succeed(Option.none()),
233
+ setOwner: () => Effect.void,
233
234
  getPublishDefaultVisibility: () => Effect.succeed(Option.none()),
234
235
  getMinimumReleaseAge: () => Effect.succeed("24h"),
235
236
  getMinimumReleaseAgeExclude: () => Effect.succeed([]),
@@ -41,6 +41,7 @@ export interface PendingClosureRestorationFailure {
41
41
  readonly retained: ReadonlyArray<string>;
42
42
  }
43
43
  export interface WorkspaceTransactionContext {
44
+ readonly isTransitionCompromised: () => boolean;
44
45
  readonly fs: FileSystem.FileSystem;
45
46
  readonly path: Path.Path;
46
47
  readonly workspaceDir: string;
package/package.json CHANGED
@@ -4,8 +4,8 @@
4
4
  "url": "https://github.com/agentxm/axm/issues"
5
5
  },
6
6
  "dependencies": {
7
- "@agentxm/extension-model": "^0.28.10",
8
- "@agentxm/registry-protocol": "^0.28.10",
7
+ "@agentxm/extension-model": "^0.28.12",
8
+ "@agentxm/registry-protocol": "^0.28.12",
9
9
  "effect": "4.0.0-rc.112",
10
10
  "jsonc-parser": "^3.3.1",
11
11
  "semver": "^7.8.5",
@@ -55,5 +55,5 @@
55
55
  },
56
56
  "sideEffects": false,
57
57
  "type": "module",
58
- "version": "0.28.10"
58
+ "version": "0.28.12"
59
59
  }