pi-apexlang 0.1.0 → 0.2.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/README.md +13 -0
- package/extensions/apexlang/index.ts +16 -3
- package/extensions/lib/apexlang-cli.d.mts +113 -2
- package/extensions/lib/apexlang-cli.mjs +1426 -26
- package/extensions/lib/apexlang-runtime-roundtrip.mjs +43 -0
- package/extensions/lib/apexlang-sqlcl-pty.py +157 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -90,6 +90,19 @@ code** requires an explicit target mode:
|
|
|
90
90
|
Without GUI support, the tool always stops after checking and reports import
|
|
91
91
|
as a follow-up.
|
|
92
92
|
|
|
93
|
+
When refreshing a full APEXlang export, run one SQLcl export with explicit
|
|
94
|
+
replacement semantics:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
apex export -applicationid <id> -exptype APEXLANG -split -dir <absolute-parent-directory> -force
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`-dir` names the parent directory; SQLcl creates the application-alias folder
|
|
101
|
+
below it. The `-force` flag removes and recreates that export folder, so a
|
|
102
|
+
repeat export produces one current snapshot instead of collision copies such
|
|
103
|
+
as `application_1.apx` and `p00005_1.apx`. Because this replaces the complete
|
|
104
|
+
local export, preserve or import any local-only work before refreshing it.
|
|
105
|
+
|
|
93
106
|
All app paths must remain inside the active Pi workspace. The adapter rejects
|
|
94
107
|
traversal, app-tree symlinks, and multiply linked files on mutating vocabulary
|
|
95
108
|
fixes; verifies live workspace input against `deployments/default.json`; and
|
|
@@ -20,6 +20,8 @@ const CHECK_ONLY_CHOICE = "Check APEXlang code (recommended) — stop after the
|
|
|
20
20
|
const IMPORT_CHOICE = "Check and import APEXlang code — revalidate and import in one SQLcl session";
|
|
21
21
|
const UPDATE_EXISTING_CHOICE = "Update an existing app — require one proven remote target";
|
|
22
22
|
const CREATE_NEW_CHOICE = "Create a new app — require proof that the alias is absent";
|
|
23
|
+
const EXPORT_OVERWRITE_GUIDELINE =
|
|
24
|
+
"For a full APEXlang export refresh, run exactly one SQLcl `apex export` command with `-force` and `-dir` set to the absolute parent directory. Never export without `-force` into an existing destination: SQLcl can collision-suffix every artifact as `*_1.apx` instead of replacing the snapshot.";
|
|
23
25
|
|
|
24
26
|
function trimOutput(value: string, outputRoot?: string): string {
|
|
25
27
|
if (value.length <= MAX_TOOL_OUTPUT) return value;
|
|
@@ -110,6 +112,7 @@ export function createApexlangTool(overrides: Partial<ApexlangDependencies> = {}
|
|
|
110
112
|
promptGuidelines: [
|
|
111
113
|
"Load the apexlang skill before using the apexlang tool and follow its routing and Missing Inputs rules.",
|
|
112
114
|
"Use apexlang workspace_probe before app-scoped APEXlang work.",
|
|
115
|
+
EXPORT_OVERWRITE_GUIDELINE,
|
|
113
116
|
"Use apexlang runtime_validate only after the user provides both db_connection_name and the matching APEX workspace_name; import requires the tool's separate post-check GUI choice."
|
|
114
117
|
],
|
|
115
118
|
executionMode: "sequential",
|
|
@@ -157,7 +160,7 @@ export function createApexlangTool(overrides: Partial<ApexlangDependencies> = {}
|
|
|
157
160
|
),
|
|
158
161
|
list: Type.Optional(Type.Boolean({ description: "List matching compiler component types." })),
|
|
159
162
|
supporting_objects: Type.Optional(
|
|
160
|
-
Type.Boolean({ description: "Include supporting objects in runtime preflight
|
|
163
|
+
Type.Boolean({ description: "Include supporting objects in runtime preflight, validation, and import." })
|
|
161
164
|
),
|
|
162
165
|
fix_vocab: Type.Optional(
|
|
163
166
|
Type.Boolean({ description: "Apply local vocabulary fixes after interactive confirmation." })
|
|
@@ -250,6 +253,12 @@ export function createApexlangTool(overrides: Partial<ApexlangDependencies> = {}
|
|
|
250
253
|
};
|
|
251
254
|
}
|
|
252
255
|
if (choice === IMPORT_CHOICE) {
|
|
256
|
+
const expectedAppDigest = String(result.appDigest ?? "").trim().toLowerCase();
|
|
257
|
+
if (!/^[a-f0-9]{64}$/.test(expectedAppDigest)) {
|
|
258
|
+
throw new Error(
|
|
259
|
+
"APEXlang live check did not produce a valid application snapshot digest; import is blocked until it is revalidated."
|
|
260
|
+
);
|
|
261
|
+
}
|
|
253
262
|
const targetChoice = await ctx.ui.select("Choose the explicitly intended import target:", [
|
|
254
263
|
UPDATE_EXISTING_CHOICE,
|
|
255
264
|
CREATE_NEW_CHOICE
|
|
@@ -286,7 +295,9 @@ export function createApexlangTool(overrides: Partial<ApexlangDependencies> = {}
|
|
|
286
295
|
],
|
|
287
296
|
details: { action: input.action, targetResolutionMode, provingTarget: true }
|
|
288
297
|
});
|
|
289
|
-
const proofResult = await dependencies.runCreateNewProof(input, runOptions
|
|
298
|
+
const proofResult = await dependencies.runCreateNewProof(input, runOptions, {
|
|
299
|
+
expectedAppDigest
|
|
300
|
+
});
|
|
290
301
|
if (!createNewTargetProved(proofResult)) {
|
|
291
302
|
throw new Error(
|
|
292
303
|
failureOutput(
|
|
@@ -329,7 +340,8 @@ export function createApexlangTool(overrides: Partial<ApexlangDependencies> = {}
|
|
|
329
340
|
});
|
|
330
341
|
const importResult = await dependencies.runImport(input, runOptions, {
|
|
331
342
|
targetResolutionMode,
|
|
332
|
-
createNewConfirmed
|
|
343
|
+
createNewConfirmed,
|
|
344
|
+
expectedAppDigest
|
|
333
345
|
});
|
|
334
346
|
const importOutput = processOutput(importResult);
|
|
335
347
|
if (!liveImportPassed(importResult)) {
|
|
@@ -416,6 +428,7 @@ export {
|
|
|
416
428
|
CHECK_ONLY_CHOICE,
|
|
417
429
|
IMPORT_CHOICE,
|
|
418
430
|
CREATE_NEW_CHOICE,
|
|
431
|
+
EXPORT_OVERWRITE_GUIDELINE,
|
|
419
432
|
UPDATE_EXISTING_CHOICE,
|
|
420
433
|
actionWritesProject,
|
|
421
434
|
confirmationMessage,
|
|
@@ -43,11 +43,21 @@ export interface ApexlangRunOptions {
|
|
|
43
43
|
export interface ApexlangImportOptions {
|
|
44
44
|
targetResolutionMode?: "update-existing" | "create-new";
|
|
45
45
|
createNewConfirmed?: boolean;
|
|
46
|
+
expectedAppDigest?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ApexlangApprovedImportOptions extends ApexlangImportOptions {
|
|
50
|
+
expectedAppDigest: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface ApexlangCreateNewProofOptions {
|
|
54
|
+
expectedAppDigest: string;
|
|
46
55
|
}
|
|
47
56
|
|
|
48
57
|
export interface ProcessTreeOptions {
|
|
49
58
|
cwd: string;
|
|
50
59
|
env?: NodeJS.ProcessEnv;
|
|
60
|
+
input?: string;
|
|
51
61
|
maxBuffer?: number;
|
|
52
62
|
signal?: AbortSignal;
|
|
53
63
|
timeoutMs?: number;
|
|
@@ -60,11 +70,43 @@ export interface ApexlangProcessResult {
|
|
|
60
70
|
stderr: string;
|
|
61
71
|
}
|
|
62
72
|
|
|
73
|
+
export interface SqlclValidationImportOptions extends ProcessTreeOptions {
|
|
74
|
+
validateCommand: string;
|
|
75
|
+
importCommand: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface SqlclValidationImportResult extends ApexlangProcessResult {
|
|
79
|
+
validationAccepted: boolean;
|
|
80
|
+
validationEvidence: {
|
|
81
|
+
accepted: boolean;
|
|
82
|
+
reason: string;
|
|
83
|
+
warningCount?: number;
|
|
84
|
+
validationSuccessCount?: number;
|
|
85
|
+
outputSha256?: string;
|
|
86
|
+
};
|
|
87
|
+
ptyBacked: true;
|
|
88
|
+
ptyProcessGroupReady: boolean;
|
|
89
|
+
sessionReady: boolean;
|
|
90
|
+
validationSent: boolean;
|
|
91
|
+
importSent: boolean;
|
|
92
|
+
importCompleted: boolean;
|
|
93
|
+
hardFailureDetected: boolean;
|
|
94
|
+
orderedMergedOutput: true;
|
|
95
|
+
validationOutput: string;
|
|
96
|
+
importOutput: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
63
99
|
export interface ApexlangRunResult extends ApexlangProcessResult {
|
|
64
100
|
action: ApexlangAction;
|
|
65
101
|
command: ApexlangCommand;
|
|
66
102
|
outputRoot: string;
|
|
67
103
|
preludeResults: ApexlangProcessResult[];
|
|
104
|
+
runtimeApp: {
|
|
105
|
+
appPath?: string;
|
|
106
|
+
staged: boolean;
|
|
107
|
+
workspaceSource?: "workspace.name" | "app.workspace.name" | "explicit_workspace_name";
|
|
108
|
+
};
|
|
109
|
+
appDigest?: string;
|
|
68
110
|
}
|
|
69
111
|
|
|
70
112
|
export const APEXLANG_SKILL_ROOT: string;
|
|
@@ -91,11 +133,79 @@ export function validateMaterializationPaths(options: {
|
|
|
91
133
|
requested: string;
|
|
92
134
|
suggested: string;
|
|
93
135
|
}): Promise<string>;
|
|
136
|
+
export function prepareRuntimeApp(
|
|
137
|
+
input: ApexlangInput,
|
|
138
|
+
cwd: string,
|
|
139
|
+
outputRoot: string,
|
|
140
|
+
options?: { forceStage?: boolean }
|
|
141
|
+
): Promise<{
|
|
142
|
+
appPath?: string;
|
|
143
|
+
staged: boolean;
|
|
144
|
+
workspaceSource?: "workspace.name" | "app.workspace.name" | "explicit_workspace_name";
|
|
145
|
+
}>;
|
|
146
|
+
export function computeApexlangAppDigest(appPath: string): Promise<string>;
|
|
147
|
+
export function classifyWarningOnlyRuntimePayload(
|
|
148
|
+
payload: Record<string, unknown>,
|
|
149
|
+
transcript: string,
|
|
150
|
+
expectedImportIntent?: "validate-only" | "validate-and-import"
|
|
151
|
+
): {
|
|
152
|
+
accepted: boolean;
|
|
153
|
+
reason: string;
|
|
154
|
+
attemptLabel?: string;
|
|
155
|
+
warningCount?: number;
|
|
156
|
+
validationSuccessCount?: number;
|
|
157
|
+
attemptSha256?: string;
|
|
158
|
+
};
|
|
159
|
+
export function classifyWarningCompatibleSqlclValidation(output: string): {
|
|
160
|
+
accepted: boolean;
|
|
161
|
+
reason: string;
|
|
162
|
+
warningCount: number;
|
|
163
|
+
validationSuccessCount: number;
|
|
164
|
+
outputSha256?: string;
|
|
165
|
+
};
|
|
166
|
+
export function proveWarningOnlyProblemsAreDiagnostics(
|
|
167
|
+
payload: Record<string, any>,
|
|
168
|
+
result: Pick<ApexlangRunResult, "outputRoot">
|
|
169
|
+
): Promise<{
|
|
170
|
+
accepted: boolean;
|
|
171
|
+
reason?: string;
|
|
172
|
+
problemCount?: number;
|
|
173
|
+
problemsPath?: string;
|
|
174
|
+
problemsSha256?: string;
|
|
175
|
+
}>;
|
|
176
|
+
export function validateUpdateExistingImportProof(
|
|
177
|
+
payload: Record<string, any>,
|
|
178
|
+
input: ApexlangInput,
|
|
179
|
+
stagedAppPath: string
|
|
180
|
+
): {
|
|
181
|
+
canonicalId: number;
|
|
182
|
+
canonicalAlias: string;
|
|
183
|
+
sourceId: number;
|
|
184
|
+
sourceAlias: string;
|
|
185
|
+
workspaceId: string;
|
|
186
|
+
workspaceName: string;
|
|
187
|
+
};
|
|
188
|
+
export function buildWarningCompatibleImportCommands(options: {
|
|
189
|
+
appPath: string;
|
|
190
|
+
workspaceId: string;
|
|
191
|
+
canonicalId: number;
|
|
192
|
+
}): { validateCommand: string; importCommand: string };
|
|
193
|
+
export function runWarningCompatibleImport(
|
|
194
|
+
input: ApexlangInput,
|
|
195
|
+
result: ApexlangRunResult,
|
|
196
|
+
options: ApexlangRunOptions,
|
|
197
|
+
dependencies?: { sessionRunner?: typeof executeSqlclValidationThenImport }
|
|
198
|
+
): Promise<ApexlangRunResult>;
|
|
94
199
|
export function executeProcessTree(
|
|
95
200
|
executable: string,
|
|
96
201
|
args: string[],
|
|
97
202
|
options: ProcessTreeOptions
|
|
98
203
|
): Promise<ApexlangProcessResult>;
|
|
204
|
+
export function executeSqlclValidationThenImport(
|
|
205
|
+
executable: string,
|
|
206
|
+
args: string[],
|
|
207
|
+
options: SqlclValidationImportOptions
|
|
208
|
+
): Promise<SqlclValidationImportResult>;
|
|
99
209
|
export function runApexlang(
|
|
100
210
|
input: ApexlangInput,
|
|
101
211
|
options: ApexlangRunOptions
|
|
@@ -103,9 +213,10 @@ export function runApexlang(
|
|
|
103
213
|
export function runApexlangImport(
|
|
104
214
|
input: ApexlangInput,
|
|
105
215
|
options: ApexlangRunOptions,
|
|
106
|
-
importOptions
|
|
216
|
+
importOptions: ApexlangApprovedImportOptions
|
|
107
217
|
): Promise<ApexlangRunResult>;
|
|
108
218
|
export function runApexlangCreateNewProof(
|
|
109
219
|
input: ApexlangInput,
|
|
110
|
-
options: ApexlangRunOptions
|
|
220
|
+
options: ApexlangRunOptions,
|
|
221
|
+
proofOptions: ApexlangCreateNewProofOptions
|
|
111
222
|
): Promise<ApexlangRunResult>;
|