agenshield 0.6.1 → 0.7.0

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.
@@ -42,10 +42,11 @@ export const WIZARD_STEPS = [
42
42
  },
43
43
  // Setup phase
44
44
  {
45
- id: 'backup',
46
- name: 'Backup Installation',
47
- description: 'Save backup for safe reversal',
45
+ id: 'cleanup-previous',
46
+ name: 'Clean Previous Installation',
47
+ description: 'Remove any previous AgenShield installation',
48
48
  phase: 'setup',
49
+ requiresSudo: true,
49
50
  dependsOn: ['confirm'],
50
51
  },
51
52
  {
@@ -54,7 +55,7 @@ export const WIZARD_STEPS = [
54
55
  description: 'Create socket access and workspace groups',
55
56
  phase: 'setup',
56
57
  requiresSudo: true,
57
- dependsOn: ['backup'],
58
+ dependsOn: ['cleanup-previous'],
58
59
  },
59
60
  {
60
61
  id: 'create-agent-user',
@@ -89,19 +90,43 @@ export const WIZARD_STEPS = [
89
90
  dependsOn: ['create-directories'],
90
91
  },
91
92
  {
92
- id: 'generate-seatbelt',
93
- name: 'Generate Seatbelt Profiles',
94
- description: 'Generate macOS sandbox profiles',
93
+ id: 'install-homebrew',
94
+ name: 'Install Homebrew',
95
+ description: 'Install user-specific Homebrew for agent user (this may take up to 2 minutes)',
95
96
  phase: 'setup',
96
97
  requiresSudo: true,
97
98
  dependsOn: ['create-directories'],
98
99
  },
100
+ {
101
+ id: 'install-nvm',
102
+ name: 'Install NVM & Node.js',
103
+ description: 'Install NVM and Node.js for agent user (this may take up to 2 minutes)',
104
+ phase: 'setup',
105
+ requiresSudo: true,
106
+ dependsOn: ['install-homebrew'],
107
+ },
108
+ {
109
+ id: 'configure-shell',
110
+ name: 'Configure Shell',
111
+ description: 'Set up guarded shell with Homebrew and NVM paths',
112
+ phase: 'setup',
113
+ requiresSudo: true,
114
+ dependsOn: ['install-nvm'],
115
+ },
99
116
  {
100
117
  id: 'install-wrappers',
101
118
  name: 'Install Wrappers',
102
119
  description: 'Install command wrappers to agent home bin directory (this may take up to a minute)',
103
120
  phase: 'setup',
104
121
  requiresSudo: true,
122
+ dependsOn: ['configure-shell'],
123
+ },
124
+ {
125
+ id: 'generate-seatbelt',
126
+ name: 'Generate Seatbelt Profiles',
127
+ description: 'Generate macOS sandbox profiles',
128
+ phase: 'setup',
129
+ requiresSudo: true,
105
130
  dependsOn: ['create-directories'],
106
131
  },
107
132
  {
@@ -120,6 +145,14 @@ export const WIZARD_STEPS = [
120
145
  requiresSudo: true,
121
146
  dependsOn: ['create-directories'],
122
147
  },
148
+ {
149
+ id: 'install-sudoers',
150
+ name: 'Install Sudoers Rule',
151
+ description: 'Grant broker passwordless sudo for agent operations',
152
+ phase: 'setup',
153
+ requiresSudo: true,
154
+ dependsOn: ['create-broker-user', 'create-agent-user'],
155
+ },
123
156
  {
124
157
  id: 'install-policies',
125
158
  name: 'Install Policies',
@@ -131,40 +164,78 @@ export const WIZARD_STEPS = [
131
164
  {
132
165
  id: 'setup-launchdaemon',
133
166
  name: 'Setup LaunchDaemon',
134
- description: 'Create and load launchd plist (this may take up to a minute)',
167
+ description: 'Create and load broker launchd plist (this may take up to a minute)',
135
168
  phase: 'setup',
136
169
  requiresSudo: true,
137
170
  dependsOn: ['install-broker', 'install-daemon-config'],
138
171
  },
139
172
  {
140
- id: 'migrate',
141
- name: 'Migrate Installation',
142
- description: 'Move target application to sandbox',
173
+ id: 'copy-openclaw-config',
174
+ name: 'Copy OpenClaw Config',
175
+ description: 'Copy and sanitize OpenClaw config from host user',
143
176
  phase: 'setup',
144
177
  requiresSudo: true,
145
- dependsOn: ['install-wrappers', 'setup-launchdaemon'],
178
+ dependsOn: ['create-directories'],
179
+ },
180
+ {
181
+ id: 'install-openclaw',
182
+ name: 'Install OpenClaw',
183
+ description: 'Install OpenClaw in agent sandbox via NVM npm (this may take up to 3 minutes)',
184
+ phase: 'setup',
185
+ requiresSudo: true,
186
+ dependsOn: ['setup-launchdaemon', 'install-wrappers', 'copy-openclaw-config'],
187
+ },
188
+ {
189
+ id: 'stop-host-openclaw',
190
+ name: 'Stop Host OpenClaw',
191
+ description: 'Stop OpenClaw daemon and gateway on host user',
192
+ phase: 'setup',
193
+ dependsOn: ['install-openclaw'],
194
+ },
195
+ {
196
+ id: 'onboard-openclaw',
197
+ name: 'Initialize OpenClaw',
198
+ description: 'Run openclaw onboard to initialize agent environment (this may take up to 2 minutes)',
199
+ phase: 'setup',
200
+ requiresSudo: true,
201
+ dependsOn: ['stop-host-openclaw'],
146
202
  },
147
203
  {
148
204
  id: 'verify',
149
205
  name: 'Verify Installation',
150
- description: 'Test sandboxed application',
206
+ description: 'Verify users, groups, and directories',
151
207
  phase: 'setup',
152
208
  requiresSudo: true,
153
- dependsOn: ['migrate'],
209
+ dependsOn: ['onboard-openclaw'],
210
+ },
211
+ {
212
+ id: 'start-openclaw',
213
+ name: 'Start OpenClaw',
214
+ description: 'Install and start OpenClaw LaunchDaemons with intercepted Node.js',
215
+ phase: 'setup',
216
+ requiresSudo: true,
217
+ dependsOn: ['verify'],
154
218
  },
155
219
  {
156
220
  id: 'setup-passcode',
157
221
  name: 'Setup Passcode',
158
222
  description: 'Set a passcode to protect sensitive configuration',
159
223
  phase: 'setup',
160
- dependsOn: ['verify'],
224
+ dependsOn: ['start-openclaw'],
225
+ },
226
+ {
227
+ id: 'open-dashboard',
228
+ name: 'Open Dashboard',
229
+ description: 'Open AgenShield dashboard in browser',
230
+ phase: 'setup',
231
+ dependsOn: ['setup-passcode'],
161
232
  },
162
233
  {
163
234
  id: 'complete',
164
235
  name: 'Complete',
165
236
  description: 'Setup finished successfully',
166
237
  phase: 'setup',
167
- dependsOn: ['setup-passcode'],
238
+ dependsOn: ['open-dashboard'],
168
239
  },
169
240
  ];
170
241
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/wizard/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4NH;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,kBAAkB;IAClB;QACE,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,+CAA+C;QAC5D,KAAK,EAAE,WAAW;KACnB;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,+DAA+D;QAC5E,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,CAAC,eAAe,CAAC;KAC7B;IACD;QACE,EAAE,EAAE,gBAAgB;QACpB,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,yCAAyC;QACtD,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,CAAC,QAAQ,CAAC;KACtB;IACD;QACE,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,2BAA2B;QACxC,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,CAAC,gBAAgB,CAAC;KAC9B;IACD;QACE,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,qCAAqC;QAClD,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,CAAC,WAAW,CAAC;KACzB;IAED,cAAc;IACd;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,+BAA+B;QAC5C,KAAK,EAAE,OAAO;QACd,SAAS,EAAE,CAAC,SAAS,CAAC;KACvB;IACD;QACE,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,2CAA2C;QACxD,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,QAAQ,CAAC;KACtB;IACD;QACE,EAAE,EAAE,mBAAmB;QACvB,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,gDAAgD;QAC7D,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,eAAe,CAAC;KAC7B;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,+BAA+B;QAC5C,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,eAAe,CAAC;KAC7B;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,+CAA+C;QAC5D,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;KACvD;IACD;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,sDAAsD;QACnE,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,oBAAoB,CAAC;KAClC;IACD;QACE,EAAE,EAAE,mBAAmB;QACvB,IAAI,EAAE,4BAA4B;QAClC,WAAW,EAAE,iCAAiC;QAC9C,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,oBAAoB,CAAC;KAClC;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,qFAAqF;QAClG,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,oBAAoB,CAAC;KAClC;IACD;QACE,EAAE,EAAE,gBAAgB;QACpB,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,uBAAuB;QACpC,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,oBAAoB,CAAC;KAClC;IACD;QACE,EAAE,EAAE,uBAAuB;QAC3B,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,kCAAkC;QAC/C,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,oBAAoB,CAAC;KAClC;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,iCAAiC;QAC9C,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,oBAAoB,CAAC;KAClC;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,8DAA8D;QAC3E,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,gBAAgB,EAAE,uBAAuB,CAAC;KACvD;IACD;QACE,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,oCAAoC;QACjD,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;KACtD;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,4BAA4B;QACzC,KAAK,EAAE,OAAO;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,CAAC,SAAS,CAAC;KACvB;IACD;QACE,EAAE,EAAE,gBAAgB;QACpB,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,mDAAmD;QAChE,KAAK,EAAE,OAAO;QACd,SAAS,EAAE,CAAC,QAAQ,CAAC;KACtB;IACD;QACE,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,6BAA6B;QAC1C,KAAK,EAAE,OAAO;QACd,SAAS,EAAE,CAAC,gBAAgB,CAAC;KAC9B;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAA4B;IAC1D,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAChC,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,MAAM,EAAE,SAAkB;KAC3B,CAAC,CAAC,CAAC;AACN,CAAC","sourcesContent":["/**\n * Types for the setup wizard\n */\n\nimport type { OriginalInstallation, UserConfig, PathsConfig } from '@agenshield/ipc';\nimport type { TargetPreset, PresetDetectionResult } from '@agenshield/sandbox';\n\nexport type WizardStepStatus = 'pending' | 'running' | 'completed' | 'error' | 'skipped';\n\n/**\n * Wizard step IDs\n */\nexport type WizardStepId =\n | 'prerequisites'\n | 'detect'\n | 'install-target'\n | 'configure'\n | 'confirm'\n | 'backup'\n | 'create-groups'\n | 'create-agent-user'\n | 'create-broker-user'\n | 'create-directories'\n | 'setup-socket'\n | 'generate-seatbelt'\n | 'install-wrappers'\n | 'install-broker'\n | 'install-daemon-config'\n | 'install-policies'\n | 'setup-launchdaemon'\n | 'migrate'\n | 'verify'\n | 'setup-passcode'\n | 'complete';\n\nexport interface WizardStep {\n id: WizardStepId;\n name: string;\n description: string;\n status: WizardStepStatus;\n error?: string;\n}\n\nexport interface WizardState {\n currentStep: number;\n steps: WizardStep[];\n isComplete: boolean;\n hasError: boolean;\n}\n\n/**\n * User information after creation\n */\nexport interface SandboxUserInfo {\n username: string;\n uid: number;\n gid: number;\n homeDir: string;\n shell: string;\n}\n\n/**\n * Wizard options passed from CLI\n */\nexport interface WizardOptions {\n /** Target preset to use: 'openclaw', 'custom', or auto-detect if not specified */\n targetPreset?: string;\n /** Entry point for custom target (Node.js file path) */\n entryPoint?: string;\n /** Base name for users/groups (default: 'agenshield') */\n baseName?: string;\n /** Optional prefix for user/group names (for testing) */\n prefix?: string;\n /** Optional base UID (for testing) */\n baseUid?: number;\n /** Optional base GID (for testing) */\n baseGid?: number;\n /** Dry run mode - show what would be done without making changes */\n dryRun?: boolean;\n /** Skip confirmation prompt */\n skipConfirm?: boolean;\n /** Verbose output */\n verbose?: boolean;\n /** Node.js version to install via NVM (default: '24') */\n nodeVersion?: string;\n}\n\nexport interface WizardContext {\n /** Wizard options from CLI */\n options?: WizardOptions;\n\n /** User configuration (dynamic based on prefix/baseUid/baseName) */\n userConfig?: UserConfig;\n\n /** Paths configuration */\n pathsConfig?: PathsConfig;\n\n /** Selected target preset */\n preset?: TargetPreset;\n\n /** Detection result from the preset */\n presetDetection?: PresetDetectionResult;\n\n /** Original installation info for backup (set during backup step) */\n originalInstallation?: OriginalInstallation;\n\n /** Agent user info */\n agentUser?: SandboxUserInfo;\n\n /** Broker user info */\n brokerUser?: SandboxUserInfo;\n\n /** Groups created */\n groupsCreated?: {\n socket: { name: string; gid: number };\n workspace: { name: string; gid: number };\n };\n\n /** Directory structure created */\n directories?: {\n binDir: string;\n wrappersDir: string;\n configDir: string;\n packageDir: string;\n npmDir: string;\n socketDir: string;\n logDir: string;\n seatbeltDir: string;\n };\n\n /** Socket setup result */\n socketSetup?: {\n path: string;\n success: boolean;\n };\n\n /** Seatbelt profiles generated */\n seatbeltProfiles?: {\n agentProfile: string;\n operationProfiles: string[];\n };\n\n /** Wrappers installed */\n wrappersInstalled?: string[];\n\n /** Broker installation */\n brokerInstalled?: {\n binaryPath: string;\n success: boolean;\n };\n\n /** Daemon configuration */\n daemonConfig?: {\n configPath: string;\n success: boolean;\n };\n\n /** Policies installed */\n policiesInstalled?: {\n builtinCount: number;\n customCount: number;\n };\n\n /** LaunchDaemon setup */\n launchDaemon?: {\n plistPath: string;\n loaded: boolean;\n };\n\n /** Migration result */\n migration?: {\n success: boolean;\n newPaths?: {\n packagePath: string;\n binaryPath: string;\n configPath?: string;\n };\n };\n\n /** Verification result */\n verification?: {\n usersValid: boolean;\n groupsValid: boolean;\n directoriesValid: boolean;\n socketValid: boolean;\n daemonRunning: boolean;\n networkBlocked: boolean;\n };\n\n /** Passcode setup result */\n passcodeSetup?: {\n /** Whether passcode was set */\n configured: boolean;\n /** Whether user skipped passcode setup */\n skipped: boolean;\n };\n\n /** Passcode value (temporary, only during wizard flow) */\n passcodeValue?: string;\n\n /** Whether the target can be installed (e.g. via npm) */\n targetInstallable?: boolean;\n\n /** Whether the user requested target installation */\n installTargetRequested?: boolean;\n}\n\n/**\n * Step definition for wizard\n */\nexport interface WizardStepDefinition {\n id: WizardStepId;\n name: string;\n description: string;\n /** Whether this step requires sudo */\n requiresSudo?: boolean;\n /** Dependencies (other step IDs that must complete first) */\n dependsOn?: WizardStepId[];\n /** Phase: 'detection' (runs before confirm) or 'setup' (runs after confirm) */\n phase: 'detection' | 'setup';\n}\n\n/**\n * All wizard step definitions\n */\nexport const WIZARD_STEPS: WizardStepDefinition[] = [\n // Detection phase\n {\n id: 'prerequisites',\n name: 'Check Prerequisites',\n description: 'Verify Node.js 22+, macOS, and required tools',\n phase: 'detection',\n },\n {\n id: 'detect',\n name: 'Detect Target',\n description: 'Find target application (auto-detect or use specified preset)',\n phase: 'detection',\n dependsOn: ['prerequisites'],\n },\n {\n id: 'install-target',\n name: 'Install Target',\n description: 'Install target application if not found',\n phase: 'detection',\n dependsOn: ['detect'],\n },\n {\n id: 'configure',\n name: 'Configure',\n description: 'Set up user configuration',\n phase: 'detection',\n dependsOn: ['install-target'],\n },\n {\n id: 'confirm',\n name: 'Confirm Setup',\n description: 'Show plan and get user confirmation',\n phase: 'detection',\n dependsOn: ['configure'],\n },\n\n // Setup phase\n {\n id: 'backup',\n name: 'Backup Installation',\n description: 'Save backup for safe reversal',\n phase: 'setup',\n dependsOn: ['confirm'],\n },\n {\n id: 'create-groups',\n name: 'Create Groups',\n description: 'Create socket access and workspace groups',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['backup'],\n },\n {\n id: 'create-agent-user',\n name: 'Create Agent User',\n description: 'Create sandboxed agent user with guarded shell',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-groups'],\n },\n {\n id: 'create-broker-user',\n name: 'Create Broker User',\n description: 'Create broker user for daemon',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-groups'],\n },\n {\n id: 'create-directories',\n name: 'Create Directories',\n description: 'Create /opt/agenshield, /etc/agenshield, etc.',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-agent-user', 'create-broker-user'],\n },\n {\n id: 'setup-socket',\n name: 'Setup Socket',\n description: 'Create /var/run/agenshield/ with correct permissions',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'generate-seatbelt',\n name: 'Generate Seatbelt Profiles',\n description: 'Generate macOS sandbox profiles',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-wrappers',\n name: 'Install Wrappers',\n description: 'Install command wrappers to agent home bin directory (this may take up to a minute)',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-broker',\n name: 'Install Broker',\n description: 'Install broker binary',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-daemon-config',\n name: 'Install Daemon Config',\n description: 'Write daemon configuration files',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-policies',\n name: 'Install Policies',\n description: 'Write default security policies',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'setup-launchdaemon',\n name: 'Setup LaunchDaemon',\n description: 'Create and load launchd plist (this may take up to a minute)',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['install-broker', 'install-daemon-config'],\n },\n {\n id: 'migrate',\n name: 'Migrate Installation',\n description: 'Move target application to sandbox',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['install-wrappers', 'setup-launchdaemon'],\n },\n {\n id: 'verify',\n name: 'Verify Installation',\n description: 'Test sandboxed application',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['migrate'],\n },\n {\n id: 'setup-passcode',\n name: 'Setup Passcode',\n description: 'Set a passcode to protect sensitive configuration',\n phase: 'setup',\n dependsOn: ['verify'],\n },\n {\n id: 'complete',\n name: 'Complete',\n description: 'Setup finished successfully',\n phase: 'setup',\n dependsOn: ['setup-passcode'],\n },\n];\n\n/**\n * Get step IDs for a specific phase\n */\nexport function getStepsByPhase(phase: 'detection' | 'setup'): WizardStepId[] {\n return WIZARD_STEPS.filter((s) => s.phase === phase).map((s) => s.id);\n}\n\n/**\n * Get all step IDs in order\n */\nexport function getAllStepIds(): WizardStepId[] {\n return WIZARD_STEPS.map((s) => s.id);\n}\n\n/**\n * Create initial wizard steps from definitions\n */\nexport function createWizardSteps(): WizardStep[] {\n return WIZARD_STEPS.map((def) => ({\n id: def.id,\n name: def.name,\n description: def.description,\n status: 'pending' as const,\n }));\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/wizard/types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Types for the setup wizard\n */\n\nimport type { OriginalInstallation, UserConfig, PathsConfig, MigrationScanResult, MigrationSelection } from '@agenshield/ipc';\nimport type { TargetPreset, PresetDetectionResult } from '@agenshield/sandbox';\n\nexport type WizardStepStatus = 'pending' | 'running' | 'completed' | 'error' | 'skipped';\n\n/**\n * Wizard step IDs\n */\nexport type WizardStepId =\n | 'prerequisites'\n | 'detect'\n | 'install-target'\n | 'configure'\n | 'confirm'\n | 'cleanup-previous'\n | 'create-groups'\n | 'create-agent-user'\n | 'create-broker-user'\n | 'create-directories'\n | 'setup-socket'\n | 'install-homebrew'\n | 'install-nvm'\n | 'configure-shell'\n | 'install-wrappers'\n | 'generate-seatbelt'\n | 'install-broker'\n | 'install-daemon-config'\n | 'install-sudoers'\n | 'install-policies'\n | 'setup-launchdaemon'\n | 'install-openclaw'\n | 'copy-openclaw-config'\n | 'stop-host-openclaw'\n | 'onboard-openclaw'\n | 'verify'\n | 'start-openclaw'\n | 'setup-passcode'\n | 'open-dashboard'\n | 'complete';\n\nexport interface WizardStep {\n id: WizardStepId;\n name: string;\n description: string;\n status: WizardStepStatus;\n error?: string;\n}\n\nexport interface WizardState {\n currentStep: number;\n steps: WizardStep[];\n isComplete: boolean;\n hasError: boolean;\n}\n\n/**\n * User information after creation\n */\nexport interface SandboxUserInfo {\n username: string;\n uid: number;\n gid: number;\n homeDir: string;\n shell: string;\n}\n\n/**\n * Wizard options passed from CLI\n */\nexport interface WizardOptions {\n /** Target preset to use: 'openclaw', 'custom', or auto-detect if not specified */\n targetPreset?: string;\n /** Entry point for custom target (Node.js file path) */\n entryPoint?: string;\n /** Base name for users/groups (default: 'agenshield') */\n baseName?: string;\n /** Optional prefix for user/group names (for testing) */\n prefix?: string;\n /** Optional base UID (for testing) */\n baseUid?: number;\n /** Optional base GID (for testing) */\n baseGid?: number;\n /** Dry run mode - show what would be done without making changes */\n dryRun?: boolean;\n /** Skip confirmation prompt */\n skipConfirm?: boolean;\n /** Verbose output */\n verbose?: boolean;\n /** Node.js version to install via NVM (default: '24') */\n nodeVersion?: string;\n}\n\nexport interface WizardContext {\n /** Wizard options from CLI */\n options?: WizardOptions;\n\n /** User configuration (dynamic based on prefix/baseUid/baseName) */\n userConfig?: UserConfig;\n\n /** Paths configuration */\n pathsConfig?: PathsConfig;\n\n /** Selected target preset */\n preset?: TargetPreset;\n\n /** Detection result from the preset */\n presetDetection?: PresetDetectionResult;\n\n /** Original installation info for backup (set during backup step) */\n originalInstallation?: OriginalInstallation;\n\n /** Agent user info */\n agentUser?: SandboxUserInfo;\n\n /** Broker user info */\n brokerUser?: SandboxUserInfo;\n\n /** Groups created */\n groupsCreated?: {\n socket: { name: string; gid: number };\n workspace: { name: string; gid: number };\n };\n\n /** Directory structure created */\n directories?: {\n binDir: string;\n wrappersDir: string;\n configDir: string;\n packageDir?: string;\n npmDir: string;\n socketDir: string;\n logDir: string;\n seatbeltDir: string;\n };\n\n /** Socket setup result */\n socketSetup?: {\n path: string;\n success: boolean;\n };\n\n /** Seatbelt profiles generated */\n seatbeltProfiles?: {\n agentProfile: string;\n operationProfiles: string[];\n };\n\n /** Wrappers installed */\n wrappersInstalled?: string[];\n\n /** Broker installation */\n brokerInstalled?: {\n binaryPath: string;\n success: boolean;\n };\n\n /** Daemon configuration */\n daemonConfig?: {\n configPath: string;\n success: boolean;\n };\n\n /** Policies installed */\n policiesInstalled?: {\n builtinCount: number;\n customCount: number;\n };\n\n /** LaunchDaemon setup */\n launchDaemon?: {\n plistPath: string;\n loaded: boolean;\n };\n\n /** Migration result */\n migration?: {\n success: boolean;\n newPaths?: {\n packagePath: string;\n binaryPath: string;\n configPath?: string;\n };\n };\n\n /** Verification result */\n verification?: {\n usersValid: boolean;\n groupsValid: boolean;\n directoriesValid: boolean;\n socketValid: boolean;\n daemonRunning: boolean;\n networkBlocked: boolean;\n };\n\n /** Passcode setup result */\n passcodeSetup?: {\n /** Whether passcode was set */\n configured: boolean;\n /** Whether user skipped passcode setup */\n skipped: boolean;\n };\n\n /** Passcode value (temporary, only during wizard flow) */\n passcodeValue?: string;\n\n /** Whether the target can be installed (e.g. via npm) */\n targetInstallable?: boolean;\n\n /** Whether the user requested target installation */\n installTargetRequested?: boolean;\n\n /** Migration scan result (from scan-source step) */\n scanResult?: MigrationScanResult;\n\n /** User's migration selection (from select-items step) */\n migrationSelection?: MigrationSelection;\n\n // ── New setup flow fields ──────────────────────────────────────────────\n\n /** Homebrew installation result */\n homebrewInstalled?: {\n brewPath: string;\n success: boolean;\n };\n\n /** NVM installation result */\n nvmInstalled?: {\n nvmDir: string;\n nodeVersion: string;\n nodeBinaryPath: string;\n success: boolean;\n };\n\n /** Shell configuration result */\n shellConfigured?: {\n success: boolean;\n };\n\n /** OpenClaw installation result (via npm in agent sandbox) */\n openclawInstalled?: {\n version: string;\n binaryPath: string;\n success: boolean;\n };\n\n /** OpenClaw config copy result */\n openclawConfigCopied?: {\n configDir: string;\n sanitized: boolean;\n success: boolean;\n };\n\n /** Host OpenClaw stop result */\n hostOpenclawStopped?: {\n daemonStopped: boolean;\n gatewayStopped: boolean;\n };\n\n /** OpenClaw LaunchDaemon setup */\n openclawLaunchDaemons?: {\n daemonPlistPath: string;\n gatewayPlistPath: string;\n loaded: boolean;\n };\n\n /** OpenClaw onboard result */\n openclawOnboarded?: {\n success: boolean;\n };\n\n /** OpenClaw gateway process (started inline) */\n openclawGateway?: {\n pid: number;\n running: boolean;\n };\n}\n\n/**\n * Step definition for wizard\n */\nexport interface WizardStepDefinition {\n id: WizardStepId;\n name: string;\n description: string;\n /** Whether this step requires sudo */\n requiresSudo?: boolean;\n /** Dependencies (other step IDs that must complete first) */\n dependsOn?: WizardStepId[];\n /** Phase: 'detection' (runs before confirm) or 'setup' (runs after confirm) */\n phase: 'detection' | 'setup';\n}\n\n/**\n * All wizard step definitions\n */\nexport const WIZARD_STEPS: WizardStepDefinition[] = [\n // Detection phase\n {\n id: 'prerequisites',\n name: 'Check Prerequisites',\n description: 'Verify Node.js 22+, macOS, and required tools',\n phase: 'detection',\n },\n {\n id: 'detect',\n name: 'Detect Target',\n description: 'Find target application (auto-detect or use specified preset)',\n phase: 'detection',\n dependsOn: ['prerequisites'],\n },\n {\n id: 'install-target',\n name: 'Install Target',\n description: 'Install target application if not found',\n phase: 'detection',\n dependsOn: ['detect'],\n },\n {\n id: 'configure',\n name: 'Configure',\n description: 'Set up user configuration',\n phase: 'detection',\n dependsOn: ['install-target'],\n },\n {\n id: 'confirm',\n name: 'Confirm Setup',\n description: 'Show plan and get user confirmation',\n phase: 'detection',\n dependsOn: ['configure'],\n },\n\n // Setup phase\n {\n id: 'cleanup-previous',\n name: 'Clean Previous Installation',\n description: 'Remove any previous AgenShield installation',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['confirm'],\n },\n {\n id: 'create-groups',\n name: 'Create Groups',\n description: 'Create socket access and workspace groups',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['cleanup-previous'],\n },\n {\n id: 'create-agent-user',\n name: 'Create Agent User',\n description: 'Create sandboxed agent user with guarded shell',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-groups'],\n },\n {\n id: 'create-broker-user',\n name: 'Create Broker User',\n description: 'Create broker user for daemon',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-groups'],\n },\n {\n id: 'create-directories',\n name: 'Create Directories',\n description: 'Create /opt/agenshield, /etc/agenshield, etc.',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-agent-user', 'create-broker-user'],\n },\n {\n id: 'setup-socket',\n name: 'Setup Socket',\n description: 'Create /var/run/agenshield/ with correct permissions',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-homebrew',\n name: 'Install Homebrew',\n description: 'Install user-specific Homebrew for agent user (this may take up to 2 minutes)',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-nvm',\n name: 'Install NVM & Node.js',\n description: 'Install NVM and Node.js for agent user (this may take up to 2 minutes)',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['install-homebrew'],\n },\n {\n id: 'configure-shell',\n name: 'Configure Shell',\n description: 'Set up guarded shell with Homebrew and NVM paths',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['install-nvm'],\n },\n {\n id: 'install-wrappers',\n name: 'Install Wrappers',\n description: 'Install command wrappers to agent home bin directory (this may take up to a minute)',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['configure-shell'],\n },\n {\n id: 'generate-seatbelt',\n name: 'Generate Seatbelt Profiles',\n description: 'Generate macOS sandbox profiles',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-broker',\n name: 'Install Broker',\n description: 'Install broker binary',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-daemon-config',\n name: 'Install Daemon Config',\n description: 'Write daemon configuration files',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-sudoers',\n name: 'Install Sudoers Rule',\n description: 'Grant broker passwordless sudo for agent operations',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-broker-user', 'create-agent-user'],\n },\n {\n id: 'install-policies',\n name: 'Install Policies',\n description: 'Write default security policies',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'setup-launchdaemon',\n name: 'Setup LaunchDaemon',\n description: 'Create and load broker launchd plist (this may take up to a minute)',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['install-broker', 'install-daemon-config'],\n },\n {\n id: 'copy-openclaw-config',\n name: 'Copy OpenClaw Config',\n description: 'Copy and sanitize OpenClaw config from host user',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['create-directories'],\n },\n {\n id: 'install-openclaw',\n name: 'Install OpenClaw',\n description: 'Install OpenClaw in agent sandbox via NVM npm (this may take up to 3 minutes)',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['setup-launchdaemon', 'install-wrappers', 'copy-openclaw-config'],\n },\n {\n id: 'stop-host-openclaw',\n name: 'Stop Host OpenClaw',\n description: 'Stop OpenClaw daemon and gateway on host user',\n phase: 'setup',\n dependsOn: ['install-openclaw'],\n },\n {\n id: 'onboard-openclaw',\n name: 'Initialize OpenClaw',\n description: 'Run openclaw onboard to initialize agent environment (this may take up to 2 minutes)',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['stop-host-openclaw'],\n },\n {\n id: 'verify',\n name: 'Verify Installation',\n description: 'Verify users, groups, and directories',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['onboard-openclaw'],\n },\n {\n id: 'start-openclaw',\n name: 'Start OpenClaw',\n description: 'Install and start OpenClaw LaunchDaemons with intercepted Node.js',\n phase: 'setup',\n requiresSudo: true,\n dependsOn: ['verify'],\n },\n {\n id: 'setup-passcode',\n name: 'Setup Passcode',\n description: 'Set a passcode to protect sensitive configuration',\n phase: 'setup',\n dependsOn: ['start-openclaw'],\n },\n {\n id: 'open-dashboard',\n name: 'Open Dashboard',\n description: 'Open AgenShield dashboard in browser',\n phase: 'setup',\n dependsOn: ['setup-passcode'],\n },\n {\n id: 'complete',\n name: 'Complete',\n description: 'Setup finished successfully',\n phase: 'setup',\n dependsOn: ['open-dashboard'],\n },\n];\n\n/**\n * Get step IDs for a specific phase\n */\nexport function getStepsByPhase(phase: 'detection' | 'setup'): WizardStepId[] {\n return WIZARD_STEPS.filter((s) => s.phase === phase).map((s) => s.id);\n}\n\n/**\n * Get all step IDs in order\n */\nexport function getAllStepIds(): WizardStepId[] {\n return WIZARD_STEPS.map((s) => s.id);\n}\n\n/**\n * Create initial wizard steps from definitions\n */\nexport function createWizardSteps(): WizardStep[] {\n return WIZARD_STEPS.map((def) => ({\n id: def.id,\n name: def.name,\n description: def.description,\n status: 'pending' as const,\n }));\n}\n"]}