@vpxa/aikit 0.1.81 → 0.1.83
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 +52 -0
- package/package.json +1 -1
- package/packages/cli/dist/index.js +2 -2
- package/packages/cli/dist/user-C05ypatU.js +5 -0
- package/packages/core/dist/index.d.ts +26 -0
- package/packages/flows/dist/index.d.ts +8 -0
- package/packages/flows/dist/index.js +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/server-DyCYX0nU.js +1277 -0
- package/packages/server/dist/{version-check-D4j0Pykd.js → version-check-AMfxaZUw.js} +1 -1
- package/packages/store/dist/index.d.ts +50 -4
- package/packages/store/dist/index.js +12 -12
- package/scaffold/dist/definitions/bodies.mjs +44 -0
- package/packages/cli/dist/user-vbJwa7x2.js +0 -5
- package/packages/server/dist/server-VgZC6Q43.js +0 -1277
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{createLogger as a}from"../../core/dist/index.js";import{homedir as o}from"node:os";import{execFile as s}from"node:child_process";const c=a(`server`);function l(){let e=r(n(i(import.meta.url)),`..`,`..`,`..`,`package.json`);try{return JSON.parse(t(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}function u(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=(n[e]??0)-(r[e]??0);if(t!==0)return t>0?1:-1}return 0}function d(){let e=l();fetch(`https://registry.npmjs.org/@vpxa/aikit/latest`,{signal:AbortSignal.timeout(5e3)}).then(e=>{if(e.ok)return e.json()}).then(t=>{if(!t||typeof t!=`object`)return;let n=t.version;n&&u(e,n)<0&&c.warn(`Update available`,{currentVersion:e,latestVersion:n,updateCommand:`aikit upgrade`})}).catch(()=>{})}function f(){try{let n=r(o(),`.copilot`,`.aikit-scaffold.json`);return e(n)?JSON.parse(t(n,`utf-8`)).version??null:null}catch{return null}}function p(){try{let n=r(process.cwd(),`.github`,`.aikit-scaffold.json`);return e(n)?JSON.parse(t(n,`utf-8`)).version??null:null}catch{return null}}let m=`idle`,h=null;function g(){return{state:m,error:h}}function _(){try{let t=l(),a=f(),o=p();if(!(a!=null&&a!==t)&&!(o!=null&&o!==t)||m===`pending`||m===`success`)return;m=`pending`,h=null,c.info(`Scaffold version mismatch — auto-upgrading`,{serverVersion:t,userScaffoldVersion:a,workspaceScaffoldVersion:o});let u=
|
|
1
|
+
import{existsSync as e,readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{createLogger as a}from"../../core/dist/index.js";import{homedir as o}from"node:os";import{execFile as s}from"node:child_process";const c=a(`server`);function l(){let e=r(n(i(import.meta.url)),`..`,`..`,`..`,`package.json`);try{return JSON.parse(t(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}function u(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=(n[e]??0)-(r[e]??0);if(t!==0)return t>0?1:-1}return 0}function d(){let e=l();fetch(`https://registry.npmjs.org/@vpxa/aikit/latest`,{signal:AbortSignal.timeout(5e3)}).then(e=>{if(e.ok)return e.json()}).then(t=>{if(!t||typeof t!=`object`)return;let n=t.version;n&&u(e,n)<0&&c.warn(`Update available`,{currentVersion:e,latestVersion:n,updateCommand:`aikit upgrade`})}).catch(()=>{})}function f(){try{let n=r(o(),`.copilot`,`.aikit-scaffold.json`);return e(n)?JSON.parse(t(n,`utf-8`)).version??null:null}catch{return null}}function p(){try{let n=r(process.cwd(),`.github`,`.aikit-scaffold.json`);return e(n)?JSON.parse(t(n,`utf-8`)).version??null:null}catch{return null}}let m=`idle`,h=null;function g(){return{state:m,error:h}}function _(){try{let t=l(),a=f(),o=p();if(!(a!=null&&a!==t)&&!(o!=null&&o!==t)||m===`pending`||m===`success`)return;m=`pending`,h=null,c.info(`Scaffold version mismatch — auto-upgrading`,{serverVersion:t,userScaffoldVersion:a,workspaceScaffoldVersion:o});let u=n(i(import.meta.url)),d=[r(u,`..`,`..`,`..`,`bin`,`aikit.mjs`),r(u,`..`,`bin`,`aikit.mjs`),...process.argv[1]?[r(n(process.argv[1]),`aikit.mjs`)]:[]],g=d.find(t=>e(t));if(!g){m=`failed`,h=`aikit CLI binary not found. Tried: ${d.join(`, `)}`,c.warn(`Cannot auto-upgrade: aikit CLI binary not found`,{candidates:d,platform:process.platform});return}s(process.execPath,[g,`upgrade`],{timeout:3e4,windowsHide:!0},(e,t,n)=>{e?(m=`failed`,h=e.message,c.warn(`Auto-upgrade failed`,{error:e.message,stderr:n?.slice(0,500),binPath:g,platform:process.platform})):(m=`success`,h=null,c.info(`Auto-upgrade complete`))}).unref()}catch(e){m=`failed`,h=e instanceof Error?e.message:String(e),c.warn(`Auto-upgrade check failed`,{error:h})}}export{_ as autoUpgradeScaffold,d as checkForUpdates,l as getCurrentVersion,g as getUpgradeState};
|
|
@@ -251,18 +251,64 @@ declare class LanceStore implements IKnowledgeStore {
|
|
|
251
251
|
private fromLanceRecord;
|
|
252
252
|
}
|
|
253
253
|
//#endregion
|
|
254
|
+
//#region packages/store/src/sqlite-adapter.d.ts
|
|
255
|
+
/**
|
|
256
|
+
* SQLite adapter abstraction — allows swapping between better-sqlite3 (native)
|
|
257
|
+
* and sql.js (WASM) without changing consumer code.
|
|
258
|
+
*
|
|
259
|
+
* Primary adapter is configurable; the other serves as automatic fallback
|
|
260
|
+
* when the primary fails to load (e.g. native binary missing on the platform).
|
|
261
|
+
*/
|
|
262
|
+
type SqliteAdapterType = 'better-sqlite3' | 'sql.js';
|
|
263
|
+
interface ISqliteAdapter {
|
|
264
|
+
/** Which adapter implementation is active */
|
|
265
|
+
readonly type: SqliteAdapterType;
|
|
266
|
+
/** Open or create the database at the given file path */
|
|
267
|
+
open(dbPath: string): Promise<void>;
|
|
268
|
+
/** Execute DDL or multi-statement SQL (CREATE TABLE, BEGIN, COMMIT, etc.) */
|
|
269
|
+
exec(sql: string): void;
|
|
270
|
+
/** Set a PRAGMA value */
|
|
271
|
+
pragma(pragma: string): void;
|
|
272
|
+
/** Run a parameterized SELECT, return all rows */
|
|
273
|
+
queryAll<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
|
|
274
|
+
/** Run a parameterized INSERT/UPDATE/DELETE */
|
|
275
|
+
run(sql: string, params?: unknown[]): void;
|
|
276
|
+
/** Flush to disk — no-op for file-backed engines, required for in-memory engines */
|
|
277
|
+
flush(): void;
|
|
278
|
+
/** Close the database connection */
|
|
279
|
+
close(): void;
|
|
280
|
+
}
|
|
281
|
+
interface SqliteAdapterOptions {
|
|
282
|
+
/** Which adapter to try first. Default: 'sql.js' (safest for npx distribution) */
|
|
283
|
+
primary?: SqliteAdapterType;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Create a SQLite adapter with automatic fallback.
|
|
287
|
+
*
|
|
288
|
+
* Tries the primary adapter first; if it fails to load (missing native binary,
|
|
289
|
+
* unsupported platform, etc.), falls back to the other adapter transparently.
|
|
290
|
+
*/
|
|
291
|
+
declare function createSqliteAdapter(dbPath: string, options?: SqliteAdapterOptions): Promise<ISqliteAdapter>;
|
|
292
|
+
//#endregion
|
|
254
293
|
//#region packages/store/src/sqlite-graph-store.d.ts
|
|
255
294
|
declare class SqliteGraphStore implements IGraphStore {
|
|
256
|
-
private
|
|
295
|
+
private adapter;
|
|
257
296
|
private readonly dbPath;
|
|
297
|
+
private readonly adapterOptions?;
|
|
258
298
|
constructor(options?: {
|
|
259
299
|
path?: string;
|
|
300
|
+
sqliteAdapter?: SqliteAdapterOptions;
|
|
260
301
|
});
|
|
261
302
|
initialize(): Promise<void>;
|
|
262
|
-
private
|
|
303
|
+
private configureAdapter;
|
|
263
304
|
private createTables;
|
|
264
305
|
private migrateSchema;
|
|
265
|
-
private
|
|
306
|
+
private getAdapter;
|
|
307
|
+
/**
|
|
308
|
+
* Ensure the adapter is open, lazily re-opening after close().
|
|
309
|
+
* Must be called from any public async method that may be invoked after close().
|
|
310
|
+
*/
|
|
311
|
+
private ensureOpen;
|
|
266
312
|
private query;
|
|
267
313
|
private run;
|
|
268
314
|
upsertNode(node: GraphNode): Promise<void>;
|
|
@@ -309,4 +355,4 @@ interface StoreConfig {
|
|
|
309
355
|
}
|
|
310
356
|
declare function createStore(config: StoreConfig): Promise<IKnowledgeStore>;
|
|
311
357
|
//#endregion
|
|
312
|
-
export { type DepthGroupedResult, type GraphEdge, type GraphNode, type GraphStats, type GraphTraversalOptions, type GraphTraversalResult, type GraphValidationResult, type IGraphStore, type IKnowledgeStore, LanceStore, type ProcessInfo, type SearchOptions, SqliteGraphStore, type StoreBackend, type StoreConfig, type Symbol360, createStore };
|
|
358
|
+
export { type DepthGroupedResult, type GraphEdge, type GraphNode, type GraphStats, type GraphTraversalOptions, type GraphTraversalResult, type GraphValidationResult, type IGraphStore, type IKnowledgeStore, type ISqliteAdapter, LanceStore, type ProcessInfo, type SearchOptions, type SqliteAdapterOptions, type SqliteAdapterType, SqliteGraphStore, type StoreBackend, type StoreConfig, type Symbol360, createSqliteAdapter, createStore };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as e}from"./lance-store-jdHZp-V4.js";import{AIKIT_PATHS as t}from"../../core/dist/index.js";import{existsSync as n,mkdirSync as r}from"node:fs";import{dirname as
|
|
1
|
+
import{t as e}from"./lance-store-jdHZp-V4.js";import{AIKIT_PATHS as t}from"../../core/dist/index.js";import{existsSync as n,mkdirSync as r,readFileSync as i,writeFileSync as a}from"node:fs";import{dirname as o,join as s}from"node:path";var c=class{type=`better-sqlite3`;db=null;async open(e){let t=(await import(`better-sqlite3`)).default;this.db=new t(e)}exec(e){this.getDb().exec(e)}pragma(e){this.getDb().pragma(e)}queryAll(e,t=[]){return this.getDb().prepare(e).all(...t)}run(e,t=[]){this.getDb().prepare(e).run(...t)}flush(){}close(){this.db&&=(this.db.close(),null)}getDb(){if(!this.db)throw Error(`BetterSqliteAdapter: database not opened`);return this.db}},l=class{type=`sql.js`;db=null;dbPath=``;dirty=!1;inTransaction=!1;async open(e){this.dbPath=e;let t=(await import(`sql.js`)).default,r=await t();if(n(e)){let t=i(e);this.db=new r.Database(t)}else this.db=new r.Database}exec(e){let t=e.trimStart().toUpperCase();t.startsWith(`BEGIN`)?this.inTransaction=!0:(t.startsWith(`COMMIT`)||t.startsWith(`ROLLBACK`))&&(this.inTransaction=!1),this.getDb().run(e),this.dirty=!0}pragma(e){this.getDb().exec(`PRAGMA ${e}`)}queryAll(e,t=[]){let n=this.getDb().prepare(e);t.length>0&&n.bind(t);let r=[];for(;n.step();)r.push(n.getAsObject());return n.free(),r}run(e,t=[]){let n=this.getDb(),r=e.trimStart().toUpperCase(),i=!this.inTransaction&&(r.startsWith(`INSERT`)||r.startsWith(`UPDATE`));if(i&&n.run(`SAVEPOINT fk_check`),t.length>0){let r=n.prepare(e);try{r.bind(t),r.step()}finally{r.free()}}else n.run(e);if(i){if(n.exec(`PRAGMA foreign_key_check`).length>0)throw n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`),Error(`FOREIGN KEY constraint failed`);n.run(`RELEASE fk_check`)}this.dirty=!0}flush(){if(!this.dirty||!this.db)return;let e=this.db.export();a(this.dbPath,Buffer.from(e)),this.dirty=!1}close(){this.db&&=(this.flush(),this.db.close(),null)}getDb(){if(!this.db)throw Error(`SqlJsAdapter: database not opened`);return this.db}};async function u(e,t){let n=t?.primary??`sql.js`,r=[n,n===`better-sqlite3`?`sql.js`:`better-sqlite3`];for(let t of r)try{let r=t===`better-sqlite3`?new c:new l;return await r.open(e),t!==n&&console.error(`[aikit] SQLite adapter: primary "${n}" unavailable, using fallback "${t}"`),r}catch(e){let n=e instanceof Error?e.message:String(e);console.error(`[aikit] SQLite adapter "${t}" failed to load: ${n}`)}throw Error(`[aikit] No SQLite adapter available. Tried: ${r.join(`, `)}. Install either better-sqlite3 or sql.js.`)}var d=class{adapter=null;dbPath;adapterOptions;constructor(e){let n=e?.path??t.data;this.dbPath=s(n,`graph.db`),this.adapterOptions=e?.sqliteAdapter}async initialize(){let e=o(this.dbPath);n(e)||r(e,{recursive:!0}),this.adapter=await u(this.dbPath,this.adapterOptions),this.configureAdapter(this.adapter),this.createTables(this.adapter),this.migrateSchema(this.adapter),this.adapter.flush()}configureAdapter(e){e.pragma(`journal_mode = WAL`),e.pragma(`foreign_keys = ON`)}createTables(e){e.exec(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS nodes (
|
|
3
3
|
id TEXT PRIMARY KEY,
|
|
4
4
|
type TEXT NOT NULL,
|
|
@@ -39,37 +39,37 @@ import{t as e}from"./lance-store-jdHZp-V4.js";import{AIKIT_PATHS as t}from"../..
|
|
|
39
39
|
FOREIGN KEY (process_id) REFERENCES processes(id) ON DELETE CASCADE,
|
|
40
40
|
FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE
|
|
41
41
|
)
|
|
42
|
-
`),e.exec(`CREATE INDEX IF NOT EXISTS idx_process_steps_node ON process_steps(node_id)`)}migrateSchema(e){for(let t of[`ALTER TABLE edges ADD COLUMN confidence REAL DEFAULT 1.0`,`ALTER TABLE nodes ADD COLUMN community TEXT`])try{e.exec(t)}catch{}e.exec(`CREATE INDEX IF NOT EXISTS idx_nodes_community ON nodes(community)`)}
|
|
42
|
+
`),e.exec(`CREATE INDEX IF NOT EXISTS idx_process_steps_node ON process_steps(node_id)`)}migrateSchema(e){for(let t of[`ALTER TABLE edges ADD COLUMN confidence REAL DEFAULT 1.0`,`ALTER TABLE nodes ADD COLUMN community TEXT`])try{e.exec(t)}catch{}e.exec(`CREATE INDEX IF NOT EXISTS idx_nodes_community ON nodes(community)`)}getAdapter(){if(!this.adapter)throw Error(`SqliteGraphStore not initialized — call initialize() first`);return this.adapter}async ensureOpen(){this.adapter||(this.adapter=await u(this.dbPath,this.adapterOptions),this.configureAdapter(this.adapter))}query(e,t=[]){return this.getAdapter().queryAll(e,t)}run(e,t=[]){this.getAdapter().run(e,t)}async upsertNode(e){await this.ensureOpen(),this.run(`INSERT INTO nodes (id, type, name, properties, source_record_id, source_path, created_at, community)
|
|
43
43
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
44
44
|
ON CONFLICT(id) DO UPDATE SET
|
|
45
45
|
type = excluded.type, name = excluded.name, properties = excluded.properties,
|
|
46
46
|
source_record_id = excluded.source_record_id, source_path = excluded.source_path,
|
|
47
|
-
community = excluded.community`,[e.id,e.type,e.name,JSON.stringify(e.properties),e.sourceRecordId??null,e.sourcePath??null,e.createdAt??new Date().toISOString(),e.community??null])}async upsertEdge(e){this.run(`INSERT INTO edges (id, from_id, to_id, type, weight, confidence, properties)
|
|
47
|
+
community = excluded.community`,[e.id,e.type,e.name,JSON.stringify(e.properties),e.sourceRecordId??null,e.sourcePath??null,e.createdAt??new Date().toISOString(),e.community??null]),this.getAdapter().flush()}async upsertEdge(e){await this.ensureOpen(),this.run(`INSERT INTO edges (id, from_id, to_id, type, weight, confidence, properties)
|
|
48
48
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
49
49
|
ON CONFLICT(id) DO UPDATE SET
|
|
50
50
|
from_id = excluded.from_id, to_id = excluded.to_id,
|
|
51
|
-
type = excluded.type, weight = excluded.weight, confidence = excluded.confidence, properties = excluded.properties`,[e.id,e.fromId,e.toId,e.type,e.weight??1,e.confidence??1,JSON.stringify(e.properties??{})])}async upsertNodes(e){if(e.length===0)return;let t=this.
|
|
51
|
+
type = excluded.type, weight = excluded.weight, confidence = excluded.confidence, properties = excluded.properties`,[e.id,e.fromId,e.toId,e.type,e.weight??1,e.confidence??1,JSON.stringify(e.properties??{})]),this.getAdapter().flush()}async upsertNodes(e){if(e.length===0)return;await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{for(let t of e)this.run(`INSERT INTO nodes (id, type, name, properties, source_record_id, source_path, created_at, community)
|
|
52
52
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
53
53
|
ON CONFLICT(id) DO UPDATE SET
|
|
54
54
|
type = excluded.type, name = excluded.name, properties = excluded.properties,
|
|
55
55
|
source_record_id = excluded.source_record_id, source_path = excluded.source_path,
|
|
56
|
-
community = excluded.community`,[t.id,t.type,t.name,JSON.stringify(t.properties),t.sourceRecordId??null,t.sourcePath??null,t.createdAt??new Date().toISOString(),t.community??null]);t.exec(`COMMIT`)}catch(e){throw t.exec(`ROLLBACK`),e}}async upsertEdges(e){if(e.length===0)return;let t=this.
|
|
56
|
+
community = excluded.community`,[t.id,t.type,t.name,JSON.stringify(t.properties),t.sourceRecordId??null,t.sourcePath??null,t.createdAt??new Date().toISOString(),t.community??null]);t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async upsertEdges(e){if(e.length===0)return;await this.ensureOpen();let t=this.getAdapter();t.pragma(`foreign_keys = OFF`),t.exec(`BEGIN TRANSACTION`);try{for(let t of e)this.run(`INSERT INTO edges (id, from_id, to_id, type, weight, confidence, properties)
|
|
57
57
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
58
58
|
ON CONFLICT(id) DO UPDATE SET
|
|
59
59
|
from_id = excluded.from_id, to_id = excluded.to_id,
|
|
60
|
-
type = excluded.type, weight = excluded.weight, confidence = excluded.confidence, properties = excluded.properties`,[t.id,t.fromId,t.toId,t.type,t.weight??1,t.confidence??1,JSON.stringify(t.properties??{})]);t.exec(`COMMIT`)}catch(e){throw t.exec(`ROLLBACK`),e}finally{t.pragma(`foreign_keys = ON`)}}async getNode(e){let t=this.query(`SELECT * FROM nodes WHERE id = ?`,[e]);return t.length>0?
|
|
60
|
+
type = excluded.type, weight = excluded.weight, confidence = excluded.confidence, properties = excluded.properties`,[t.id,t.fromId,t.toId,t.type,t.weight??1,t.confidence??1,JSON.stringify(t.properties??{})]);t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}finally{t.pragma(`foreign_keys = ON`)}}async getNode(e){await this.ensureOpen();let t=this.query(`SELECT * FROM nodes WHERE id = ?`,[e]);return t.length>0?p(t[0]):null}async getNeighbors(e,t){await this.ensureOpen();let n=t?.direction??`both`,r=t?.edgeType,i=t?.limit??50,a=[],o=[],s=new Set;if(n===`outgoing`||n===`both`){let t=`
|
|
61
61
|
SELECT e.id AS edge_id, e.from_id, e.to_id, e.type AS edge_type, e.weight,
|
|
62
62
|
e.confidence AS edge_confidence, e.properties AS edge_props,
|
|
63
63
|
n.id AS node_id, n.type AS node_type, n.name AS node_name, n.properties AS node_props,
|
|
64
64
|
n.source_record_id AS node_src_rec, n.source_path AS node_src_path,
|
|
65
65
|
n.created_at AS node_created, n.community AS node_community
|
|
66
|
-
FROM edges e JOIN nodes n ON e.to_id = n.id WHERE e.from_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(
|
|
66
|
+
FROM edges e JOIN nodes n ON e.to_id = n.id WHERE e.from_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(h(e)),s.has(e.node_id)||(s.add(e.node_id),a.push(g(e)))}if(n===`incoming`||n===`both`){let t=`
|
|
67
67
|
SELECT e.id AS edge_id, e.from_id, e.to_id, e.type AS edge_type, e.weight,
|
|
68
68
|
e.confidence AS edge_confidence, e.properties AS edge_props,
|
|
69
69
|
n.id AS node_id, n.type AS node_type, n.name AS node_name, n.properties AS node_props,
|
|
70
70
|
n.source_record_id AS node_src_rec, n.source_path AS node_src_path,
|
|
71
71
|
n.created_at AS node_created, n.community AS node_community
|
|
72
|
-
FROM edges e JOIN nodes n ON e.from_id = n.id WHERE e.to_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(
|
|
72
|
+
FROM edges e JOIN nodes n ON e.from_id = n.id WHERE e.to_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(h(e)),s.has(e.node_id)||(s.add(e.node_id),a.push(g(e)))}return{nodes:a,edges:o}}async traverse(e,t){await this.ensureOpen();let n=t?.maxDepth??2,r=t?.direction??`both`,i=t?.edgeType,a=t?.limit??50,o=new Map,s=new Map,c=new Set,l=[{nodeId:e,depth:0}];for(;l.length>0&&o.size<a;){let e=l.shift();if(!e||c.has(e.nodeId)||e.depth>n)continue;c.add(e.nodeId);let t=await this.getNeighbors(e.nodeId,{direction:r,edgeType:i,limit:a-o.size});for(let r of t.nodes)o.has(r.id)||(o.set(r.id,r),e.depth+1<n&&l.push({nodeId:r.id,depth:e.depth+1}));for(let e of t.edges)s.set(e.id,e)}return{nodes:[...o.values()],edges:[...s.values()]}}async findNodes(e){await this.ensureOpen();let t=[],n=[];e.type&&(t.push(`type = ?`),n.push(e.type)),e.namePattern&&(t.push(`name LIKE ?`),n.push(`%${e.namePattern}%`)),e.sourcePath&&(t.push(`source_path = ?`),n.push(e.sourcePath));let r=t.length>0?`WHERE ${t.join(` AND `)}`:``,i=e.limit??100;return this.query(`SELECT * FROM nodes ${r} LIMIT ?`,[...n,i]).map(e=>p(e))}async findEdges(e){await this.ensureOpen();let t=[],n=[];e.type&&(t.push(`type = ?`),n.push(e.type)),e.fromId&&(t.push(`from_id = ?`),n.push(e.fromId)),e.toId&&(t.push(`to_id = ?`),n.push(e.toId));let r=t.length>0?`WHERE ${t.join(` AND `)}`:``,i=e.limit??100;return this.query(`SELECT * FROM edges ${r} LIMIT ?`,[...n,i]).map(e=>m(e))}async deleteNode(e){await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM edges WHERE from_id = ? OR to_id = ?`,[e,e]),this.run(`DELETE FROM nodes WHERE id = ?`,[e]),t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async deleteBySourcePath(e){await this.ensureOpen();let t=this.query(`SELECT id FROM nodes WHERE source_path = ?`,[e]);if(t.length===0)return 0;let n=this.getAdapter();n.exec(`BEGIN TRANSACTION`);try{for(let e of t)this.run(`DELETE FROM edges WHERE from_id = ? OR to_id = ?`,[e.id,e.id]);this.run(`DELETE FROM nodes WHERE source_path = ?`,[e]),n.exec(`COMMIT`),n.flush()}catch(e){throw n.exec(`ROLLBACK`),e}return t.length}async clear(){await this.ensureOpen(),this.run(`DELETE FROM process_steps`),this.run(`DELETE FROM processes`),this.run(`DELETE FROM edges`),this.run(`DELETE FROM nodes`),this.getAdapter().flush()}async getStats(){await this.ensureOpen();let e=this.query(`SELECT COUNT(*) as count FROM nodes`)[0]?.count??0,t=this.query(`SELECT COUNT(*) as count FROM edges`)[0]?.count??0,n=this.query(`SELECT type, COUNT(*) as count FROM nodes GROUP BY type`),r={};for(let e of n)r[e.type]=e.count;let i=this.query(`SELECT type, COUNT(*) as count FROM edges GROUP BY type`),a={};for(let e of i)a[e.type]=e.count;return{nodeCount:e,edgeCount:t,nodeTypes:r,edgeTypes:a}}async validate(){await this.ensureOpen();let e=await this.getStats(),t=this.query(`SELECT e.id AS edgeId,
|
|
73
73
|
CASE
|
|
74
74
|
WHEN n1.id IS NULL THEN e.from_id
|
|
75
75
|
WHEN n2.id IS NULL THEN e.to_id
|
|
@@ -81,10 +81,10 @@ import{t as e}from"./lance-store-jdHZp-V4.js";import{AIKIT_PATHS as t}from"../..
|
|
|
81
81
|
FROM nodes n
|
|
82
82
|
LEFT JOIN edges e1 ON n.id = e1.from_id
|
|
83
83
|
LEFT JOIN edges e2 ON n.id = e2.to_id
|
|
84
|
-
WHERE e1.id IS NULL AND e2.id IS NULL`).map(e=>e.id);return{valid:t.length===0,orphanNodes:n,danglingEdges:t,stats:e}}async setNodeCommunity(e,t){this.run(`UPDATE nodes SET community = ? WHERE id = ?`,[t,e])}async detectCommunities(){let e=this.query(`SELECT id FROM nodes`),t=new Map;for(let n of e)t.set(n.id,n.id);for(let n=0;n<10;n++){let n=!1,r=new Map(t);for(let i of e){let e=this.query(`SELECT to_id AS neighbor_id FROM edges WHERE from_id = ?
|
|
84
|
+
WHERE e1.id IS NULL AND e2.id IS NULL`).map(e=>e.id);return{valid:t.length===0,orphanNodes:n,danglingEdges:t,stats:e}}async setNodeCommunity(e,t){await this.ensureOpen(),this.run(`UPDATE nodes SET community = ? WHERE id = ?`,[t,e]),this.getAdapter().flush()}async detectCommunities(){await this.ensureOpen();let e=this.query(`SELECT id FROM nodes`),t=new Map;for(let n of e)t.set(n.id,n.id);for(let n=0;n<10;n++){let n=!1,r=new Map(t);for(let i of e){let e=this.query(`SELECT to_id AS neighbor_id FROM edges WHERE from_id = ?
|
|
85
85
|
UNION
|
|
86
|
-
SELECT from_id AS neighbor_id FROM edges WHERE to_id = ?`,[i.id,i.id]),a=new Map,o=t.get(i.id)??i.id;a.set(o,1);for(let n of e){let e=t.get(n.neighbor_id)??n.neighbor_id;a.set(e,(a.get(e)??0)+1)}let s=o,c=0;for(let[e,t]of a)(t>c||t===c&&e<s)&&(c=t,s=e);o!==s&&(r.set(i.id,s),n=!0)}t.clear();for(let[e,n]of r)t.set(e,n);if(!n)break}let n=this.
|
|
87
|
-
VALUES (?, ?, ?, '{}', ?)`,[a,e,t,o]);for(let e=0;e<n.length;e++)this.run(`INSERT INTO process_steps (process_id, node_id, step_order) VALUES (?, ?, ?)`,[a,n[e],e]);s.exec(`COMMIT`)}catch(e){throw s.exec(`ROLLBACK`),e}return{id:a,entryNodeId:e,label:t,properties:{},steps:n,createdAt:o}}async getProcesses(e){let t;t=e?this.query(`SELECT DISTINCT p.id, p.entry_node_id, p.label, p.properties, p.created_at
|
|
86
|
+
SELECT from_id AS neighbor_id FROM edges WHERE to_id = ?`,[i.id,i.id]),a=new Map,o=t.get(i.id)??i.id;a.set(o,1);for(let n of e){let e=t.get(n.neighbor_id)??n.neighbor_id;a.set(e,(a.get(e)??0)+1)}let s=o,c=0;for(let[e,t]of a)(t>c||t===c&&e<s)&&(c=t,s=e);o!==s&&(r.set(i.id,s),n=!0)}t.clear();for(let[e,n]of r)t.set(e,n);if(!n)break}let n=this.getAdapter();n.exec(`BEGIN TRANSACTION`);try{for(let[e,n]of t)this.run(`UPDATE nodes SET community = ? WHERE id = ?`,[n,e]);n.exec(`COMMIT`),n.flush()}catch(e){throw n.exec(`ROLLBACK`),e}let r={};for(let[e,n]of t)r[n]||(r[n]=[]),r[n].push(e);return r}async traceProcess(e,t){await this.ensureOpen();let n=[],r=new Set,i=[e];for(;i.length>0;){let e=i.shift();if(!e||r.has(e))continue;r.add(e),n.push(e);let t=this.query(`SELECT to_id FROM edges WHERE from_id = ? AND type = 'calls'`,[e]);for(let e of t)r.has(e.to_id)||i.push(e.to_id)}let a=`proc_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,o=new Date().toISOString(),s=this.getAdapter();s.exec(`BEGIN TRANSACTION`);try{this.run(`INSERT INTO processes (id, entry_node_id, label, properties, created_at)
|
|
87
|
+
VALUES (?, ?, ?, '{}', ?)`,[a,e,t,o]);for(let e=0;e<n.length;e++)this.run(`INSERT INTO process_steps (process_id, node_id, step_order) VALUES (?, ?, ?)`,[a,n[e],e]);s.exec(`COMMIT`),s.flush()}catch(e){throw s.exec(`ROLLBACK`),e}return{id:a,entryNodeId:e,label:t,properties:{},steps:n,createdAt:o}}async getProcesses(e){await this.ensureOpen();let t;t=e?this.query(`SELECT DISTINCT p.id, p.entry_node_id, p.label, p.properties, p.created_at
|
|
88
88
|
FROM processes p
|
|
89
89
|
JOIN process_steps ps ON p.id = ps.process_id
|
|
90
|
-
WHERE ps.node_id = ?`,[e]):this.query(`SELECT * FROM processes`);let n=[];for(let e of t){let t=this.query(`SELECT node_id FROM process_steps WHERE process_id = ? ORDER BY step_order`,[e.id]);n.push({id:e.id,entryNodeId:e.entry_node_id,label:e.label,properties:
|
|
90
|
+
WHERE ps.node_id = ?`,[e]):this.query(`SELECT * FROM processes`);let n=[];for(let e of t){let t=this.query(`SELECT node_id FROM process_steps WHERE process_id = ? ORDER BY step_order`,[e.id]);n.push({id:e.id,entryNodeId:e.entry_node_id,label:e.label,properties:f(e.properties),steps:t.map(e=>e.node_id),createdAt:e.created_at})}return n}async deleteProcess(e){await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM process_steps WHERE process_id = ?`,[e]),this.run(`DELETE FROM processes WHERE id = ?`,[e]),t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async depthGroupedTraversal(e,t=3,n){await this.ensureOpen();let r=n?.direction??`both`,i=n?.edgeType,a=n?.limit??100,o={},s=new Set;s.add(e);let c=[e];for(let e=1;e<=t;e++){let t=[],n=[];for(let e of c){let o=await this.getNeighbors(e,{direction:r,edgeType:i,limit:a});for(let e of o.nodes)s.has(e.id)||(s.add(e.id),t.push(e.id),n.push(e))}if(n.length>0&&(o[e]=n),c=t,c.length===0||s.size>=a)break}return o}async getCohesionScore(e){let t=this.query(`SELECT id FROM nodes WHERE community = ?`,[e]);if(t.length===0)return 0;let n=new Set(t.map(e=>e.id)),r=t.map(()=>`?`).join(`,`),i=t.map(e=>e.id),a=this.query(`SELECT from_id, to_id FROM edges WHERE from_id IN (${r}) OR to_id IN (${r})`,[...i,...i]);if(a.length===0)return 0;let o=0;for(let e of a)n.has(e.from_id)&&n.has(e.to_id)&&o++;return o/a.length}async getSymbol360(e){let t=await this.getNode(e);if(!t)throw Error(`Node '${e}' not found`);let n=await this.findEdges({toId:e}),r=await this.findEdges({fromId:e}),i=await this.getProcesses(e);return{node:t,incoming:n,outgoing:r,community:t.community??null,processes:i}}async close(){this.adapter&&=(this.adapter.close(),null)}};function f(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function p(e){return{id:e.id,type:e.type,name:e.name,properties:f(e.properties),sourceRecordId:e.source_record_id??void 0,sourcePath:e.source_path??void 0,createdAt:e.created_at,community:e.community??void 0}}function m(e){return{id:e.id,fromId:e.from_id,toId:e.to_id,type:e.type,weight:e.weight??1,confidence:e.confidence??1,properties:f(e.properties)}}function h(e){return{id:e.edge_id,fromId:e.from_id,toId:e.to_id,type:e.edge_type,weight:e.weight??1,confidence:e.edge_confidence??1,properties:f(e.edge_props??`{}`)}}function g(e){return{id:e.node_id,type:e.node_type,name:e.node_name,properties:f(e.node_props??`{}`),sourceRecordId:e.node_src_rec??void 0,sourcePath:e.node_src_path??void 0,createdAt:e.node_created,community:e.node_community??void 0}}async function _(e){switch(e.backend){case`lancedb`:{let{LanceStore:t}=await import(`./lance-store-jdHZp-V4.js`).then(e=>e.n);return new t({path:e.path})}default:throw Error(`Unknown store backend: "${e.backend}". Supported: lancedb`)}}export{e as LanceStore,d as SqliteGraphStore,u as createSqliteAdapter,_ as createStore};
|
|
@@ -143,6 +143,50 @@ Reviewers add findings to the Orchestrator's existing \`evidence_map\` \`task_id
|
|
|
143
143
|
| \`flow_reset\` | Abandon the active flow (preserves run directory for history) |
|
|
144
144
|
| \`flow_read_instruction\` | Read the current step's instruction with \`{{artifacts_path}}\` resolved |
|
|
145
145
|
| \`flow_runs\` | List all flow runs (current and past) with topic, status, progress |
|
|
146
|
+
| \`flow_add\` | Install a new flow from a git URL, local path, or shorthand (e.g. "openspec") |
|
|
147
|
+
| \`flow_remove\` | Remove an installed flow by name (builtin flows cannot be removed) |
|
|
148
|
+
| \`flow_update\` | Update an installed flow to its latest version (git pull / npm update) |
|
|
149
|
+
|
|
150
|
+
### Multi-Root Workspace Support
|
|
151
|
+
|
|
152
|
+
When the IDE workspace contains **multiple repository roots**, flows support cross-repo orchestration:
|
|
153
|
+
|
|
154
|
+
**Detection:** \`flow_list\` and \`flow_status\` return \`allRoots\` — the list of all workspace roots. When \`allRoots.length > 1\`, the workspace is multi-root.
|
|
155
|
+
|
|
156
|
+
**Single-repo task (default):** Omit the \`roots\` parameter — flow creates \`.flows/\` in the primary root only.
|
|
157
|
+
|
|
158
|
+
**Multi-repo task:** Pass \`roots\` to \`flow_start\` listing ALL participating repositories:
|
|
159
|
+
\`\`\`
|
|
160
|
+
flow_start({
|
|
161
|
+
flow: "aikit:advanced",
|
|
162
|
+
topic: "cross-repo-auth",
|
|
163
|
+
roots: ["E:/repos/api-gateway", "E:/repos/auth-service", "E:/repos/shared-types", "E:/repos/frontend"]
|
|
164
|
+
})
|
|
165
|
+
\`\`\`
|
|
166
|
+
This creates \`.flows/cross-repo-auth/\` with synchronized \`meta.json\` in each listed root. Every \`flow_step\`, \`flow_reset\`, and state change is automatically replicated to all roots.
|
|
167
|
+
|
|
168
|
+
**Decision criteria for multi-root flows:**
|
|
169
|
+
|
|
170
|
+
| Signal | Action |
|
|
171
|
+
|--------|--------|
|
|
172
|
+
| Task touches files in 1 repo | Omit \`roots\` (single-root default) |
|
|
173
|
+
| Task touches files in 2+ repos | Pass those repos as \`roots\` |
|
|
174
|
+
| Shared types/contracts change | Include all repos that consume them |
|
|
175
|
+
| Unsure which repos are affected | Use \`blast_radius\` + \`graph\` first, then decide |
|
|
176
|
+
|
|
177
|
+
**Template variables in step instructions:**
|
|
178
|
+
- \`{{workspace_root}}\` — primary root (first in \`roots\` array)
|
|
179
|
+
- \`{{all_roots}}\` — JSON array of all participating roots
|
|
180
|
+
- \`{{artifacts_path}}\` — primary root's \`.flows/<slug>/.spec/\`
|
|
181
|
+
- \`{{run_dir}}\` — primary root's \`.flows/<slug>/\`
|
|
182
|
+
|
|
183
|
+
**Subagent dispatch in multi-root:** When dispatching subagents for a multi-root flow, always include the target root in the prompt:
|
|
184
|
+
\`\`\`
|
|
185
|
+
Scope: E:/repos/auth-service/src/auth.ts
|
|
186
|
+
Root: E:/repos/auth-service
|
|
187
|
+
Artifacts: E:/repos/auth-service/.flows/cross-repo-auth/.spec/
|
|
188
|
+
\`\`\`
|
|
189
|
+
Each subagent operates on ONE root. The Orchestrator coordinates across roots via batched dispatch.
|
|
146
190
|
|
|
147
191
|
## Emergency: STOP → ASSESS → CONTAIN → RECOVER → DOCUMENT
|
|
148
192
|
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{a as e,n as t,r as n}from"./constants-B8_CApx0.js";import{n as r,t as i}from"./templates-ArdAVWoY.js";import{loadAdapter as a,n as o,r as s,smartCopyFromMemory as c,t as l}from"./scaffold-WMQ2uQ48.js";import{existsSync as u,mkdirSync as d,readFileSync as f,rmSync as p,unlinkSync as m,writeFileSync as h}from"node:fs";import{dirname as g,join as _,resolve as v}from"node:path";import{fileURLToPath as y}from"node:url";import{getGlobalDataDir as b,saveRegistry as x}from"../../core/dist/index.js";import{homedir as S}from"node:os";function C(e){let t=e;for(let e=0;e<10;e++){try{let e=_(t,`package.json`);if(u(e)&&JSON.parse(f(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=g(t);if(e===t)break;t=e}return v(e,`..`,`..`,`..`)}function w(){let e=S(),t=process.platform,n=[],r=v(e,`.copilot`),i=v(r,`instructions`),a=v(e,`.claude`),o=v(e,`.cursor`),s=v(e,`.windsurf`);if(t===`win32`){let t=process.env.APPDATA??v(e,`AppData`,`Roaming`);n.push({ide:`VS Code`,configDir:v(t,`Code`,`User`),mcpConfigPath:v(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:v(t,`Code - Insiders`,`User`),mcpConfigPath:v(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:v(t,`VSCodium`,`User`),mcpConfigPath:v(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:v(t,`Cursor`,`User`),mcpConfigPath:v(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:v(t,`Cursor Nightly`,`User`),mcpConfigPath:v(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:v(t,`Windsurf`,`User`),mcpConfigPath:v(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:s,instructionsRoot:null})}else if(t===`darwin`){let t=v(e,`Library`,`Application Support`);n.push({ide:`VS Code`,configDir:v(t,`Code`,`User`),mcpConfigPath:v(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:v(t,`Code - Insiders`,`User`),mcpConfigPath:v(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:v(t,`VSCodium`,`User`),mcpConfigPath:v(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:v(t,`Cursor`,`User`),mcpConfigPath:v(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:v(t,`Cursor Nightly`,`User`),mcpConfigPath:v(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:v(t,`Windsurf`,`User`),mcpConfigPath:v(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:s,instructionsRoot:null})}else{let t=process.env.XDG_CONFIG_HOME??v(e,`.config`);n.push({ide:`VS Code`,configDir:v(t,`Code`,`User`),mcpConfigPath:v(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:v(t,`Code - Insiders`,`User`),mcpConfigPath:v(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:v(t,`VSCodium`,`User`),mcpConfigPath:v(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:v(t,`Cursor`,`User`),mcpConfigPath:v(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:v(t,`Cursor Nightly`,`User`),mcpConfigPath:v(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:v(t,`Windsurf`,`User`),mcpConfigPath:v(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:s,instructionsRoot:null})}return n.push({ide:`Claude Code`,configDir:v(e,`.claude`),mcpConfigPath:v(e,`.claude`,`mcp.json`),globalScaffoldRoot:a,instructionsRoot:null}),n.push({ide:`Copilot CLI`,configDir:r,mcpConfigPath:v(r,`mcp-config.json`),globalScaffoldRoot:null,instructionsRoot:null}),n.filter(e=>u(e.configDir))}function T(e,n,r=!1){let{mcpConfigPath:i,configDir:a}=e,o={...t},s={};if(u(i)){try{let e=f(i,`utf-8`);s=JSON.parse(e)}catch{let e=`${i}.bak`;h(e,f(i,`utf-8`),`utf-8`),console.log(` Backed up invalid ${i} to ${e}`),s={}}if((s.servers??s.mcpServers??{})[n]&&!r){console.log(` ${e.ide}: ${n} already configured (use --force to update)`);return}}let c=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`,`Windsurf`]).has(e.ide)?`servers`:`mcpServers`,l=s[c]??{};e.ide===`Copilot CLI`?l[n]={...o,tools:[`*`]}:l[n]=o,s[c]=l,d(a,{recursive:!0}),h(i,`${JSON.stringify(s,null,2)}\n`,`utf-8`),console.log(` ${e.ide}: configured ${n} in ${i}`)}const E=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function D(t,n=!1){if(!E.has(t.ide))return;let r=v(t.configDir,`settings.json`),i={};if(u(r))try{let e=f(r,`utf-8`);i=JSON.parse(e)}catch{console.log(` ${t.ide}: skipped settings.json (invalid JSON)`);return}let a=!1;for(let[t,r]of Object.entries(e))if(typeof r==`object`&&r){let e=typeof i[t]==`object`&&i[t]!==null?i[t]:{},n={...e,...r};JSON.stringify(n)!==JSON.stringify(e)&&(i[t]=n,a=!0)}else (n||!(t in i))&&(i[t]=r,a=!0);a&&(h(r,`${JSON.stringify(i,null,2)}\n`,`utf-8`),console.log(` ${t.ide}: updated settings.json`))}async function O(e,t,n,f,m=!1){let g=new Set;for(let e of t)e.globalScaffoldRoot&&g.add(e.globalScaffoldRoot);if(g.size===0){console.log(` No IDEs with global scaffold support detected.`);return}let _=await a(e,`copilot`),y=new Map;for(let e of _){let t=e.path.indexOf(`/`);if(t===-1)continue;let n=e.path.substring(0,t);if(n!==`agents`&&n!==`prompts`)continue;let r=y.get(n)??[];r.push({path:e.path.substring(t+1),content:e.content}),y.set(n,r)}let b=await a(e,`skills`),x=new Map;for(let e of b){let t=e.path.indexOf(`/`);if(t===-1)continue;let n=e.path.substring(0,t),r=x.get(n)??[];r.push({path:e.path.substring(t+1),content:e.content}),x.set(n,r)}let C=await a(e,`flows`),w=new Map;for(let e of C){let t=e.path.indexOf(`/`);if(t===-1)continue;let n=e.path.substring(0,t),r=w.get(n)??[];r.push({path:e.path.substring(t+1),content:e.content}),w.set(n,r)}let T=(e,t)=>{let n=y.get(t);if(!n||n.length===0)return;let r=v(e,`.aikit-scaffold.json`),i=o(r)??l(f);i.version=f,c(n,v(e,t),i,t,m),s(r,i)};for(let e of g){T(e,`agents`),T(e,`prompts`);{let t=v(e,`.aikit-scaffold.json`),n=o(t)??l(f);n.version=f;for(let[t,r]of x)c(r,v(e,`skills`,t),n,`skills/${t}`,m);s(t,n)}{let t=v(e,`.aikit-scaffold.json`),n=o(t)??l(f);n.version=f;for(let t of w.keys()){let n=v(e,`flows`,t,`skills`);u(n)&&(p(n,{recursive:!0,force:!0}),console.log(` ${e}: migrated ${t} flow to steps/ layout`))}for(let[t,r]of w)c(r,v(e,`flows`,t),n,`flows/${t}`,m);s(t,n)}console.log(` ${e}: scaffold updated (${x.size} skills)`)}let E=new Set,D=r(`aikit`,n),O=i(`aikit`,n);for(let e of t){if(!e.globalScaffoldRoot)continue;let t=e.globalScaffoldRoot;if(e.ide===`Claude Code`){let e=v(t,`CLAUDE.md`);h(e,`${D}\n---\n\n${O}`,`utf-8`),E.add(e)}else if(e.ide===`VS Code`||e.ide===`VS Code Insiders`||e.ide===`VSCodium`){let n=e.instructionsRoot??t;d(n,{recursive:!0});let r=v(n,`copilot-instructions.md`);E.has(r)||(h(r,`---\napplyTo: "**"\n---\n\n${D}\n---\n\n${O}`,`utf-8`),E.add(r));let i=v(S(),`.github`),a=v(i,`copilot-instructions.md`);E.has(a)||(d(i,{recursive:!0}),h(a,`${D}\n---\n\n${O}`,`utf-8`),E.add(a)),T(e.configDir,`prompts`)}else if(e.ide===`Cursor`||e.ide===`Cursor Nightly`){let e=v(t,`rules`);d(e,{recursive:!0});let n=v(e,`aikit.mdc`);E.has(n)||(h(n,`${D}\n---\n\n${O}`,`utf-8`),E.add(n))}else if(e.ide===`Windsurf`){let e=v(t,`rules`);d(e,{recursive:!0});let n=v(e,`aikit.md`);E.has(n)||(h(n,`${D}\n---\n\n${O}`,`utf-8`),E.add(n))}}E.size>0&&console.log(` Instruction files: ${[...E].join(`, `)}`)}function k(e){let t=[];for(let n of e){if(!n.globalScaffoldRoot)continue;let e=n.globalScaffoldRoot;if(n.ide===`VS Code`||n.ide===`VS Code Insiders`||n.ide===`VSCodium`){let r=n.instructionsRoot??e;t.push(v(r,`kb.instructions.md`)),t.push(v(r,`aikit.instructions.md`))}else n.ide===`Cursor`||n.ide===`Cursor Nightly`?t.push(v(e,`rules`,`kb.mdc`)):n.ide===`Windsurf`&&t.push(v(e,`rules`,`kb.md`))}for(let e of t)u(e)&&(m(e),console.log(` Removed legacy file: ${e}`))}async function A(e){let t=n,r=C(g(y(import.meta.url))),i=JSON.parse(f(v(r,`package.json`),`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${i}...\n`);let a=b();d(a,{recursive:!0}),console.log(` Global data store: ${a}`),x({version:1,workspaces:{}}),console.log(` Created registry.json`);let o=w();if(o.length===0)console.log(`
|
|
2
|
-
No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${o.length} IDE(s):`);for(let n of o)T(n,t,e.force),D(n,e.force)}console.log(`
|
|
3
|
-
Installing scaffold files:`),await O(r,o,t,i,e.force),k(o),console.log(`
|
|
4
|
-
User-level AI Kit installation complete!`),console.log(`
|
|
5
|
-
Next steps:`),console.log(` 1. Open any workspace in your IDE`),console.log(` 2. The AI Kit server will auto-start and index the workspace`),console.log(` 3. Agents, prompts, skills & instructions are available globally`),console.log(` 4. No per-workspace init needed — just open a project and start coding`)}export{A as initUser};
|