@lesliechan721/aw 0.1.0-beta.10 → 0.1.0-beta.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.
- package/dist/authoring/assets/aw-config.d.mts +1 -50
- package/dist/authoring/assets/aw-config.mjs +58 -928
- package/dist/authoring/assets/aw-config.mjs.map +1 -1
- package/dist/authoring/scripts/init-plugin.mjs +28 -33
- package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/lib/plugin-version-check.d.mts +1 -0
- package/dist/authoring/scripts/lib/plugin-version-check.mjs +229 -8
- package/dist/authoring/scripts/lib/plugin-version-check.mjs.map +1 -1
- package/dist/authoring/scripts/validate-plugin.mjs +159 -48
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/bundle-plugins.js +18 -4
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/scripts/test-plugin-scripts.d.ts +2 -0
- package/dist/scripts/test-plugin-scripts.js +21 -5
- package/dist/scripts/test-plugin-scripts.js.map +1 -1
- package/dist/src/commands/aw-capabilities.d.ts +1 -1
- package/dist/src/commands/aw-capabilities.js +1 -1
- package/dist/src/commands/aw-capabilities.js.map +1 -1
- package/dist/src/commands/catalog-dev-source.d.ts +6 -3
- package/dist/src/commands/catalog-dev-source.js +96 -35
- package/dist/src/commands/catalog-dev-source.js.map +1 -1
- package/dist/src/commands/catalog-publication-inspection.d.ts +1 -1
- package/dist/src/commands/catalog-publication-inspection.js +54 -8
- package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
- package/dist/src/commands/catalog-publication-journal.js +1 -1
- package/dist/src/commands/catalog-publication-journal.js.map +1 -1
- package/dist/src/commands/catalog-source.d.ts +19 -4
- package/dist/src/commands/catalog-source.js +121 -12
- package/dist/src/commands/catalog-source.js.map +1 -1
- package/dist/src/commands/catalog-store.d.ts +26 -7
- package/dist/src/commands/catalog-store.js +361 -42
- package/dist/src/commands/catalog-store.js.map +1 -1
- package/dist/src/commands/console.js +28 -17
- package/dist/src/commands/console.js.map +1 -1
- package/dist/src/commands/operation-plan.d.ts +2 -1
- package/dist/src/commands/operation-plan.js +24 -0
- package/dist/src/commands/operation-plan.js.map +1 -1
- package/dist/src/commands/operation-planner.d.ts +2 -2
- package/dist/src/commands/operation-planner.js +22 -20
- package/dist/src/commands/operation-planner.js.map +1 -1
- package/dist/src/commands/options.d.ts +2 -2
- package/dist/src/commands/options.js +18 -4
- package/dist/src/commands/options.js.map +1 -1
- package/dist/src/commands/plugin-capabilities.js +2 -2
- package/dist/src/commands/plugin-capabilities.js.map +1 -1
- package/dist/src/commands/rebuild-command.d.ts +19 -0
- package/dist/src/commands/rebuild-command.js +828 -283
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +25 -47
- package/dist/src/commands/rebuild-integration.js +1176 -1016
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/rebuild-operations.d.ts +50 -12
- package/dist/src/commands/rebuild-operations.js +207 -101
- package/dist/src/commands/rebuild-operations.js.map +1 -1
- package/dist/src/commands/status-v6.d.ts +21 -2
- package/dist/src/commands/status-v6.js +163 -31
- package/dist/src/commands/status-v6.js.map +1 -1
- package/dist/src/commands/sync-command.d.ts +17 -0
- package/dist/src/commands/sync-command.js +45 -37
- package/dist/src/commands/sync-command.js.map +1 -1
- package/dist/src/commands/write-commands.d.ts +5 -0
- package/dist/src/commands/write-commands.js +50 -3
- package/dist/src/commands/write-commands.js.map +1 -1
- package/dist/src/generators/local-plugin.js +14 -4
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.js +260 -91
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/command-receipt.js +1 -3
- package/dist/src/output/command-receipt.js.map +1 -1
- package/dist/src/output/rebuild-progress.js +1 -3
- package/dist/src/output/rebuild-progress.js.map +1 -1
- package/dist/src/portable/materializer.js +10 -8
- package/dist/src/portable/materializer.js.map +1 -1
- package/dist/src/tui/catalog-generation.js +41 -1
- package/dist/src/tui/catalog-generation.js.map +1 -1
- package/dist/src/tui/catalog-sources/session.d.ts +1 -0
- package/dist/src/tui/catalog-sources/session.js +16 -3
- package/dist/src/tui/catalog-sources/session.js.map +1 -1
- package/dist/src/tui/catalog-sources/types.d.ts +3 -2
- package/dist/src/tui/components.d.ts +4 -0
- package/dist/src/tui/components.js +36 -24
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/console-app-v4.d.ts +13 -4
- package/dist/src/tui/console-app-v4.js +2065 -857
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.js +731 -62
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +156 -10
- package/dist/src/tui/controller.js +1187 -163
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/diagnostic-projection.d.ts +22 -0
- package/dist/src/tui/diagnostic-projection.js +437 -0
- package/dist/src/tui/diagnostic-projection.js.map +1 -0
- package/dist/src/tui/diagnostics.d.ts +1 -1
- package/dist/src/tui/diagnostics.js +7 -2
- package/dist/src/tui/diagnostics.js.map +1 -1
- package/dist/src/tui/glossary.d.ts +23 -0
- package/dist/src/tui/glossary.js +42 -0
- package/dist/src/tui/glossary.js.map +1 -0
- package/dist/src/tui/index.d.ts +4 -1
- package/dist/src/tui/index.js +4 -1
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/keys.d.ts +44 -0
- package/dist/src/tui/keys.js +43 -15
- package/dist/src/tui/keys.js.map +1 -1
- package/dist/src/tui/lifecycle-action-view.d.ts +6 -0
- package/dist/src/tui/lifecycle-action-view.js +34 -0
- package/dist/src/tui/lifecycle-action-view.js.map +1 -0
- package/dist/src/tui/model.d.ts +12 -2
- package/dist/src/tui/model.js +128 -52
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/operation-diagnostic-screens.d.ts +21 -0
- package/dist/src/tui/operation-diagnostic-screens.js +101 -0
- package/dist/src/tui/operation-diagnostic-screens.js.map +1 -0
- package/dist/src/tui/operation-history.d.ts +80 -0
- package/dist/src/tui/operation-history.js +130 -0
- package/dist/src/tui/operation-history.js.map +1 -0
- package/dist/src/tui/operation-review-planner.js +366 -99
- package/dist/src/tui/operation-review-planner.js.map +1 -1
- package/dist/src/tui/router.d.ts +82 -17
- package/dist/src/tui/router.js +186 -38
- package/dist/src/tui/router.js.map +1 -1
- package/dist/src/tui/screen-registry.d.ts +546 -0
- package/dist/src/tui/screen-registry.js +179 -0
- package/dist/src/tui/screen-registry.js.map +1 -0
- package/dist/src/tui/session-console-app.d.ts +6 -0
- package/dist/src/tui/session-console-app.js +13 -0
- package/dist/src/tui/session-console-app.js.map +1 -0
- package/dist/src/tui/session-host.d.ts +44 -0
- package/dist/src/tui/session-host.js +197 -0
- package/dist/src/tui/session-host.js.map +1 -0
- package/dist/src/types.d.ts +64 -3
- package/dist/src/types.js +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/agent-version.js +1 -1
- package/dist/src/utils/agent-version.js.map +1 -1
- package/dist/src/utils/artifact-plan.d.ts +2 -2
- package/dist/src/utils/artifact-plan.js +8 -6
- package/dist/src/utils/artifact-plan.js.map +1 -1
- package/dist/src/utils/artifact-renderer.d.ts +2 -1
- package/dist/src/utils/artifact-renderer.js +139 -120
- package/dist/src/utils/artifact-renderer.js.map +1 -1
- package/dist/src/utils/artifact-request.d.ts +5 -0
- package/dist/src/utils/artifact-request.js +40 -0
- package/dist/src/utils/artifact-request.js.map +1 -1
- package/dist/src/utils/bundle-layout.js +4 -4
- package/dist/src/utils/bundle-layout.js.map +1 -1
- package/dist/src/utils/catalog-capability-projection.d.ts +8 -0
- package/dist/src/utils/catalog-capability-projection.js +14 -0
- package/dist/src/utils/catalog-capability-projection.js.map +1 -0
- package/dist/src/utils/catalog-generation-resolver.d.ts +14 -2
- package/dist/src/utils/catalog-generation-resolver.js +49 -27
- package/dist/src/utils/catalog-generation-resolver.js.map +1 -1
- package/dist/src/utils/catalog-generation-service.d.ts +8 -1
- package/dist/src/utils/catalog-generation-service.js +81 -47
- package/dist/src/utils/catalog-generation-service.js.map +1 -1
- package/dist/src/utils/catalog-generation-store.d.ts +1 -0
- package/dist/src/utils/catalog-generation-store.js +60 -5
- package/dist/src/utils/catalog-generation-store.js.map +1 -1
- package/dist/src/utils/catalog-operation-context.js +1 -0
- package/dist/src/utils/catalog-operation-context.js.map +1 -1
- package/dist/src/utils/catalog-public-error.js +4 -0
- package/dist/src/utils/catalog-public-error.js.map +1 -1
- package/dist/src/utils/catalog-source-impact.d.ts +3 -2
- package/dist/src/utils/catalog-source-impact.js +142 -20
- package/dist/src/utils/catalog-source-impact.js.map +1 -1
- package/dist/src/utils/catalog-source-references.js +95 -9
- package/dist/src/utils/catalog-source-references.js.map +1 -1
- package/dist/src/utils/catalog-sources.d.ts +1 -1
- package/dist/src/utils/catalog-sources.js +19 -3
- package/dist/src/utils/catalog-sources.js.map +1 -1
- package/dist/src/utils/codex-manager.js +8 -0
- package/dist/src/utils/codex-manager.js.map +1 -1
- package/dist/src/utils/codex-native-observation.d.ts +34 -1
- package/dist/src/utils/codex-native-observation.js +132 -0
- package/dist/src/utils/codex-native-observation.js.map +1 -1
- package/dist/src/utils/codex-reconciler.d.ts +0 -2
- package/dist/src/utils/codex-reconciler.js.map +1 -1
- package/dist/src/utils/codex-shared-native.d.ts +2 -26
- package/dist/src/utils/codex-shared-native.js +8 -82
- package/dist/src/utils/codex-shared-native.js.map +1 -1
- package/dist/src/utils/git-catalog-provider.d.ts +3 -0
- package/dist/src/utils/git-catalog-provider.js +40 -1
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/local-marketplace.d.ts +1 -0
- package/dist/src/utils/local-marketplace.js +69 -73
- package/dist/src/utils/local-marketplace.js.map +1 -1
- package/dist/src/utils/multi-source-catalog.js +1 -0
- package/dist/src/utils/multi-source-catalog.js.map +1 -1
- package/dist/src/utils/native-cli.d.ts +9 -4
- package/dist/src/utils/native-cli.js +280 -34
- package/dist/src/utils/native-cli.js.map +1 -1
- package/dist/src/utils/path-catalog-provider.js +2 -0
- package/dist/src/utils/path-catalog-provider.js.map +1 -1
- package/dist/src/utils/plugin-config-impact.d.ts +33 -0
- package/dist/src/utils/plugin-config-impact.js +298 -0
- package/dist/src/utils/plugin-config-impact.js.map +1 -0
- package/dist/src/utils/plugin-config-write.d.ts +36 -14
- package/dist/src/utils/plugin-config-write.js +709 -225
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/plugin-config.d.ts +58 -4
- package/dist/src/utils/plugin-config.js +328 -60
- package/dist/src/utils/plugin-config.js.map +1 -1
- package/dist/src/utils/plugin-scripts.d.ts +20 -12
- package/dist/src/utils/plugin-scripts.js +389 -114
- package/dist/src/utils/plugin-scripts.js.map +1 -1
- package/dist/src/utils/process-tree.d.ts +2 -2
- package/dist/src/utils/process-tree.js +1 -1
- package/dist/src/utils/process-tree.js.map +1 -1
- package/dist/src/utils/project-boundary.d.ts +11 -1
- package/dist/src/utils/project-boundary.js +33 -11
- package/dist/src/utils/project-boundary.js.map +1 -1
- package/dist/src/utils/safe-operation-diagnostic.d.ts +15 -0
- package/dist/src/utils/safe-operation-diagnostic.js +33 -0
- package/dist/src/utils/safe-operation-diagnostic.js.map +1 -0
- package/dist/src/utils/sensitive-content.d.ts +4 -0
- package/dist/src/utils/sensitive-content.js +36 -0
- package/dist/src/utils/sensitive-content.js.map +1 -0
- package/dist/src/utils/windows-claude-shim.d.ts +9 -0
- package/dist/src/utils/windows-claude-shim.js +141 -0
- package/dist/src/utils/windows-claude-shim.js.map +1 -0
- package/dist/vitest.config.js +91 -10
- package/dist/vitest.config.js.map +1 -1
- package/package.json +9 -9
- package/dist/authoring/templates/aw-config-runtime.d.mts +0 -2
- package/dist/authoring/templates/aw-config-runtime.mjs +0 -407
- package/dist/authoring/templates/aw-config-runtime.mjs.map +0 -1
|
@@ -3,16 +3,24 @@ import { randomUUID } from 'node:crypto';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
5
|
import { redactString } from '../output/redact.js';
|
|
6
|
-
import { observeProcessTree, terminateProcessTree } from './process-tree.js';
|
|
6
|
+
import { createWindowsJobInvocation, observeProcessTree, terminateProcessTree, } from './process-tree.js';
|
|
7
7
|
import { resolveAwHome } from './paths.js';
|
|
8
8
|
import { resolveEffectivePluginConfig } from './plugin-config.js';
|
|
9
9
|
import { assertTestWritablePath } from './test-path-fence.js';
|
|
10
|
+
import { attachSafeOperationError } from './safe-operation-diagnostic.js';
|
|
11
|
+
import { collectSensitiveTokenRepresentations, containsBlockedSensitiveToken, } from './sensitive-content.js';
|
|
10
12
|
export { calculateFileDigest } from './bundle-integrity.js';
|
|
11
|
-
export const PLUGIN_SCRIPT_TIMEOUT_DEFAULT_MS =
|
|
13
|
+
export const PLUGIN_SCRIPT_TIMEOUT_DEFAULT_MS = 300_000;
|
|
12
14
|
export const PLUGIN_SCRIPT_TIMEOUT_MIN_MS = 1_000;
|
|
13
|
-
export const PLUGIN_SCRIPT_TIMEOUT_MAX_MS =
|
|
15
|
+
export const PLUGIN_SCRIPT_TIMEOUT_MAX_MS = 1_800_000;
|
|
14
16
|
const OUTPUT_LIMIT = 64 * 1024;
|
|
15
|
-
const
|
|
17
|
+
const WINDOWS_JOB_CLOSE_TIMEOUT_MS = 4_500;
|
|
18
|
+
class PluginProcessInputError extends Error {
|
|
19
|
+
constructor(cause) {
|
|
20
|
+
super('Plugin process input could not be sent.', { cause });
|
|
21
|
+
this.name = 'PluginProcessInputError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
16
24
|
export async function resolveBundledPluginFilePath(options) {
|
|
17
25
|
const bundleRoot = await fs.realpath(options.bundleRoot);
|
|
18
26
|
const relativePath = options.pluginRelativePath.startsWith('./') ? options.pluginRelativePath.slice(2) : options.pluginRelativePath;
|
|
@@ -83,32 +91,47 @@ export function collectSensitivePluginConfigValues(manifest, values) {
|
|
|
83
91
|
});
|
|
84
92
|
});
|
|
85
93
|
}
|
|
94
|
+
export function assertNoSensitiveConfigValues(value, sensitiveValues, message) {
|
|
95
|
+
const strings = [];
|
|
96
|
+
const visit = (entry) => {
|
|
97
|
+
if (typeof entry === 'string') {
|
|
98
|
+
strings.push(entry);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (Array.isArray(entry)) {
|
|
102
|
+
entry.forEach(visit);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (entry !== null && typeof entry === 'object') {
|
|
106
|
+
Object.entries(entry).forEach(([key, child]) => {
|
|
107
|
+
strings.push(key);
|
|
108
|
+
visit(child);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
visit(value);
|
|
113
|
+
if (strings.some((entry) => containsBlockedSensitiveToken(entry, sensitiveValues))) {
|
|
114
|
+
throw new Error(message);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export function assertNoSensitiveConfigInFiles(files, sensitiveValues, message) {
|
|
118
|
+
assertNoSensitiveConfigValues(Object.entries(files).map(([relativePath, content]) => ({
|
|
119
|
+
relativePath,
|
|
120
|
+
content: content.toString('utf8'),
|
|
121
|
+
})), sensitiveValues, message);
|
|
122
|
+
}
|
|
86
123
|
function findSensitiveTokenMatches(value, sensitiveValue, startLimit) {
|
|
87
124
|
if (sensitiveValue === '')
|
|
88
125
|
return [];
|
|
89
|
-
if (sensitiveValue.length >= 8 && !/^(?:true|false|-?\d+(?:\.\d+)?)$/u.test(sensitiveValue)) {
|
|
90
|
-
const matches = [];
|
|
91
|
-
for (let start = value.indexOf(sensitiveValue); start >= 0 && start < startLimit; start = value.indexOf(sensitiveValue, start + 1)) {
|
|
92
|
-
matches.push({ start, end: start + sensitiveValue.length });
|
|
93
|
-
}
|
|
94
|
-
return matches;
|
|
95
|
-
}
|
|
96
|
-
const escaped = sensitiveValue.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
97
|
-
const numeric = /^-?\d+(?:\.\d+)?$/u.test(sensitiveValue);
|
|
98
|
-
const boundary = numeric ? '\\p{L}\\p{N}_.+-' : '\\p{L}\\p{N}_';
|
|
99
|
-
const pattern = new RegExp(`(?<![${boundary}])${escaped}(?![${boundary}])`, 'uy');
|
|
100
126
|
const matches = [];
|
|
101
127
|
for (let start = value.indexOf(sensitiveValue); start >= 0 && start < startLimit; start = value.indexOf(sensitiveValue, start + 1)) {
|
|
102
|
-
|
|
103
|
-
if (pattern.test(value))
|
|
104
|
-
matches.push({ start, end: start + sensitiveValue.length });
|
|
128
|
+
matches.push({ start, end: start + sensitiveValue.length });
|
|
105
129
|
}
|
|
106
130
|
return matches;
|
|
107
131
|
}
|
|
108
132
|
function collectMergedSensitiveTokenMatches(value, sensitiveValues, startLimit) {
|
|
109
|
-
const matches =
|
|
110
|
-
.
|
|
111
|
-
.flatMap((sensitiveValue) => findSensitiveTokenMatches(value, sensitiveValue, startLimit))
|
|
133
|
+
const matches = collectSensitiveTokenRepresentations(sensitiveValues)
|
|
134
|
+
.flatMap((representation) => findSensitiveTokenMatches(value, representation, startLimit))
|
|
112
135
|
.sort((left, right) => left.start - right.start || right.end - left.end);
|
|
113
136
|
const merged = [];
|
|
114
137
|
for (const match of matches) {
|
|
@@ -141,113 +164,365 @@ export function truncatePluginScriptOutput(value) {
|
|
|
141
164
|
export function summarizePluginScriptOutput(value, sensitiveValues) {
|
|
142
165
|
return redactString(redactSensitiveTokenWindow(value, sensitiveValues, Math.min(value.length, OUTPUT_LIMIT))).trim();
|
|
143
166
|
}
|
|
167
|
+
function summarizePreApplyFailureOutput(value, roots, sensitiveValues) {
|
|
168
|
+
const summary = redactString(sanitizePreApplyErrorMessage(value, roots, sensitiveValues, Math.min(value.length, OUTPUT_LIMIT))).trim();
|
|
169
|
+
const lines = summary.split('\n').map((line) => line.trim()).filter(Boolean);
|
|
170
|
+
const includesRuntimeStack = lines.some((line) => line.startsWith('file://')
|
|
171
|
+
|| line.startsWith('at ')
|
|
172
|
+
|| /^Node\.js v/u.test(line));
|
|
173
|
+
if (!includesRuntimeStack)
|
|
174
|
+
return summary;
|
|
175
|
+
return lines.find((line) => /^(?:[A-Za-z]*Error|Error):/u.test(line)) ?? '';
|
|
176
|
+
}
|
|
144
177
|
function resolveOutputCaptureLimit(sensitiveValues) {
|
|
145
|
-
const maxSensitiveTokenLength = sensitiveValues.reduce((maximum, value) => Math.max(maximum, value.length), 0);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
178
|
+
const maxSensitiveTokenLength = collectSensitiveTokenRepresentations(sensitiveValues).reduce((maximum, value) => Math.max(maximum, value.length), 0);
|
|
179
|
+
return OUTPUT_LIMIT + maxSensitiveTokenLength;
|
|
180
|
+
}
|
|
181
|
+
function privateRootVariants(root) {
|
|
182
|
+
const normalized = path.resolve(root);
|
|
183
|
+
return [...new Set([
|
|
184
|
+
normalized,
|
|
185
|
+
normalized.replaceAll('\\', '/'),
|
|
186
|
+
...(normalized.startsWith('/var/') ? [`/private${normalized}`] : []),
|
|
187
|
+
...(normalized.startsWith('/private/var/') ? [normalized.slice('/private'.length)] : []),
|
|
188
|
+
])];
|
|
189
|
+
}
|
|
190
|
+
function sanitizePreApplyErrorMessage(value, roots, sensitiveValues, windowEnd = value.length) {
|
|
191
|
+
const matches = [
|
|
192
|
+
...roots
|
|
193
|
+
.filter(({ root }) => root.trim() !== '')
|
|
194
|
+
.flatMap(({ root, replacement }) => privateRootVariants(root)
|
|
195
|
+
.flatMap((variant) => findSensitiveTokenMatches(value, variant, windowEnd)
|
|
196
|
+
.map((match) => ({ ...match, replacement })))),
|
|
197
|
+
...collectSensitiveTokenRepresentations(sensitiveValues)
|
|
198
|
+
.flatMap((representation) => findSensitiveTokenMatches(value, representation, windowEnd)
|
|
199
|
+
.map((match) => ({ ...match, replacement: '[REDACTED]' }))),
|
|
200
|
+
].sort((left, right) => left.start - right.start || right.end - left.end);
|
|
201
|
+
const merged = [];
|
|
202
|
+
for (const match of matches) {
|
|
203
|
+
const previous = merged.at(-1);
|
|
204
|
+
if (previous && match.start < previous.end) {
|
|
205
|
+
previous.end = Math.max(previous.end, match.end);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
merged.push({ ...match, replacement: match.replacement ?? '[REDACTED]' });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
let output = '';
|
|
212
|
+
let offset = 0;
|
|
213
|
+
for (const match of merged) {
|
|
214
|
+
output += `${value.slice(offset, match.start)}${match.replacement}`;
|
|
215
|
+
offset = Math.min(match.end, windowEnd);
|
|
216
|
+
}
|
|
217
|
+
return output + value.slice(offset, windowEnd);
|
|
218
|
+
}
|
|
219
|
+
export function createDefaultPluginProcessRunner(dependencies = {}) {
|
|
220
|
+
const platform = dependencies.platform ?? process.platform;
|
|
221
|
+
const spawnImpl = dependencies.spawn ?? spawn;
|
|
222
|
+
const observeProcessTreeImpl = dependencies.observeProcessTree ?? observeProcessTree;
|
|
223
|
+
const terminateProcessTreeImpl = dependencies.terminateProcessTree ?? terminateProcessTree;
|
|
224
|
+
const createWindowsJobInvocationImpl = dependencies.createWindowsJobInvocation ??
|
|
225
|
+
(dependencies.spawn ? undefined : createWindowsJobInvocation);
|
|
226
|
+
return {
|
|
227
|
+
run(invocation, options) {
|
|
228
|
+
return new Promise((resolve, reject) => {
|
|
229
|
+
options.signal?.throwIfAborted();
|
|
230
|
+
const marker = randomUUID();
|
|
231
|
+
const windowsJobInvocation = platform === 'win32' && createWindowsJobInvocationImpl
|
|
232
|
+
? createWindowsJobInvocationImpl(invocation.command, invocation.args)
|
|
233
|
+
: undefined;
|
|
234
|
+
const child = spawnImpl(windowsJobInvocation?.command ?? invocation.command, windowsJobInvocation?.args ?? invocation.args, { cwd: invocation.cwd, env: { ...invocation.env, AW_NATIVE_CLI_PROCESS_MARKER: marker }, shell: false, stdio: ['pipe', 'pipe', 'pipe'], detached: platform !== 'win32' });
|
|
235
|
+
let stdout = '';
|
|
236
|
+
let stderr = '';
|
|
237
|
+
let timedOut = false;
|
|
238
|
+
let aborted = false;
|
|
239
|
+
let settled = false;
|
|
240
|
+
let terminating = false;
|
|
241
|
+
let inputCompleted = child.stdin === null;
|
|
242
|
+
let inputError;
|
|
243
|
+
let childExited = false;
|
|
244
|
+
let cleanupCompleted = false;
|
|
245
|
+
let completedExitCode = null;
|
|
246
|
+
let completedSignal = null;
|
|
247
|
+
let windowsJobCloseTimer;
|
|
248
|
+
const outputCaptureLimit = resolveOutputCaptureLimit(options.sensitiveValues ?? []);
|
|
249
|
+
let observation;
|
|
250
|
+
if (!windowsJobInvocation && child.pid !== undefined)
|
|
251
|
+
observation = observeProcessTreeImpl(child.pid, marker);
|
|
252
|
+
const timer = setTimeout(() => { timedOut = true; terminate(); }, options.timeoutMs);
|
|
253
|
+
const abort = () => { aborted = true; terminate(); };
|
|
254
|
+
const cleanup = () => { clearTimeout(timer); if (windowsJobCloseTimer)
|
|
255
|
+
clearTimeout(windowsJobCloseTimer); options.signal?.removeEventListener('abort', abort); observation?.dispose(); };
|
|
256
|
+
const result = () => ({ exitCode: completedExitCode, signal: completedSignal, stdout, stderr, timedOut });
|
|
257
|
+
const settleImmediately = (error) => {
|
|
258
|
+
if (settled)
|
|
259
|
+
return;
|
|
260
|
+
settled = true;
|
|
261
|
+
cleanup();
|
|
175
262
|
reject(error);
|
|
176
|
-
|
|
263
|
+
};
|
|
264
|
+
const settleIfComplete = () => {
|
|
265
|
+
if (settled || !childExited || !cleanupCompleted || !inputCompleted)
|
|
266
|
+
return;
|
|
267
|
+
settled = true;
|
|
268
|
+
cleanup();
|
|
269
|
+
if (aborted) {
|
|
270
|
+
try {
|
|
271
|
+
options.signal?.throwIfAborted();
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
reject(error);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (inputError && !(inputError.code === 'EPIPE'
|
|
279
|
+
&& completedExitCode === 0
|
|
280
|
+
&& completedSignal === null) && !timedOut && completedExitCode === 0 && completedSignal === null) {
|
|
281
|
+
reject(new PluginProcessInputError(inputError));
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
resolve(result());
|
|
285
|
+
};
|
|
286
|
+
function terminate(requireConfirmedCleanup = false, allowUnobservedWindowsProcessOnNormalCompletion = false) {
|
|
287
|
+
if (settled || terminating)
|
|
288
|
+
return;
|
|
289
|
+
terminating = true;
|
|
290
|
+
clearTimeout(timer);
|
|
291
|
+
const direct = (signal) => { if (child.exitCode === null && child.signalCode === null)
|
|
292
|
+
child.kill(signal); };
|
|
293
|
+
if (windowsJobInvocation) {
|
|
294
|
+
try {
|
|
295
|
+
if (child.exitCode === null && child.signalCode === null && child.kill('SIGKILL') === false) {
|
|
296
|
+
throw new Error('Windows Job helper did not accept termination.');
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
settleImmediately(error);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
windowsJobCloseTimer = setTimeout(() => settleImmediately(new Error('Windows Job helper exit could not be confirmed.')), WINDOWS_JOB_CLOSE_TIMEOUT_MS);
|
|
304
|
+
windowsJobCloseTimer.unref();
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
const termination = child.pid === undefined
|
|
308
|
+
? Promise.resolve(direct('SIGKILL'))
|
|
309
|
+
: terminateProcessTreeImpl(child.pid, direct, {}, {
|
|
310
|
+
observation,
|
|
311
|
+
requireConfirmedCleanup,
|
|
312
|
+
...(allowUnobservedWindowsProcessOnNormalCompletion
|
|
313
|
+
? { allowUnobservedWindowsProcessOnNormalCompletion: true }
|
|
314
|
+
: {}),
|
|
315
|
+
});
|
|
316
|
+
void Promise.resolve(termination).then(() => { cleanupCompleted = true; settleIfComplete(); }, (error) => settleImmediately(error));
|
|
177
317
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
318
|
+
child.stdout?.setEncoding('utf8');
|
|
319
|
+
child.stderr?.setEncoding('utf8');
|
|
320
|
+
child.stdout?.on('data', (chunk) => { if (stdout.length < outputCaptureLimit)
|
|
321
|
+
stdout += chunk.slice(0, outputCaptureLimit - stdout.length); });
|
|
322
|
+
child.stderr?.on('data', (chunk) => { if (stderr.length < outputCaptureLimit)
|
|
323
|
+
stderr += chunk.slice(0, outputCaptureLimit - stderr.length); });
|
|
324
|
+
child.on('error', (error) => { if (!settled && (!terminating || windowsJobInvocation))
|
|
325
|
+
settleImmediately(error); });
|
|
326
|
+
const complete = (exitCode, signal) => {
|
|
327
|
+
if (settled)
|
|
328
|
+
return;
|
|
329
|
+
childExited = true;
|
|
330
|
+
completedExitCode = exitCode;
|
|
331
|
+
completedSignal = signal;
|
|
332
|
+
if (windowsJobInvocation) {
|
|
333
|
+
cleanupCompleted = true;
|
|
334
|
+
settleIfComplete();
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (terminating) {
|
|
338
|
+
settleIfComplete();
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
terminate(true, platform === 'win32' && exitCode === 0 && signal === null);
|
|
342
|
+
};
|
|
343
|
+
child.on(platform === 'win32' ? 'close' : 'exit', complete);
|
|
344
|
+
if (child.stdin) {
|
|
345
|
+
const completeInput = (error) => {
|
|
346
|
+
if (error !== undefined && error !== null)
|
|
347
|
+
inputError = error;
|
|
348
|
+
inputCompleted = true;
|
|
349
|
+
settleIfComplete();
|
|
350
|
+
};
|
|
351
|
+
child.stdin.once('error', completeInput);
|
|
352
|
+
child.stdin.once('finish', completeInput);
|
|
353
|
+
try {
|
|
354
|
+
child.stdin.end(invocation.stdin ?? '', completeInput);
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
completeInput(error);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
options.signal?.addEventListener('abort', abort, { once: true });
|
|
361
|
+
if (options.signal?.aborted)
|
|
362
|
+
abort();
|
|
363
|
+
});
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
export const defaultPluginProcessRunner = createDefaultPluginProcessRunner();
|
|
368
|
+
export async function runPreApplyScript(options) {
|
|
369
|
+
const declaration = options.plugin.manifest.scripts?.preApply;
|
|
212
370
|
if (!declaration)
|
|
213
371
|
return;
|
|
214
|
-
const
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
372
|
+
const awHome = resolveAwHome(options.context.env);
|
|
373
|
+
const codexHome = options.context.env.AW_CODEX_HOME || path.join(awHome, 'isolated-codex-home');
|
|
374
|
+
const claudeHome = options.context.env.AW_CLAUDE_HOME || path.join(awHome, 'isolated-claude-home');
|
|
375
|
+
let tempDir;
|
|
376
|
+
let interruptSignal;
|
|
377
|
+
let interruptReason;
|
|
378
|
+
let sensitiveValues = [];
|
|
379
|
+
let runnerCleanupConfirmed = false;
|
|
380
|
+
let removeInterruptListeners;
|
|
381
|
+
const privateRoots = () => [
|
|
382
|
+
...(tempDir ? [
|
|
383
|
+
{ root: path.join(tempDir, 'home'), replacement: '[temporary-home]' },
|
|
384
|
+
{ root: path.join(tempDir, 'tmp'), replacement: '[temporary]' },
|
|
385
|
+
{ root: tempDir, replacement: '[temporary]' },
|
|
386
|
+
] : []),
|
|
387
|
+
{ root: codexHome, replacement: '[codex-home]' },
|
|
388
|
+
{ root: claudeHome, replacement: '[claude-home]' },
|
|
389
|
+
{ root: awHome, replacement: '[aw-home]' },
|
|
390
|
+
{ root: options.plugin.rootDir, replacement: '[plugin-root]' },
|
|
391
|
+
{ root: options.cwd, replacement: '[project-root]' },
|
|
392
|
+
];
|
|
232
393
|
try {
|
|
394
|
+
const entryPath = await resolveBundledPluginFilePath({ bundleRoot: options.plugin.rootDir, pluginRelativePath: declaration.path, fieldName: 'preApply script' });
|
|
395
|
+
const effective = options.plugin.manifest.config?.fields
|
|
396
|
+
? await resolveEffectivePluginConfig({ sourceId: options.plugin.sourceId, sourceIdentity: options.plugin.sourceIdentity, logicalIdentity: options.plugin.catalogLogicalIdentity, pluginName: options.plugin.manifest.name, manifest: options.plugin.manifest, targetScope: options.scope, cwd: options.cwd, env: options.context.env })
|
|
397
|
+
: { values: {}, issues: [] };
|
|
398
|
+
if (effective.issues.length > 0)
|
|
399
|
+
throw new Error(`preApply config is invalid for ${options.plugin.manifest.name}.`);
|
|
400
|
+
const payload = {
|
|
401
|
+
schemaVersion: 1,
|
|
402
|
+
plugin: { pluginId: options.plugin.pluginId ?? `${options.plugin.sourceId}/${options.plugin.manifest.name}`, name: options.plugin.manifest.name, version: options.plugin.manifest.version, rootDir: options.plugin.rootDir },
|
|
403
|
+
target: { platform: options.platform, scope: options.scope, ...(options.scope === 'project' ? { projectRoot: options.cwd } : {}) },
|
|
404
|
+
config: { values: effective.values },
|
|
405
|
+
};
|
|
406
|
+
const tempRoot = assertTestWritablePath(path.join(awHome, 'tmp'), 'preApply temp root');
|
|
407
|
+
await fs.ensureDir(tempRoot);
|
|
408
|
+
tempDir = await fs.mkdtemp(path.join(tempRoot, 'plugin-pre-apply-'));
|
|
233
409
|
await fs.ensureDir(path.join(tempDir, 'home'));
|
|
234
410
|
await fs.ensureDir(path.join(tempDir, 'tmp'));
|
|
235
|
-
const env = buildPluginScriptSpawnEnv({ commandEnv: options.context.env, contextPath: '', tempDir, plugin: payload.plugin, event: '
|
|
411
|
+
const env = buildPluginScriptSpawnEnv({ commandEnv: options.context.env, contextPath: '', tempDir, plugin: payload.plugin, event: 'preApply', platform: options.platform, scope: options.scope, bundleRoot: options.plugin.rootDir });
|
|
236
412
|
delete env.AW_PLUGIN_CONTEXT;
|
|
237
|
-
|
|
413
|
+
sensitiveValues = collectSensitivePluginConfigValues(options.plugin.manifest, effective.values);
|
|
238
414
|
const invocation = buildNodeScriptInvocation({ entryPath, cwd: options.plugin.rootDir, env, stdin: `${JSON.stringify(payload)}\n` });
|
|
239
415
|
const runOptions = { timeoutMs: resolvePluginScriptTimeoutMs({ cliTimeoutMs: options.scriptTimeoutMs, manifestTimeoutMs: declaration.timeoutMs }) };
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
416
|
+
const interruptController = new AbortController();
|
|
417
|
+
const handleInterrupt = (signal) => {
|
|
418
|
+
if (interruptSignal)
|
|
419
|
+
return;
|
|
420
|
+
interruptSignal = signal;
|
|
421
|
+
interruptReason = new Error(`preApply interrupted by ${signal}.`);
|
|
422
|
+
interruptController.abort(interruptReason);
|
|
423
|
+
};
|
|
424
|
+
const handleSigint = () => handleInterrupt('SIGINT');
|
|
425
|
+
const handleSigterm = () => handleInterrupt('SIGTERM');
|
|
426
|
+
process.on('SIGINT', handleSigint);
|
|
427
|
+
process.on('SIGTERM', handleSigterm);
|
|
428
|
+
removeInterruptListeners = () => {
|
|
429
|
+
process.removeListener('SIGINT', handleSigint);
|
|
430
|
+
process.removeListener('SIGTERM', handleSigterm);
|
|
431
|
+
};
|
|
432
|
+
let result;
|
|
433
|
+
try {
|
|
434
|
+
result = options.runner
|
|
435
|
+
? await options.runner.run(invocation, { ...runOptions, signal: interruptController.signal })
|
|
436
|
+
: await defaultPluginProcessRunner.run(invocation, { ...runOptions, sensitiveValues, signal: interruptController.signal });
|
|
437
|
+
runnerCleanupConfirmed = true;
|
|
438
|
+
}
|
|
439
|
+
catch (error) {
|
|
440
|
+
if (interruptSignal && error === interruptReason) {
|
|
441
|
+
runnerCleanupConfirmed = true;
|
|
442
|
+
}
|
|
443
|
+
else if (interruptSignal) {
|
|
444
|
+
throw new Error(`preApply process cleanup failed after ${interruptSignal}.`);
|
|
445
|
+
}
|
|
446
|
+
else if (error instanceof PluginProcessInputError) {
|
|
447
|
+
throw attachSafeOperationError(new Error('preApply input could not be sent.'), {
|
|
448
|
+
code: 'preApplyInputFailed',
|
|
449
|
+
stage: 'preApply',
|
|
450
|
+
safeMessage: 'The preApply context could not be sent to the process.',
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
const causeCode = error && typeof error === 'object' && 'code' in error
|
|
455
|
+
&& typeof error.code === 'string' ? error.code : undefined;
|
|
456
|
+
const safeCauseCode = causeCode === 'ENOENT' || causeCode === 'EACCES' || causeCode === 'EPERM'
|
|
457
|
+
? causeCode : undefined;
|
|
458
|
+
throw attachSafeOperationError(new Error('preApply could not start.'), {
|
|
459
|
+
code: safeCauseCode === 'ENOENT' ? 'preApplyExecutableMissing' : 'preApplyStartFailed',
|
|
460
|
+
stage: 'preApply',
|
|
461
|
+
safeMessage: causeCode === 'ENOENT'
|
|
462
|
+
? 'The preApply executable is not available.'
|
|
463
|
+
: 'The preApply process could not start.',
|
|
464
|
+
...(safeCauseCode ? {
|
|
465
|
+
cause: { code: safeCauseCode, safeMessage: `Process start failed (${safeCauseCode}).` },
|
|
466
|
+
} : {}),
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (!result)
|
|
471
|
+
return;
|
|
472
|
+
const stdout = summarizePreApplyFailureOutput(result.stdout, privateRoots(), sensitiveValues);
|
|
473
|
+
const stderr = summarizePreApplyFailureOutput(result.stderr, privateRoots(), sensitiveValues);
|
|
474
|
+
const output = [
|
|
475
|
+
...(stdout ? [`stdout: ${stdout}`] : []),
|
|
476
|
+
...(stderr ? [`stderr: ${stderr}`] : []),
|
|
477
|
+
].join('; ');
|
|
244
478
|
if (result.timedOut)
|
|
245
|
-
throw new Error(`
|
|
246
|
-
|
|
247
|
-
|
|
479
|
+
throw attachSafeOperationError(new Error(`preApply timed out.${output ? ` ${output}` : ''}`), {
|
|
480
|
+
code: 'preApplyTimedOut',
|
|
481
|
+
stage: 'preApply',
|
|
482
|
+
safeMessage: 'The preApply process timed out.',
|
|
483
|
+
exitCode: 124,
|
|
484
|
+
});
|
|
485
|
+
if (result.exitCode !== 0) {
|
|
486
|
+
throw attachSafeOperationError(new Error(`preApply failed with exit code ${result.exitCode}.${output ? ` ${output}` : ''}`), {
|
|
487
|
+
code: 'preApplyExited',
|
|
488
|
+
stage: 'preApply',
|
|
489
|
+
safeMessage: 'The preApply process exited unsuccessfully.',
|
|
490
|
+
...(result.exitCode === null ? {} : { exitCode: result.exitCode }),
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
catch (error) {
|
|
495
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
496
|
+
const failure = new Error(redactString(sanitizePreApplyErrorMessage(message, privateRoots(), sensitiveValues)));
|
|
497
|
+
const diagnostic = error && typeof error === 'object' && 'operationDiagnostic' in error
|
|
498
|
+
? error.operationDiagnostic
|
|
499
|
+
: undefined;
|
|
500
|
+
throw diagnostic ? Object.assign(failure, { operationDiagnostic: diagnostic }) : failure;
|
|
248
501
|
}
|
|
249
502
|
finally {
|
|
250
|
-
|
|
503
|
+
let tempCleanupError;
|
|
504
|
+
try {
|
|
505
|
+
if (tempDir)
|
|
506
|
+
await fs.remove(tempDir);
|
|
507
|
+
}
|
|
508
|
+
catch (error) {
|
|
509
|
+
tempCleanupError = error;
|
|
510
|
+
}
|
|
511
|
+
removeInterruptListeners?.();
|
|
512
|
+
if (interruptSignal) {
|
|
513
|
+
if (tempCleanupError) {
|
|
514
|
+
process.stderr.write(`preApply temporary directory cleanup failed after ${interruptSignal}.\n`);
|
|
515
|
+
process.exit(1);
|
|
516
|
+
}
|
|
517
|
+
if (!runnerCleanupConfirmed) {
|
|
518
|
+
process.stderr.write(`preApply process cleanup failed after ${interruptSignal}.\n`);
|
|
519
|
+
process.exit(1);
|
|
520
|
+
}
|
|
521
|
+
process.exit(interruptSignal === 'SIGINT' ? 130 : 143);
|
|
522
|
+
}
|
|
523
|
+
if (tempCleanupError) {
|
|
524
|
+
throw tempCleanupError;
|
|
525
|
+
}
|
|
251
526
|
}
|
|
252
527
|
}
|
|
253
528
|
//# sourceMappingURL=plugin-scripts.js.map
|