@agentxm/extension-authoring 0.28.12 → 0.28.13

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 (75) hide show
  1. package/dist/src/adopt/adopt-extension.d.ts +71 -0
  2. package/dist/src/adopt/adopt-extension.js +174 -0
  3. package/dist/src/authored-declaration.d.ts +49 -0
  4. package/dist/src/authored-declaration.js +86 -0
  5. package/dist/src/authored-package-errors.d.ts +91 -0
  6. package/dist/src/authored-package-errors.js +36 -0
  7. package/dist/src/create/authoring-owner.d.ts +54 -0
  8. package/dist/src/create/authoring-owner.js +93 -0
  9. package/dist/src/create/create-extension.d.ts +127 -0
  10. package/dist/src/create/create-extension.js +440 -0
  11. package/dist/src/create/errors.d.ts +59 -0
  12. package/dist/src/create/errors.js +54 -0
  13. package/dist/src/create/scaffold-name.d.ts +15 -0
  14. package/dist/src/create/scaffold-name.js +16 -0
  15. package/dist/src/create/scaffolds/hook.d.ts +19 -0
  16. package/dist/src/create/scaffolds/hook.js +118 -0
  17. package/dist/src/create/scaffolds/knowledge.d.ts +14 -0
  18. package/dist/src/create/scaffolds/knowledge.js +45 -0
  19. package/dist/src/create/scaffolds/mcp-server.d.ts +17 -0
  20. package/dist/src/create/scaffolds/mcp-server.js +57 -0
  21. package/dist/src/create/scaffolds/pack.d.ts +13 -0
  22. package/dist/src/create/scaffolds/pack.js +37 -0
  23. package/dist/src/create/scaffolds/rule.d.ts +14 -0
  24. package/dist/src/create/scaffolds/rule.js +46 -0
  25. package/dist/src/create/scaffolds/scaffold.d.ts +51 -0
  26. package/dist/src/create/scaffolds/scaffold.js +45 -0
  27. package/dist/src/create/scaffolds/skill.d.ts +12 -0
  28. package/dist/src/create/scaffolds/skill.js +47 -0
  29. package/dist/src/create/scaffolds/subagent.d.ts +12 -0
  30. package/dist/src/create/scaffolds/subagent.js +47 -0
  31. package/dist/src/create-preflight.d.ts +3 -2
  32. package/dist/src/create-preflight.js +2 -1
  33. package/dist/src/errors.d.ts +1 -1
  34. package/dist/src/errors.js +1 -1
  35. package/dist/src/fork/fork-extension.d.ts +87 -0
  36. package/dist/src/fork/fork-extension.js +253 -0
  37. package/dist/src/fork-package.d.ts +2 -2
  38. package/dist/src/fork-package.js +4 -4
  39. package/dist/src/import/import-native-extension.d.ts +119 -0
  40. package/dist/src/import/import-native-extension.js +310 -0
  41. package/dist/src/import-native-package.d.ts +2 -2
  42. package/dist/src/import-native-package.js +4 -4
  43. package/dist/src/index.d.ts +20 -11
  44. package/dist/src/index.js +26 -13
  45. package/dist/src/packs/add-to-pack.d.ts +2 -2
  46. package/dist/src/packs/add-to-pack.js +4 -3
  47. package/dist/src/packs/change-pack-membership.d.ts +56 -0
  48. package/dist/src/packs/change-pack-membership.js +246 -0
  49. package/dist/src/packs/configured-pack-selector.d.ts +24 -0
  50. package/dist/src/packs/configured-pack-selector.js +53 -0
  51. package/dist/src/packs/glob.d.ts +14 -0
  52. package/dist/src/packs/glob.js +44 -0
  53. package/dist/src/packs/membership-errors.d.ts +122 -0
  54. package/dist/src/packs/membership-errors.js +47 -0
  55. package/dist/src/packs/remove-from-pack.d.ts +2 -2
  56. package/dist/src/packs/remove-from-pack.js +4 -3
  57. package/dist/src/step-failure.d.ts +31 -0
  58. package/dist/src/step-failure.js +253 -0
  59. package/dist/src/testing.d.ts +68 -0
  60. package/dist/src/testing.js +135 -0
  61. package/dist/src/version/change-authored-version.d.ts +73 -0
  62. package/dist/src/version/change-authored-version.js +224 -0
  63. package/dist/src/version/errors.d.ts +65 -0
  64. package/dist/src/version/errors.js +73 -0
  65. package/package.json +23 -8
  66. package/dist/src/desired-identity.d.ts +0 -19
  67. package/dist/src/desired-identity.js +0 -26
  68. package/dist/src/failure-adapter.d.ts +0 -31
  69. package/dist/src/failure-adapter.js +0 -23
  70. package/dist/src/hooks/new-hook.d.ts +0 -46
  71. package/dist/src/hooks/new-hook.js +0 -164
  72. package/dist/src/packs/new-pack.d.ts +0 -37
  73. package/dist/src/packs/new-pack.js +0 -90
  74. package/dist/src/skills/new-skill.d.ts +0 -38
  75. package/dist/src/skills/new-skill.js +0 -102
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The starter content a new subagent is created with.
3
+ *
4
+ * @experimental This API is unstable and may change without notice.
5
+ */
6
+ import * as Effect from "effect/Effect";
7
+ import * as Path from "effect/Path";
8
+ import { decodeExtensionNameSync } from "@agentxm/extension-model/unstable/extensions";
9
+ import { MANIFEST_FILENAME, MANIFEST_SCHEMA_URL, } from "@agentxm/extension-model/unstable/subagents/manifest-schema";
10
+ import { decodeVersionSync } from "@agentxm/extension-model/unstable/version-constraints";
11
+ import { manifestText, stageFileAt } from "./scaffold.js";
12
+ const INITIAL_VERSION = decodeVersionSync("0.0.1");
13
+ const subagentBody = (name) => [
14
+ "---",
15
+ `name: ${name}`,
16
+ "---",
17
+ "",
18
+ "Describe what this subagent does and when to delegate work to it.\n",
19
+ ].join("\n");
20
+ export const subagentScaffold = (args) => {
21
+ const body = `src/${args.name}.md`;
22
+ const manifest = {
23
+ $schema: MANIFEST_SCHEMA_URL,
24
+ owner: args.owner,
25
+ type: "subagent",
26
+ name: decodeExtensionNameSync(args.name),
27
+ version: INITIAL_VERSION,
28
+ };
29
+ return {
30
+ subject: "Subagent",
31
+ version: INITIAL_VERSION,
32
+ contentFiles: [MANIFEST_FILENAME, body],
33
+ entryFile: body,
34
+ populate: (stagingPath) => Effect.gen(function* () {
35
+ const path = yield* Path.Path;
36
+ yield* stageFileAt({
37
+ path: path.join(stagingPath, MANIFEST_FILENAME),
38
+ contents: manifestText(manifest),
39
+ });
40
+ yield* stageFileAt({
41
+ path: path.join(stagingPath, "src", `${args.name}.md`),
42
+ contents: subagentBody(args.name),
43
+ });
44
+ }),
45
+ };
46
+ };
47
+ //# sourceMappingURL=subagent.js.map
@@ -1,6 +1,7 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as FileSystem from "effect/FileSystem";
3
- import { CreateDestinationExists, CreateDestinationInspectionFailed, CreateNameConfigured } from "@agentxm/extension-workspace";
3
+ import { CreateDestinationInspectionFailed, CreateNameConfigured } from "./authored-package-errors.js";
4
+ import { CreateDestinationExists } from "@agentxm/extension-materialization";
4
5
  export interface CreateOnlyPreflightArgs {
5
6
  readonly subject: string;
6
7
  readonly name: string;
@@ -8,5 +9,5 @@ export interface CreateOnlyPreflightArgs {
8
9
  readonly destinations: ReadonlyArray<string>;
9
10
  }
10
11
  /** Refuse every declared identity/path collision before a create operation mutates the workspace. */
11
- export declare const preflightCreateOnly: (args: CreateOnlyPreflightArgs) => Effect.Effect<undefined, CreateNameConfigured | CreateDestinationExists | CreateDestinationInspectionFailed, FileSystem.FileSystem>;
12
+ export declare const preflightCreateOnly: (args: CreateOnlyPreflightArgs) => Effect.Effect<undefined, CreateNameConfigured | CreateDestinationInspectionFailed | CreateDestinationExists, FileSystem.FileSystem>;
12
13
  //# sourceMappingURL=create-preflight.d.ts.map
@@ -1,6 +1,7 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as FileSystem from "effect/FileSystem";
3
- import { CreateDestinationExists, CreateDestinationInspectionFailed, CreateNameConfigured, } from "@agentxm/extension-workspace";
3
+ import { CreateDestinationInspectionFailed, CreateNameConfigured, } from "./authored-package-errors.js";
4
+ import { CreateDestinationExists } from "@agentxm/extension-materialization";
4
5
  /** Refuse every declared identity/path collision before a create operation mutates the workspace. */
5
6
  export const preflightCreateOnly = Effect.fn("Extensions.preflightCreateOnly")(function* (args) {
6
7
  if (args.configured) {
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import * as Schema from "effect/Schema";
9
9
  declare const AuthoringFailed_base: Schema.Class<AuthoringFailed, Schema.TaggedStruct<"AuthoringFailed", {
10
- readonly category: Schema.Literals<readonly ["conflict", "internal", "not_found", "validation"]>;
10
+ readonly category: Schema.Literals<readonly ["conflict", "internal", "not_found", "usage", "validation"]>;
11
11
  readonly detail: Schema.String;
12
12
  readonly recover: Schema.optional<Schema.String>;
13
13
  readonly suggestions: Schema.optional<Schema.$Array<Schema.Struct<{
@@ -18,7 +18,7 @@ const CarriedSuggestedActionSchema = Schema.Struct({
18
18
  * `suggestions`, and `cause` carry over verbatim.
19
19
  */
20
20
  export class AuthoringFailed extends Schema.TaggedError()("AuthoringFailed", {
21
- category: Schema.Literals(["conflict", "internal", "not_found", "validation"]),
21
+ category: Schema.Literals(["conflict", "internal", "not_found", "usage", "validation"]),
22
22
  detail: Schema.String,
23
23
  recover: Schema.optional(Schema.String),
24
24
  suggestions: Schema.optional(Schema.Array(CarriedSuggestedActionSchema)),
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Forking a managed AXM package into workspace authorship.
3
+ *
4
+ * A fork reads one package out of a source the person named, rewrites its
5
+ * identity to the target the workspace will author, and publishes it as a new
6
+ * canonical package. The source is never touched, and the fork starts at its
7
+ * own initial version rather than inheriting the original's.
8
+ *
9
+ * `prepare` settles every decision and stages the rewritten package into a
10
+ * scoped temporary directory: which package the source resolves to, whether
11
+ * the target identity is one this workspace may author, whether the
12
+ * destination is free, and what activation the fork carries. Nothing under
13
+ * the workspace is written. `previewOrApply` resolves the frozen candidate, so
14
+ * a preview and an apply describe one decision — and the staged content is
15
+ * re-hashed before publication, so content that changed between the two
16
+ * refuses rather than lands.
17
+ *
18
+ * @experimental This API is unstable and may change without notice.
19
+ */
20
+ import * as Effect from "effect/Effect";
21
+ import * as FileSystem from "effect/FileSystem";
22
+ import type * as HttpClient from "effect/unstable/http/HttpClient";
23
+ import * as Option from "effect/Option";
24
+ import * as Path from "effect/Path";
25
+ import type * as Scope from "effect/Scope";
26
+ import { ExtensionManagers, McpSecretStore, type ManagerRequirements, type RecipeRequirements } from "@agentxm/extension-materialization";
27
+ import { type ExtensionType, type FqnInvalidError, type Handle } from "@agentxm/extension-model/unstable/extensions";
28
+ import { SourceHostProviders, WorkspaceCatalog, type SourceResolutionFailure } from "@agentxm/extension-sources";
29
+ import { type CandidateFingerprintFailed, type ExecutionCandidate, type PlanExecution } from "@agentxm/workspace-operations";
30
+ import type { CodingAgentRepository } from "@agentxm/workspace-projection";
31
+ import { WorkspaceMutations, type ConfiguredAgentOutcomesProvider, type LockfileValidationError, type PackageContentHashFailed, type WorkspaceLockfileReadFailure, type WorkspaceSettingsReadFailure } from "@agentxm/workspace-state";
32
+ import { AuthoringFailed } from "../errors.js";
33
+ import type { AuthoredPackageError } from "../authored-package-errors.js";
34
+ import type { FrontmatterParseFailure } from "@agentxm/extension-content";
35
+ import { AuthoringScopeUnsupported, type AuthoringOwnerMismatch, type AuthoringOwnerRequired } from "../create/errors.js";
36
+ export interface ForkExtensionRequest {
37
+ /** Registry, workspace, local, or Git AXM package source, as typed. */
38
+ readonly source: string;
39
+ /** Owner-qualified identity the fork will carry. */
40
+ readonly target: string;
41
+ /** Source package identity, when the source holds more than one package. */
42
+ readonly from: Option.Option<string>;
43
+ /** Materialize the fork immediately instead of leaving it declared and inert. */
44
+ readonly enable: boolean;
45
+ /**
46
+ * Whether the invoking surface can prompt for a connection input an MCP
47
+ * server's manifest requires.
48
+ */
49
+ readonly nonInteractive: boolean;
50
+ }
51
+ /** What every step in a fork may require when it runs. */
52
+ export type ForkExtensionRequirements = ManagerRequirements | RecipeRequirements | WorkspaceMutations | CodingAgentRepository | McpSecretStore;
53
+ /** A settled fork: every decision is made and nothing under the workspace is written. */
54
+ export interface ForkExtensionCandidate {
55
+ readonly type: ExtensionType;
56
+ /** Owner-qualified identity of the fork. */
57
+ readonly fqn: string;
58
+ readonly owner: Handle;
59
+ readonly name: string;
60
+ /** Owner-qualified identity of the package the fork was taken from. */
61
+ readonly sourceFqn: string;
62
+ /** Where the source package was found, in operator-facing terms. */
63
+ readonly origin: string;
64
+ /** Workspace-relative directory the fork will occupy. */
65
+ readonly authoredPath: string;
66
+ /** Workspace-relative settings file the declaration is written to. */
67
+ readonly settingsPath: string;
68
+ /** Whether the fork is materialized once it is declared. */
69
+ readonly enabled: boolean;
70
+ readonly execution: ExecutionCandidate<ForkExtensionRequirements>;
71
+ }
72
+ /** Every failure settling a fork can surface before anything is written. */
73
+ export type ForkExtensionFailure = AuthoringFailed | AuthoredPackageError | FrontmatterParseFailure | AuthoringOwnerRequired | AuthoringOwnerMismatch | AuthoringScopeUnsupported | SourceResolutionFailure | PackageContentHashFailed | LockfileValidationError | WorkspaceLockfileReadFailure | WorkspaceSettingsReadFailure | CandidateFingerprintFailed | FqnInvalidError;
74
+ /** Everything settling a fork reads before it freezes a candidate. */
75
+ export type PrepareForkExtensionRequirements = FileSystem.FileSystem | Path.Path | Scope.Scope | HttpClient.HttpClient | WorkspaceMutations | ExtensionManagers | SourceHostProviders | WorkspaceCatalog | ConfiguredAgentOutcomesProvider;
76
+ /** The plan a fork resolves; it names the operation everywhere the fork is reported. */
77
+ export declare const forkExtensionPlanName = "Fork AXM extension package";
78
+ /** Settle a fork and stage its content without writing anything to the workspace. */
79
+ export declare const prepareForkExtension: (request: ForkExtensionRequest) => Effect.Effect<ForkExtensionCandidate, ForkExtensionFailure, PrepareForkExtensionRequirements>;
80
+ /** Preview or apply a settled fork, resolving to one operation outcome. */
81
+ export declare const previewOrApplyForkExtension: (candidate: ForkExtensionCandidate, execution: PlanExecution) => Effect.Effect<import("@agentxm/workspace-operations").OperationResolution<never>, WorkspaceSettingsReadFailure | import("@agentxm/workspace-operations").ApprovalRecoveryMissing | import("@agentxm/workspace-operations").PlanInteractionFailed | import("@agentxm/workspace-transactions").WorkspaceTransitionAcquireFailure, ConfiguredAgentOutcomesProvider | import("@agentxm/workspace-operations").OperationJournal | import("@agentxm/workspace-operations").ResolvePlanInteraction | import("@agentxm/workspace-transactions").FootprintRecorder | ForkExtensionRequirements>;
82
+ /** The fork use case: settle a request, then preview or apply it. */
83
+ export declare const ForkExtension: {
84
+ readonly prepare: (request: ForkExtensionRequest) => Effect.Effect<ForkExtensionCandidate, ForkExtensionFailure, PrepareForkExtensionRequirements>;
85
+ readonly previewOrApply: (candidate: ForkExtensionCandidate, execution: PlanExecution) => Effect.Effect<import("@agentxm/workspace-operations").OperationResolution<never>, WorkspaceSettingsReadFailure | import("@agentxm/workspace-operations").ApprovalRecoveryMissing | import("@agentxm/workspace-operations").PlanInteractionFailed | import("@agentxm/workspace-transactions").WorkspaceTransitionAcquireFailure, ConfiguredAgentOutcomesProvider | import("@agentxm/workspace-operations").OperationJournal | import("@agentxm/workspace-operations").ResolvePlanInteraction | import("@agentxm/workspace-transactions").FootprintRecorder | ForkExtensionRequirements>;
86
+ };
87
+ //# sourceMappingURL=fork-extension.d.ts.map
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Forking a managed AXM package into workspace authorship.
3
+ *
4
+ * A fork reads one package out of a source the person named, rewrites its
5
+ * identity to the target the workspace will author, and publishes it as a new
6
+ * canonical package. The source is never touched, and the fork starts at its
7
+ * own initial version rather than inheriting the original's.
8
+ *
9
+ * `prepare` settles every decision and stages the rewritten package into a
10
+ * scoped temporary directory: which package the source resolves to, whether
11
+ * the target identity is one this workspace may author, whether the
12
+ * destination is free, and what activation the fork carries. Nothing under
13
+ * the workspace is written. `previewOrApply` resolves the frozen candidate, so
14
+ * a preview and an apply describe one decision — and the staged content is
15
+ * re-hashed before publication, so content that changed between the two
16
+ * refuses rather than lands.
17
+ *
18
+ * @experimental This API is unstable and may change without notice.
19
+ */
20
+ import * as Effect from "effect/Effect";
21
+ import * as FileSystem from "effect/FileSystem";
22
+ import * as Option from "effect/Option";
23
+ import * as Path from "effect/Path";
24
+ import { ExtensionManagers, McpSecretStore, buildAuthoredExtensionStep, copyExtensionDirectory, createCanonicalDirectory, materializeAuthoredMcpServer, recoverCanonicalDirectory, } from "@agentxm/extension-materialization";
25
+ import { extensionTypeFromPlural, extensionTypeToPlural, formatFqn, parseFqn, parseSourceQualifiedRegistrySourcePatternParts, } from "@agentxm/extension-model/unstable/extensions";
26
+ import { SourceHostProviders, WorkspaceCatalog, findExtensionPackagesFromSource, inspectExtensionPackage, resolveSource, } from "@agentxm/extension-sources";
27
+ import { operationPresentation, prepareExecutionCandidate, resolveExecutionCandidate, } from "@agentxm/workspace-operations";
28
+ import { WorkspaceMutations, computePackageContentHash, } from "@agentxm/workspace-state";
29
+ import { authoredDeclaration } from "../authored-declaration.js";
30
+ import { preflightCreateOnly } from "../create-preflight.js";
31
+ import { AuthoringFailed } from "../errors.js";
32
+ import { authoringStepFailure } from "../step-failure.js";
33
+ import { requireAuthoredOwner, settingsRelativePath } from "../create/authoring-owner.js";
34
+ import { AuthoringScopeUnsupported, } from "../create/errors.js";
35
+ import { forkExtensionPackage } from "../fork-package.js";
36
+ /** The version a fork starts at, regardless of what the source published. */
37
+ const INITIAL_FORK_VERSION = "0.1.0";
38
+ // -----------------------------------------------------------------------------
39
+ // Source selection
40
+ // -----------------------------------------------------------------------------
41
+ const exactFilter = (fqn) => ({
42
+ names: [fqn.name],
43
+ owner: Option.some(fqn.owner),
44
+ type: fqn.type,
45
+ });
46
+ /**
47
+ * Which packages in the named source the fork will consider.
48
+ *
49
+ * An explicit `--from` identity is decisive. Otherwise a source that already
50
+ * names an owner, type, and name in its own syntax narrows to that package,
51
+ * and anything else considers every package the source holds — which is what
52
+ * makes "the source contains more than one" an answerable ambiguity rather
53
+ * than a silent first-match.
54
+ */
55
+ const filterForSource = (source, from) => {
56
+ if (Option.isSome(from)) {
57
+ return Effect.fromResult(parseFqn(from.value)).pipe(Effect.map(exactFilter));
58
+ }
59
+ const registry = parseSourceQualifiedRegistrySourcePatternParts(source);
60
+ if (registry?.type !== undefined && registry.name !== undefined) {
61
+ return Effect.succeed({
62
+ names: [registry.name],
63
+ owner: Option.some(registry.owner),
64
+ type: extensionTypeFromPlural[registry.type],
65
+ });
66
+ }
67
+ return Effect.succeed({ names: [], owner: Option.none(), type: "*" });
68
+ };
69
+ const selectPackage = (packages) => {
70
+ const candidate = packages[0];
71
+ if (candidate === undefined) {
72
+ return Effect.fail(new AuthoringFailed({
73
+ category: "not_found",
74
+ detail: "No managed AXM extension package was found; use skills import or subagents import for supported unmanaged/native content",
75
+ }));
76
+ }
77
+ if (packages.length > 1) {
78
+ return Effect.fail(new AuthoringFailed({
79
+ category: "validation",
80
+ detail: "The source contains multiple AXM packages; select one with --from <FQN>",
81
+ }));
82
+ }
83
+ return Effect.succeed(candidate);
84
+ };
85
+ /**
86
+ * Build the fork's publication step with the requirements this use case keeps
87
+ * in `R`, so the workspace facade and the credential store stay requirements
88
+ * rather than captured values.
89
+ */
90
+ const forkStep = (manager, args) => buildAuthoredExtensionStep(manager, args);
91
+ /** The plan a fork resolves; it names the operation everywhere the fork is reported. */
92
+ export const forkExtensionPlanName = "Fork AXM extension package";
93
+ // -----------------------------------------------------------------------------
94
+ // prepare
95
+ // -----------------------------------------------------------------------------
96
+ /** Settle a fork and stage its content without writing anything to the workspace. */
97
+ export const prepareForkExtension = Effect.fn("ForkExtension.prepare")(function* (request) {
98
+ const ws = yield* WorkspaceMutations;
99
+ const fs = yield* FileSystem.FileSystem;
100
+ const path = yield* Path.Path;
101
+ const managers = yield* ExtensionManagers;
102
+ const providers = yield* SourceHostProviders;
103
+ const target = yield* Effect.fromResult(parseFqn(request.target));
104
+ yield* requireAuthoredOwner(target.owner, { subject: "package", command: "fork" });
105
+ if (ws.layout.scope !== "project") {
106
+ return yield* new AuthoringScopeUnsupported({ subject: "fork", scope: ws.layout.scope });
107
+ }
108
+ const source = yield* resolveSource(request.source);
109
+ const filter = yield* filterForSource(request.source, request.from);
110
+ const packages = source.type === "workspace"
111
+ ? [
112
+ {
113
+ ...(yield* inspectExtensionPackage(path.join(ws.layout.authoredRoot(source.extensionType), source.name))),
114
+ origin: providers.origin(source),
115
+ },
116
+ ].filter((candidate) => filter.type !== "*" && filter.type !== candidate.identity.type
117
+ ? false
118
+ : filter.names.length > 0 && !filter.names.includes(candidate.identity.name)
119
+ ? false
120
+ : Option.isNone(filter.owner) || filter.owner.value === candidate.identity.owner)
121
+ : yield* findExtensionPackagesFromSource(source, filter);
122
+ const selected = yield* selectPackage(packages);
123
+ const name = target.name;
124
+ const targetDir = path.join(ws.layout.authoredRoot(target.type), name);
125
+ const authoredPath = path.relative(ws.baseDir, targetDir);
126
+ const settingsPath = settingsRelativePath(path, ws);
127
+ const fqn = formatFqn(target);
128
+ // Refuse an occupied destination here, so a preview refuses it too; the
129
+ // closure repeats the check under the transaction lock in case the
130
+ // destination is claimed between preview and apply.
131
+ const createOnly = preflightCreateOnly({
132
+ subject: "Fork target",
133
+ name,
134
+ configured: false,
135
+ destinations: [targetDir],
136
+ });
137
+ yield* createOnly;
138
+ const stagingRoot = yield* fs.makeTempDirectoryScoped({ prefix: "axm-fork-" }).pipe(Effect.mapError((cause) => new AuthoringFailed({
139
+ category: "internal",
140
+ detail: "Fork staging directory could not be created",
141
+ cause,
142
+ })));
143
+ const stagedPackage = path.join(stagingRoot, "package");
144
+ yield* forkExtensionPackage({
145
+ sourceDir: selected.directory,
146
+ targetDir: stagedPackage,
147
+ sourceIdentity: selected.identity,
148
+ target,
149
+ });
150
+ const stagedHash = yield* computePackageContentHash(stagedPackage);
151
+ const declaration = authoredDeclaration(ws, target.type, name);
152
+ const current = yield* declaration.read;
153
+ const enabled = request.enable || Option.getOrElse(current.enabled, () => false);
154
+ const artifact = {
155
+ path: authoredPath,
156
+ scope: ws.scope,
157
+ version: INITIAL_FORK_VERSION,
158
+ change: "created",
159
+ targets: [
160
+ { path: authoredPath, change: "created" },
161
+ { path: settingsPath, change: "created" },
162
+ ],
163
+ };
164
+ const sourceFqn = `${selected.identity.owner}/${extensionTypeToPlural[selected.identity.type]}/${selected.identity.name}`;
165
+ const common = {
166
+ toStepFailure: authoringStepFailure,
167
+ location: targetDir,
168
+ versionRange: Option.none(),
169
+ label: `Fork ${sourceFqn} -> ${fqn}`,
170
+ message: `Forked ${fqn}`,
171
+ enabled,
172
+ allowConfiguredSourceTransition: true,
173
+ markAuthored: declaration.declare({ enabled: true, env: current.env }),
174
+ finalizeAuthored: declaration.declare({ enabled, env: current.env }),
175
+ plannedArtifact: artifact,
176
+ buildArtifact: () => Effect.succeed(artifact),
177
+ preflight: Effect.gen(function* () {
178
+ yield* recoverCanonicalDirectory({ baseDir: ws.baseDir, canonicalPath: targetDir });
179
+ yield* createOnly;
180
+ }),
181
+ scaffold: createCanonicalDirectory({
182
+ baseDir: ws.baseDir,
183
+ canonicalPath: targetDir,
184
+ subject: "Fork target",
185
+ populate: (publicationPath) => copyExtensionDirectory(stagedPackage, publicationPath).pipe(Effect.mapError((cause) => new AuthoringFailed({
186
+ category: "internal",
187
+ detail: `Prepared fork could not be staged for ${authoredPath}`,
188
+ cause,
189
+ }))),
190
+ validate: (publicationPath) => computePackageContentHash(publicationPath).pipe(Effect.flatMap((currentHash) => currentHash === stagedHash
191
+ ? Effect.void
192
+ : new AuthoringFailed({
193
+ category: "conflict",
194
+ detail: "Prepared fork content changed before it could be applied",
195
+ }))),
196
+ }).pipe(Effect.asVoid),
197
+ };
198
+ const step = (() => {
199
+ switch (target.type) {
200
+ case "skill":
201
+ return forkStep(managers.skill, { ...common, target: { type: "skill", name } });
202
+ case "subagent":
203
+ return forkStep(managers.subagent, { ...common, target: { type: "subagent", name } });
204
+ case "rule":
205
+ return forkStep(managers.rule, { ...common, target: { type: "rule", name } });
206
+ case "hook":
207
+ return forkStep(managers.hook, { ...common, target: { type: "hook", name } });
208
+ case "knowledge":
209
+ return forkStep(managers.knowledge, { ...common, target: { type: "knowledge", name } });
210
+ case "pack":
211
+ return forkStep(managers.pack, {
212
+ ...common,
213
+ target: { type: "pack", owner: target.owner, name },
214
+ });
215
+ case "mcp-server":
216
+ return forkStep(managers["mcp-server"], {
217
+ ...common,
218
+ target: { type: "mcp-server", name },
219
+ materializeInstall: (ref) => materializeAuthoredMcpServer({ ref, nonInteractive: request.nonInteractive }),
220
+ });
221
+ }
222
+ })();
223
+ const plan = {
224
+ _tag: "Plan",
225
+ name: forkExtensionPlanName,
226
+ description: Option.some(`Create ${fqn} from ${selected.origin}; the source remains unchanged and the fork starts ${enabled ? "enabled" : "disabled"}`),
227
+ presentation: operationPresentation({ imperative: "fork", past: "Forked", gerund: "Forking" }, target.type),
228
+ jobs: [{ concurrency: 1, steps: [step] }],
229
+ };
230
+ return {
231
+ type: target.type,
232
+ fqn,
233
+ owner: target.owner,
234
+ name,
235
+ sourceFqn,
236
+ origin: selected.origin,
237
+ authoredPath,
238
+ settingsPath,
239
+ enabled,
240
+ execution: yield* prepareExecutionCandidate(plan),
241
+ };
242
+ });
243
+ // -----------------------------------------------------------------------------
244
+ // previewOrApply
245
+ // -----------------------------------------------------------------------------
246
+ /** Preview or apply a settled fork, resolving to one operation outcome. */
247
+ export const previewOrApplyForkExtension = (candidate, execution) => resolveExecutionCandidate(candidate.execution, execution);
248
+ /** The fork use case: settle a request, then preview or apply it. */
249
+ export const ForkExtension = {
250
+ prepare: prepareForkExtension,
251
+ previewOrApply: previewOrApplyForkExtension,
252
+ };
253
+ //# sourceMappingURL=fork-extension.js.map
@@ -1,8 +1,8 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as FileSystem from "effect/FileSystem";
3
3
  import * as Path from "effect/Path";
4
- import { ForkPackageConflict, ForkPackageFailed, ForkPackageInvalid } from "@agentxm/extension-workspace";
5
- import { type FrontmatterParseFailure } from "@agentxm/registry-protocol/unstable/content/frontmatter";
4
+ import { ForkPackageConflict, ForkPackageFailed, ForkPackageInvalid } from "./authored-package-errors.js";
5
+ import { type FrontmatterParseFailure } from "@agentxm/extension-content";
6
6
  import type { ExtensionFqnParts, ExtensionName, ExtensionType } from "@agentxm/extension-model/unstable/extensions/common";
7
7
  import type { Handle } from "@agentxm/extension-model/unstable/extensions/handle";
8
8
  export interface ForkExtensionPackageArgs {
@@ -4,10 +4,10 @@ import * as Option from "effect/Option";
4
4
  import * as Path from "effect/Path";
5
5
  import * as Schema from "effect/Schema";
6
6
  import YAML from "yaml";
7
- import { ForkPackageConflict, ForkPackageFailed, ForkPackageInvalid, } from "@agentxm/extension-workspace";
8
- import { ManifestIdentitySchema, manifestFilenameForType, manifestSchemaForType, } from "@agentxm/registry-protocol/unstable/publish/manifest-policy";
9
- import { copyExtensionDirectory } from "@agentxm/extension-workspace";
10
- import { parseFrontmatterEffect, } from "@agentxm/registry-protocol/unstable/content/frontmatter";
7
+ import { ForkPackageConflict, ForkPackageFailed, ForkPackageInvalid, } from "./authored-package-errors.js";
8
+ import { ManifestIdentitySchema, manifestFilenameForType, manifestSchemaForType, } from "@agentxm/extension-content";
9
+ import { copyExtensionDirectory } from "@agentxm/extension-materialization";
10
+ import { parseFrontmatterEffect } from "@agentxm/extension-content";
11
11
  const INITIAL_FORK_VERSION = "0.1.0";
12
12
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
13
13
  const readJson = (filePath) => Effect.gen(function* () {
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Importing native, unmanaged content as an authored AXM package.
3
+ *
4
+ * Three routes share one decision: a native skill directory or file, a native
5
+ * subagent document, and a native MCP connection declared in an agent's own
6
+ * config all become a workspace-authored package that carries the identity the
7
+ * person asked for, not the identity the native content happened to have. The
8
+ * native source is never modified — except for an MCP connection, whose native
9
+ * declaration is retired only after the managed package validates, because
10
+ * leaving both would give one connection two owners.
11
+ *
12
+ * `prepare` settles the identity, the destination, and the activation, and
13
+ * stages the converted package into a scoped temporary directory; nothing
14
+ * under the workspace is written. `previewOrApply` resolves that candidate.
15
+ *
16
+ * @experimental This API is unstable and may change without notice.
17
+ */
18
+ import * as Effect from "effect/Effect";
19
+ import * as FileSystem from "effect/FileSystem";
20
+ import type * as HttpClient from "effect/unstable/http/HttpClient";
21
+ import * as Option from "effect/Option";
22
+ import * as Path from "effect/Path";
23
+ import type * as Scope from "effect/Scope";
24
+ import { ExtensionManagers, McpSecretStore, type ManagerRequirements, type NativeMcpEntryRef, type RecipeRequirements } from "@agentxm/extension-materialization";
25
+ import { type FqnInvalidError, type Handle } from "@agentxm/extension-model/unstable/extensions";
26
+ import { SourceHostProviders, WorkspaceCatalog, type SourceResolutionFailure } from "@agentxm/extension-sources";
27
+ import { type CandidateFingerprintFailed, type ExecutionCandidate, type PlanExecution } from "@agentxm/workspace-operations";
28
+ import type { CodingAgentRepository } from "@agentxm/workspace-projection";
29
+ import { WorkspaceMutations, type ConfiguredAgentOutcomesProvider, type LockfileValidationError, type PackageContentHashFailed, type WorkspaceLockfileReadFailure, type WorkspaceSettingsReadFailure } from "@agentxm/workspace-state";
30
+ import type { AuthoredPackageError } from "../authored-package-errors.js";
31
+ import { AuthoringFailed } from "../errors.js";
32
+ import { AuthoringScopeUnsupported, type AuthoringOwnerMismatch, type AuthoringOwnerRequired } from "../create/errors.js";
33
+ import type { FrontmatterParseFailure } from "@agentxm/extension-content";
34
+ /** The extension types native content can be imported as. */
35
+ export type NativeImportType = "skill" | "subagent" | "mcp-server";
36
+ interface ImportRequestBase {
37
+ /** Owner-qualified identity the imported package will carry. */
38
+ readonly target: string;
39
+ /** Materialize the import immediately instead of leaving it declared and inert. */
40
+ readonly enable: boolean;
41
+ }
42
+ export interface ImportNativeSkillRequest extends ImportRequestBase {
43
+ readonly type: "skill";
44
+ /** Local or Git native source, as the person typed it. */
45
+ readonly source: string;
46
+ }
47
+ export interface ImportNativeSubagentRequest extends ImportRequestBase {
48
+ readonly type: "subagent";
49
+ readonly source: string;
50
+ }
51
+ /** One native MCP connection the workspace discovered, in package terms. */
52
+ export interface NativeMcpCandidate {
53
+ /** The native connection key. */
54
+ readonly name: string;
55
+ /**
56
+ * The remote form the connection has, or none when it is a local command
57
+ * that no package manifest can represent losslessly.
58
+ */
59
+ readonly remote: Option.Option<{
60
+ readonly url: string;
61
+ readonly headers: Readonly<Record<string, string>>;
62
+ }>;
63
+ /** Connection inputs the declaration carries. */
64
+ readonly env: Readonly<Record<string, string>>;
65
+ /** Every native declaration of this connection, across agent config files. */
66
+ readonly entries: ReadonlyArray<NativeMcpEntryRef>;
67
+ }
68
+ /** What the workspace discovered about its unmanaged native MCP connections. */
69
+ export interface NativeMcpDiscovery {
70
+ readonly candidates: ReadonlyArray<NativeMcpCandidate>;
71
+ /** Connection keys whose native declarations disagree across agents. */
72
+ readonly conflicts: ReadonlyArray<string>;
73
+ }
74
+ export interface ImportNativeMcpServerRequest extends ImportRequestBase {
75
+ readonly type: "mcp-server";
76
+ readonly discovery: NativeMcpDiscovery;
77
+ /**
78
+ * Whether the invoking surface can prompt for a connection input the
79
+ * converted manifest requires.
80
+ */
81
+ readonly nonInteractive: boolean;
82
+ }
83
+ /** What a person asked to import. */
84
+ export type ImportNativeExtensionRequest = ImportNativeSkillRequest | ImportNativeSubagentRequest | ImportNativeMcpServerRequest;
85
+ /** What every step in a native import may require when it runs. */
86
+ export type ImportNativeExtensionRequirements = ManagerRequirements | RecipeRequirements | WorkspaceMutations | CodingAgentRepository | McpSecretStore;
87
+ /** A settled import: every decision is made and nothing under the workspace is written. */
88
+ export interface ImportNativeExtensionCandidate {
89
+ readonly type: NativeImportType;
90
+ readonly fqn: string;
91
+ readonly owner: Handle;
92
+ readonly name: string;
93
+ /** Where the native content came from, in operator-facing terms. */
94
+ readonly origin: string;
95
+ /** Workspace-relative directory the package will occupy. */
96
+ readonly authoredPath: string;
97
+ /** Workspace-relative settings file the declaration is written to. */
98
+ readonly settingsPath: string;
99
+ /** Whether the import is materialized once it is declared. */
100
+ readonly enabled: boolean;
101
+ readonly execution: ExecutionCandidate<ImportNativeExtensionRequirements>;
102
+ }
103
+ /** Every failure settling a native import can surface before anything is written. */
104
+ export type ImportNativeExtensionFailure = AuthoringFailed | AuthoredPackageError | FrontmatterParseFailure | AuthoringOwnerRequired | AuthoringOwnerMismatch | AuthoringScopeUnsupported | SourceResolutionFailure | PackageContentHashFailed | LockfileValidationError | WorkspaceLockfileReadFailure | WorkspaceSettingsReadFailure | CandidateFingerprintFailed | FqnInvalidError;
105
+ /** Everything settling a native import reads before it freezes a candidate. */
106
+ export type PrepareImportNativeExtensionRequirements = FileSystem.FileSystem | Path.Path | Scope.Scope | HttpClient.HttpClient | WorkspaceMutations | ExtensionManagers | SourceHostProviders | WorkspaceCatalog | ConfiguredAgentOutcomesProvider;
107
+ /** The plan a native import resolves. */
108
+ export declare const importNativeExtensionPlanName: (type: NativeImportType) => string;
109
+ /** Settle a native import and stage its converted content, writing nothing. */
110
+ export declare const prepareImportNativeExtension: (request: ImportNativeExtensionRequest) => Effect.Effect<ImportNativeExtensionCandidate, ImportNativeExtensionFailure, PrepareImportNativeExtensionRequirements>;
111
+ /** Preview or apply a settled native import, resolving to one operation outcome. */
112
+ export declare const previewOrApplyImportNativeExtension: (candidate: ImportNativeExtensionCandidate, execution: PlanExecution) => Effect.Effect<import("@agentxm/workspace-operations").OperationResolution<never>, WorkspaceSettingsReadFailure | import("@agentxm/workspace-operations").ApprovalRecoveryMissing | import("@agentxm/workspace-operations").PlanInteractionFailed | import("@agentxm/workspace-transactions").WorkspaceTransitionAcquireFailure, ConfiguredAgentOutcomesProvider | import("@agentxm/workspace-operations").OperationJournal | import("@agentxm/workspace-operations").ResolvePlanInteraction | import("@agentxm/workspace-transactions").FootprintRecorder | ImportNativeExtensionRequirements>;
113
+ /** The native-import use case: settle a request, then preview or apply it. */
114
+ export declare const ImportNativeExtension: {
115
+ readonly prepare: (request: ImportNativeExtensionRequest) => Effect.Effect<ImportNativeExtensionCandidate, ImportNativeExtensionFailure, PrepareImportNativeExtensionRequirements>;
116
+ readonly previewOrApply: (candidate: ImportNativeExtensionCandidate, execution: PlanExecution) => Effect.Effect<import("@agentxm/workspace-operations").OperationResolution<never>, WorkspaceSettingsReadFailure | import("@agentxm/workspace-operations").ApprovalRecoveryMissing | import("@agentxm/workspace-operations").PlanInteractionFailed | import("@agentxm/workspace-transactions").WorkspaceTransitionAcquireFailure, ConfiguredAgentOutcomesProvider | import("@agentxm/workspace-operations").OperationJournal | import("@agentxm/workspace-operations").ResolvePlanInteraction | import("@agentxm/workspace-transactions").FootprintRecorder | ImportNativeExtensionRequirements>;
117
+ };
118
+ export {};
119
+ //# sourceMappingURL=import-native-extension.d.ts.map