codebyplan 1.2.0 → 1.3.1

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/cli.js +40 -7
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -14,7 +14,7 @@ var VERSION, PACKAGE_NAME;
14
14
  var init_version = __esm({
15
15
  "src/lib/version.ts"() {
16
16
  "use strict";
17
- VERSION = "1.2.0";
17
+ VERSION = "1.3.1";
18
18
  PACKAGE_NAME = "codebyplan";
19
19
  }
20
20
  });
@@ -296,21 +296,45 @@ var init_hook_registry = __esm({
296
296
  });
297
297
 
298
298
  // src/lib/variables.ts
299
+ function splitFrontmatter(content) {
300
+ const fmMatch = content.match(/^(---\s*\n[\s\S]*?\n---\n?)([\s\S]*)$/);
301
+ if (fmMatch) {
302
+ return { frontmatter: fmMatch[1], body: fmMatch[2] };
303
+ }
304
+ if (content.startsWith("#!/") || content.startsWith("# @")) {
305
+ const lines = content.split("\n");
306
+ let headerEnd = 0;
307
+ for (let i = 0; i < lines.length; i++) {
308
+ if (lines[i].startsWith("#") || lines[i].startsWith("#!/") || lines[i].trim() === "") {
309
+ headerEnd = i + 1;
310
+ } else {
311
+ break;
312
+ }
313
+ }
314
+ return {
315
+ frontmatter: lines.slice(0, headerEnd).join("\n") + "\n",
316
+ body: lines.slice(headerEnd).join("\n")
317
+ };
318
+ }
319
+ return { frontmatter: "", body: content };
320
+ }
299
321
  function substituteVariables(content, repoData) {
300
322
  if (!content.includes("{{")) return content;
301
- let result = content;
323
+ const { frontmatter, body } = splitFrontmatter(content);
324
+ let result = body;
302
325
  for (const [name, resolver] of Object.entries(TEMPLATE_VARIABLES)) {
303
326
  const placeholder = `{{${name}}}`;
304
327
  if (result.includes(placeholder)) {
305
328
  result = result.replaceAll(placeholder, resolver(repoData));
306
329
  }
307
330
  }
308
- return result;
331
+ return frontmatter + result;
309
332
  }
310
333
  function escapeRegex(str) {
311
334
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
312
335
  }
313
336
  function reverseSubstituteVariables(content, repoData) {
337
+ const { frontmatter, body } = splitFrontmatter(content);
314
338
  const entries = [];
315
339
  for (const [name, resolver] of Object.entries(TEMPLATE_VARIABLES)) {
316
340
  const value = resolver(repoData);
@@ -318,7 +342,7 @@ function reverseSubstituteVariables(content, repoData) {
318
342
  entries.push([value, `{{${name}}}`]);
319
343
  }
320
344
  entries.sort((a, b) => b[0].length - a[0].length);
321
- let result = content;
345
+ let result = body;
322
346
  for (const [value, placeholder] of entries) {
323
347
  if (value.length < 8) {
324
348
  const pattern = new RegExp(`\\b${escapeRegex(value)}\\b`, "g");
@@ -327,7 +351,7 @@ function reverseSubstituteVariables(content, repoData) {
327
351
  result = result.replaceAll(value, placeholder);
328
352
  }
329
353
  }
330
- return result;
354
+ return frontmatter + result;
331
355
  }
332
356
  var TEMPLATE_VARIABLES;
333
357
  var init_variables = __esm({
@@ -2200,6 +2224,10 @@ async function runSyncInner(repoId, projectPath, dryRun, force, fix = false) {
2200
2224
  claudeFileId: null
2201
2225
  });
2202
2226
  } else if (!local && remote) {
2227
+ const remoteScope = remote.scope ?? "shared";
2228
+ if (remoteScope.startsWith("local:") && remoteScope !== `local:${repoData.name}`) {
2229
+ continue;
2230
+ }
2203
2231
  const resolvedContent = substituteVariables(remote.content, repoData);
2204
2232
  const hadSyncedThisFile = remote.id ? fileRepoByClaudeFileId.has(remote.id) : fileRepoHashes.has(key);
2205
2233
  const recommended = hadSyncedThisFile ? "delete" : "pull";
@@ -2220,6 +2248,10 @@ async function runSyncInner(repoId, projectPath, dryRun, force, fix = false) {
2220
2248
  claudeFileId: remote.id ?? null
2221
2249
  });
2222
2250
  } else if (local && remote) {
2251
+ const remoteScope = remote.scope ?? "shared";
2252
+ if (remoteScope.startsWith("local:") && remoteScope !== `local:${repoData.name}`) {
2253
+ continue;
2254
+ }
2223
2255
  const resolvedRemote = substituteVariables(remote.content, repoData);
2224
2256
  if (local.content === resolvedRemote) {
2225
2257
  continue;
@@ -2780,7 +2812,7 @@ function getLocalFilePath(claudeDir, projectPath, remote) {
2780
2812
  }
2781
2813
  function getSyncVersion() {
2782
2814
  try {
2783
- return "1.2.0";
2815
+ return "1.3.1";
2784
2816
  } catch {
2785
2817
  return "unknown";
2786
2818
  }
@@ -2810,7 +2842,8 @@ function flattenSyncData(data) {
2810
2842
  content: file.content,
2811
2843
  category: file.category,
2812
2844
  updated_at: file.updated_at,
2813
- content_hash: file.content_hash
2845
+ content_hash: file.content_hash,
2846
+ scope: file.scope
2814
2847
  });
2815
2848
  }
2816
2849
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebyplan",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "CLI for CodeByPlan — AI-powered development planning and tracking",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  "repository": {
34
34
  "type": "git",
35
35
  "url": "https://github.com/codebyplan/codebyplan.git",
36
- "directory": "packages/codebyplan"
36
+ "directory": "packages/codebyplan-package"
37
37
  },
38
38
  "license": "MIT",
39
39
  "publishConfig": {