ferix-code 0.0.2-beta.21 → 0.0.2-beta.23

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.
Files changed (2) hide show
  1. package/dist/index.js +165 -60
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -74,10 +74,10 @@ init_esm_shims();
74
74
  // ../sync/dist/index.js
75
75
  init_esm_shims();
76
76
 
77
- // ../sync/dist/chunk-63UBJFJU.js
77
+ // ../sync/dist/chunk-XQ7UIC5I.js
78
78
  init_esm_shims();
79
79
 
80
- // ../sync/dist/chunk-SKJVRL7W.js
80
+ // ../sync/dist/chunk-MSWOW6ZJ.js
81
81
  init_esm_shims();
82
82
  import { Schema as S } from "effect";
83
83
  var PackageNameSchema = S.String.pipe(
@@ -112,15 +112,21 @@ var DependenciesSchema = S.Record({
112
112
  key: S.String,
113
113
  value: DependencyVersionSchema
114
114
  });
115
+ var WorkspacesSchema = S.Union(
116
+ S.Array(S.String),
117
+ S.Struct({ packages: S.Array(S.String) })
118
+ );
115
119
  var PackageJsonSchema = S.Struct({
116
120
  name: S.optional(S.String),
117
121
  version: S.optional(S.String),
118
122
  dependencies: S.optional(DependenciesSchema),
119
- devDependencies: S.optional(DependenciesSchema)
123
+ devDependencies: S.optional(DependenciesSchema),
124
+ workspaces: S.optional(WorkspacesSchema)
120
125
  });
121
126
  var SyncOptionsSchema = S.Struct({
122
127
  dryRun: S.optional(S.Boolean),
123
- global: S.optional(S.Boolean)
128
+ global: S.optional(S.Boolean),
129
+ dev: S.optional(S.Boolean)
124
130
  });
125
131
  var InstallOptionsSchema = S.Struct({
126
132
  dryRun: S.optional(S.Boolean),
@@ -130,7 +136,8 @@ var SyncResultSchema = S.Struct({
130
136
  dependencies: S.Array(S.String),
131
137
  orgs: S.Array(S.String),
132
138
  skillRepos: S.Array(SkillRepoSchema),
133
- installed: S.Array(S.String)
139
+ installed: S.Array(S.String),
140
+ packageJsonCount: S.Number
134
141
  });
135
142
  var decodePackageJson = S.decodeUnknown(PackageJsonSchema);
136
143
  var decodePackageOrgsResponse = S.decodeUnknown(
@@ -139,7 +146,9 @@ var decodePackageOrgsResponse = S.decodeUnknown(
139
146
  var decodeSkillReposResponse = S.decodeUnknown(
140
147
  SkillReposResponseSchema
141
148
  );
142
- var CONVEX_URL = "https://benevolent-marmot-861.convex.cloud";
149
+ var CONVEX_URL_PROD = "https://groovy-mallard-649.convex.cloud";
150
+ var CONVEX_URL_DEV = "https://majestic-gnu-964.convex.cloud";
151
+ var getConvexUrl = (dev) => dev ? CONVEX_URL_DEV : CONVEX_URL_PROD;
143
152
  var NON_NPM_VERSION_PREFIXES = [
144
153
  "workspace:",
145
154
  "file:",
@@ -6077,12 +6086,12 @@ var wrapper_default = import_websocket.default;
6077
6086
  var nodeWebSocket = wrapper_default;
6078
6087
  setDefaultWebSocketConstructor(nodeWebSocket);
6079
6088
 
6080
- // ../sync/dist/chunk-63UBJFJU.js
6089
+ // ../sync/dist/chunk-XQ7UIC5I.js
6081
6090
  import { Effect, Schema as S2 } from "effect";
6082
- var findSkillRepos = (orgs) => Effect.gen(function* () {
6091
+ var findSkillRepos = (orgs, dev) => Effect.gen(function* () {
6083
6092
  const response = yield* Effect.tryPromise({
6084
6093
  try: async () => {
6085
- const client = new ConvexHttpClient(CONVEX_URL);
6094
+ const client = new ConvexHttpClient(getConvexUrl(dev));
6086
6095
  return await client.query(api.directories.getByOwners, {
6087
6096
  owners: [...orgs]
6088
6097
  });
@@ -6139,13 +6148,13 @@ var installSkills = (repos, options = {}) => {
6139
6148
  });
6140
6149
  };
6141
6150
 
6142
- // ../sync/dist/chunk-52VC6QQ3.js
6151
+ // ../sync/dist/chunk-BAZKO52B.js
6143
6152
  init_esm_shims();
6144
6153
  import { Effect as Effect3, Schema as S3 } from "effect";
6145
- var resolvePackageOrgs = (packageNames) => Effect3.gen(function* () {
6154
+ var resolvePackageOrgs = (packageNames, dev) => Effect3.gen(function* () {
6146
6155
  const response = yield* Effect3.tryPromise({
6147
6156
  try: async () => {
6148
- const client = new ConvexHttpClient(CONVEX_URL);
6157
+ const client = new ConvexHttpClient(getConvexUrl(dev));
6149
6158
  return await client.action(api.packageOrg.resolve, {
6150
6159
  packageNames: [...packageNames]
6151
6160
  });
@@ -6171,8 +6180,8 @@ var resolvePackageOrgs = (packageNames) => Effect3.gen(function* () {
6171
6180
  });
6172
6181
 
6173
6182
  // ../sync/dist/index.js
6174
- import { access, readFile } from "fs/promises";
6175
- import { resolve } from "path";
6183
+ import { access, readdir, readFile } from "fs/promises";
6184
+ import { dirname, join, resolve } from "path";
6176
6185
  import { Effect as Effect4, Schema as S4 } from "effect";
6177
6186
  var validateFileExists = (filePath) => Effect4.tryPromise({
6178
6187
  try: async () => {
@@ -6227,34 +6236,123 @@ var extractDependencies = (pkg) => {
6227
6236
  }
6228
6237
  return Array.from(allDeps.keys());
6229
6238
  };
6230
- var emptyResult = (dependencies = [], orgs = []) => ({
6239
+ var emptyResult = (dependencies = [], orgs = [], packageJsonCount = 1) => ({
6231
6240
  dependencies: [...dependencies],
6232
6241
  orgs: [...orgs],
6233
6242
  skillRepos: [],
6234
- installed: []
6243
+ installed: [],
6244
+ packageJsonCount
6235
6245
  });
6236
6246
  var toMutableSkillRepos = (repos) => repos.map((r) => ({ owner: r.owner, repo: r.repo, githubUrl: r.githubUrl }));
6247
+ var extractWorkspacePatterns = (pkg) => {
6248
+ const workspaces = pkg.workspaces;
6249
+ if (!workspaces) {
6250
+ return [];
6251
+ }
6252
+ if (Array.isArray(workspaces)) {
6253
+ return workspaces.filter((w) => typeof w === "string");
6254
+ }
6255
+ if (typeof workspaces === "object" && "packages" in workspaces) {
6256
+ const packages = workspaces.packages;
6257
+ if (Array.isArray(packages)) {
6258
+ return packages.filter((w) => typeof w === "string");
6259
+ }
6260
+ }
6261
+ return [];
6262
+ };
6263
+ var expandGlobPattern = async (rootDir, pattern) => {
6264
+ if (pattern.endsWith("/*")) {
6265
+ const baseDir = pattern.slice(0, -2);
6266
+ const fullPath2 = join(rootDir, baseDir);
6267
+ try {
6268
+ const entries = await readdir(fullPath2, { withFileTypes: true });
6269
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => join(fullPath2, entry.name));
6270
+ } catch {
6271
+ return [];
6272
+ }
6273
+ }
6274
+ if (pattern.endsWith("/**")) {
6275
+ const baseDir = pattern.slice(0, -3);
6276
+ const fullPath2 = join(rootDir, baseDir);
6277
+ try {
6278
+ const entries = await readdir(fullPath2, { withFileTypes: true });
6279
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => join(fullPath2, entry.name));
6280
+ } catch {
6281
+ return [];
6282
+ }
6283
+ }
6284
+ const fullPath = join(rootDir, pattern);
6285
+ try {
6286
+ await access(fullPath);
6287
+ return [fullPath];
6288
+ } catch {
6289
+ return [];
6290
+ }
6291
+ };
6292
+ var discoverPackageJsonFiles = (rootPath, rootPkg) => Effect4.tryPromise({
6293
+ try: async () => {
6294
+ const rootDir = dirname(rootPath);
6295
+ const patterns = extractWorkspacePatterns(rootPkg);
6296
+ if (patterns.length === 0) {
6297
+ return [rootPath];
6298
+ }
6299
+ const packageJsonPaths = [rootPath];
6300
+ for (const pattern of patterns) {
6301
+ const dirs = await expandGlobPattern(rootDir, pattern);
6302
+ for (const dir of dirs) {
6303
+ const pkgPath = join(dir, "package.json");
6304
+ try {
6305
+ await access(pkgPath);
6306
+ packageJsonPaths.push(pkgPath);
6307
+ } catch {
6308
+ }
6309
+ }
6310
+ }
6311
+ return packageJsonPaths;
6312
+ },
6313
+ catch: (error) => new PackageJsonError({
6314
+ message: `Failed to discover workspace packages: ${error instanceof Error ? error.message : String(error)}`,
6315
+ path: rootPath,
6316
+ cause: error
6317
+ })
6318
+ });
6319
+ var readPackageJson = (filePath) => Effect4.gen(function* () {
6320
+ const content = yield* readFileContent(filePath);
6321
+ const json = yield* parseJson(content, filePath);
6322
+ return yield* validatePackageJson(json, filePath);
6323
+ });
6237
6324
  var sync = (packageJsonPath, options = {}) => Effect4.gen(function* () {
6238
6325
  const absolutePath = yield* validateFileExists(packageJsonPath);
6239
- const content = yield* readFileContent(absolutePath);
6240
- const json = yield* parseJson(content, absolutePath);
6241
- const pkg = yield* validatePackageJson(json, absolutePath);
6242
- const dependencies = extractDependencies(pkg);
6326
+ const rootPkg = yield* readPackageJson(absolutePath);
6327
+ const packageJsonPaths = yield* discoverPackageJsonFiles(
6328
+ absolutePath,
6329
+ rootPkg
6330
+ );
6331
+ const packageJsonCount = packageJsonPaths.length;
6332
+ const allDependencies = /* @__PURE__ */ new Set();
6333
+ for (const pkgPath of packageJsonPaths) {
6334
+ const pkg = yield* readPackageJson(pkgPath);
6335
+ const deps = extractDependencies(pkg);
6336
+ for (const dep of deps) {
6337
+ allDependencies.add(dep);
6338
+ }
6339
+ }
6340
+ const dependencies = Array.from(allDependencies);
6243
6341
  if (dependencies.length === 0) {
6244
- return emptyResult();
6342
+ return emptyResult([], [], packageJsonCount);
6245
6343
  }
6246
- const packageOrgs = yield* resolvePackageOrgs(dependencies);
6344
+ const packageOrgs = yield* resolvePackageOrgs(dependencies, options.dev);
6247
6345
  const orgs = Array.from(
6248
6346
  new Set(
6249
6347
  packageOrgs.map((p) => p.githubOrg).filter((org) => org !== null)
6250
6348
  )
6251
6349
  );
6252
6350
  if (orgs.length === 0) {
6253
- return emptyResult([...dependencies]);
6351
+ return emptyResult([...dependencies], [], packageJsonCount);
6254
6352
  }
6255
- const skillRepos = yield* findSkillRepos(orgs);
6353
+ const skillRepos = yield* findSkillRepos(orgs, options.dev);
6256
6354
  if (skillRepos.length === 0) {
6257
- return emptyResult([...dependencies], orgs);
6355
+ return emptyResult([...dependencies], orgs, packageJsonCount);
6258
6356
  }
6259
6357
  const installed = yield* installSkills(skillRepos, {
6260
6358
  dryRun: options.dryRun,
@@ -6264,7 +6362,8 @@ var sync = (packageJsonPath, options = {}) => Effect4.gen(function* () {
6264
6362
  dependencies: [...dependencies],
6265
6363
  orgs,
6266
6364
  skillRepos: toMutableSkillRepos(skillRepos),
6267
- installed: [...installed]
6365
+ installed: [...installed],
6366
+ packageJsonCount
6268
6367
  };
6269
6368
  });
6270
6369
 
@@ -6276,7 +6375,7 @@ import pc17 from "picocolors";
6276
6375
  // package.json
6277
6376
  var package_default = {
6278
6377
  name: "ferix-code",
6279
- version: "0.0.2-beta.21",
6378
+ version: "0.0.2-beta.23",
6280
6379
  description: "Composable RALPH loops for AI coding agents - v2 with Effect",
6281
6380
  type: "module",
6282
6381
  bin: {
@@ -8785,7 +8884,7 @@ import {
8785
8884
  readFile as readFile2,
8786
8885
  rm
8787
8886
  } from "fs/promises";
8788
- import { dirname, join } from "path";
8887
+ import { dirname as dirname2, join as join2 } from "path";
8789
8888
  import { promisify as promisify2 } from "util";
8790
8889
  import { Effect as Effect8, Layer } from "effect";
8791
8890
 
@@ -8831,7 +8930,7 @@ var WORKTREES_DIR = ".ferix/worktrees";
8831
8930
  var GITDIR_REGEX = /^gitdir:\s*(.+)$/m;
8832
8931
  var BRANCH_PREFIX = "ferix";
8833
8932
  function getWorktreeDir(sessionId) {
8834
- return join(process.cwd(), WORKTREES_DIR, sessionId);
8933
+ return join2(process.cwd(), WORKTREES_DIR, sessionId);
8835
8934
  }
8836
8935
  function getBranchName(sessionId) {
8837
8936
  return `${BRANCH_PREFIX}/${sessionId}`;
@@ -8895,11 +8994,11 @@ function copyUntrackedFiles(worktreeDir) {
8895
8994
  return;
8896
8995
  }
8897
8996
  for (const file of untrackedFiles) {
8898
- const srcPath = join(process.cwd(), file);
8899
- const destPath = join(worktreeDir, file);
8997
+ const srcPath = join2(process.cwd(), file);
8998
+ const destPath = join2(worktreeDir, file);
8900
8999
  yield* Effect8.tryPromise({
8901
9000
  try: async () => {
8902
- await mkdir(dirname(destPath), { recursive: true });
9001
+ await mkdir(dirname2(destPath), { recursive: true });
8903
9002
  await copyFile(srcPath, destPath);
8904
9003
  },
8905
9004
  catch: () => new GitError({
@@ -8910,7 +9009,7 @@ function copyUntrackedFiles(worktreeDir) {
8910
9009
  }
8911
9010
  yield* Effect8.tryPromise({
8912
9011
  try: async () => {
8913
- const gitFilePath = join(worktreeDir, ".git");
9012
+ const gitFilePath = join2(worktreeDir, ".git");
8914
9013
  const gitFileContent = await readFile2(gitFilePath, "utf-8");
8915
9014
  const gitDirMatch = gitFileContent.match(GITDIR_REGEX);
8916
9015
  const gitDirPath = gitDirMatch?.[1]?.trim();
@@ -8918,8 +9017,8 @@ function copyUntrackedFiles(worktreeDir) {
8918
9017
  return;
8919
9018
  }
8920
9019
  const gitDir = gitDirPath;
8921
- const excludePath = join(gitDir, "info", "exclude");
8922
- await mkdir(dirname(excludePath), { recursive: true });
9020
+ const excludePath = join2(gitDir, "info", "exclude");
9021
+ await mkdir(dirname2(excludePath), { recursive: true });
8923
9022
  const excludeContent = "\n# Untracked files copied from main worktree (auto-generated by ferix)\n" + untrackedFiles.join("\n") + "\n";
8924
9023
  await appendFile(excludePath, excludeContent);
8925
9024
  },
@@ -8934,7 +9033,7 @@ var make = {
8934
9033
  createWorktree: (sessionId, baseBranch) => Effect8.gen(function* () {
8935
9034
  const worktreeDir = getWorktreeDir(sessionId);
8936
9035
  const branchName = getBranchName(sessionId);
8937
- const worktreesBase = join(process.cwd(), WORKTREES_DIR);
9036
+ const worktreesBase = join2(process.cwd(), WORKTREES_DIR);
8938
9037
  yield* Effect8.tryPromise({
8939
9038
  try: () => mkdir(worktreesBase, { recursive: true }),
8940
9039
  catch: (error) => new GitError({
@@ -9311,7 +9410,7 @@ var MemoryGit = {
9311
9410
  // src/layers/guardrails/file-system.ts
9312
9411
  init_esm_shims();
9313
9412
  import { mkdir as mkdir2, readFile as readFile3, writeFile } from "fs/promises";
9314
- import { join as join2 } from "path";
9413
+ import { join as join3 } from "path";
9315
9414
  import { DateTime, Effect as Effect10, Layer as Layer3 } from "effect";
9316
9415
 
9317
9416
  // src/domain/index.ts
@@ -10333,10 +10432,10 @@ function ensureDir(dirPath) {
10333
10432
  }).pipe(Effect10.asVoid);
10334
10433
  }
10335
10434
  function getSessionDir(sessionId) {
10336
- return join2(process.cwd(), PLANS_DIR, sessionId);
10435
+ return join3(process.cwd(), PLANS_DIR, sessionId);
10337
10436
  }
10338
10437
  function getGuardrailsPath(sessionId) {
10339
- return join2(getSessionDir(sessionId), "guardrails.json");
10438
+ return join3(getSessionDir(sessionId), "guardrails.json");
10340
10439
  }
10341
10440
  function serializeGuardrails(guardrails) {
10342
10441
  return JSON.stringify(guardrails, null, 2);
@@ -10982,8 +11081,8 @@ function createProviderLayer2(name) {
10982
11081
 
10983
11082
  // src/layers/plan/file-system.ts
10984
11083
  init_esm_shims();
10985
- import { access as access3, mkdir as mkdir3, readdir, readFile as readFile4, writeFile as writeFile2 } from "fs/promises";
10986
- import { join as join3 } from "path";
11084
+ import { access as access3, mkdir as mkdir3, readdir as readdir2, readFile as readFile4, writeFile as writeFile2 } from "fs/promises";
11085
+ import { join as join4 } from "path";
10987
11086
  import { Effect as Effect16, Layer as Layer7 } from "effect";
10988
11087
 
10989
11088
  // src/services/plan-store.ts
@@ -11005,10 +11104,10 @@ function ensureDir2(dirPath) {
11005
11104
  }).pipe(Effect16.asVoid);
11006
11105
  }
11007
11106
  function getSessionDir2(sessionId) {
11008
- return join3(process.cwd(), PLANS_DIR2, sessionId);
11107
+ return join4(process.cwd(), PLANS_DIR2, sessionId);
11009
11108
  }
11010
11109
  function getPlanPath(sessionId, planId) {
11011
- return join3(getSessionDir2(sessionId), `${planId}.json`);
11110
+ return join4(getSessionDir2(sessionId), `${planId}.json`);
11012
11111
  }
11013
11112
  function generatePlanId(taskNumber) {
11014
11113
  return PlanId(`task-${taskNumber}`);
@@ -11048,7 +11147,7 @@ var make3 = {
11048
11147
  const existingPlans = yield* Effect16.tryPromise({
11049
11148
  try: async () => {
11050
11149
  try {
11051
- const files = await readdir(sessionDir);
11150
+ const files = await readdir2(sessionDir);
11052
11151
  return files.filter((f) => f.endsWith(".json")).length;
11053
11152
  } catch {
11054
11153
  return 0;
@@ -11087,8 +11186,8 @@ var make3 = {
11087
11186
  }
11088
11187
  const sessionDirs = yield* Effect16.tryPromise({
11089
11188
  try: async () => {
11090
- const plansDir = join3(process.cwd(), PLANS_DIR2);
11091
- const dirs = await readdir(plansDir);
11189
+ const plansDir = join4(process.cwd(), PLANS_DIR2);
11190
+ const dirs = await readdir2(plansDir);
11092
11191
  return dirs;
11093
11192
  },
11094
11193
  catch: (error) => new PlanStoreError({
@@ -11144,7 +11243,7 @@ var make3 = {
11144
11243
  const files = yield* Effect16.tryPromise({
11145
11244
  try: async () => {
11146
11245
  try {
11147
- return await readdir(sessionDir);
11246
+ return await readdir2(sessionDir);
11148
11247
  } catch {
11149
11248
  return [];
11150
11249
  }
@@ -11253,7 +11352,7 @@ var MemoryPlan = {
11253
11352
  // src/layers/progress/file-system.ts
11254
11353
  init_esm_shims();
11255
11354
  import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
11256
- import { join as join4 } from "path";
11355
+ import { join as join5 } from "path";
11257
11356
  import { DateTime as DateTime3, Effect as Effect18, Layer as Layer9 } from "effect";
11258
11357
 
11259
11358
  // src/services/progress-store.ts
@@ -11275,10 +11374,10 @@ function ensureDir3(dirPath) {
11275
11374
  }).pipe(Effect18.asVoid);
11276
11375
  }
11277
11376
  function getSessionDir3(sessionId) {
11278
- return join4(process.cwd(), PLANS_DIR3, sessionId);
11377
+ return join5(process.cwd(), PLANS_DIR3, sessionId);
11279
11378
  }
11280
11379
  function getProgressPath(sessionId) {
11281
- return join4(getSessionDir3(sessionId), "progress.json");
11380
+ return join5(getSessionDir3(sessionId), "progress.json");
11282
11381
  }
11283
11382
  function serializeProgress(progress) {
11284
11383
  return JSON.stringify(progress, null, 2);
@@ -11457,7 +11556,7 @@ var MemoryProgress = {
11457
11556
  // src/layers/session/file-system.ts
11458
11557
  init_esm_shims();
11459
11558
  import { mkdir as mkdir5, readFile as readFile6, writeFile as writeFile4 } from "fs/promises";
11460
- import { join as join5 } from "path";
11559
+ import { join as join6 } from "path";
11461
11560
  import { DateTime as DateTime5, Effect as Effect20, Layer as Layer11 } from "effect";
11462
11561
  import { humanId } from "human-id";
11463
11562
 
@@ -11484,7 +11583,7 @@ function ensureDir4(dirPath) {
11484
11583
  }).pipe(Effect20.asVoid);
11485
11584
  }
11486
11585
  function getSessionPath(sessionId) {
11487
- return join5(process.cwd(), SESSIONS_DIR, `${sessionId}.json`);
11586
+ return join6(process.cwd(), SESSIONS_DIR, `${sessionId}.json`);
11488
11587
  }
11489
11588
  function serializeSession(session) {
11490
11589
  return JSON.stringify(session, null, 2);
@@ -11513,7 +11612,7 @@ function deserializeSession(json) {
11513
11612
  }
11514
11613
  var make5 = {
11515
11614
  create: (originalTask) => Effect20.gen(function* () {
11516
- const sessionsDir = join5(process.cwd(), SESSIONS_DIR);
11615
+ const sessionsDir = join6(process.cwd(), SESSIONS_DIR);
11517
11616
  yield* ensureDir4(sessionsDir);
11518
11617
  const now = yield* DateTime5.now;
11519
11618
  const timestampMs = DateTime5.toEpochMillis(now);
@@ -12259,7 +12358,7 @@ import { DateTime as DateTime8, Effect as Effect25, pipe, Ref as Ref10, Stream a
12259
12358
  // src/layers/plan/task-generation.ts
12260
12359
  init_esm_shims();
12261
12360
  import { mkdir as mkdir6, readFile as readFile7, writeFile as writeFile5 } from "fs/promises";
12262
- import { join as join6 } from "path";
12361
+ import { join as join7 } from "path";
12263
12362
  import { Effect as Effect23 } from "effect";
12264
12363
  var PLANS_DIR4 = ".ferix/plans";
12265
12364
  function ensureDir5(dirPath) {
@@ -12273,10 +12372,10 @@ function ensureDir5(dirPath) {
12273
12372
  }).pipe(Effect23.asVoid);
12274
12373
  }
12275
12374
  function getSessionDir4(sessionId) {
12276
- return join6(process.cwd(), PLANS_DIR4, sessionId);
12375
+ return join7(process.cwd(), PLANS_DIR4, sessionId);
12277
12376
  }
12278
12377
  function getTasksMdPath(sessionId) {
12279
- return join6(getSessionDir4(sessionId), "tasks.md");
12378
+ return join7(getSessionDir4(sessionId), "tasks.md");
12280
12379
  }
12281
12380
  function writeTasksMd(sessionId, tasks) {
12282
12381
  return Effect23.gen(function* () {
@@ -13855,17 +13954,23 @@ program.command("run", { isDefault: true }).argument("<task>", "Task description
13855
13954
  process.exit(1);
13856
13955
  }
13857
13956
  });
13858
- program.command("sync").description("Discover and install skills based on your dependencies").option("-p, --path <path>", "Path to package.json", "./package.json").option("-d, --dry-run", "List skills without installing").option("-g, --global", "Install globally instead of project-level").action(async (options) => {
13957
+ program.command("sync").description("Discover and install skills based on your dependencies").option("-p, --path <path>", "Path to package.json", "./package.json").option("-n, --dry-run", "List skills without installing").option("-g, --global", "Install globally instead of project-level").option("-d, --dev", "Use development server instead of production").action(async (options) => {
13859
13958
  try {
13860
- console.log("\nScanning package.json...");
13959
+ console.log("\nScanning for package.json files...");
13861
13960
  const result = await Effect29.runPromise(
13862
13961
  sync(options.path, {
13863
13962
  dryRun: options.dryRun ?? false,
13864
- global: options.global ?? false
13963
+ global: options.global ?? false,
13964
+ dev: options.dev ?? false
13865
13965
  })
13866
13966
  );
13967
+ if (options.dev) {
13968
+ console.log(pc17.yellow("Using development server"));
13969
+ }
13970
+ const packageMsg = result.packageJsonCount > 1 ? `Found ${pc17.bold(String(result.packageJsonCount))} package.json files (monorepo)` : "Found 1 package.json file";
13971
+ console.log(packageMsg);
13867
13972
  console.log(
13868
- `Found ${pc17.bold(String(result.dependencies.length))} dependencies`
13973
+ `Found ${pc17.bold(String(result.dependencies.length))} dependencies (deduplicated)`
13869
13974
  );
13870
13975
  console.log(
13871
13976
  `Resolved ${pc17.bold(String(result.orgs.length))} unique GitHub organizations`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ferix-code",
3
- "version": "0.0.2-beta.21",
3
+ "version": "0.0.2-beta.23",
4
4
  "description": "Composable RALPH loops for AI coding agents - v2 with Effect",
5
5
  "type": "module",
6
6
  "bin": {