@nuucognition/flint-cli 0.4.0-alpha.0 → 0.4.0-alpha.2

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.
@@ -31,7 +31,6 @@ import {
31
31
  readFlintToml,
32
32
  removeShardFromConfig,
33
33
  resolveShardMode,
34
- stampSynced,
35
34
  toKebabCase,
36
35
  writeFlintJson,
37
36
  writeFlintToml
@@ -2450,12 +2449,12 @@ async function createRepository(flintPath, name, remote) {
2450
2449
  if (await pathExists2(repoPath)) {
2451
2450
  throw new Error(`Repository folder already exists: ${repoPath}`);
2452
2451
  }
2452
+ if (remote) {
2453
+ return cloneRepository(flintPath, name, remote);
2454
+ }
2453
2455
  await mkdir42(repoPath, { recursive: true });
2454
2456
  try {
2455
2457
  await execAsync2("git init", { cwd: repoPath });
2456
- if (remote) {
2457
- await execAsync2(`git remote add origin "${remote}"`, { cwd: repoPath });
2458
- }
2459
2458
  } catch (error) {
2460
2459
  const message = error instanceof Error ? error.message : String(error);
2461
2460
  await rm6(repoPath, { recursive: true, force: true });
@@ -2489,6 +2488,12 @@ async function removeRepositoryFolder(flintPath, name) {
2489
2488
  async function updateRepository(flintPath, name, url) {
2490
2489
  const repoPath = getRepositoryPath(flintPath, name);
2491
2490
  if (await pathExists2(repoPath)) {
2491
+ try {
2492
+ await execAsync2("git rev-parse HEAD", { cwd: repoPath });
2493
+ } catch {
2494
+ await rm6(repoPath, { recursive: true, force: true });
2495
+ return cloneRepository(flintPath, name, url);
2496
+ }
2492
2497
  await execAsync2("git pull", { cwd: repoPath });
2493
2498
  return repoPath;
2494
2499
  }
@@ -4661,13 +4666,14 @@ async function getGitStatus(flintPath) {
4661
4666
  };
4662
4667
  }
4663
4668
  }
4664
- async function runGit(flintPath, args) {
4669
+ async function runGit(flintPath, args, options) {
4665
4670
  try {
4666
4671
  const quotedArgs = args.map(
4667
4672
  (arg) => arg.includes(" ") ? `"${arg}"` : arg
4668
4673
  );
4669
4674
  const { stdout, stderr } = await execAsync4(`git ${quotedArgs.join(" ")}`, {
4670
- cwd: flintPath
4675
+ cwd: flintPath,
4676
+ env: options?.env ? { ...process.env, ...options.env } : void 0
4671
4677
  });
4672
4678
  return { success: true, output: stdout || stderr };
4673
4679
  } catch (err) {
@@ -4713,6 +4719,82 @@ async function getCurrentBranch(cwd) {
4713
4719
  const result = await runGit(cwd, ["branch", "--show-current"]);
4714
4720
  return result.success ? result.output.trim() || null : null;
4715
4721
  }
4722
+ async function isRebaseInProgress(cwd) {
4723
+ const result = await runGit(cwd, ["rev-parse", "--git-path", "rebase-merge"]);
4724
+ if (result.success) {
4725
+ const { access: access5 } = await import("fs/promises");
4726
+ const path = await import("path");
4727
+ const rebasePath = path.resolve(cwd, result.output.trim());
4728
+ try {
4729
+ await access5(rebasePath);
4730
+ return true;
4731
+ } catch {
4732
+ }
4733
+ }
4734
+ const result2 = await runGit(cwd, ["rev-parse", "--git-path", "rebase-apply"]);
4735
+ if (result2.success) {
4736
+ const { access: access5 } = await import("fs/promises");
4737
+ const path = await import("path");
4738
+ const rebasePath = path.resolve(cwd, result2.output.trim());
4739
+ try {
4740
+ await access5(rebasePath);
4741
+ return true;
4742
+ } catch {
4743
+ return false;
4744
+ }
4745
+ }
4746
+ return false;
4747
+ }
4748
+ async function getRebaseBranch(cwd) {
4749
+ const result = await runGit(cwd, ["rev-parse", "--git-path", "rebase-merge/head-name"]);
4750
+ if (result.success) {
4751
+ const { readFile: readFile9 } = await import("fs/promises");
4752
+ const path = await import("path");
4753
+ const headNamePath = path.resolve(cwd, result.output.trim());
4754
+ try {
4755
+ const ref = (await readFile9(headNamePath, "utf-8")).trim();
4756
+ return ref.replace(/^refs\/heads\//, "");
4757
+ } catch {
4758
+ }
4759
+ }
4760
+ return null;
4761
+ }
4762
+ async function getConflictFiles(cwd) {
4763
+ const result = await runGit(cwd, ["diff", "--name-only", "--diff-filter=U"]);
4764
+ if (result.success && result.output.trim()) {
4765
+ return result.output.trim().split("\n").filter(Boolean);
4766
+ }
4767
+ return [];
4768
+ }
4769
+ async function hasConflictMarkers(cwd, files) {
4770
+ const { readFile: readFile9 } = await import("fs/promises");
4771
+ const path = await import("path");
4772
+ let filesToCheck = files;
4773
+ if (!filesToCheck || filesToCheck.length === 0) {
4774
+ const result = await runGit(cwd, ["diff", "--name-only", "HEAD"]);
4775
+ if (result.success && result.output.trim()) {
4776
+ filesToCheck = result.output.trim().split("\n").filter(Boolean);
4777
+ } else {
4778
+ const staged = await runGit(cwd, ["diff", "--name-only", "--cached"]);
4779
+ if (staged.success && staged.output.trim()) {
4780
+ filesToCheck = staged.output.trim().split("\n").filter(Boolean);
4781
+ } else {
4782
+ return [];
4783
+ }
4784
+ }
4785
+ }
4786
+ const conflicted = [];
4787
+ for (const file of filesToCheck) {
4788
+ try {
4789
+ const content = await readFile9(path.resolve(cwd, file), "utf-8");
4790
+ if (content.includes("<<<<<<<") && content.includes("=======") && content.includes(">>>>>>>")) {
4791
+ conflicted.push(file);
4792
+ }
4793
+ } catch {
4794
+ }
4795
+ }
4796
+ return conflicted;
4797
+ }
4716
4798
  async function hasUncommittedChanges(cwd) {
4717
4799
  const result = await runGit(cwd, ["status", "--porcelain"]);
4718
4800
  return result.success && result.output.trim().length > 0;
@@ -5152,10 +5234,6 @@ async function syncFlint(flintPath, progress) {
5152
5234
  error: `Failed to update .gitignore: ${err instanceof Error ? err.message : String(err)}`
5153
5235
  });
5154
5236
  }
5155
- try {
5156
- await stampSynced(currentFlintPath);
5157
- } catch {
5158
- }
5159
5237
  return result;
5160
5238
  }
5161
5239
  var __dirname = dirname5(fileURLToPath(import.meta.url));
@@ -6018,6 +6096,10 @@ export {
6018
6096
  pushTags,
6019
6097
  pushWithTags,
6020
6098
  getCurrentBranch,
6099
+ isRebaseInProgress,
6100
+ getRebaseBranch,
6101
+ getConflictFiles,
6102
+ hasConflictMarkers,
6021
6103
  hasUncommittedChanges,
6022
6104
  hasUnpushedCommits,
6023
6105
  getRemoteUrl,
@@ -42,6 +42,7 @@ import {
42
42
  getCodebaseMetadataDir,
43
43
  getCodebaseMetadataPath,
44
44
  getConfigValue,
45
+ getConflictFiles,
45
46
  getCurrentBranch,
46
47
  getFlintConfigDir,
47
48
  getFlintDeclarations,
@@ -57,6 +58,7 @@ import {
57
58
  getOpenApps,
58
59
  getPersonFilePath,
59
60
  getPreset,
61
+ getRebaseBranch,
60
62
  getReferencesMetadataDir,
61
63
  getRemoteUrl,
62
64
  getRepositoryPath,
@@ -75,6 +77,7 @@ import {
75
77
  getUnfulfilledFlints,
76
78
  getWorkspaceRepositoriesDir,
77
79
  groupIntoTurns,
80
+ hasConflictMarkers,
78
81
  hasPreset,
79
82
  hasShardScripts,
80
83
  hasUncommittedChanges,
@@ -88,6 +91,7 @@ import {
88
91
  isInsideFlint,
89
92
  isInsideMesh,
90
93
  isOwnerRepo,
94
+ isRebaseInProgress,
91
95
  isShardInstalled,
92
96
  isValidFlint,
93
97
  isValidStatus,
@@ -147,7 +151,7 @@ import {
147
151
  writeIdentityState,
148
152
  writeReferencesState,
149
153
  writeSession
150
- } from "./chunk-S2CPVR65.js";
154
+ } from "./chunk-TTXIQOT3.js";
151
155
  import {
152
156
  runConcurrent
153
157
  } from "./chunk-V7YA5RXL.js";
@@ -311,6 +315,7 @@ export {
311
315
  getCodebaseMetadataDir,
312
316
  getCodebaseMetadataPath,
313
317
  getConfigValue,
318
+ getConflictFiles,
314
319
  getCurrentBranch,
315
320
  getExportDeclarations,
316
321
  getFlintConfigDir,
@@ -340,6 +345,7 @@ export {
340
345
  getOpenApps,
341
346
  getPersonFilePath,
342
347
  getPreset,
348
+ getRebaseBranch,
343
349
  getRemoteUrl,
344
350
  getRepositoryPath,
345
351
  getRepositoryStatus,
@@ -369,6 +375,7 @@ export {
369
375
  getWorkspaceRepositoriesDir,
370
376
  getWorkspaceRepository,
371
377
  groupIntoTurns,
378
+ hasConflictMarkers,
372
379
  hasFlintJson,
373
380
  hasFlintToml,
374
381
  hasMigration,
@@ -389,6 +396,7 @@ export {
389
396
  isLocalShard,
390
397
  isOwnerRepo,
391
398
  isPathRegistered,
399
+ isRebaseInProgress,
392
400
  isShardInstalled,
393
401
  isValidFlint,
394
402
  isValidStatus,
package/dist/index.js CHANGED
@@ -20,11 +20,13 @@ import {
20
20
  freezeShard,
21
21
  fulfillCodebase,
22
22
  getCodebaseDeclarations,
23
+ getConflictFiles,
23
24
  getCurrentBranch,
24
25
  getGitStatus,
25
26
  getIdentity,
26
27
  getInstalledShardsWithVersions,
27
28
  getPreset,
29
+ getRebaseBranch,
28
30
  getRemoteUrl,
29
31
  getRepositoryStatus,
30
32
  getSessionPath,
@@ -33,6 +35,7 @@ import {
33
35
  getStatus,
34
36
  getTypePrefix,
35
37
  getUnfulfilledCodebases,
38
+ hasConflictMarkers,
36
39
  hasUncommittedChanges,
37
40
  hasUnpushedCommits,
38
41
  healAllShards,
@@ -42,6 +45,7 @@ import {
42
45
  isGitHubSourceSpecifier,
43
46
  isGitInitialized,
44
47
  isOwnerRepo,
48
+ isRebaseInProgress,
45
49
  isValidStatus,
46
50
  listPresets,
47
51
  listRemoteVersionTags,
@@ -77,7 +81,7 @@ import {
77
81
  updateSession,
78
82
  updateShards,
79
83
  updateSourceRepository
80
- } from "./chunk-S2CPVR65.js";
84
+ } from "./chunk-TTXIQOT3.js";
81
85
  import "./chunk-V7YA5RXL.js";
82
86
  import {
83
87
  findFlintByName,
@@ -3219,7 +3223,7 @@ Failed to fetch published shards: ${msg}`));
3219
3223
  return cmd;
3220
3224
  })()
3221
3225
  ).addCommand(
3222
- new Command5("release").description("Tag and publish a version from a dev shard").argument("<name>", "Shard name").argument("<version>", "Version to release (e.g. 0.3.0)").option("-p, --path <dir>", "Path to flint").action(async (name, version, options) => {
3226
+ new Command5("release").description("Tag and publish a version from a dev shard (version derived from shard.yaml)").argument("<name>", "Shard name").argument("[version]", "Version to release (default: read from shard.yaml)").option("-p, --path <dir>", "Path to flint").action(async (name, version, options) => {
3223
3227
  try {
3224
3228
  const flintPath = await resolveFlint(options.path);
3225
3229
  const installed = await getInstalledShardsWithVersions(flintPath);
@@ -3251,12 +3255,13 @@ Shard not found: "${name}"`));
3251
3255
  Could not read version from shard.yaml`));
3252
3256
  process.exit(1);
3253
3257
  }
3254
- if (manifest.version !== version) {
3258
+ if (version && manifest.version !== version) {
3255
3259
  console.error(pc8.red(`
3256
3260
  Version mismatch: shard.yaml says "${manifest.version}" but you requested "${version}"`));
3257
3261
  console.log(pc8.dim(` Update shard.yaml version first, then run release again.`));
3258
3262
  process.exit(1);
3259
3263
  }
3264
+ version = manifest.version;
3260
3265
  const dirty = await hasUncommittedChanges(shardPath);
3261
3266
  if (dirty) {
3262
3267
  console.error(pc8.red(`
@@ -3730,6 +3735,11 @@ async function handleSync(flintPath, customMessage) {
3730
3735
  console.error(pc10.red("Git not initialized. Run `flint git init` first."));
3731
3736
  process.exit(1);
3732
3737
  }
3738
+ const rebasing = await isRebaseInProgress(flintPath);
3739
+ if (rebasing) {
3740
+ await handleRebaseContinue(flintPath);
3741
+ return;
3742
+ }
3733
3743
  try {
3734
3744
  console.log(pc10.dim("Running flint sync..."));
3735
3745
  await syncFlint(flintPath);
@@ -3770,7 +3780,15 @@ async function handleSync(flintPath, customMessage) {
3770
3780
  const pull = await runGit(flintPath, ["pull", "--rebase", "origin", branch]);
3771
3781
  if (!pull.success) {
3772
3782
  if (pull.error?.includes("CONFLICT") || pull.error?.includes("conflict")) {
3773
- console.error(pc10.red("Merge conflict detected. Resolve conflicts manually, then run `flint git sync` again."));
3783
+ const conflicts = await getConflictFiles(flintPath);
3784
+ console.error(pc10.red("\nMerge conflict detected. Resolve these files:"));
3785
+ console.log();
3786
+ for (const file of conflicts) {
3787
+ console.log(pc10.yellow(` ${file}`));
3788
+ }
3789
+ console.log();
3790
+ console.log(pc10.dim("Edit the files above to remove conflict markers (<<<<<<< / ======= / >>>>>>>)"));
3791
+ console.log(pc10.dim("Then run `flint git sync` again to continue."));
3774
3792
  process.exit(1);
3775
3793
  }
3776
3794
  const pullRetry = await runGit(flintPath, ["pull", "--rebase"]);
@@ -3782,6 +3800,57 @@ async function handleSync(flintPath, customMessage) {
3782
3800
  }
3783
3801
  }
3784
3802
  console.log(pc10.green("\u2713 Pulled"));
3803
+ await pushToRemote(flintPath, branch);
3804
+ console.log();
3805
+ console.log(pc10.bold("Sync complete."));
3806
+ }
3807
+ async function handleRebaseContinue(flintPath) {
3808
+ console.log(pc10.dim("Rebase in progress \u2014 continuing..."));
3809
+ const markerFiles = await hasConflictMarkers(flintPath);
3810
+ if (markerFiles.length > 0) {
3811
+ console.error(pc10.red("\nFiles still contain conflict markers:"));
3812
+ console.log();
3813
+ for (const file of markerFiles) {
3814
+ console.log(pc10.yellow(` ${file}`));
3815
+ }
3816
+ console.log();
3817
+ console.log(pc10.dim("Remove all <<<<<<< / ======= / >>>>>>> markers, then run `flint git sync` again."));
3818
+ process.exit(1);
3819
+ }
3820
+ const branch = await getRebaseBranch(flintPath);
3821
+ if (!branch) {
3822
+ console.error(pc10.red("Could not determine branch from rebase state."));
3823
+ console.log(pc10.dim("You can manually run: git rebase --abort"));
3824
+ process.exit(1);
3825
+ }
3826
+ const add = await runGit(flintPath, ["add", "-A"]);
3827
+ if (!add.success) {
3828
+ console.error(pc10.red(`Failed to stage changes: ${add.error}`));
3829
+ process.exit(1);
3830
+ }
3831
+ const cont = await runGit(flintPath, ["rebase", "--continue"], { env: { GIT_EDITOR: "true" } });
3832
+ if (!cont.success) {
3833
+ if (cont.error?.includes("CONFLICT") || cont.error?.includes("conflict")) {
3834
+ const conflicts = await getConflictFiles(flintPath);
3835
+ console.error(pc10.red("\nAnother conflict during rebase. Resolve these files:"));
3836
+ console.log();
3837
+ for (const file of conflicts) {
3838
+ console.log(pc10.yellow(` ${file}`));
3839
+ }
3840
+ console.log();
3841
+ console.log(pc10.dim("Then run `flint git sync` again."));
3842
+ process.exit(1);
3843
+ }
3844
+ console.error(pc10.red(`Rebase continue failed: ${cont.error}`));
3845
+ console.log(pc10.dim("You can manually run: git rebase --abort"));
3846
+ process.exit(1);
3847
+ }
3848
+ console.log(pc10.green("\u2713 Rebase completed"));
3849
+ await pushToRemote(flintPath, branch);
3850
+ console.log();
3851
+ console.log(pc10.bold("Sync complete."));
3852
+ }
3853
+ async function pushToRemote(flintPath, branch) {
3785
3854
  console.log(pc10.dim("Pushing to remote..."));
3786
3855
  const push = await runGit(flintPath, ["push", "origin", branch]);
3787
3856
  if (!push.success) {
@@ -3793,15 +3862,15 @@ async function handleSync(flintPath, customMessage) {
3793
3862
  }
3794
3863
  }
3795
3864
  console.log(pc10.green("\u2713 Pushed"));
3796
- console.log();
3797
- console.log(pc10.bold("Sync complete."));
3798
3865
  }
3799
3866
  async function buildSyncCommitMessage(flintPath, customMessage) {
3800
3867
  const identity = await getIdentity(flintPath);
3801
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "");
3868
+ const now = /* @__PURE__ */ new Date();
3869
+ const timestamp = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")} ${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`;
3802
3870
  let msg = "";
3803
3871
  if (identity?.person) {
3804
- msg += `${identity.person}: `;
3872
+ const displayName = identity.person.replace(/^@/, "");
3873
+ msg += `${displayName}: `;
3805
3874
  }
3806
3875
  msg += `sync ${timestamp}`;
3807
3876
  if (customMessage) {
@@ -7667,7 +7736,7 @@ var sendCommand = new Command29("send").description("Send files to another Flint
7667
7736
  console.log();
7668
7737
  let sourceFlintName = "Unknown";
7669
7738
  try {
7670
- const { readFlintToml: readFlintToml3 } = await import("./dist-ONKP44ML.js");
7739
+ const { readFlintToml: readFlintToml3 } = await import("./dist-JRUBIV33.js");
7671
7740
  const toml = await readFlintToml3(flintPath);
7672
7741
  if (toml?.flint?.name) {
7673
7742
  sourceFlintName = toml.flint.name;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuucognition/flint-cli",
3
- "version": "0.4.0-alpha.0",
3
+ "version": "0.4.0-alpha.2",
4
4
  "type": "module",
5
5
  "description": "Flint cognitive workspace CLI",
6
6
  "license": "PROPRIETARY",
@@ -26,12 +26,12 @@
26
26
  "tsup": "^8.3.5",
27
27
  "tsx": "^4.19.2",
28
28
  "typescript": "^5.9.2",
29
+ "@nuucognition/eslint-config": "0.0.0",
29
30
  "@nuucognition/flint": "0.1.0",
30
31
  "@nuucognition/flint-migrations": "0.1.0",
31
32
  "@nuucognition/flint-server": "0.0.1",
32
- "@nuucognition/typescript-config": "0.0.0",
33
33
  "@nuucognition/flint-runtime": "0.0.1",
34
- "@nuucognition/eslint-config": "0.0.0"
34
+ "@nuucognition/typescript-config": "0.0.0"
35
35
  },
36
36
  "scripts": {
37
37
  "predev": "pnpm --dir ../../packages/flint build && pnpm --dir ../../packages/flint-migrations build && pnpm --dir ../../packages/flint-runtime build && pnpm --dir ../../packages/flint-server build",