@primitive.ai/prim 0.1.0-alpha.8 → 0.1.0-alpha.9

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.
@@ -11,6 +11,11 @@ function getStagedFiles() {
11
11
  });
12
12
  return output.trim().split("\n").filter((f) => f.length > 0);
13
13
  }
14
+ function getStagedDiff(files) {
15
+ return execSync(`git diff --cached -- ${files.map((f) => `"${f}"`).join(" ")}`, {
16
+ encoding: "utf-8"
17
+ });
18
+ }
14
19
  function matchPattern(filePath, pattern) {
15
20
  const regexStr = pattern.replaceAll("**", "\xA7GLOBSTAR\xA7").replaceAll("*", "[^/]*").replaceAll("\xA7GLOBSTAR\xA7", ".*");
16
21
  const regex = new RegExp(`^${regexStr}$`);
@@ -39,29 +44,35 @@ function findAffectedContexts(stagedFiles, specs) {
39
44
  return affected;
40
45
  }
41
46
  var HOOK_TIMEOUT_MS = 1e4;
42
- async function main() {
43
- const stagedFiles = getStagedFiles();
47
+ var defaultDeps = {
48
+ getClient,
49
+ getStagedFiles,
50
+ getStagedDiff
51
+ };
52
+ async function syncAffectedSpecs(deps = defaultDeps) {
53
+ const stagedFiles = deps.getStagedFiles();
44
54
  if (stagedFiles.length === 0) {
45
- process.exit(0);
55
+ return [];
46
56
  }
47
- const client = getClient();
57
+ const client = deps.getClient();
48
58
  let mappings = [];
49
59
  try {
50
60
  mappings = await client.get("/api/cli/specs/mappings", {
51
61
  signal: AbortSignal.timeout(HOOK_TIMEOUT_MS)
52
62
  });
53
63
  } catch {
54
- process.exit(0);
64
+ return [];
55
65
  }
56
66
  if (mappings.length === 0) {
57
- process.exit(0);
67
+ return [];
58
68
  }
59
69
  const affectedContexts = findAffectedContexts(stagedFiles, mappings);
60
70
  if (affectedContexts.size === 0) {
61
- process.exit(0);
71
+ return [];
62
72
  }
63
73
  console.log(`[prim] ${String(affectedContexts.size)} spec(s) affected by staged changes:`);
64
- for (const [contextId] of affectedContexts) {
74
+ const synced = [];
75
+ for (const [contextId, affected] of affectedContexts) {
65
76
  try {
66
77
  const ctx = await client.get(`/api/cli/contexts/${contextId}`, {
67
78
  signal: AbortSignal.timeout(HOOK_TIMEOUT_MS)
@@ -74,18 +85,39 @@ async function main() {
74
85
  console.log(` [skip] ${contextId} \u2014 not a spec document`);
75
86
  continue;
76
87
  }
77
- await client.post(`/api/cli/contexts/${contextId}/sync`, void 0, {
78
- signal: AbortSignal.timeout(HOOK_TIMEOUT_MS)
79
- });
88
+ const diffContent = deps.getStagedDiff(affected.matchedFiles);
89
+ if (!diffContent) {
90
+ console.log(` [skip] ${contextId} \u2014 no diff content`);
91
+ continue;
92
+ }
93
+ await client.post(
94
+ `/api/cli/contexts/${contextId}/sync-diff`,
95
+ { diffContent, affectedFiles: affected.matchedFiles },
96
+ { signal: AbortSignal.timeout(HOOK_TIMEOUT_MS) }
97
+ );
80
98
  console.log(` [synced] ${contextId} \u2014 ${ctx.name ?? "(unnamed)"}`);
99
+ synced.push(contextId);
81
100
  } catch (error) {
82
101
  const message = error instanceof Error ? error.message : String(error);
83
102
  console.error(` [error] ${contextId} \u2014 ${message}`);
84
103
  }
85
104
  }
86
- process.exit(0);
105
+ return synced;
87
106
  }
88
- main().catch((error) => {
89
- console.error("[prim] Pre-commit hook error:", error);
107
+ async function main() {
108
+ await syncAffectedSpecs();
90
109
  process.exit(0);
91
- });
110
+ }
111
+ var isDirectExecution = typeof process !== "undefined" && process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/\\/g, "/"));
112
+ if (isDirectExecution) {
113
+ main().catch((error) => {
114
+ console.error("[prim] Pre-commit hook error:", error);
115
+ process.exit(0);
116
+ });
117
+ }
118
+ export {
119
+ HOOK_TIMEOUT_MS,
120
+ findAffectedContexts,
121
+ matchPattern,
122
+ syncAffectedSpecs
123
+ };
package/dist/index.js CHANGED
@@ -333,7 +333,7 @@ if command -v prim-pre-commit >/dev/null 2>&1; then
333
333
  elif [ -f "./node_modules/.bin/prim-pre-commit" ]; then
334
334
  ./node_modules/.bin/prim-pre-commit
335
335
  else
336
- npx --yes @primitive.ai/prim pre-commit-hook 2>/dev/null || true
336
+ npx --yes -p @primitive.ai/prim prim-pre-commit 2>/dev/null || true
337
337
  fi
338
338
  `;
339
339
  var PRIM_BLOCK_START = "# >>> prim pre-commit hook >>>";
@@ -344,7 +344,7 @@ if command -v prim-pre-commit >/dev/null 2>&1; then
344
344
  elif [ -f "./node_modules/.bin/prim-pre-commit" ]; then
345
345
  ./node_modules/.bin/prim-pre-commit
346
346
  else
347
- npx --yes @primitive.ai/prim pre-commit-hook 2>/dev/null || true
347
+ npx --yes -p @primitive.ai/prim prim-pre-commit 2>/dev/null || true
348
348
  fi
349
349
  ${PRIM_BLOCK_END}`;
350
350
  function getGitRoot() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitive.ai/prim",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.9",
4
4
  "description": "CLI for managing Primitive specs, contexts, and git hooks",
5
5
  "type": "module",
6
6
  "license": "MIT",