@merchantduo/code 0.3.0-beta.2 → 0.4.0-beta.1
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/app/runtime.d.ts +1 -0
- package/dist/app/runtime.js +26 -6
- package/dist/app/status.js +9 -2
- package/dist/app/system-prompt.js +204 -12
- package/dist/config/schema.d.ts +9 -171
- package/dist/config/schema.js +11 -3
- package/dist/integrations/pi/context.d.ts +14 -0
- package/dist/integrations/pi/context.js +96 -13
- package/dist/integrations/pi/environment.js +61 -15
- package/dist/magento/index.d.ts +1 -1
- package/dist/magento/inspector.d.ts +3 -2
- package/dist/magento/inspector.js +51 -2
- package/dist/magento/model.d.ts +8 -0
- package/package.json +8 -8
- package/skills/magento-2.4/SKILL.md +560 -169
package/dist/app/runtime.d.ts
CHANGED
|
@@ -38,5 +38,6 @@ export declare class MerchantDuoRuntime {
|
|
|
38
38
|
setMagerun2(capability: Magerun2Capability): void;
|
|
39
39
|
setEnvironmentStatus(status: EnvironmentStatus): SessionState;
|
|
40
40
|
startEnvironment(cwd: string): Promise<SessionState>;
|
|
41
|
+
refreshMagento(cwd: string): Promise<SessionState>;
|
|
41
42
|
stopEnvironment(cwd: string): Promise<SessionState>;
|
|
42
43
|
}
|
package/dist/app/runtime.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadConfig, selectEnvironment, setProjectTheme, } from "#config/index";
|
|
2
2
|
import { EnvironmentBackend } from "#environments/backend";
|
|
3
|
-
import { resolvePermissionMode } from "#app/permission-mode";
|
|
3
|
+
import { resolvePermissionMode, } from "#app/permission-mode";
|
|
4
4
|
import { DefaultMagentoInspector, } from "#magento/index";
|
|
5
5
|
import { ChangeTracker } from "#workflows/change-tracker";
|
|
6
6
|
import { NativeProbeLog } from "#app/native-operations";
|
|
@@ -23,7 +23,11 @@ export class MerchantDuoRuntime {
|
|
|
23
23
|
const selected = selectEnvironment(loaded.config, cwd, process.env.MERCHANTDUO_SELECTED_ENV);
|
|
24
24
|
const backend = new EnvironmentBackend(selected.environment, cwd);
|
|
25
25
|
const nativeLog = new NativeProbeLog();
|
|
26
|
-
await nativeLog.start({
|
|
26
|
+
await nativeLog.start({
|
|
27
|
+
project: cwd,
|
|
28
|
+
session: `${process.pid}`,
|
|
29
|
+
environment: selected.name,
|
|
30
|
+
});
|
|
27
31
|
const environmentStatus = await nativeStatus(backend, nativeLog);
|
|
28
32
|
this.#state = {
|
|
29
33
|
...loaded,
|
|
@@ -32,7 +36,9 @@ export class MerchantDuoRuntime {
|
|
|
32
36
|
nativeLog,
|
|
33
37
|
environmentStatus,
|
|
34
38
|
permissionMode: resolvePermissionMode(selected.environment, process.env.MERCHANTDUO_PERMISSION_MODE),
|
|
35
|
-
magento: environmentStatus === "running"
|
|
39
|
+
magento: environmentStatus === "running"
|
|
40
|
+
? await this.inspector.inspect(backend, (argv, result) => nativeLog.record(backend.command(argv), result), selected.environment)
|
|
41
|
+
: stoppedMagentoSnapshot(),
|
|
36
42
|
};
|
|
37
43
|
return this.#state;
|
|
38
44
|
}
|
|
@@ -87,7 +93,13 @@ export class MerchantDuoRuntime {
|
|
|
87
93
|
throw new Error(result.stderr || result.stdout || "Could not start environment");
|
|
88
94
|
state.environmentStatus = await state.backend.status();
|
|
89
95
|
if (state.environmentStatus === "running")
|
|
90
|
-
|
|
96
|
+
await this.refreshMagento(cwd);
|
|
97
|
+
return state;
|
|
98
|
+
}
|
|
99
|
+
async refreshMagento(cwd) {
|
|
100
|
+
const state = await this.boot(cwd);
|
|
101
|
+
if (state.environmentStatus === "running")
|
|
102
|
+
state.magento = await this.inspector.inspect(state.backend, undefined, state.selected.environment);
|
|
91
103
|
return state;
|
|
92
104
|
}
|
|
93
105
|
async stopEnvironment(cwd) {
|
|
@@ -105,7 +117,13 @@ export class MerchantDuoRuntime {
|
|
|
105
117
|
}
|
|
106
118
|
}
|
|
107
119
|
function stoppedMagentoSnapshot() {
|
|
108
|
-
return {
|
|
120
|
+
return {
|
|
121
|
+
cacheTypes: [],
|
|
122
|
+
database: { status: "unavailable" },
|
|
123
|
+
warnings: ["Environment is stopped"],
|
|
124
|
+
evidence: [],
|
|
125
|
+
themes: [],
|
|
126
|
+
};
|
|
109
127
|
}
|
|
110
128
|
async function nativeStatus(backend, log) {
|
|
111
129
|
if (backend.environment.type === "ssh")
|
|
@@ -117,5 +135,7 @@ async function nativeStatus(backend, log) {
|
|
|
117
135
|
return "stopped";
|
|
118
136
|
const result = await backend.runCommand(spec);
|
|
119
137
|
await log.record(spec, result);
|
|
120
|
-
return result.exitCode === 0 && wardenRunning(result.stdout)
|
|
138
|
+
return result.exitCode === 0 && wardenRunning(result.stdout)
|
|
139
|
+
? "running"
|
|
140
|
+
: "stopped";
|
|
121
141
|
}
|
package/dist/app/status.js
CHANGED
|
@@ -2,10 +2,17 @@ export function setInitializingStatus(ctx) {
|
|
|
2
2
|
ctx.ui.setStatus("merchantduo", "Initializing Magento context…");
|
|
3
3
|
}
|
|
4
4
|
export function refreshStatus(ctx, state) {
|
|
5
|
+
const database = state.magento.database.status === "unavailable"
|
|
6
|
+
? ["🛢️ unavailable", "🌐 unavailable"]
|
|
7
|
+
: [
|
|
8
|
+
`🛢️ ${state.magento.database.name} (${state.magento.database.location})`,
|
|
9
|
+
`🌐 ${state.magento.database.status === "ready" ? "ready" : "not ready"}`,
|
|
10
|
+
];
|
|
5
11
|
const parts = [
|
|
6
12
|
`M${state.magento.version ?? "?"}`,
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
`🖥️ ${state.selected.name} (${state.environmentStatus})`,
|
|
14
|
+
...database,
|
|
15
|
+
`🔐 ${state.permissionMode === "read-only" ? "r-o" : state.permissionMode}`,
|
|
9
16
|
...(state.config.activeTheme === "all" ? [] : [state.config.activeTheme]),
|
|
10
17
|
...(state.testing?.frontendUrl ? [state.testing.frontendUrl] : []),
|
|
11
18
|
];
|
|
@@ -2,28 +2,220 @@ import { packagePath } from "#shared/package-paths";
|
|
|
2
2
|
export function mage2genRoot() {
|
|
3
3
|
return packagePath("vendor/mage2gen");
|
|
4
4
|
}
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* System-level Magento contract.
|
|
7
|
+
*
|
|
8
|
+
* Keep this intentionally narrower than the
|
|
9
|
+
* `magento-extension-best-practices` skill.
|
|
10
|
+
*
|
|
11
|
+
* The skill is loaded into every Magento session after this prompt and owns
|
|
12
|
+
* implementation heuristics: plugins vs preferences, DI patterns, data access,
|
|
13
|
+
* PHP signature compatibility, Ponytail/YAGNI behavior, frontend conventions,
|
|
14
|
+
* testing strategy, cache/indexer concerns, etc.
|
|
15
|
+
*
|
|
16
|
+
* This prompt owns:
|
|
17
|
+
* - MerchantDuo identity and environment behavior
|
|
18
|
+
* - requirement to inspect the real project
|
|
19
|
+
* - tool boundaries
|
|
20
|
+
* - operation/execution rules
|
|
21
|
+
* - environment lifecycle
|
|
22
|
+
* - Mage2Gen/module generation
|
|
23
|
+
* - safety constraints
|
|
24
|
+
*/
|
|
25
|
+
const generalMagentoEngineeringPrompt = `# Magento Engineering
|
|
26
|
+
|
|
27
|
+
Work against the Magento project that actually exists, not an assumed reference installation.
|
|
28
|
+
|
|
29
|
+
For implementation decisions, load and follow the \`magento-extension-best-practices\` skill. It is the primary Magento coding and architecture guidance for the session.
|
|
30
|
+
|
|
31
|
+
Before making a version-, edition-, module-, theme-, or vendor-specific assumption, inspect the relevant project state when it materially affects the change. Do not assume Commerce features, Hyvä, Luma behavior, optional modules, extension APIs, or third-party package versions are present.
|
|
32
|
+
|
|
33
|
+
Ground changes in the existing source. Inspect the affected implementation, its relevant callers/configuration, and local conventions before editing. Do not perform broad architecture research when the local flow already makes the required change clear.
|
|
34
|
+
|
|
35
|
+
Never edit files under \`vendor/\` directly.`;
|
|
7
36
|
export function merchantDuoSystemPrompt(operatorRole, mage2genPath = mage2genRoot()) {
|
|
8
37
|
return `${generalMagentoEngineeringPrompt}
|
|
9
38
|
|
|
10
|
-
You are MerchantDuo, a senior Magento 2.4
|
|
39
|
+
You are MerchantDuo, a senior Magento 2.4 implementation partner working directly in the selected MerchantDuo environment and theme scope.
|
|
40
|
+
|
|
41
|
+
Make focused production changes to the selected project. Preserve established project conventions unless they are directly responsible for the problem being fixed. Do not introduce compatibility layers, abstractions, migrations, cleanup, or unrelated refactoring unless the task requires them.
|
|
42
|
+
|
|
43
|
+
${operatorRole ? `The operator is a ${operatorRole.replace(/-/g, " ")}. Use this only to frame explanations and recommendations. It does not change available tools, permissions, or supported work.
|
|
44
|
+
|
|
45
|
+
` : ""}# Source inspection
|
|
46
|
+
|
|
47
|
+
Before editing, inspect enough of the real execution path to understand the change.
|
|
48
|
+
|
|
49
|
+
Normally this means the affected file plus directly relevant configuration, callers, plugins, preferences, subclasses, templates, or tests.
|
|
50
|
+
|
|
51
|
+
Expand the search only when needed to resolve uncertainty.
|
|
52
|
+
|
|
53
|
+
When Magento behavior or the correct extension mechanism is unclear or version-sensitive, inspect the closest relevant implementation in \`vendor/magento\`. Search installed third-party modules or project modules when they are more relevant to the actual flow.
|
|
54
|
+
|
|
55
|
+
Do not turn source inspection into ceremony. Once the implementation path is clear, make the smallest appropriate change.
|
|
56
|
+
|
|
57
|
+
# New modules
|
|
58
|
+
|
|
59
|
+
For every request to create a new Magento module, call \`mage2gen_generate_module\` before writing custom module files.
|
|
60
|
+
|
|
61
|
+
Mage2Gen is available at:
|
|
62
|
+
|
|
63
|
+
\`${mage2genPath}\`
|
|
64
|
+
|
|
65
|
+
It requires Python 3 and generates only into the selected Magento project.
|
|
66
|
+
|
|
67
|
+
After generation:
|
|
68
|
+
|
|
69
|
+
1. inspect the generated files;
|
|
70
|
+
2. remove or change anything the task does not need;
|
|
71
|
+
3. implement the requested behavior.
|
|
72
|
+
|
|
73
|
+
Do not hand-create standard Magento module boilerplate when Mage2Gen can represent it.
|
|
74
|
+
|
|
75
|
+
Skip Mage2Gen only when it cannot represent the requested module structure or when the task is only modifying an existing module. If skipped for a new module, state the concrete limitation.
|
|
76
|
+
|
|
77
|
+
# Post-change operations
|
|
78
|
+
|
|
79
|
+
After changing code, inspect what actually changed and determine whether any Magento operation is required.
|
|
80
|
+
|
|
81
|
+
Do not automatically run or recommend the traditional full Magento deployment sequence.
|
|
82
|
+
|
|
83
|
+
Examples of operation triggers:
|
|
84
|
+
|
|
85
|
+
- module registration, enablement, setup metadata, schema, or data patches may require \`setup:upgrade\`;
|
|
86
|
+
- DI changes may require generated-code/DI compilation in production or the project's build pipeline;
|
|
87
|
+
- frontend/static asset changes may require static-content deployment depending on deployment mode and pipeline;
|
|
88
|
+
- configuration/layout changes may require only the relevant cache clean;
|
|
89
|
+
- ordinary PHP changes often require no setup operation;
|
|
90
|
+
- indexing should run only when the affected data/indexer actually requires it.
|
|
91
|
+
|
|
92
|
+
Deployment mode is part of the decision.
|
|
93
|
+
|
|
94
|
+
If the detected snapshot mode is:
|
|
95
|
+
|
|
96
|
+
- **developer**: do not normally compile DI or deploy static content unless the specific change requires it;
|
|
97
|
+
- **default**: compile/deploy only when required by the change;
|
|
98
|
+
- **production**: account for the project's production deployment workflow and required generated/static artifacts.
|
|
99
|
+
|
|
100
|
+
If deployment mode is unknown, report that rather than inventing a deployment sequence.
|
|
101
|
+
|
|
102
|
+
# Magento operational tools
|
|
103
|
+
|
|
104
|
+
For supported Magento operational work, use \`magento_workflow\`.
|
|
105
|
+
|
|
106
|
+
This includes:
|
|
107
|
+
|
|
108
|
+
- cache clean or flush;
|
|
109
|
+
- maintenance enable or disable;
|
|
110
|
+
- setup upgrade;
|
|
111
|
+
- DI compilation;
|
|
112
|
+
- static-content deployment;
|
|
113
|
+
- indexing;
|
|
114
|
+
- supported tests;
|
|
115
|
+
- deployment operations.
|
|
116
|
+
|
|
117
|
+
When the user explicitly requests execution, call \`magento_workflow\` with \`execute: true\` immediately.
|
|
118
|
+
|
|
119
|
+
Do not ask for a separate conversational confirmation. The harness confirmation dialog is the authoritative confirmation boundary.
|
|
120
|
+
|
|
121
|
+
When execution was not requested, do not mutate the environment. Explain or preview the relevant operation instead.
|
|
122
|
+
|
|
123
|
+
Do not replace supported workflow operations with raw shell commands.
|
|
124
|
+
|
|
125
|
+
# n98-magerun2
|
|
126
|
+
|
|
127
|
+
For an n98-magerun2 command that is not covered by \`magento_workflow\`, use \`magerun2\`.
|
|
128
|
+
|
|
129
|
+
Pass the command as an exact \`args: string[]\` vector.
|
|
130
|
+
|
|
131
|
+
Never construct a shell command string, shell interpolation, or command pipeline around magerun2.
|
|
132
|
+
|
|
133
|
+
When execution was not explicitly requested, return/inspect its preview without \`execute: true\`.
|
|
134
|
+
|
|
135
|
+
When execution was explicitly requested, use \`execute: true\`. The harness confirmation remains the only confirmation boundary.
|
|
136
|
+
|
|
137
|
+
Never send \`dev:console\` through \`magerun2\`.
|
|
138
|
+
|
|
139
|
+
Use \`magento_php_repl\` for Magento PHP console work.
|
|
140
|
+
|
|
141
|
+
# Permission modes
|
|
142
|
+
|
|
143
|
+
The active MerchantDuo permission mode is provided in startup context.
|
|
144
|
+
|
|
145
|
+
It can be changed only with:
|
|
146
|
+
|
|
147
|
+
\`/duo-switch-permissions read-only|normal|yolo\`
|
|
148
|
+
|
|
149
|
+
Semantics:
|
|
150
|
+
|
|
151
|
+
- **read-only** prevents direct workspace write/edit operations, although separately approved operations may still mutate;
|
|
152
|
+
- **normal** uses ordinary local/Warden workspace behavior and normal SSH confirmation boundaries;
|
|
153
|
+
- **yolo** removes MerchantDuo-specific dialogs where supported.
|
|
154
|
+
|
|
155
|
+
Yolo does not bypass:
|
|
156
|
+
|
|
157
|
+
- explicit \`execute: true\` requirements;
|
|
158
|
+
- stopped-environment restrictions;
|
|
159
|
+
- SSH lifecycle restrictions;
|
|
160
|
+
- Mage2Gen SSH restrictions;
|
|
161
|
+
- remote workflow restrictions;
|
|
162
|
+
- PHP-console boundaries;
|
|
163
|
+
- credential protections;
|
|
164
|
+
- protected URL handling.
|
|
165
|
+
|
|
166
|
+
Do not infer additional permissions from the mode name.
|
|
167
|
+
|
|
168
|
+
# Environment lifecycle
|
|
169
|
+
|
|
170
|
+
Environment lifecycle actions must match the actual selected environment.
|
|
171
|
+
|
|
172
|
+
## Warden
|
|
173
|
+
|
|
174
|
+
Use the known Warden controls exposed by MerchantDuo.
|
|
175
|
+
|
|
176
|
+
Inside Warden, use container paths under the configured project root, normally:
|
|
177
|
+
|
|
178
|
+
\`/var/www/html\`
|
|
179
|
+
|
|
180
|
+
If a tool reports a different mapped path, follow the tool result.
|
|
181
|
+
|
|
182
|
+
## SSH
|
|
183
|
+
|
|
184
|
+
SSH environments are always treated as already running.
|
|
185
|
+
|
|
186
|
+
Never start, stop, or restart an SSH environment.
|
|
187
|
+
|
|
188
|
+
Do not attempt to manage the remote host lifecycle.
|
|
189
|
+
|
|
190
|
+
## Local environments
|
|
191
|
+
|
|
192
|
+
Do not guess how a local environment starts or stops.
|
|
193
|
+
|
|
194
|
+
When the user requests a local environment start or stop:
|
|
195
|
+
|
|
196
|
+
1. inspect the project's actual lifecycle configuration;
|
|
197
|
+
2. determine the smallest exact command;
|
|
198
|
+
3. call \`environment_start\` or \`environment_stop\` with that command.
|
|
199
|
+
|
|
200
|
+
Never guess a generic Docker, Docker Compose, npm, systemd, or service command.
|
|
201
|
+
|
|
202
|
+
Never start, stop, or restart unrelated host services.
|
|
11
203
|
|
|
12
|
-
|
|
204
|
+
When inspecting environment state without changing it, use \`environment_set_status\` only after determining the actual status.
|
|
13
205
|
|
|
14
|
-
|
|
206
|
+
# Validation after edits
|
|
15
207
|
|
|
16
|
-
|
|
208
|
+
Inspect the result of writes and edits.
|
|
17
209
|
|
|
18
|
-
|
|
210
|
+
If a tool reports a Magento XML/XSD validation error caused by the change, fix it before considering the change complete.
|
|
19
211
|
|
|
20
|
-
|
|
212
|
+
Use the smallest validation appropriate to the changed code. Do not run broad compilation, deployment, indexing, cache flushes, or full test suites merely as generic validation.
|
|
21
213
|
|
|
22
|
-
|
|
214
|
+
# Secrets and protected configuration
|
|
23
215
|
|
|
24
|
-
|
|
216
|
+
Never inspect \`app/etc/env.php\`.
|
|
25
217
|
|
|
26
|
-
|
|
218
|
+
Do not read, expose, print, copy, or search for credentials, secrets, private keys, access tokens, database passwords, or protected service URLs.
|
|
27
219
|
|
|
28
|
-
|
|
220
|
+
Use project/tool-provided abstractions when environment configuration is required.`;
|
|
29
221
|
}
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -9,48 +9,16 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
9
9
|
frontendUrl: z.ZodOptional<z.ZodString>;
|
|
10
10
|
adminUrl: z.ZodOptional<z.ZodString>;
|
|
11
11
|
allowInsecureTls: z.ZodDefault<z.ZodBoolean>;
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
frontendUrl?: string | undefined;
|
|
15
|
-
adminUrl?: string | undefined;
|
|
16
|
-
}, {
|
|
17
|
-
frontendUrl?: string | undefined;
|
|
18
|
-
adminUrl?: string | undefined;
|
|
19
|
-
allowInsecureTls?: boolean | undefined;
|
|
20
|
-
}>>;
|
|
21
|
-
environments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
|
|
12
|
+
}, z.core.$strict>>;
|
|
13
|
+
environments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
22
14
|
type: z.ZodLiteral<"local">;
|
|
23
15
|
root: z.ZodString;
|
|
24
16
|
testing: z.ZodOptional<z.ZodObject<{
|
|
25
17
|
frontendUrl: z.ZodOptional<z.ZodString>;
|
|
26
18
|
adminUrl: z.ZodOptional<z.ZodString>;
|
|
27
19
|
allowInsecureTls: z.ZodDefault<z.ZodBoolean>;
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
frontendUrl?: string | undefined;
|
|
31
|
-
adminUrl?: string | undefined;
|
|
32
|
-
}, {
|
|
33
|
-
frontendUrl?: string | undefined;
|
|
34
|
-
adminUrl?: string | undefined;
|
|
35
|
-
allowInsecureTls?: boolean | undefined;
|
|
36
|
-
}>>;
|
|
37
|
-
}, "strict", z.ZodTypeAny, {
|
|
38
|
-
type: "local";
|
|
39
|
-
root: string;
|
|
40
|
-
testing?: {
|
|
41
|
-
allowInsecureTls: boolean;
|
|
42
|
-
frontendUrl?: string | undefined;
|
|
43
|
-
adminUrl?: string | undefined;
|
|
44
|
-
} | undefined;
|
|
45
|
-
}, {
|
|
46
|
-
type: "local";
|
|
47
|
-
root: string;
|
|
48
|
-
testing?: {
|
|
49
|
-
frontendUrl?: string | undefined;
|
|
50
|
-
adminUrl?: string | undefined;
|
|
51
|
-
allowInsecureTls?: boolean | undefined;
|
|
52
|
-
} | undefined;
|
|
53
|
-
}>, z.ZodObject<{
|
|
20
|
+
}, z.core.$strict>>;
|
|
21
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
54
22
|
type: z.ZodLiteral<"warden">;
|
|
55
23
|
projectRoot: z.ZodString;
|
|
56
24
|
root: z.ZodString;
|
|
@@ -60,38 +28,8 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
60
28
|
frontendUrl: z.ZodOptional<z.ZodString>;
|
|
61
29
|
adminUrl: z.ZodOptional<z.ZodString>;
|
|
62
30
|
allowInsecureTls: z.ZodDefault<z.ZodBoolean>;
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
frontendUrl?: string | undefined;
|
|
66
|
-
adminUrl?: string | undefined;
|
|
67
|
-
}, {
|
|
68
|
-
frontendUrl?: string | undefined;
|
|
69
|
-
adminUrl?: string | undefined;
|
|
70
|
-
allowInsecureTls?: boolean | undefined;
|
|
71
|
-
}>>;
|
|
72
|
-
}, "strict", z.ZodTypeAny, {
|
|
73
|
-
type: "warden";
|
|
74
|
-
root: string;
|
|
75
|
-
projectRoot: string;
|
|
76
|
-
filesService: string;
|
|
77
|
-
targets: Record<string, string>;
|
|
78
|
-
testing?: {
|
|
79
|
-
allowInsecureTls: boolean;
|
|
80
|
-
frontendUrl?: string | undefined;
|
|
81
|
-
adminUrl?: string | undefined;
|
|
82
|
-
} | undefined;
|
|
83
|
-
}, {
|
|
84
|
-
type: "warden";
|
|
85
|
-
root: string;
|
|
86
|
-
projectRoot: string;
|
|
87
|
-
testing?: {
|
|
88
|
-
frontendUrl?: string | undefined;
|
|
89
|
-
adminUrl?: string | undefined;
|
|
90
|
-
allowInsecureTls?: boolean | undefined;
|
|
91
|
-
} | undefined;
|
|
92
|
-
filesService?: string | undefined;
|
|
93
|
-
targets?: Record<string, string> | undefined;
|
|
94
|
-
}>, z.ZodObject<{
|
|
31
|
+
}, z.core.$strict>>;
|
|
32
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
95
33
|
type: z.ZodLiteral<"ssh">;
|
|
96
34
|
host: z.ZodString;
|
|
97
35
|
root: z.ZodString;
|
|
@@ -99,109 +37,9 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
99
37
|
frontendUrl: z.ZodOptional<z.ZodString>;
|
|
100
38
|
adminUrl: z.ZodOptional<z.ZodString>;
|
|
101
39
|
allowInsecureTls: z.ZodDefault<z.ZodBoolean>;
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
adminUrl?: string | undefined;
|
|
106
|
-
}, {
|
|
107
|
-
frontendUrl?: string | undefined;
|
|
108
|
-
adminUrl?: string | undefined;
|
|
109
|
-
allowInsecureTls?: boolean | undefined;
|
|
110
|
-
}>>;
|
|
111
|
-
}, "strict", z.ZodTypeAny, {
|
|
112
|
-
type: "ssh";
|
|
113
|
-
root: string;
|
|
114
|
-
host: string;
|
|
115
|
-
testing?: {
|
|
116
|
-
allowInsecureTls: boolean;
|
|
117
|
-
frontendUrl?: string | undefined;
|
|
118
|
-
adminUrl?: string | undefined;
|
|
119
|
-
} | undefined;
|
|
120
|
-
}, {
|
|
121
|
-
type: "ssh";
|
|
122
|
-
root: string;
|
|
123
|
-
host: string;
|
|
124
|
-
testing?: {
|
|
125
|
-
frontendUrl?: string | undefined;
|
|
126
|
-
adminUrl?: string | undefined;
|
|
127
|
-
allowInsecureTls?: boolean | undefined;
|
|
128
|
-
} | undefined;
|
|
129
|
-
}>]>>>;
|
|
130
|
-
}, "strict", z.ZodTypeAny, {
|
|
131
|
-
testing: {
|
|
132
|
-
allowInsecureTls: boolean;
|
|
133
|
-
frontendUrl?: string | undefined;
|
|
134
|
-
adminUrl?: string | undefined;
|
|
135
|
-
};
|
|
136
|
-
activeTheme: string;
|
|
137
|
-
environments: Record<string, {
|
|
138
|
-
type: "local";
|
|
139
|
-
root: string;
|
|
140
|
-
testing?: {
|
|
141
|
-
allowInsecureTls: boolean;
|
|
142
|
-
frontendUrl?: string | undefined;
|
|
143
|
-
adminUrl?: string | undefined;
|
|
144
|
-
} | undefined;
|
|
145
|
-
} | {
|
|
146
|
-
type: "warden";
|
|
147
|
-
root: string;
|
|
148
|
-
projectRoot: string;
|
|
149
|
-
filesService: string;
|
|
150
|
-
targets: Record<string, string>;
|
|
151
|
-
testing?: {
|
|
152
|
-
allowInsecureTls: boolean;
|
|
153
|
-
frontendUrl?: string | undefined;
|
|
154
|
-
adminUrl?: string | undefined;
|
|
155
|
-
} | undefined;
|
|
156
|
-
} | {
|
|
157
|
-
type: "ssh";
|
|
158
|
-
root: string;
|
|
159
|
-
host: string;
|
|
160
|
-
testing?: {
|
|
161
|
-
allowInsecureTls: boolean;
|
|
162
|
-
frontendUrl?: string | undefined;
|
|
163
|
-
adminUrl?: string | undefined;
|
|
164
|
-
} | undefined;
|
|
165
|
-
}>;
|
|
166
|
-
defaultEnvironment?: string | undefined;
|
|
167
|
-
}, {
|
|
168
|
-
testing?: {
|
|
169
|
-
frontendUrl?: string | undefined;
|
|
170
|
-
adminUrl?: string | undefined;
|
|
171
|
-
allowInsecureTls?: boolean | undefined;
|
|
172
|
-
} | undefined;
|
|
173
|
-
defaultEnvironment?: string | undefined;
|
|
174
|
-
activeTheme?: string | undefined;
|
|
175
|
-
environments?: Record<string, {
|
|
176
|
-
type: "local";
|
|
177
|
-
root: string;
|
|
178
|
-
testing?: {
|
|
179
|
-
frontendUrl?: string | undefined;
|
|
180
|
-
adminUrl?: string | undefined;
|
|
181
|
-
allowInsecureTls?: boolean | undefined;
|
|
182
|
-
} | undefined;
|
|
183
|
-
} | {
|
|
184
|
-
type: "warden";
|
|
185
|
-
root: string;
|
|
186
|
-
projectRoot: string;
|
|
187
|
-
testing?: {
|
|
188
|
-
frontendUrl?: string | undefined;
|
|
189
|
-
adminUrl?: string | undefined;
|
|
190
|
-
allowInsecureTls?: boolean | undefined;
|
|
191
|
-
} | undefined;
|
|
192
|
-
filesService?: string | undefined;
|
|
193
|
-
targets?: Record<string, string> | undefined;
|
|
194
|
-
} | {
|
|
195
|
-
type: "ssh";
|
|
196
|
-
root: string;
|
|
197
|
-
host: string;
|
|
198
|
-
testing?: {
|
|
199
|
-
frontendUrl?: string | undefined;
|
|
200
|
-
adminUrl?: string | undefined;
|
|
201
|
-
allowInsecureTls?: boolean | undefined;
|
|
202
|
-
} | undefined;
|
|
203
|
-
}> | undefined;
|
|
204
|
-
}>;
|
|
40
|
+
}, z.core.$strict>>;
|
|
41
|
+
}, z.core.$strict>]>>>;
|
|
42
|
+
}, z.core.$strict>;
|
|
205
43
|
export type MerchantConfig = Omit<z.infer<typeof ConfigSchema>, "environments"> & {
|
|
206
44
|
environments: Record<string, Environment>;
|
|
207
45
|
};
|
package/dist/config/schema.js
CHANGED
|
@@ -12,14 +12,20 @@ const testing = z
|
|
|
12
12
|
allowInsecureTls: z.boolean().default(true),
|
|
13
13
|
})
|
|
14
14
|
.strict();
|
|
15
|
-
const local = z
|
|
15
|
+
const local = z
|
|
16
|
+
.object({
|
|
17
|
+
type: z.literal("local"),
|
|
18
|
+
root: z.string(),
|
|
19
|
+
testing: testing.optional(),
|
|
20
|
+
})
|
|
21
|
+
.strict();
|
|
16
22
|
const warden = z
|
|
17
23
|
.object({
|
|
18
24
|
type: z.literal("warden"),
|
|
19
25
|
projectRoot: z.string(),
|
|
20
26
|
root: z.string(),
|
|
21
27
|
filesService: z.string().default("php-fpm"),
|
|
22
|
-
targets: z.record(z.string()).default({ default: "php-fpm" }),
|
|
28
|
+
targets: z.record(z.string(), z.string()).default({ default: "php-fpm" }),
|
|
23
29
|
testing: testing.optional(),
|
|
24
30
|
})
|
|
25
31
|
.strict();
|
|
@@ -36,6 +42,8 @@ export const ConfigSchema = z
|
|
|
36
42
|
defaultEnvironment: z.string().optional(),
|
|
37
43
|
activeTheme: z.string().default("all"),
|
|
38
44
|
testing: testing.default({ allowInsecureTls: true }),
|
|
39
|
-
environments: z
|
|
45
|
+
environments: z
|
|
46
|
+
.record(z.string(), z.union([local, warden, ssh]))
|
|
47
|
+
.default({}),
|
|
40
48
|
})
|
|
41
49
|
.strict();
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { runtime } from "#integrations/pi/session";
|
|
3
|
+
import type { MagentoSnapshot } from "#magento/model";
|
|
4
|
+
type CoreUpgradeContext = {
|
|
5
|
+
selected: {
|
|
6
|
+
name: string;
|
|
7
|
+
};
|
|
8
|
+
magento: Pick<MagentoSnapshot, "edition" | "version" | "phpVersion">;
|
|
9
|
+
};
|
|
3
10
|
export default function context(pi: ExtensionAPI): void;
|
|
11
|
+
/**
|
|
12
|
+
* Algorithm: inspect the selected instance and authoritative release evidence without mutation;
|
|
13
|
+
* compare every newer core target against the instance; present plans; wait for one chat choice;
|
|
14
|
+
* then constrain later upgrade work to that selected target and the normal permission boundaries.
|
|
15
|
+
*/
|
|
16
|
+
export declare function coreUpgradePrompt(state: CoreUpgradeContext): string;
|
|
4
17
|
export declare function statusMessage(state: Awaited<ReturnType<typeof runtime.boot>>): string;
|
|
18
|
+
export {};
|