@automaton-labs/aib 0.0.3 → 0.0.4
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/bin/cli.js +2 -2
- package/dist/commands/config-command.js +1 -3
- package/dist/commands/config-output.js +8 -0
- package/dist/commands/init-workspace.js +1 -3
- package/dist/commands/inspect-tree.js +3 -3
- package/dist/commands/reveal-command.js +5 -0
- package/dist/commands/sync-command.js +2 -2
- package/dist/config/local-config.js +3 -3
- package/dist/config/resolve-command-alias.js +1 -1
- package/dist/config/tsconfig-discovery.js +1 -0
- package/dist/config/workspace-root.js +3 -3
- package/dist/config/workspace-state.js +1 -1
- package/dist/dsl/aib-dsl.js +1 -1
- package/dist/help/bootstrap.md +21 -11
- package/dist/help/docs/first-setup.md +277 -0
- package/dist/help/docs/inspect.tree.md +8 -6
- package/dist/help/docs/patterns.md +12 -3
- package/dist/help/dsl/bootstrap.md +21 -11
- package/dist/help/dsl/docs/first-setup.md +277 -0
- package/dist/help/dsl/docs/inspect.tree.md +8 -6
- package/dist/help/dsl/docs/patterns.md +12 -3
- package/dist/help/dsl/full.md +21 -11
- package/dist/help/dsl/topics/first-setup.md +275 -0
- package/dist/help/dsl/topics/inspect.tree.md +8 -6
- package/dist/help/dsl/topics/patterns.md +12 -3
- package/dist/help/full.md +21 -11
- package/dist/help/help-meta.json +11 -7
- package/dist/help/index.md +6 -0
- package/dist/help/json/bootstrap.md +21 -11
- package/dist/help/json/docs/first-setup.md +277 -0
- package/dist/help/json/docs/inspect.tree.md +8 -6
- package/dist/help/json/docs/patterns.md +12 -3
- package/dist/help/json/full.md +21 -11
- package/dist/help/json/topics/first-setup.md +275 -0
- package/dist/help/json/topics/inspect.tree.md +8 -6
- package/dist/help/json/topics/patterns.md +12 -3
- package/dist/help/topics/first-setup.md +275 -0
- package/dist/help/topics/inspect.tree.md +8 -6
- package/dist/help/topics/patterns.md +12 -3
- package/dist/runtime/run-command.js +1 -1
- package/extension/vscode-refactor-bridge-extension.vsix +0 -0
- package/package.json +1 -1
- package/runtimes/launcher/win-x64/aib.exe +0 -0
- package/scripts/install-windows-launcher.cjs +1 -0
- package/scripts/provision-runtime.cjs +99 -41
|
@@ -152,10 +152,19 @@ shortestAlias rewrite to the shortest valid alias specifier
|
|
|
152
152
|
preferAlias:
|
|
153
153
|
@shared/* prefer one alias pattern when several aliases can resolve the same file
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
AIB has four config exclude fields:
|
|
156
|
+
inspect.graph.exclude
|
|
157
|
+
inspect.tree.files.exclude
|
|
158
|
+
inspect.tree.onlyDirs.exclude
|
|
159
|
+
sync.tsconfig.exclude
|
|
157
160
|
|
|
158
|
-
|
|
161
|
+
For all of them, node_modules, .git, dist, build, out, and .tmp are skipped by default.
|
|
162
|
+
|
|
163
|
+
Use config excludes for generated files, backups, local copies, nested workspaces, seed projects, or other repository-specific noise.
|
|
164
|
+
|
|
165
|
+
Graph excludes affect graph counts, hubs, entrypoints, leaves, edges, imports, importedBy, and saved graph files.
|
|
166
|
+
Tree excludes affect directory/file discovery output.
|
|
167
|
+
Tsconfig excludes affect which TypeScript configs AIB syncs and watches.
|
|
159
168
|
|
|
160
169
|
Leave feedback while working.
|
|
161
170
|
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
Use this when the user asks you to set up AIB for a repository.
|
|
2
|
+
|
|
3
|
+
If you have not loaded the current bootstrap, run:
|
|
4
|
+
aib help bootstrap
|
|
5
|
+
|
|
6
|
+
1. Detect existing setup
|
|
7
|
+
|
|
8
|
+
Run:
|
|
9
|
+
|
|
10
|
+
aib config
|
|
11
|
+
|
|
12
|
+
If AIB reports that no config exists, continue to initialization.
|
|
13
|
+
|
|
14
|
+
If config exists:
|
|
15
|
+
- verify that root is the intended repository root;
|
|
16
|
+
- keep existing settings if they are still valid and useful;
|
|
17
|
+
- only add missing project-specific aliases, rules, or excludes;
|
|
18
|
+
- do not regenerate aib.json.
|
|
19
|
+
|
|
20
|
+
If config resolves from a parent directory, verify that this is intentional.
|
|
21
|
+
Do not continue setup inside a nested worktree or copied project if AIB is using the parent repository config.
|
|
22
|
+
|
|
23
|
+
2. Initialize if missing
|
|
24
|
+
|
|
25
|
+
From the repository root, run:
|
|
26
|
+
|
|
27
|
+
aib init --session-dir .tmp/aib
|
|
28
|
+
|
|
29
|
+
Use the output to check:
|
|
30
|
+
- root is the intended repository root;
|
|
31
|
+
- config is <root>/aib.json;
|
|
32
|
+
- sessionDir is set;
|
|
33
|
+
- cleanup/deletion/runtime TTLs are shown;
|
|
34
|
+
- not set includes the setup sections that still need decisions.
|
|
35
|
+
|
|
36
|
+
Do not create sessions yet.
|
|
37
|
+
|
|
38
|
+
3. Configure repository-specific behavior
|
|
39
|
+
|
|
40
|
+
Edit aib.json directly.
|
|
41
|
+
|
|
42
|
+
Keep existing settings if they are still valid and useful.
|
|
43
|
+
Update settings that are stale, noisy, too broad, or no longer match the repository.
|
|
44
|
+
|
|
45
|
+
Use not set as the checklist for the setup sections below.
|
|
46
|
+
|
|
47
|
+
4. Configure path aliases
|
|
48
|
+
|
|
49
|
+
Run:
|
|
50
|
+
|
|
51
|
+
aib reveal tsaliases
|
|
52
|
+
|
|
53
|
+
Use this to see existing tsconfig paths and baseUrl values.
|
|
54
|
+
They can reveal stable work areas, but they are not a list to copy.
|
|
55
|
+
|
|
56
|
+
Add pathAliases for long paths that are likely to appear repeatedly in AIB requests.
|
|
57
|
+
Prefer aliases for real work areas, package roots, or deep directories.
|
|
58
|
+
|
|
59
|
+
A good alias:
|
|
60
|
+
- saves meaningful path tokens;
|
|
61
|
+
- points to a stable work area;
|
|
62
|
+
- is easy to recognize later.
|
|
63
|
+
|
|
64
|
+
A bad alias:
|
|
65
|
+
- duplicates a short path like "src": "src";
|
|
66
|
+
- points to a rarely used folder;
|
|
67
|
+
- mirrors the directory tree without a workflow reason.
|
|
68
|
+
|
|
69
|
+
Having 20-30 good aliases is fine for a large repo or monorepo.
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
|
|
73
|
+
"pathAliases": {
|
|
74
|
+
"wstore": "apps/web/src/shared/store",
|
|
75
|
+
"wapi": "apps/web/src/shared/api",
|
|
76
|
+
"whooks": "apps/web/src/shared/utils/hooks",
|
|
77
|
+
"pmail": "packages/email/src",
|
|
78
|
+
"putils": "packages/utils/src",
|
|
79
|
+
"arules": "docs/agent/rules"
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
5. Configure import rules
|
|
83
|
+
|
|
84
|
+
Set importRules to the import style this repository should use after move/modulePlan mutations.
|
|
85
|
+
|
|
86
|
+
If the repository has one style, use one broad rule:
|
|
87
|
+
|
|
88
|
+
"importRules": [
|
|
89
|
+
{
|
|
90
|
+
"scope": ".",
|
|
91
|
+
"specifier": "shortest",
|
|
92
|
+
"ending": "auto",
|
|
93
|
+
"builtin": "node",
|
|
94
|
+
"unusedImports": "remove"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
Use scoped rules only when areas differ by style, for example packages use aliases but scripts use relative imports:
|
|
99
|
+
|
|
100
|
+
"importRules": [
|
|
101
|
+
{
|
|
102
|
+
"scope": "packages",
|
|
103
|
+
"specifier": "shortest",
|
|
104
|
+
"ending": "auto",
|
|
105
|
+
"builtin": "node",
|
|
106
|
+
"unusedImports": "remove"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"scope": "scripts",
|
|
110
|
+
"specifier": "relative",
|
|
111
|
+
"ending": "auto",
|
|
112
|
+
"builtin": "node",
|
|
113
|
+
"unusedImports": "remove"
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
Use the most specific scope that matches the real convention.
|
|
118
|
+
Do not add scoped rules just because directories exist.
|
|
119
|
+
|
|
120
|
+
6. Configure import normalization
|
|
121
|
+
|
|
122
|
+
Add importNormalize only for cleanup commands the agent is likely to run more than once.
|
|
123
|
+
|
|
124
|
+
Use it when the repo has a clear normalization target:
|
|
125
|
+
|
|
126
|
+
"importNormalize": [
|
|
127
|
+
{
|
|
128
|
+
"scope": "src",
|
|
129
|
+
"to": "shortestAlias",
|
|
130
|
+
"preferAlias": "@/*",
|
|
131
|
+
"exclude": [
|
|
132
|
+
"src/generated",
|
|
133
|
+
"src/**/dist"
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"scope": "scripts",
|
|
138
|
+
"to": "relative",
|
|
139
|
+
"exclude": [
|
|
140
|
+
"scripts/**/*.cjs",
|
|
141
|
+
"scripts/**/*.mjs"
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
Choose scopes from real repo conventions.
|
|
147
|
+
Do not copy importRules into importNormalize automatically.
|
|
148
|
+
Leave it unset if normalization is not a repeated workflow.
|
|
149
|
+
|
|
150
|
+
7. Configure tree and graph excludes
|
|
151
|
+
|
|
152
|
+
Add excludes for noise the repository is known to contain.
|
|
153
|
+
|
|
154
|
+
Use tree excludes for what the agent should not see while mapping folders.
|
|
155
|
+
Use graph excludes for files that should not affect graph counts, hubs, entrypoints, leaves, edges, or saved graph views.
|
|
156
|
+
|
|
157
|
+
Built-in excludes already skip common noise such as node_modules, .git, dist, build, out, and .tmp.
|
|
158
|
+
Add config excludes for repository-specific noise.
|
|
159
|
+
|
|
160
|
+
For example, if the user often creates hard-copy directories or backup files before risky edits, those copies can make tree and graph output noisy.
|
|
161
|
+
Exclude them explicitly:
|
|
162
|
+
|
|
163
|
+
"inspect.tree.onlyDirs.exclude": [
|
|
164
|
+
"**/*copy",
|
|
165
|
+
"**/*copy/**"
|
|
166
|
+
],
|
|
167
|
+
"inspect.tree.files.exclude": [
|
|
168
|
+
"**/* copy.ts",
|
|
169
|
+
"**/*.generated.ts"
|
|
170
|
+
],
|
|
171
|
+
"inspect.graph.exclude": [
|
|
172
|
+
"**/* copy.ts",
|
|
173
|
+
"**/*.generated.ts",
|
|
174
|
+
"src/generated/**"
|
|
175
|
+
]
|
|
176
|
+
|
|
177
|
+
Prefer narrow patterns for known noise:
|
|
178
|
+
- generated files;
|
|
179
|
+
- local copy/backup folders;
|
|
180
|
+
- build artifacts not already skipped by defaults;
|
|
181
|
+
- vendored or checked-in output.
|
|
182
|
+
|
|
183
|
+
These are common cases, not mandatory rules.
|
|
184
|
+
If the repository needs one of these areas for reasoning or mutation impact checks, do not exclude it.
|
|
185
|
+
|
|
186
|
+
Do not exclude broad source areas to make output smaller.
|
|
187
|
+
If output is too large, use scope, depth, limit, graph view, or graph toggles first.
|
|
188
|
+
|
|
189
|
+
8. Configure TypeScript config discovery
|
|
190
|
+
|
|
191
|
+
Check which TypeScript configs AIB will sync and watch:
|
|
192
|
+
|
|
193
|
+
aib reveal tsconfigs +all
|
|
194
|
+
|
|
195
|
+
If output includes nested workspaces, seed projects, snapshots, backups, copied apps, or other non-primary projects, exclude them:
|
|
196
|
+
|
|
197
|
+
"sync.tsconfig.exclude": [
|
|
198
|
+
"dev-seed/**",
|
|
199
|
+
"snapshots/**"
|
|
200
|
+
]
|
|
201
|
+
|
|
202
|
+
Do not exclude real package/app configs just to reduce output.
|
|
203
|
+
|
|
204
|
+
After editing aib.json, run:
|
|
205
|
+
|
|
206
|
+
aib sync
|
|
207
|
+
|
|
208
|
+
Then check again:
|
|
209
|
+
|
|
210
|
+
aib reveal tsconfigs +all
|
|
211
|
+
|
|
212
|
+
Visible tsconfigs should describe the active project surface.
|
|
213
|
+
Excluded tsconfigs should be things the agent should not use for setup decisions.
|
|
214
|
+
|
|
215
|
+
Use +nec only when you need to compare visible configs with config-excluded configs:
|
|
216
|
+
|
|
217
|
+
aib reveal tsconfigs +nec
|
|
218
|
+
|
|
219
|
+
9. Sync and verify
|
|
220
|
+
|
|
221
|
+
After all aib.json edits, run:
|
|
222
|
+
|
|
223
|
+
aib sync
|
|
224
|
+
|
|
225
|
+
If sync fails, fix aib.json and rerun sync.
|
|
226
|
+
|
|
227
|
+
Check the final config summary:
|
|
228
|
+
|
|
229
|
+
aib config
|
|
230
|
+
|
|
231
|
+
Run one compact tree batch using important aliases:
|
|
232
|
+
|
|
233
|
+
aib inspect --stdin
|
|
234
|
+
|
|
235
|
+
Input:
|
|
236
|
+
tree @<important-alias> depth=3 +onlyDirs limit=80
|
|
237
|
+
tree @<another-important-alias> depth=3 +onlyDirs limit=80
|
|
238
|
+
|
|
239
|
+
Check final TypeScript config discovery:
|
|
240
|
+
|
|
241
|
+
aib reveal tsconfigs
|
|
242
|
+
|
|
243
|
+
Confirm:
|
|
244
|
+
- aliases resolve;
|
|
245
|
+
- obvious tree noise is hidden;
|
|
246
|
+
- visible tsconfigs match the active project surface;
|
|
247
|
+
- config sections are set intentionally.
|
|
248
|
+
|
|
249
|
+
10. Note operational constraints
|
|
250
|
+
|
|
251
|
+
Before reporting back, identify any constraints the user should know.
|
|
252
|
+
|
|
253
|
+
Worktrees:
|
|
254
|
+
AIB resolves config from the nearest parent aib.json.
|
|
255
|
+
If the repository uses nested copied projects or worktrees inside the repo root, AIB may resolve the parent config.
|
|
256
|
+
Do not set up AIB inside nested worktrees that should behave as independent repositories.
|
|
257
|
+
Independent worktrees should live outside the main repo root or have their own intended aib.json boundary.
|
|
258
|
+
|
|
259
|
+
TTL:
|
|
260
|
+
Sessions and managed runtime are cleaned up after inactivity according to aib config session.
|
|
261
|
+
Tell the user if you changed these defaults or left them as-is.
|
|
262
|
+
|
|
263
|
+
Watchers:
|
|
264
|
+
AIB watches aib.json and visible tsconfig files after sync.
|
|
265
|
+
If config changes are not reflected, run aib sync.
|
|
266
|
+
|
|
267
|
+
11. Report to user
|
|
268
|
+
|
|
269
|
+
Report:
|
|
270
|
+
- whether AIB config already existed or was initialized;
|
|
271
|
+
- which aliases were added and why;
|
|
272
|
+
- which importRules/importNormalize settings were added or intentionally left unset;
|
|
273
|
+
- which tree/graph/tsconfig excludes were added;
|
|
274
|
+
- whether sync and verification passed;
|
|
275
|
+
- any worktree, TTL, watcher, or tsconfig discovery constraints the user should know.
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
Use tree to list a compact directory layout.
|
|
2
2
|
It is useful before focused inspect when you know the area but not the exact file.
|
|
3
3
|
|
|
4
|
-
node_modules, .git, dist, build, out, and .tmp are skipped by default.
|
|
5
|
-
|
|
6
4
|
Controls:
|
|
7
|
-
scope, depth, minDepth, limit,
|
|
5
|
+
scope, depth, minDepth, limit, only, exclude, onlyDirs, ned, nec
|
|
8
6
|
|
|
9
7
|
Specific:
|
|
10
8
|
depth max nesting depth; depth=N
|
|
11
9
|
minDepth hide shallower paths; minDepth=N
|
|
12
10
|
onlyDirs show directories only; +onlyDirs
|
|
13
|
-
|
|
11
|
+
only only matching files/dirs; only=[...]
|
|
12
|
+
exclude skip matching files/dirs; exclude=[...]
|
|
13
|
+
ned no-default-exclude; ignore built-in excludes; +ned
|
|
14
|
+
nec no-config-exclude; ignore aib.json tree excludes; +nec
|
|
14
15
|
|
|
15
16
|
Run:
|
|
16
17
|
aib inspect --stdin
|
|
17
18
|
|
|
18
19
|
Input:
|
|
19
|
-
tree src depth=4 +onlyDirs limit=200
|
|
20
|
-
tree @svc depth=3
|
|
20
|
+
tree src depth=4 +onlyDirs limit=200 +ned +nec
|
|
21
|
+
tree @svc depth=3 only=["**/*.ts"] exclude=["**/*.test.ts","**/* copy.ts"]
|
|
22
|
+
tree src depth=3 only=["src/services/**"] limit=80
|
|
@@ -152,10 +152,19 @@ shortestAlias rewrite to the shortest valid alias specifier
|
|
|
152
152
|
preferAlias:
|
|
153
153
|
@shared/* prefer one alias pattern when several aliases can resolve the same file
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
AIB has four config exclude fields:
|
|
156
|
+
inspect.graph.exclude
|
|
157
|
+
inspect.tree.files.exclude
|
|
158
|
+
inspect.tree.onlyDirs.exclude
|
|
159
|
+
sync.tsconfig.exclude
|
|
157
160
|
|
|
158
|
-
|
|
161
|
+
For all of them, node_modules, .git, dist, build, out, and .tmp are skipped by default.
|
|
162
|
+
|
|
163
|
+
Use config excludes for generated files, backups, local copies, nested workspaces, seed projects, or other repository-specific noise.
|
|
164
|
+
|
|
165
|
+
Graph excludes affect graph counts, hubs, entrypoints, leaves, edges, imports, importedBy, and saved graph files.
|
|
166
|
+
Tree excludes affect directory/file discovery output.
|
|
167
|
+
Tsconfig excludes affect which TypeScript configs AIB syncs and watches.
|
|
159
168
|
|
|
160
169
|
Leave feedback while working.
|
|
161
170
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.runCommand
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.runCommand=z;const P=require("../commands/list-instances"),b=require("../commands/ping"),k=require("../commands/runtime-info"),S=require("../commands/print-config"),R=require("../commands/init-skill-usage"),x=require("../commands/init-workspace"),A=require("../commands/inspect"),c=require("../commands/captured-input"),E=require("../commands/module-plan-command"),D=require("../commands/rename-command"),N=require("../commands/move-command"),O=require("../commands/refactor-command"),U=require("../commands/imports-command"),W=require("../commands/execution-command"),T=require("../commands/observability-command"),M=require("../commands/help-command"),F=require("../commands/generate-docs-command"),j=require("../commands/feedback-command"),Q=require("../commands/doctor"),G=require("../commands/diagnostics-command"),H=require("../commands/session-workspace"),y=require("../commands/session-workspace"),I=require("../config/path-aliases"),J=require("../commands/runtime-command"),K=require("../commands/sync-command"),L=require("../commands/reveal-command"),p=require("../client/transport-options"),m=require("../shared/errors"),l=require("./input-source"),$=require("../config/workspace-state");async function z(n){return(0,y.runWithSessionOverride)(n.sessionId,()=>B(n))}async function B(n){const{command:o,restArgs:d,cwd:r,instanceId:_,metricsSpans:C}=n,u=V(o)?(0,$.ensureWorkspaceState)(r):null,g=u?(0,y.readSessionPathAliasOverrides)(r):{},f={...u?.pathAliases??{},...g},e=(0,I.expandPathAliasesInArgs)(r,d,f),a=await(0,l.resolveCommandInputSource)({command:o,cwd:r,restArgs:e,...n.stdinPayload!==void 0?{preResolvedPayload:(0,I.expandPathAliasesInJson)(r,n.stdinPayload,f)}:{},...n.stdinInputSource!==void 0?{preResolvedSource:n.stdinInputSource}:{}}),s=a.payload,t={};_!==void 0&&(t.explicitInstanceId=_),n.autoStartIde!==void 0&&(t.autoStartIde=n.autoStartIde),n.transport!==void 0&&(t.transport=n.transport),n.metricsEnabled===!0&&(t.metricsEnabled=!0),u&&(t.importRules=u.importRules,t.mutationComments=u.mutationComments);const w=(0,p.getPreferredTransport)();n.transport&&(0,p.setPreferredTransport)(n.transport);try{switch(o){case"doctor":return(0,Q.runDoctor)({cwd:r,runtime:e.includes("--runtime"),verbose:e.includes("--verbose"),json:e.includes("--json")});case"diagnostics":return await(0,G.runDiagnosticsCommand)(e),{ok:!0,command:"diagnostics"};case"session":return(0,H.runSessionWorkspaceCommand)(r,e,s);case"init":return(0,x.runInitWorkspace)(r,d);case"help":return(0,M.runHelpCommand)(e);case"generate-docs":return(0,F.runGenerateDocsCommand)(r,d);case"sync":return(0,K.runSyncCommand)(r,e);case"reveal":return(0,L.runRevealCommand)(r,e);case"observability":return(0,T.runObservabilityCommand)(r,e);case"feedback":case"note":return(0,j.runFeedbackCommand)(r,d,o);case"runtime":return(0,J.runRuntimeCommand)(r,e);case"imports":return(0,c.attachCapturedInput)(r,"imports",s,await(0,U.runImportsCommand)(r,e,s,t,C),a.source);case"listInstances":return(0,P.runListInstances)();case"ping":return(0,b.runPing)(r,t);case"runtimeInfo":return(0,k.runRuntimeInfo)(r,t);case"printConfig":return(0,S.runPrintConfig)(r,t);case"initSkillUsage":case"init-skill-usage":{const i=e.findIndex(h=>h==="--cli-name"),q=i>=0&&e[i+1]?e[i+1]:"aib",v={cwd:r,cliName:q??"aib"};return v.resolveOptions=t,(0,R.runInitSkillUsage)(v)}case"inspect":return(0,c.attachCapturedInput)(r,e[0]==="graph"?"graph":"inspect",s,await(0,A.runInspect)(r,e,s,t),a.source);case"modulePlan":return(0,c.attachCapturedInput)(r,"modulePlan",s,await(0,E.runModulePlanCommand)(r,e,s,t,n.modulePlanExecutionId?{executionId:n.modulePlanExecutionId}:{}),a.source);case"execution":return(0,W.runExecutionCommand)(r,e);case"rename":{if(!(e[0]==="apply"&&typeof e[1]=="string"&&!e[1].startsWith("--"))&&(0,l.commandRequiresPayload)(o,e,a))throw new m.CliError("STDIN_REQUIRED","rename preview/apply/validate expects a payload on stdin or --from, except preview-id apply/help.");return(0,c.attachCapturedInput)(r,"rename",s,await(0,D.runRenameCommand)(r,e,s,t),a.source)}case"move":{if(!(e[0]==="toFile"&&e[1]==="apply"&&typeof e[2]=="string"&&!e[2].startsWith("--"))&&(0,l.commandRequiresPayload)(o,e,a))throw new m.CliError("STDIN_REQUIRED","move toFile preview/apply/validate expects a payload on stdin or --from.");return(0,c.attachCapturedInput)(r,"move",s,await(0,N.runMoveCommand)(r,e,s,t),a.source)}case"refactor":{if(!(e[0]==="batch"&&e[1]==="apply"&&typeof e[2]=="string"&&!e[2].startsWith("--"))&&(0,l.commandRequiresPayload)(o,e,a))throw new m.CliError("STDIN_REQUIRED","refactor batch preview/apply/validate expects a payload on stdin or --from, except preview-id apply/help.");return(0,c.attachCapturedInput)(r,"refactor",s,await(0,O.runRefactorCommand)(r,e,s,t),a.source)}default:throw new m.CliError("UNKNOWN_COMMAND",`Unknown command: ${o}`,{availableCommands:["doctor","diagnostics","listInstances","ping","runtimeInfo","printConfig","init-skill-usage","init","help","generate-docs","sync","reveal","inspect","imports","execution","move","rename","refactor","modulePlan","session","runtime","trace","observability","feedback","note"]})}}finally{(0,p.setPreferredTransport)(w)}}function V(n){return n!=="init"&&n!=="help"&&n!=="generate-docs"&&n!=="observability"&&n!=="feedback"&&n!=="note"&&n!=="runtime"&&n!=="diagnostics"&&n!=="doctor"&&n!=="reveal"}
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -50,6 +50,7 @@ if (!npmPrefix) {
|
|
|
50
50
|
|
|
51
51
|
fs.mkdirSync(npmPrefix, { recursive: true });
|
|
52
52
|
fs.copyFileSync(launcherPath, path.join(npmPrefix, "aib.exe"));
|
|
53
|
+
fs.writeFileSync(path.join(npmPrefix, "aib.node-cli.txt"), `${path.join(packageRoot, "dist", "bin", "aib.js")}\n`, "utf8");
|
|
53
54
|
|
|
54
55
|
const ps1ShimPath = path.join(npmPrefix, "aib.ps1");
|
|
55
56
|
const ps1BackupPath = path.join(npmPrefix, "aib.ps1.bak");
|
|
@@ -24,6 +24,8 @@ main().catch((error) => {
|
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
async function main() {
|
|
27
|
+
cleanupOldTempDownloads();
|
|
28
|
+
|
|
27
29
|
if (runtimeComplete()) {
|
|
28
30
|
if (!options.quiet) {
|
|
29
31
|
reporter.info(`aib runtime ready: ${path.relative(process.cwd(), runtimesDir) || runtimesDir}`);
|
|
@@ -57,27 +59,31 @@ async function main() {
|
|
|
57
59
|
|
|
58
60
|
reporter.info(`aib runtime: provisioning ${platformKey}`);
|
|
59
61
|
const resolution = source || url
|
|
60
|
-
? {
|
|
62
|
+
? { ...(source ? { archivePath: path.resolve(source), tempDir: null } : await downloadRuntimeArchive(url, "runtime archive")), expectedSha256: options.sha256 ?? process.env.AIB_RUNTIME_SHA256 ?? null }
|
|
61
63
|
: await resolveFromManifest(manifestSource, manifestUrl);
|
|
62
64
|
const archivePath = resolution.archivePath;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
try {
|
|
66
|
+
if (!fs.existsSync(archivePath)) {
|
|
67
|
+
throw new Error(`Runtime archive not found: ${archivePath}`);
|
|
68
|
+
}
|
|
69
|
+
if (resolution.expectedSha256) {
|
|
70
|
+
reporter.info("aib runtime: verifying checksum");
|
|
71
|
+
assertSha256(archivePath, resolution.expectedSha256);
|
|
72
|
+
}
|
|
70
73
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
fs.mkdirSync(runtimesDir, { recursive: true });
|
|
75
|
+
reporter.info("aib runtime: extracting archive");
|
|
76
|
+
extractRuntimeArchive(archivePath);
|
|
74
77
|
|
|
75
|
-
|
|
76
|
-
|
|
78
|
+
if (!runtimeComplete()) {
|
|
79
|
+
throw new Error(`Runtime archive did not provision a complete runtime under ${runtimesDir}`);
|
|
80
|
+
}
|
|
81
|
+
} finally {
|
|
82
|
+
cleanupOwnedTempDownload(resolution.tempDir);
|
|
77
83
|
}
|
|
78
84
|
|
|
79
85
|
if (!options.quiet) {
|
|
80
|
-
reporter.info(
|
|
86
|
+
reporter.info("aib runtime: ready");
|
|
81
87
|
}
|
|
82
88
|
}
|
|
83
89
|
|
|
@@ -138,21 +144,72 @@ async function resolveFromManifest(manifestSource, manifestUrl) {
|
|
|
138
144
|
}
|
|
139
145
|
const archivePath = artifact.file && manifestSource
|
|
140
146
|
? path.resolve(path.dirname(path.resolve(manifestSource)), String(artifact.file))
|
|
141
|
-
:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
147
|
+
: null;
|
|
148
|
+
const downloaded = !archivePath && artifact.url
|
|
149
|
+
? await downloadRuntimeArchive(String(artifact.url))
|
|
150
|
+
: null;
|
|
151
|
+
const resolvedArchivePath = archivePath ?? downloaded?.archivePath ?? null;
|
|
152
|
+
const tempDir = downloaded?.tempDir ?? null;
|
|
153
|
+
if (!resolvedArchivePath) {
|
|
145
154
|
throw new Error(`Runtime manifest artifact for ${platformKey} has no url or local file.`);
|
|
146
155
|
}
|
|
147
156
|
return {
|
|
148
|
-
archivePath,
|
|
157
|
+
archivePath: resolvedArchivePath,
|
|
158
|
+
tempDir,
|
|
149
159
|
expectedSha256: typeof artifact.sha256 === "string" ? artifact.sha256 : null
|
|
150
160
|
};
|
|
151
161
|
}
|
|
152
162
|
|
|
153
163
|
async function downloadJson(url) {
|
|
154
|
-
const
|
|
155
|
-
|
|
164
|
+
const download = await downloadRuntimeArchive(url, "runtime manifest");
|
|
165
|
+
try {
|
|
166
|
+
return JSON.parse(fs.readFileSync(download.archivePath, "utf8"));
|
|
167
|
+
} finally {
|
|
168
|
+
cleanupOwnedTempDownload(download.tempDir);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function cleanupOldTempDownloads() {
|
|
173
|
+
const cutoffMs = Date.now() - 24 * 60 * 60 * 1000;
|
|
174
|
+
let entries = [];
|
|
175
|
+
try {
|
|
176
|
+
entries = fs.readdirSync(os.tmpdir(), { withFileTypes: true });
|
|
177
|
+
} catch {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
for (const entry of entries) {
|
|
181
|
+
if (!entry.isDirectory() || !entry.name.startsWith("aib-runtime-")) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const tempDir = path.join(os.tmpdir(), entry.name);
|
|
185
|
+
try {
|
|
186
|
+
const stat = fs.statSync(tempDir);
|
|
187
|
+
if (stat.mtimeMs < cutoffMs) {
|
|
188
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
189
|
+
}
|
|
190
|
+
} catch {
|
|
191
|
+
// Best-effort cleanup only.
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function cleanupOwnedTempDownload(tempDir) {
|
|
197
|
+
if (!tempDir) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
const resolvedTemp = path.resolve(tempDir);
|
|
202
|
+
const resolvedOsTemp = path.resolve(os.tmpdir());
|
|
203
|
+
const relative = path.relative(resolvedOsTemp, resolvedTemp);
|
|
204
|
+
if (path.basename(resolvedTemp).startsWith("aib-runtime-")
|
|
205
|
+
&& relative
|
|
206
|
+
&& !relative.startsWith("..")
|
|
207
|
+
&& !path.isAbsolute(relative)) {
|
|
208
|
+
fs.rmSync(resolvedTemp, { recursive: true, force: true });
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
// Best-effort cleanup only.
|
|
212
|
+
}
|
|
156
213
|
}
|
|
157
214
|
|
|
158
215
|
function defaultManifestUrl() {
|
|
@@ -281,12 +338,14 @@ function downloadRuntimeArchive(url, label = "runtime archive") {
|
|
|
281
338
|
if (response.statusCode && response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
|
282
339
|
file.close();
|
|
283
340
|
fs.rmSync(targetPath, { force: true });
|
|
341
|
+
cleanupOwnedTempDownload(tempDir);
|
|
284
342
|
downloadRuntimeArchive(new URL(response.headers.location, url).toString(), label).then(resolve, reject);
|
|
285
343
|
return;
|
|
286
344
|
}
|
|
287
345
|
if (response.statusCode !== 200) {
|
|
288
346
|
file.close();
|
|
289
347
|
fs.rmSync(targetPath, { force: true });
|
|
348
|
+
cleanupOwnedTempDownload(tempDir);
|
|
290
349
|
reject(new Error(`Runtime download failed with HTTP ${response.statusCode}: ${url}`));
|
|
291
350
|
return;
|
|
292
351
|
}
|
|
@@ -297,13 +356,14 @@ function downloadRuntimeArchive(url, label = "runtime archive") {
|
|
|
297
356
|
file.on("finish", () => {
|
|
298
357
|
file.close(() => {
|
|
299
358
|
progress.done();
|
|
300
|
-
resolve(targetPath);
|
|
359
|
+
resolve({ archivePath: targetPath, tempDir });
|
|
301
360
|
});
|
|
302
361
|
});
|
|
303
362
|
});
|
|
304
363
|
request.on("error", (error) => {
|
|
305
364
|
file.close();
|
|
306
365
|
fs.rmSync(targetPath, { force: true });
|
|
366
|
+
cleanupOwnedTempDownload(tempDir);
|
|
307
367
|
reject(error);
|
|
308
368
|
});
|
|
309
369
|
});
|
|
@@ -311,7 +371,6 @@ function downloadRuntimeArchive(url, label = "runtime archive") {
|
|
|
311
371
|
|
|
312
372
|
function createReporter(enabled) {
|
|
313
373
|
const stream = process.stderr;
|
|
314
|
-
const useCarriageReturn = Boolean(stream.isTTY);
|
|
315
374
|
return {
|
|
316
375
|
info(message) {
|
|
317
376
|
if (!enabled) {
|
|
@@ -324,37 +383,36 @@ function createReporter(enabled) {
|
|
|
324
383
|
return { add() {}, done() {} };
|
|
325
384
|
}
|
|
326
385
|
let downloadedBytes = 0;
|
|
327
|
-
let lastWriteMs = 0;
|
|
328
386
|
let ended = false;
|
|
329
|
-
|
|
330
|
-
const
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
387
|
+
let nextPercent = 10;
|
|
388
|
+
const totalKnown = Number.isFinite(totalBytes) && totalBytes > 0;
|
|
389
|
+
const showPercentProgress = totalKnown && totalBytes >= 1024 * 1024;
|
|
390
|
+
stream.write(totalKnown
|
|
391
|
+
? `${label} ${formatBytes(totalBytes)}\n`
|
|
392
|
+
: `${label}\n`);
|
|
393
|
+
const writeProgress = () => {
|
|
394
|
+
if (!showPercentProgress) {
|
|
334
395
|
return;
|
|
335
396
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
: `${label}: ${percent.toFixed(1)}% ${formatBytes(downloadedBytes)} / ${formatBytes(totalBytes)} (${formatBytes(rateBytes)}/s)`;
|
|
343
|
-
stream.write(useCarriageReturn ? `\r${text}` : `${text}\n`);
|
|
397
|
+
const percent = Math.floor(Math.min(100, (downloadedBytes / totalBytes) * 100));
|
|
398
|
+
while (percent >= nextPercent && nextPercent <= 100) {
|
|
399
|
+
const thresholdBytes = Math.min(totalBytes, Math.round((totalBytes * nextPercent) / 100));
|
|
400
|
+
stream.write(`aib runtime: ${nextPercent}% ${formatBytes(thresholdBytes)} / ${formatBytes(totalBytes)}\n`);
|
|
401
|
+
nextPercent += 10;
|
|
402
|
+
}
|
|
344
403
|
};
|
|
345
|
-
write(true);
|
|
346
404
|
return {
|
|
347
405
|
add(byteCount) {
|
|
348
406
|
downloadedBytes += byteCount;
|
|
349
|
-
|
|
407
|
+
writeProgress();
|
|
350
408
|
},
|
|
351
409
|
done() {
|
|
352
410
|
if (ended) {
|
|
353
411
|
return;
|
|
354
412
|
}
|
|
355
413
|
ended = true;
|
|
356
|
-
|
|
357
|
-
|
|
414
|
+
downloadedBytes = Math.max(downloadedBytes, totalBytes ?? downloadedBytes);
|
|
415
|
+
writeProgress();
|
|
358
416
|
}
|
|
359
417
|
};
|
|
360
418
|
}
|