@automaton-labs/aib 0.0.8 → 0.0.10

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 CHANGED
@@ -1,357 +1,21 @@
1
- # aib CLI
2
-
3
- Node-native CLI для анализа и изменения TypeScript/JavaScript workspace.
4
-
5
- Текущая цель пакета:
6
-
7
- - локальная session/workspace модель;
8
- - standalone inspect/import/mutation workers;
9
- - execution journal и восстановление owned workers;
10
- - Node-only packaging без IDE, VSIX и браузера.
11
-
12
- ## Current Commands
13
-
14
- - `aib printConfig`
15
- - `aib init-skill-usage`
16
- - `aib inspect file <file> [--ranges] [--local-only]`
17
- - `aib inspect exports <file> [--ranges]`
18
- - `aib inspect exports <file> --resolve-star`
19
- - `aib inspect members <file> <entity> [--ranges] [--offset <n>] [--limit <n>] [--all]`
20
- - `aib inspect code <file> <entity> [--parent <entity>] [--ranges] [--max-lines <n>] [--to-file <path>]`
21
- - `aib inspect dependencies <file> <entity> [--ranges]`
22
- - `aib inspect slice <file> <entity> [--max-lines <n>] [--to-file <path>]`
23
- - `aib inspect graph <file-or-directory> [--depth 0|1|2] [--exclude <glob>] [--exclude-from <file>]`
24
- - `aib inspect graph --from-file <graph.json> --focus <file> [--symbols] [--symbol-usage]`
25
- - `aib inspect --stdin`
26
- - `aib imports importers <file-or-directory>`
27
- - `aib imports unused <file>`
28
- - `aib mutate preview --stdin`
29
- - `aib mutate apply <previewId>`
30
- - `aib mutate execute --stdin`
31
- - `aib trace status|set|clear`
32
- - `aib session init|status|where|read|write|clear`
33
- - `aib session start|stop`
34
-
35
- ## Global Flags
36
-
37
- - `--cwd <path>`: выбрать корень workspace.
38
- - `--metrics`: include opt-in timing spans.
39
-
40
- Environment:
41
-
42
- - `AIB_TRACE_DIR=<path>` enables opt-in CLI trace capture for every command in that environment.
43
-
44
- ## Trace Capture
45
-
46
- Trace capture is off by default.
47
-
48
- Enable it for one command:
49
-
50
- ```powershell
51
- aib --trace-dir .aib-trace doctor
52
- ```
53
-
54
- Enable it for a trial session:
55
-
56
- ```powershell
57
- $env:AIB_TRACE_DIR = ".aib-trace"
58
- aib mutate preview --stdin
59
- ```
60
-
61
- Enable it for the current project so it survives new shells:
62
-
63
- ```powershell
64
- aib trace set .aib-trace
65
- aib trace status
66
- ```
67
-
68
- Clear the project trace setting without deleting existing trace files:
69
-
70
- ```powershell
71
- aib trace clear
72
- ```
73
-
74
- Priority is `--trace-dir`, then `AIB_TRACE_DIR`, then the project trace setting.
75
- Relative trace paths are resolved against the CLI `cwd`. Trace output includes `trace.jsonl` plus per-call request/response/meta artifacts under `calls/`.
76
-
77
- ## Inspect / Progressive Disclosure
78
-
79
- Use `inspect` when an agent needs a compact semantic map before refactoring.
80
-
81
- ```powershell
82
- aib inspect file src/service.ts
83
- aib inspect exports src/service.ts
84
- aib inspect members src/service.ts c-Service
85
- aib inspect members src/service.ts c-Service --offset 20 --limit 20
86
- aib inspect members src/service.ts c-Service --all
87
- aib inspect code src/service.ts m-save --parent c-Service
88
- aib inspect code src/service.ts v-LARGE_TABLE --to-file .aib-slices/large-table.ts
89
- aib inspect dependencies src/service.ts c-Service
90
- aib inspect slice src/service.ts c-Service --to-file .aib-slices/service.ts
91
- aib inspect exports src/index.ts --resolve-star
92
- aib inspect file src/service.ts --ranges
93
- aib inspect file src/index.ts --local-only
94
- ```
95
-
96
- Batch inspect requests:
97
-
98
- ```powershell
99
- @'
100
- {
101
- "file": "src/service.ts",
102
- "requests": [
103
- { "op": "file" },
104
- { "op": "exports" },
105
- { "op": "members", "entity": "c-Service" },
106
- { "op": "code", "entity": "m-save", "parent": "c-Service" },
107
- { "op": "slice", "entity": "c-Service", "toFile": ".aib-slices/service.ts" }
108
- ]
109
- }
110
- '@ | aib inspect --stdin
111
- ```
112
-
113
- Uniform batch requests can avoid repeating both `file` and `op`:
114
-
115
- ```powershell
116
- @'
117
- {
118
- "file": "src/service.ts",
119
- "op": "dependencies",
120
- "entities": [
121
- "f-createService",
122
- "c-Service"
123
- ]
124
- }
125
- '@ | aib inspect --stdin
126
- ```
127
-
128
- Uniform `dependencies` and `members` batches return grouped compact output keyed by entity selector.
129
-
130
- `dependencies` output is grouped by usage:
131
-
132
- ```json
133
- {
134
- "typeOnly": ["i-CartLine", "t-CurrencyCode"],
135
- "value": ["f-createMoney", "v-TIER_DISCOUNT"]
136
- }
137
- ```
138
-
139
- `unclassified` is shown only when nonempty. It means the inspect layer found a local dependency but could not safely classify the usage position with the current syntax heuristic.
140
-
141
- Default inspect output is compact and uses fixed selector aliases (`c-`, `i-`, `t-`, `f-`, `v-`, `e-`, `m-`, `p-`). Workspace selector alias overrides are intentionally ignored.
142
-
143
- `inspect file --local-only` answers the physical-file question. It reports local declarations and re-export modules without resolving `export *` through a facade:
144
-
145
- ```json
146
- {
147
- "file": "src/index.ts",
148
- "results": [
149
- {
150
- "op": "file",
151
- "mode": "local",
152
- "summary": "facade only; 3 re-exports; 0 local declarations",
153
- "symbols": [],
154
- "reexports": ["./core/types.js", "./core/service.js", "./core/index.js"]
155
- }
156
- ]
157
- }
158
- ```
159
-
160
- Use `inspect exports <file> --resolve-star` for the public API visible through a facade.
161
-
162
- `inspect graph` gives a compact local file relationship map. It is local CLI logic and does not require an IDE runtime:
163
-
164
- ```powershell
165
- aib inspect graph src/main --depth 1
166
- aib inspect graph src/main --depth 1 --exclude "**/* copy.ts"
167
- aib inspect graph src/main --depth 1 --exclude-from .aib-graph-ignore
168
- ```
169
-
170
- Graph excludes can also be configured in `.aib.json`, `.aib.json`, or `.vscode/settings.json`:
171
-
172
- ```json
173
- {
174
- "inspect": {
175
- "graph": {
176
- "exclude": ["**/* copy.ts", "src/generated/**"]
177
- }
178
- }
179
- }
180
- ```
181
-
182
- Excludes are applied before the graph model is built, so excluded files do not affect counts, hubs, leaves, edges, or saved graph files.
183
-
184
- `members` is compact by default: it returns the first page of members plus a hidden-count marker when more members exist. Use `--all` for the full list or `--offset <n> --limit <n>` to page through a large class/interface without printing every member.
185
-
186
- `code --to-file <path>` writes exact selected code to disk without printing it to stdout. Use it for large declarations that an agent needs to mechanically move or inspect without polluting context.
187
-
188
- `inspect --stdin` supports per-request `toFile` / `outputFile` for `code` and `slice` rows. This lets an agent extract several selected declarations in one CLI call while stdout only reports compact `writtenTo` paths.
189
-
190
- With a session workspace, use `save` to write selected code/slices and keep stdout compact:
191
-
192
- ```powershell
193
- aib session init --dir .tmp/aib
194
- @'
195
- {
196
- "file": "src/service.ts",
197
- "parent": "c-Service",
198
- "requests": [
199
- { "op": "code", "entity": "m-save", "save": "service-save-method" },
200
- { "op": "slice", "entity": "c-Service", "parent": null, "save": "service-class" }
201
- ]
202
- }
203
- '@ | aib inspect --stdin
204
- ```
205
-
206
- Use `bundleSave` when several inspect rows form one reusable context packet. Per-request `save` still works:
207
-
208
- ```powershell
209
- @'
210
- {
211
- "file": "src/service.ts",
212
- "parent": "c-Service",
213
- "bundleSave": "service-context",
214
- "requests": [
215
- { "op": "members", "entity": "c-Service" },
216
- { "op": "code", "entity": "m-save", "save": "service-save-method" },
217
- { "op": "slice", "entity": "c-Service", "parent": null, "save": "service-class" }
218
- ]
219
- }
220
- '@ | aib inspect --stdin
221
- ```
222
-
223
- The bundle is saved as `aib:inspect:service-context` and can be read with `session read`.
224
-
225
- Read saved artifacts back into context by handle:
226
-
227
- ```powershell
228
- aib session read aib:code:service-save-method
229
- aib session read aib:slice:service-class --head 80
230
- ```
231
-
232
- Batch reads avoid repeated CLI calls:
233
-
234
- ```powershell
235
- @'
236
- {
237
- "reads": [
238
- { "handle": "aib:code:service-save-method" },
239
- { "handle": "aib:slice:service-class", "offset": 30, "limit": 50 }
240
- ]
241
- }
242
- '@ | aib session read --stdin
243
- ```
244
-
245
- ## Mutate
246
-
247
- Use `mutate` for semantic and file mutations. `preview` validates intent and returns a preview id, `apply` applies that preview id, and `execute` performs the same mutation directly from input:
248
-
249
- ```powershell
250
- @'
251
- {
252
- "segments": [
253
- {
254
- "kind": "modulePlan",
255
- "sourceFile": "src/service.ts",
256
- "facadeFile": "src/service.ts",
257
- "modules": [
258
- {
259
- "targetFile": "src/core/types.ts",
260
- "symbols": ["i-ServiceOptions", "t-ServiceMode"]
261
- },
262
- {
263
- "targetFile": "src/core/service.ts",
264
- "symbols": ["c-Service", "f-createService"]
265
- }
266
- ]
267
- }
268
- ]
269
- }
270
- '@ | aib mutate preview --stdin
271
- ```
272
-
273
- Apply the preview if it matches intent:
274
-
275
- ```powershell
276
- aib mutate apply mutate_abc123
277
- ```
278
-
279
- Or execute directly:
280
-
281
- ```powershell
282
- @'
283
- @source src/service.ts
284
- module src/core/types.ts: i-ServiceOptions t-ServiceMode
285
- module src/core/service.ts: c-Service f-createService
286
- '@ | aib mutate execute --stdin
287
- ```
288
-
289
- The mutation response keeps a per-row result model so the caller can distinguish completed, partial, blocked, and failed outcomes without relying on legacy `plan_*` or `batch_*` command ids.
290
-
291
- Inspect output intentionally avoids IDE/debug-only details in the agent-facing path:
292
-
293
- - file paths are relative to the CLI `cwd` when possible;
294
- - a shared file path is emitted once at response level instead of repeated on every result;
295
- - successful results omit noisy `ok: true` wrappers;
296
- - `--ranges` emits compact line metadata such as `l19 1260..1278`;
297
- - character offsets and `selectionRange` stay out of stdout; use trace/debug artifacts if exact IDE ranges are needed.
298
-
299
- Line metadata is 1-based and inclusive for human/agent navigation. Add `--ranges` only when line/range navigation is needed.
300
-
301
- ## Workspace Config And Aliases
302
-
303
- Agent-facing command and selector aliases are fixed product defaults. The CLI ignores workspace-level selector alias overrides so agents can rely on one selector contract across repositories.
304
-
305
- CLI также умеет генерировать agent-facing usage instructions на основе effective config:
306
-
307
- ```powershell
308
- aib --cwd D:\dev\agent-ide\fixtures\ts-sandbox init-skill-usage
309
- aib --cwd D:\dev\agent-ide\fixtures\ts-sandbox init-skill-usage --cli-name myagentcli
310
- ```
311
-
312
- ## Local Development
313
-
314
- Из корня workspace:
315
-
316
- ```powershell
317
- cd D:\dev\agent-ide
318
- npm run cli:typecheck
319
- npm run cli:build
320
- npm run cli:link
321
- ```
322
-
323
- После `npm link` команда доступна как:
324
-
325
- ```powershell
326
- aib ping
327
- ```
328
-
329
- ## Local Tarball / npx-Oriented Flow
330
-
331
- Собрать локальный tarball:
332
-
333
- ```powershell
334
- cd D:\dev\agent-ide
335
- npm run cli:pack
336
- ```
337
-
338
- Tarball появится в:
339
-
340
- - `D:\dev\agent-ide\.tmp\aib-<version>.tgz`
341
-
342
- Дальше можно запускать CLI не через `npm link`, а через временную установку tarball.
343
-
344
- Пример:
345
-
346
- ```powershell
347
- npx --yes --package D:\dev\agent-ide\.tmp\aib-0.0.1.tgz aib ping --cwd D:\dev\agent-ide
348
- ```
349
-
350
- Это полезно как переходный локальный шаг перед будущим publishable `npx aib ...` flow.
351
-
352
- Примеры semantic-команд через tarball:
353
-
354
- ```powershell
355
- npx --yes --package D:\dev\agent-ide\.tmp\aib-0.0.1.tgz aib imports importers fixtures\ts-sandbox\src\utils --cwd D:\dev\agent-ide
356
- npx --yes --package D:\dev\agent-ide\.tmp\aib-0.0.1.tgz aib imports unused fixtures\ts-sandbox\src\services\unused-imports.ts --cwd D:\dev\agent-ide
357
- ```
1
+ # aib
2
+
3
+ Agent-oriented CLI for understanding and changing TypeScript and JavaScript workspaces.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install -g @automaton-labs/aib@beta
9
+ ```
10
+
11
+ The matching Node runtime is provisioned automatically.
12
+
13
+ ## Start
14
+
15
+ ```sh
16
+ aib help
17
+ aib doctor
18
+ aib inspect file src/service.ts
19
+ ```
20
+
21
+ Run `aib help` for inspect, mutation, session, configuration, and workflow guidance.
@@ -120,28 +120,61 @@ function upgradeConfig(cwd) {
120
120
  });
121
121
  }
122
122
  const added = {};
123
+ const removed = [];
123
124
  const config = { ...workspace.config };
125
+ const legacySessionTtl = typeof config["session.ttlMinutes"] === "number"
126
+ ? config["session.ttlMinutes"]
127
+ : null;
128
+ const sessionDefaults = {
129
+ ...workspace_root_1.MATERIALIZED_SESSION_DEFAULTS,
130
+ "session.ttlCleanMinutes": legacySessionTtl ?? 60,
131
+ "session.ttlDeleteMinutes": legacySessionTtl ?? 60
132
+ };
133
+ for (const [key, value] of Object.entries(sessionDefaults)) {
134
+ if (!Object.prototype.hasOwnProperty.call(config, key)) {
135
+ config[key] = value;
136
+ added[key] = value;
137
+ }
138
+ }
124
139
  for (const [key, value] of Object.entries(workspace_root_1.MATERIALIZED_INSPECT_DEFAULTS)) {
125
140
  if (!Object.prototype.hasOwnProperty.call(config, key)) {
126
141
  config[key] = value;
127
142
  added[key] = value;
128
143
  }
129
144
  }
145
+ for (const [key, value] of Object.entries(workspace_root_1.MATERIALIZED_OUTPUT_DEFAULTS)) {
146
+ if (!Object.prototype.hasOwnProperty.call(config, key)) {
147
+ config[key] = value;
148
+ added[key] = value;
149
+ }
150
+ }
130
151
  if (!Object.prototype.hasOwnProperty.call(config, "tsc")) {
131
152
  config.tsc = workspace_root_1.MATERIALIZED_TSC_DEFAULTS.tsc ?? null;
132
153
  added.tsc = config.tsc;
133
154
  }
134
- if (Object.keys(added).length > 0) {
155
+ for (const key of [
156
+ "session.ttlMinutes",
157
+ "runtime.managedIdeTtlMinutes",
158
+ "runtime.managedIdeWatchdogIntervalMs",
159
+ "runtime.autoStopManagedIde"
160
+ ]) {
161
+ if (Object.prototype.hasOwnProperty.call(config, key)) {
162
+ delete config[key];
163
+ removed.push(key);
164
+ }
165
+ }
166
+ if (Object.keys(added).length > 0 || removed.length > 0) {
135
167
  fs.writeFileSync(workspace.configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
136
168
  }
137
169
  return (0, agent_text_1.attachAgentText)({
138
170
  ok: true,
139
- status: Object.keys(added).length > 0 ? "upgraded" : "up-to-date",
171
+ status: Object.keys(added).length > 0 || removed.length > 0 ? "upgraded" : "up-to-date",
140
172
  root: workspace.root,
141
173
  configPath: workspace.configPath,
142
174
  added,
143
- unchanged: "existing fields preserved"
144
- }, (0, config_output_1.formatConfigUpgradeText)(added));
175
+ removed,
176
+ unchanged: "other fields preserved"
177
+ }, (0, config_output_1.formatConfigUpgradeText)(added, removed));
145
178
  }
146
179
  function parseConfigView(args) {
147
180
  if (args.length === 0) {
@@ -223,9 +256,7 @@ function readConfigTextInput(cwd) {
223
256
  sessionAutoClean: summary["session.autoClean"] !== false,
224
257
  sessionTtlCleanMinutes: typeof summary["session.ttlCleanMinutes"] === "number" ? summary["session.ttlCleanMinutes"] : 60,
225
258
  sessionAutoDelete: summary["session.autoDelete"] !== false,
226
- sessionTtlDeleteMinutes: typeof summary["session.ttlDeleteMinutes"] === "number" ? summary["session.ttlDeleteMinutes"] : 60,
227
- runtimeAutoStopManagedIde: summary["runtime.autoStopManagedIde"] !== false,
228
- runtimeManagedIdeTtlMinutes: typeof summary["runtime.managedIdeTtlMinutes"] === "number" ? summary["runtime.managedIdeTtlMinutes"] : 15
259
+ sessionTtlDeleteMinutes: typeof summary["session.ttlDeleteMinutes"] === "number" ? summary["session.ttlDeleteMinutes"] : 60
229
260
  };
230
261
  }
231
262
  function readTscConfig(config) {
@@ -108,23 +108,31 @@ function formatSessionDirMutationText(input, changed) {
108
108
  "other config fields preserved"
109
109
  ].join("\n");
110
110
  }
111
- function formatConfigUpgradeText(added) {
111
+ function formatConfigUpgradeText(added, removed) {
112
112
  const entries = Object.entries(added);
113
- if (entries.length === 0) {
113
+ if (entries.length === 0 && removed.length === 0) {
114
114
  return [
115
115
  "aib config is up to date",
116
116
  "",
117
117
  "unchanged: existing fields preserved"
118
118
  ].join("\n");
119
119
  }
120
- return [
120
+ const lines = [
121
121
  "aib config upgraded",
122
- "",
123
- "added:",
124
- ...entries.map(([key, value]) => ` ${key}: ${value}`),
125
- "",
126
- "unchanged: existing fields preserved"
127
- ].join("\n");
122
+ ];
123
+ if (entries.length > 0) {
124
+ lines.push("", "added:", ...entries.map(([key, value]) => ` ${key}: ${formatUpgradeValue(value)}`));
125
+ }
126
+ if (removed.length > 0) {
127
+ lines.push("", "removed:", ...removed.map((key) => ` ${key}`));
128
+ }
129
+ lines.push("", "unchanged: other fields preserved");
130
+ return lines.join("\n");
131
+ }
132
+ function formatUpgradeValue(value) {
133
+ return value !== null && typeof value === "object"
134
+ ? JSON.stringify(value)
135
+ : String(value);
128
136
  }
129
137
  function configSessionPayload(input) {
130
138
  return {
@@ -133,9 +141,7 @@ function configSessionPayload(input) {
133
141
  "session.autoClean": input.sessionAutoClean,
134
142
  "session.ttlCleanMinutes": input.sessionTtlCleanMinutes,
135
143
  "session.autoDelete": input.sessionAutoDelete,
136
- "session.ttlDeleteMinutes": input.sessionTtlDeleteMinutes,
137
- "runtime.autoStopManagedIde": input.runtimeAutoStopManagedIde,
138
- "runtime.managedIdeTtlMinutes": input.runtimeManagedIdeTtlMinutes
144
+ "session.ttlDeleteMinutes": input.sessionTtlDeleteMinutes
139
145
  };
140
146
  }
141
147
  function formatConfigHeader(input) {
@@ -151,7 +157,7 @@ function formatSessionLines(input) {
151
157
  if (input.sessionDir) {
152
158
  lines.push(`new sessions: <sessionDir>/<name>/**`);
153
159
  }
154
- lines.push(`session cleanup: ${formatTtl(input.sessionAutoClean, input.sessionTtlCleanMinutes)}`, `session deletion: ${formatTtl(input.sessionAutoDelete, input.sessionTtlDeleteMinutes)}`, `runtime cleanup: ${formatTtl(input.runtimeAutoStopManagedIde, input.runtimeManagedIdeTtlMinutes)}`);
160
+ lines.push(`session cleanup: ${formatTtl(input.sessionAutoClean, input.sessionTtlCleanMinutes)}`, `session deletion: ${formatTtl(input.sessionAutoDelete, input.sessionTtlDeleteMinutes)}`);
155
161
  return lines.length > 0 ? ["", ...lines] : [];
156
162
  }
157
163
  function formatConfigSections(input, sections) {
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.MATERIALIZED_TSC_DEFAULTS = exports.MATERIALIZED_INSPECT_DEFAULTS = exports.AIB_CONFIG_FILE_NAME = void 0;
36
+ exports.MATERIALIZED_TSC_DEFAULTS = exports.MATERIALIZED_OUTPUT_DEFAULTS = exports.MATERIALIZED_SESSION_DEFAULTS = exports.MATERIALIZED_INSPECT_DEFAULTS = exports.AIB_CONFIG_FILE_NAME = void 0;
37
37
  exports.initWorkspaceRoot = initWorkspaceRoot;
38
38
  exports.resolveWorkspaceRoot = resolveWorkspaceRoot;
39
39
  exports.resolveWorkspaceRootFromConfig = resolveWorkspaceRootFromConfig;
@@ -58,6 +58,16 @@ exports.MATERIALIZED_INSPECT_DEFAULTS = {
58
58
  "inspect.usages.maxCodeBlocks": 8,
59
59
  "inspect.members.maxItems": 20
60
60
  };
61
+ exports.MATERIALIZED_SESSION_DEFAULTS = {
62
+ "session.autoDelete": true,
63
+ "session.ttlDeleteMinutes": 60,
64
+ "session.autoClean": true,
65
+ "session.ttlCleanMinutes": 60
66
+ };
67
+ exports.MATERIALIZED_OUTPUT_DEFAULTS = {
68
+ "qr.outputCapKb": 32,
69
+ "rg.outputCapKb": 32
70
+ };
61
71
  exports.MATERIALIZED_TSC_DEFAULTS = {
62
72
  tsc: {
63
73
  outputCapKb: 12,
@@ -82,15 +92,12 @@ function initWorkspaceRoot(cwd, options = {}) {
82
92
  "session.ttlDeleteMinutes": ttlDeleteMinutes,
83
93
  "session.autoClean": readBoolean(existing["session.autoClean"]) ?? true,
84
94
  "session.ttlCleanMinutes": ttlCleanMinutes,
85
- "runtime.managedIdeTtlMinutes": readNumber(existing["runtime.managedIdeTtlMinutes"]) ?? 15,
86
- "runtime.managedIdeWatchdogIntervalMs": readNumber(existing["runtime.managedIdeWatchdogIntervalMs"]) ?? 30000,
87
- "runtime.autoStopManagedIde": readBoolean(existing["runtime.autoStopManagedIde"]) ?? true,
88
95
  ...(!existed ? exports.MATERIALIZED_INSPECT_DEFAULTS : {}),
96
+ ...(!existed ? exports.MATERIALIZED_OUTPUT_DEFAULTS : {}),
89
97
  ...(!existed && !Object.prototype.hasOwnProperty.call(existing, "tsc") ? exports.MATERIALIZED_TSC_DEFAULTS : {})
90
98
  };
91
99
  fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
92
100
  const sessionTtlMinutes = readNumber(config["session.ttlCleanMinutes"]) ?? 60;
93
- const runtimeTtlMinutes = readNumber(config["runtime.managedIdeTtlMinutes"]) ?? 15;
94
101
  const changed = !existed || JSON.stringify(existing) !== JSON.stringify(config);
95
102
  return {
96
103
  status: !existed ? "created" : changed ? "updated" : "unchanged",
@@ -103,8 +110,6 @@ function initWorkspaceRoot(cwd, options = {}) {
103
110
  "session.ttlCleanMinutes": sessionTtlMinutes,
104
111
  "session.autoDelete": readBoolean(config["session.autoDelete"]) ?? true,
105
112
  "session.ttlDeleteMinutes": readNumber(config["session.ttlDeleteMinutes"]) ?? 60,
106
- "runtime.autoStopManagedIde": readBoolean(config["runtime.autoStopManagedIde"]) ?? true,
107
- "runtime.managedIdeTtlMinutes": runtimeTtlMinutes,
108
113
  ...(!sessionDir ? { next: "Set the default session directory: aib config --session-dir .tmp/aib" } : {})
109
114
  };
110
115
  }
@@ -200,9 +205,7 @@ function workspaceConfigSummary(config) {
200
205
  "session.autoClean": readBoolean(config["session.autoClean"]) ?? true,
201
206
  "session.ttlCleanMinutes": readNumber(config["session.ttlCleanMinutes"]) ?? legacySessionTtl ?? 60,
202
207
  "session.autoDelete": readBoolean(config["session.autoDelete"]) ?? true,
203
- "session.ttlDeleteMinutes": readNumber(config["session.ttlDeleteMinutes"]) ?? legacySessionTtl ?? 60,
204
- "runtime.autoStopManagedIde": readBoolean(config["runtime.autoStopManagedIde"]) ?? true,
205
- "runtime.managedIdeTtlMinutes": readNumber(config["runtime.managedIdeTtlMinutes"]) ?? 15
208
+ "session.ttlDeleteMinutes": readNumber(config["session.ttlDeleteMinutes"]) ?? legacySessionTtl ?? 60
206
209
  };
207
210
  }
208
211
  function isPathInsideOrEqual(parent, child) {
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SEMANTIC_RENAME_PROCESS_TESTING = void 0;
3
4
  exports.runSemanticRenameConfigWorker = runSemanticRenameConfigWorker;
4
5
  const node_child_process_1 = require("node:child_process");
5
6
  const semantic_worker_retry_1 = require("./semantic-worker-retry");
@@ -153,7 +154,7 @@ async function terminateChild(child, pid) {
153
154
  catch { /* already gone */ }
154
155
  return waitForExit(child, EXIT_FORCE_MS);
155
156
  }
156
- if (!isAlive(pid) && child.exitCode !== null)
157
+ if (!isAlive(pid) && hasExited(child))
157
158
  return true;
158
159
  if (process.platform === "win32") {
159
160
  (0, node_child_process_1.spawnSync)("taskkill.exe", ["/PID", String(pid), "/T", "/F"], {
@@ -178,20 +179,23 @@ async function terminateChild(child, pid) {
178
179
  async function waitForDead(child, pid, timeoutMs) {
179
180
  const deadline = Date.now() + timeoutMs;
180
181
  while (Date.now() <= deadline) {
181
- if (!isAlive(pid) && child.exitCode !== null)
182
+ if (!isAlive(pid) && hasExited(child))
182
183
  return true;
183
184
  await delay(20);
184
185
  }
185
- return !isAlive(pid) && child.exitCode !== null;
186
+ return !isAlive(pid) && hasExited(child);
186
187
  }
187
188
  async function waitForExit(child, timeoutMs) {
188
189
  const deadline = Date.now() + timeoutMs;
189
190
  while (Date.now() <= deadline) {
190
- if (child.exitCode !== null)
191
+ if (hasExited(child))
191
192
  return true;
192
193
  await delay(20);
193
194
  }
194
- return child.exitCode !== null;
195
+ return hasExited(child);
196
+ }
197
+ function hasExited(child) {
198
+ return child.exitCode !== null || child.signalCode !== null;
195
199
  }
196
200
  function isAlive(pid) {
197
201
  try {
@@ -208,3 +212,6 @@ function delay(ms) {
208
212
  function workerError(code, message) {
209
213
  return Object.assign(new Error(message), { code });
210
214
  }
215
+ exports.SEMANTIC_RENAME_PROCESS_TESTING = {
216
+ hasExited
217
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@automaton-labs/aib",
3
- "version": "0.0.8",
4
- "description": "Node-native CLI for analyzing and changing TypeScript and JavaScript workspaces.",
3
+ "version": "0.0.10",
4
+ "description": "Agent-oriented CLI for understanding and changing TypeScript and JavaScript workspaces.",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },