prjct-cli 1.2.1 → 1.2.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.
- package/CHANGELOG.md +34 -1
- package/core/agentic/ground-truth.ts +5 -3
- package/core/services/hooks-service.ts +3 -4
- package/dist/bin/prjct.mjs +93 -88
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.2.2] - 2026-02-06
|
|
4
|
+
|
|
5
|
+
### Performance
|
|
6
|
+
|
|
7
|
+
- convert execSync to async in ground-truth.ts (PRJ-92) (#113)
|
|
8
|
+
- convert execSync to async in ground-truth.ts (PRJ-92)
|
|
9
|
+
|
|
10
|
+
|
|
3
11
|
## [1.2.1] - 2026-02-06
|
|
4
12
|
|
|
13
|
+
### Performance
|
|
14
|
+
|
|
15
|
+
- **Convert execSync to async in ground-truth.ts (PRJ-92)**: Replaced blocking execSync with promisify(exec) in verifyShip
|
|
16
|
+
|
|
5
17
|
### Bug Fixes
|
|
6
18
|
|
|
7
19
|
- replace raw ANSI codes with chalk library (PRJ-132) (#111)
|
|
8
|
-
- replace raw ANSI codes with chalk library (PRJ-132)
|
|
9
20
|
|
|
21
|
+
### Implementation Details
|
|
22
|
+
|
|
23
|
+
Replaced the single `execSync('git status --porcelain')` call in `verifyShip()` with `await execAsync()` using `promisify(exec)` from `node:util`. The rest of `ground-truth.ts` already used async `fs.promises` — this was the last synchronous call blocking the event loop.
|
|
24
|
+
|
|
25
|
+
### Learnings
|
|
26
|
+
|
|
27
|
+
- `exec` returns `{stdout, stderr}` object vs `execSync` returning a string directly — must destructure
|
|
28
|
+
- `promisify(exec)` is simpler than `spawn` for short-lived commands that return stdout
|
|
29
|
+
- Terminal control sequences (cursor movement) are separate from color/formatting — chalk doesn't handle them
|
|
30
|
+
|
|
31
|
+
### Test Plan
|
|
32
|
+
|
|
33
|
+
#### For QA
|
|
34
|
+
1. Run `bun run build && bun run typecheck` — zero errors
|
|
35
|
+
2. Trigger `verifyShip` path — verify async git status check works
|
|
36
|
+
3. Test with uncommitted changes — verify warning still appears
|
|
37
|
+
4. Test in non-git directory — verify graceful fallback (`gitAvailable = false`)
|
|
38
|
+
|
|
39
|
+
#### For Users
|
|
40
|
+
**What changed:** Internal performance improvement — git status check in ground-truth verifier is now async
|
|
41
|
+
**How to use:** No change needed — improvement is internal
|
|
42
|
+
**Breaking changes:** None
|
|
10
43
|
|
|
11
44
|
## [1.2.0] - 2026-02-06
|
|
12
45
|
|
|
@@ -11,14 +11,17 @@
|
|
|
11
11
|
* Source: Devin, Cursor, Augment Code patterns
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { exec } from 'node:child_process'
|
|
15
15
|
import fs from 'node:fs/promises'
|
|
16
16
|
import os from 'node:os'
|
|
17
17
|
import path from 'node:path'
|
|
18
|
+
import { promisify } from 'node:util'
|
|
18
19
|
|
|
19
20
|
import type { GroundTruthContext, VerificationResult, Verifier } from '../types'
|
|
20
21
|
import { isNotFoundError } from '../types/fs'
|
|
21
22
|
|
|
23
|
+
const execAsync = promisify(exec)
|
|
24
|
+
|
|
22
25
|
// =============================================================================
|
|
23
26
|
// Utilities
|
|
24
27
|
// =============================================================================
|
|
@@ -163,9 +166,8 @@ export async function verifyShip(context: GroundTruthContext): Promise<Verificat
|
|
|
163
166
|
|
|
164
167
|
// 1. Check for uncommitted changes
|
|
165
168
|
try {
|
|
166
|
-
const gitStatus =
|
|
169
|
+
const { stdout: gitStatus } = await execAsync('git status --porcelain', {
|
|
167
170
|
cwd: context.projectPath,
|
|
168
|
-
encoding: 'utf-8',
|
|
169
171
|
})
|
|
170
172
|
actual.hasUncommittedChanges = gitStatus.trim().length > 0
|
|
171
173
|
actual.uncommittedFiles = gitStatus.trim().split('\n').filter(Boolean).length
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
* @module services/hooks-service
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { execSync } from 'node:child_process'
|
|
15
14
|
import fs from 'node:fs'
|
|
16
15
|
import path from 'node:path'
|
|
17
16
|
import chalk from 'chalk'
|
|
@@ -209,7 +208,7 @@ ${sectionName}:
|
|
|
209
208
|
)
|
|
210
209
|
} else {
|
|
211
210
|
// Append new section
|
|
212
|
-
content = content.trimEnd()
|
|
211
|
+
content = `${content.trimEnd()}\n${hookBlock}`
|
|
213
212
|
}
|
|
214
213
|
}
|
|
215
214
|
|
|
@@ -262,7 +261,7 @@ function installDirect(projectPath: string, hooks: HookName[]): boolean {
|
|
|
262
261
|
continue // Already installed
|
|
263
262
|
}
|
|
264
263
|
// Append to existing hook
|
|
265
|
-
fs.appendFileSync(hookPath,
|
|
264
|
+
fs.appendFileSync(hookPath, `\n# prjct auto-sync\n${script.split('\n').slice(1).join('\n')}`)
|
|
266
265
|
} else {
|
|
267
266
|
fs.writeFileSync(hookPath, script, { mode: 0o755 })
|
|
268
267
|
}
|
|
@@ -291,7 +290,7 @@ function uninstallLefthook(projectPath: string): boolean {
|
|
|
291
290
|
// Clean up empty sections
|
|
292
291
|
content = content.replace(/^(post-commit|post-checkout):\s*commands:\s*$/gm, '')
|
|
293
292
|
|
|
294
|
-
fs.writeFileSync(configPath, content.trimEnd()
|
|
293
|
+
fs.writeFileSync(configPath, `${content.trimEnd()}\n`, 'utf-8')
|
|
295
294
|
return true
|
|
296
295
|
}
|
|
297
296
|
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -5549,7 +5549,8 @@ ${sectionName}:
|
|
|
5549
5549
|
fail_text: "prjct sync failed (non-blocking)"`
|
|
5550
5550
|
);
|
|
5551
5551
|
} else {
|
|
5552
|
-
content = content.trimEnd()
|
|
5552
|
+
content = `${content.trimEnd()}
|
|
5553
|
+
${hookBlock}`;
|
|
5553
5554
|
}
|
|
5554
5555
|
}
|
|
5555
5556
|
fs15.writeFileSync(configPath, content, "utf-8");
|
|
@@ -5585,7 +5586,9 @@ function installDirect(projectPath, hooks) {
|
|
|
5585
5586
|
if (existing.includes("prjct sync")) {
|
|
5586
5587
|
continue;
|
|
5587
5588
|
}
|
|
5588
|
-
fs15.appendFileSync(hookPath,
|
|
5589
|
+
fs15.appendFileSync(hookPath, `
|
|
5590
|
+
# prjct auto-sync
|
|
5591
|
+
${script.split("\n").slice(1).join("\n")}`);
|
|
5589
5592
|
} else {
|
|
5590
5593
|
fs15.writeFileSync(hookPath, script, { mode: 493 });
|
|
5591
5594
|
}
|
|
@@ -5599,7 +5602,8 @@ function uninstallLefthook(projectPath) {
|
|
|
5599
5602
|
let content = fs15.readFileSync(configPath, "utf-8");
|
|
5600
5603
|
content = content.replace(/\s*prjct-sync-[\w-]+:[\s\S]*?(?=\n\S|\n*$)/g, "");
|
|
5601
5604
|
content = content.replace(/^(post-commit|post-checkout):\s*commands:\s*$/gm, "");
|
|
5602
|
-
fs15.writeFileSync(configPath, content.trimEnd()
|
|
5605
|
+
fs15.writeFileSync(configPath, `${content.trimEnd()}
|
|
5606
|
+
`, "utf-8");
|
|
5603
5607
|
return true;
|
|
5604
5608
|
}
|
|
5605
5609
|
function uninstallHusky(projectPath) {
|
|
@@ -7352,10 +7356,11 @@ var init_context_builder = __esm({
|
|
|
7352
7356
|
});
|
|
7353
7357
|
|
|
7354
7358
|
// core/agentic/ground-truth.ts
|
|
7355
|
-
import {
|
|
7359
|
+
import { exec as exec5 } from "node:child_process";
|
|
7356
7360
|
import fs19 from "node:fs/promises";
|
|
7357
7361
|
import os6 from "node:os";
|
|
7358
7362
|
import path18 from "node:path";
|
|
7363
|
+
import { promisify as promisify5 } from "node:util";
|
|
7359
7364
|
function formatDuration2(ms) {
|
|
7360
7365
|
const hours = Math.floor(ms / (1e3 * 60 * 60));
|
|
7361
7366
|
const minutes = Math.floor(ms % (1e3 * 60 * 60) / (1e3 * 60));
|
|
@@ -7455,9 +7460,8 @@ async function verifyShip(context2) {
|
|
|
7455
7460
|
const recommendations = [];
|
|
7456
7461
|
const actual = {};
|
|
7457
7462
|
try {
|
|
7458
|
-
const gitStatus =
|
|
7459
|
-
cwd: context2.projectPath
|
|
7460
|
-
encoding: "utf-8"
|
|
7463
|
+
const { stdout: gitStatus } = await execAsync("git status --porcelain", {
|
|
7464
|
+
cwd: context2.projectPath
|
|
7461
7465
|
});
|
|
7462
7466
|
actual.hasUncommittedChanges = gitStatus.trim().length > 0;
|
|
7463
7467
|
actual.uncommittedFiles = gitStatus.trim().split("\n").filter(Boolean).length;
|
|
@@ -7839,11 +7843,12 @@ async function prepareCommand(commandName, context2, state) {
|
|
|
7839
7843
|
function requiresVerification(commandName) {
|
|
7840
7844
|
return ["done", "ship", "feature", "spec", "now", "init", "sync", "analyze"].includes(commandName);
|
|
7841
7845
|
}
|
|
7842
|
-
var verifiers, ground_truth_default;
|
|
7846
|
+
var execAsync, verifiers, ground_truth_default;
|
|
7843
7847
|
var init_ground_truth = __esm({
|
|
7844
7848
|
"core/agentic/ground-truth.ts"() {
|
|
7845
7849
|
"use strict";
|
|
7846
7850
|
init_fs();
|
|
7851
|
+
execAsync = promisify5(exec5);
|
|
7847
7852
|
__name(formatDuration2, "formatDuration");
|
|
7848
7853
|
__name(escapeRegex, "escapeRegex");
|
|
7849
7854
|
__name(formatWarnings, "formatWarnings");
|
|
@@ -14143,14 +14148,14 @@ When fragmenting tasks:
|
|
|
14143
14148
|
});
|
|
14144
14149
|
|
|
14145
14150
|
// core/agentic/tool-registry.ts
|
|
14146
|
-
import { exec as
|
|
14151
|
+
import { exec as exec6 } from "node:child_process";
|
|
14147
14152
|
import fs28 from "node:fs/promises";
|
|
14148
|
-
import { promisify as
|
|
14149
|
-
var
|
|
14153
|
+
import { promisify as promisify6 } from "node:util";
|
|
14154
|
+
var execAsync2, toolRegistry, tool_registry_default;
|
|
14150
14155
|
var init_tool_registry = __esm({
|
|
14151
14156
|
"core/agentic/tool-registry.ts"() {
|
|
14152
14157
|
"use strict";
|
|
14153
|
-
|
|
14158
|
+
execAsync2 = promisify6(exec6);
|
|
14154
14159
|
toolRegistry = {
|
|
14155
14160
|
tools: /* @__PURE__ */ new Map(),
|
|
14156
14161
|
/**
|
|
@@ -14205,7 +14210,7 @@ var init_tool_registry = __esm({
|
|
|
14205
14210
|
"Bash",
|
|
14206
14211
|
async (command) => {
|
|
14207
14212
|
try {
|
|
14208
|
-
const { stdout, stderr } = await
|
|
14213
|
+
const { stdout, stderr } = await execAsync2(command);
|
|
14209
14214
|
return { stdout, stderr };
|
|
14210
14215
|
} catch (error) {
|
|
14211
14216
|
const err = error;
|
|
@@ -16095,7 +16100,7 @@ var init_file_scorer = __esm({
|
|
|
16095
16100
|
});
|
|
16096
16101
|
|
|
16097
16102
|
// core/services/dependency-validator.ts
|
|
16098
|
-
import { execSync as
|
|
16103
|
+
import { execSync as execSync3 } from "node:child_process";
|
|
16099
16104
|
var TOOLS, DependencyValidator, DependencyError, dependencyValidator;
|
|
16100
16105
|
var init_dependency_validator = __esm({
|
|
16101
16106
|
"core/services/dependency-validator.ts"() {
|
|
@@ -16255,7 +16260,7 @@ ${hints}`
|
|
|
16255
16260
|
// ==========================================================================
|
|
16256
16261
|
executeCheck(definition) {
|
|
16257
16262
|
try {
|
|
16258
|
-
const output =
|
|
16263
|
+
const output = execSync3(definition.command, {
|
|
16259
16264
|
encoding: "utf-8",
|
|
16260
16265
|
stdio: ["pipe", "pipe", "pipe"],
|
|
16261
16266
|
timeout: 5e3
|
|
@@ -16280,7 +16285,7 @@ ${hints}`
|
|
|
16280
16285
|
}
|
|
16281
16286
|
checkUnknownTool(toolName) {
|
|
16282
16287
|
try {
|
|
16283
|
-
|
|
16288
|
+
execSync3(`${toolName} --version`, {
|
|
16284
16289
|
encoding: "utf-8",
|
|
16285
16290
|
stdio: ["pipe", "pipe", "pipe"],
|
|
16286
16291
|
timeout: 5e3
|
|
@@ -16288,7 +16293,7 @@ ${hints}`
|
|
|
16288
16293
|
return { available: true };
|
|
16289
16294
|
} catch {
|
|
16290
16295
|
try {
|
|
16291
|
-
|
|
16296
|
+
execSync3(`${toolName} -v`, {
|
|
16292
16297
|
encoding: "utf-8",
|
|
16293
16298
|
stdio: ["pipe", "pipe", "pipe"],
|
|
16294
16299
|
timeout: 5e3
|
|
@@ -16338,15 +16343,15 @@ ${hints}`
|
|
|
16338
16343
|
});
|
|
16339
16344
|
|
|
16340
16345
|
// core/services/git-analyzer.ts
|
|
16341
|
-
import { exec as
|
|
16342
|
-
import { promisify as
|
|
16343
|
-
var
|
|
16346
|
+
import { exec as exec7 } from "node:child_process";
|
|
16347
|
+
import { promisify as promisify7 } from "node:util";
|
|
16348
|
+
var execAsync3;
|
|
16344
16349
|
var init_git_analyzer = __esm({
|
|
16345
16350
|
"core/services/git-analyzer.ts"() {
|
|
16346
16351
|
"use strict";
|
|
16347
16352
|
init_constants();
|
|
16348
16353
|
init_dependency_validator();
|
|
16349
|
-
|
|
16354
|
+
execAsync3 = promisify7(exec7);
|
|
16350
16355
|
}
|
|
16351
16356
|
});
|
|
16352
16357
|
|
|
@@ -17021,16 +17026,16 @@ ${agent.description}`;
|
|
|
17021
17026
|
});
|
|
17022
17027
|
|
|
17023
17028
|
// core/services/project-index.ts
|
|
17024
|
-
import { exec as
|
|
17025
|
-
import { promisify as
|
|
17026
|
-
var
|
|
17029
|
+
import { exec as exec8 } from "node:child_process";
|
|
17030
|
+
import { promisify as promisify8 } from "node:util";
|
|
17031
|
+
var execAsync4;
|
|
17027
17032
|
var init_project_index = __esm({
|
|
17028
17033
|
"core/services/project-index.ts"() {
|
|
17029
17034
|
"use strict";
|
|
17030
17035
|
init_index_storage();
|
|
17031
17036
|
init_date_helper();
|
|
17032
17037
|
init_file_scorer();
|
|
17033
|
-
|
|
17038
|
+
execAsync4 = promisify8(exec8);
|
|
17034
17039
|
}
|
|
17035
17040
|
});
|
|
17036
17041
|
|
|
@@ -17699,10 +17704,10 @@ var init_wizard = __esm({
|
|
|
17699
17704
|
});
|
|
17700
17705
|
|
|
17701
17706
|
// core/context/generator.ts
|
|
17702
|
-
import { exec as
|
|
17707
|
+
import { exec as exec9 } from "node:child_process";
|
|
17703
17708
|
import fs34 from "node:fs/promises";
|
|
17704
17709
|
import path35 from "node:path";
|
|
17705
|
-
import { promisify as
|
|
17710
|
+
import { promisify as promisify9 } from "node:util";
|
|
17706
17711
|
async function generateContext(projectId, repoPath) {
|
|
17707
17712
|
const _globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
17708
17713
|
const contextPath = path_manager_default.getContextPath(projectId);
|
|
@@ -17760,17 +17765,17 @@ async function getGitData(repoPath) {
|
|
|
17760
17765
|
recentCommits: []
|
|
17761
17766
|
};
|
|
17762
17767
|
try {
|
|
17763
|
-
const { stdout: branch } = await
|
|
17768
|
+
const { stdout: branch } = await execAsync5("git branch --show-current", { cwd: repoPath });
|
|
17764
17769
|
data.branch = branch.trim() || "main";
|
|
17765
|
-
const { stdout: commits } = await
|
|
17770
|
+
const { stdout: commits } = await execAsync5("git rev-list --count HEAD", { cwd: repoPath });
|
|
17766
17771
|
data.commits = parseInt(commits.trim(), 10) || 0;
|
|
17767
|
-
const { stdout: contributors } = await
|
|
17772
|
+
const { stdout: contributors } = await execAsync5("git shortlog -sn --all | wc -l", {
|
|
17768
17773
|
cwd: repoPath
|
|
17769
17774
|
});
|
|
17770
17775
|
data.contributors = parseInt(contributors.trim(), 10) || 0;
|
|
17771
|
-
const { stdout: status } = await
|
|
17776
|
+
const { stdout: status } = await execAsync5("git status --porcelain", { cwd: repoPath });
|
|
17772
17777
|
data.hasChanges = status.trim().length > 0;
|
|
17773
|
-
const { stdout: log } = await
|
|
17778
|
+
const { stdout: log } = await execAsync5(
|
|
17774
17779
|
'git log --oneline -10 --pretty=format:"%h|%s|%ad" --date=short',
|
|
17775
17780
|
{ cwd: repoPath }
|
|
17776
17781
|
);
|
|
@@ -17919,13 +17924,13 @@ async function generateSummaryMd(contextPath, project, gitData, pkgData) {
|
|
|
17919
17924
|
`;
|
|
17920
17925
|
await fs34.writeFile(path35.join(contextPath, "summary.md"), content, "utf-8");
|
|
17921
17926
|
}
|
|
17922
|
-
var
|
|
17927
|
+
var execAsync5;
|
|
17923
17928
|
var init_generator = __esm({
|
|
17924
17929
|
"core/context/generator.ts"() {
|
|
17925
17930
|
"use strict";
|
|
17926
17931
|
init_path_manager();
|
|
17927
17932
|
init_storage2();
|
|
17928
|
-
|
|
17933
|
+
execAsync5 = promisify9(exec9);
|
|
17929
17934
|
__name(generateContext, "generateContext");
|
|
17930
17935
|
__name(getGitData, "getGitData");
|
|
17931
17936
|
__name(getPackageData, "getPackageData");
|
|
@@ -17940,13 +17945,13 @@ var init_generator = __esm({
|
|
|
17940
17945
|
import { exec as execCallback5 } from "node:child_process";
|
|
17941
17946
|
import fs35 from "node:fs/promises";
|
|
17942
17947
|
import path36 from "node:path";
|
|
17943
|
-
import { promisify as
|
|
17944
|
-
var
|
|
17948
|
+
import { promisify as promisify10 } from "node:util";
|
|
17949
|
+
var exec10, CodebaseAnalyzer, analyzer, analyzer_default2;
|
|
17945
17950
|
var init_analyzer2 = __esm({
|
|
17946
17951
|
"core/domain/analyzer.ts"() {
|
|
17947
17952
|
"use strict";
|
|
17948
17953
|
init_fs();
|
|
17949
|
-
|
|
17954
|
+
exec10 = promisify10(execCallback5);
|
|
17950
17955
|
CodebaseAnalyzer = class {
|
|
17951
17956
|
static {
|
|
17952
17957
|
__name(this, "CodebaseAnalyzer");
|
|
@@ -18092,7 +18097,7 @@ var init_analyzer2 = __esm({
|
|
|
18092
18097
|
*/
|
|
18093
18098
|
async getFileExtensions() {
|
|
18094
18099
|
try {
|
|
18095
|
-
const { stdout } = await
|
|
18100
|
+
const { stdout } = await exec10(
|
|
18096
18101
|
'find . -type f ! -path "*/node_modules/*" ! -path "*/.git/*" ! -path "*/dist/*" ! -path "*/.next/*" | sed "s/.*\\./\\./" | sort | uniq -c | sort -rn',
|
|
18097
18102
|
{ cwd: this.projectPath }
|
|
18098
18103
|
);
|
|
@@ -18158,7 +18163,7 @@ var init_analyzer2 = __esm({
|
|
|
18158
18163
|
*/
|
|
18159
18164
|
async getGitLog(limit = 50) {
|
|
18160
18165
|
try {
|
|
18161
|
-
const { stdout } = await
|
|
18166
|
+
const { stdout } = await exec10(`git log -n ${limit} --pretty=format:"%h|%an|%ar|%s"`, {
|
|
18162
18167
|
cwd: this.projectPath
|
|
18163
18168
|
});
|
|
18164
18169
|
return stdout;
|
|
@@ -18171,13 +18176,13 @@ var init_analyzer2 = __esm({
|
|
|
18171
18176
|
*/
|
|
18172
18177
|
async getGitStats() {
|
|
18173
18178
|
try {
|
|
18174
|
-
const { stdout: totalCommits } = await
|
|
18179
|
+
const { stdout: totalCommits } = await exec10("git rev-list --count HEAD", {
|
|
18175
18180
|
cwd: this.projectPath
|
|
18176
18181
|
});
|
|
18177
|
-
const { stdout: contributors } = await
|
|
18182
|
+
const { stdout: contributors } = await exec10('git log --format="%an" | sort -u | wc -l', {
|
|
18178
18183
|
cwd: this.projectPath
|
|
18179
18184
|
});
|
|
18180
|
-
const { stdout: firstCommit } = await
|
|
18185
|
+
const { stdout: firstCommit } = await exec10(
|
|
18181
18186
|
'git log --reverse --pretty=format:"%ar" | head -1',
|
|
18182
18187
|
{
|
|
18183
18188
|
cwd: this.projectPath
|
|
@@ -18201,7 +18206,7 @@ var init_analyzer2 = __esm({
|
|
|
18201
18206
|
*/
|
|
18202
18207
|
async countFiles() {
|
|
18203
18208
|
try {
|
|
18204
|
-
const { stdout } = await
|
|
18209
|
+
const { stdout } = await exec10(
|
|
18205
18210
|
'find . -type f ! -path "*/node_modules/*" ! -path "*/.git/*" ! -path "*/dist/*" | wc -l',
|
|
18206
18211
|
{ cwd: this.projectPath }
|
|
18207
18212
|
);
|
|
@@ -18243,7 +18248,7 @@ var init_analyzer2 = __esm({
|
|
|
18243
18248
|
*/
|
|
18244
18249
|
async findFiles(pattern) {
|
|
18245
18250
|
try {
|
|
18246
|
-
const { stdout } = await
|
|
18251
|
+
const { stdout } = await exec10(
|
|
18247
18252
|
`find . -type f -name "${pattern}" ! -path "*/node_modules/*" ! -path "*/.git/*"`,
|
|
18248
18253
|
{ cwd: this.projectPath }
|
|
18249
18254
|
);
|
|
@@ -19903,16 +19908,16 @@ var init_project_service = __esm({
|
|
|
19903
19908
|
});
|
|
19904
19909
|
|
|
19905
19910
|
// core/services/staleness-checker.ts
|
|
19906
|
-
import { exec as
|
|
19911
|
+
import { exec as exec11 } from "node:child_process";
|
|
19907
19912
|
import fs37 from "node:fs/promises";
|
|
19908
19913
|
import path39 from "node:path";
|
|
19909
|
-
import { promisify as
|
|
19910
|
-
var
|
|
19914
|
+
import { promisify as promisify11 } from "node:util";
|
|
19915
|
+
var execAsync6, DEFAULT_CONFIG, StalenessChecker, createStalenessChecker;
|
|
19911
19916
|
var init_staleness_checker = __esm({
|
|
19912
19917
|
"core/services/staleness-checker.ts"() {
|
|
19913
19918
|
"use strict";
|
|
19914
19919
|
init_path_manager();
|
|
19915
|
-
|
|
19920
|
+
execAsync6 = promisify11(exec11);
|
|
19916
19921
|
DEFAULT_CONFIG = {
|
|
19917
19922
|
commitThreshold: 10,
|
|
19918
19923
|
dayThreshold: 3,
|
|
@@ -19965,7 +19970,7 @@ var init_staleness_checker = __esm({
|
|
|
19965
19970
|
status.lastSyncCommit = projectJson.lastSyncCommit || null;
|
|
19966
19971
|
const lastSync = projectJson.lastSync;
|
|
19967
19972
|
try {
|
|
19968
|
-
const { stdout } = await
|
|
19973
|
+
const { stdout } = await execAsync6("git rev-parse --short HEAD", {
|
|
19969
19974
|
cwd: this.projectPath
|
|
19970
19975
|
});
|
|
19971
19976
|
status.currentCommit = stdout.trim();
|
|
@@ -19983,7 +19988,7 @@ var init_staleness_checker = __esm({
|
|
|
19983
19988
|
return status;
|
|
19984
19989
|
}
|
|
19985
19990
|
try {
|
|
19986
|
-
const { stdout } = await
|
|
19991
|
+
const { stdout } = await execAsync6(`git rev-list --count ${status.lastSyncCommit}..HEAD`, {
|
|
19987
19992
|
cwd: this.projectPath
|
|
19988
19993
|
});
|
|
19989
19994
|
status.commitsSinceSync = parseInt(stdout.trim(), 10) || 0;
|
|
@@ -20000,7 +20005,7 @@ var init_staleness_checker = __esm({
|
|
|
20000
20005
|
);
|
|
20001
20006
|
}
|
|
20002
20007
|
try {
|
|
20003
|
-
const { stdout } = await
|
|
20008
|
+
const { stdout } = await execAsync6(`git diff --name-only ${status.lastSyncCommit}..HEAD`, {
|
|
20004
20009
|
cwd: this.projectPath
|
|
20005
20010
|
});
|
|
20006
20011
|
status.changedFiles = stdout.trim().split("\n").filter(Boolean);
|
|
@@ -20332,7 +20337,7 @@ var init_formatters = __esm({
|
|
|
20332
20337
|
});
|
|
20333
20338
|
|
|
20334
20339
|
// core/ai-tools/registry.ts
|
|
20335
|
-
import { execSync as
|
|
20340
|
+
import { execSync as execSync4 } from "node:child_process";
|
|
20336
20341
|
import fs38 from "node:fs";
|
|
20337
20342
|
import os11 from "node:os";
|
|
20338
20343
|
import path40 from "node:path";
|
|
@@ -20341,7 +20346,7 @@ function getAIToolConfig(id) {
|
|
|
20341
20346
|
}
|
|
20342
20347
|
function commandExists(cmd) {
|
|
20343
20348
|
try {
|
|
20344
|
-
|
|
20349
|
+
execSync4(`which ${cmd}`, { stdio: "ignore" });
|
|
20345
20350
|
return true;
|
|
20346
20351
|
} catch {
|
|
20347
20352
|
return false;
|
|
@@ -21153,11 +21158,11 @@ var init_stack_detector = __esm({
|
|
|
21153
21158
|
});
|
|
21154
21159
|
|
|
21155
21160
|
// core/services/sync-service.ts
|
|
21156
|
-
import { exec as
|
|
21161
|
+
import { exec as exec12 } from "node:child_process";
|
|
21157
21162
|
import fs43 from "node:fs/promises";
|
|
21158
21163
|
import path45 from "node:path";
|
|
21159
|
-
import { promisify as
|
|
21160
|
-
var
|
|
21164
|
+
import { promisify as promisify12 } from "node:util";
|
|
21165
|
+
var execAsync7, SyncService, syncService;
|
|
21161
21166
|
var init_sync_service = __esm({
|
|
21162
21167
|
"core/services/sync-service.ts"() {
|
|
21163
21168
|
"use strict";
|
|
@@ -21170,7 +21175,7 @@ var init_sync_service = __esm({
|
|
|
21170
21175
|
init_context_generator();
|
|
21171
21176
|
init_local_state_generator();
|
|
21172
21177
|
init_stack_detector();
|
|
21173
|
-
|
|
21178
|
+
execAsync7 = promisify12(exec12);
|
|
21174
21179
|
SyncService = class {
|
|
21175
21180
|
static {
|
|
21176
21181
|
__name(this, "SyncService");
|
|
@@ -21327,19 +21332,19 @@ var init_sync_service = __esm({
|
|
|
21327
21332
|
weeklyCommits: 0
|
|
21328
21333
|
};
|
|
21329
21334
|
try {
|
|
21330
|
-
const { stdout: branch } = await
|
|
21335
|
+
const { stdout: branch } = await execAsync7("git branch --show-current", {
|
|
21331
21336
|
cwd: this.projectPath
|
|
21332
21337
|
});
|
|
21333
21338
|
data.branch = branch.trim() || "main";
|
|
21334
|
-
const { stdout: commits } = await
|
|
21339
|
+
const { stdout: commits } = await execAsync7("git rev-list --count HEAD", {
|
|
21335
21340
|
cwd: this.projectPath
|
|
21336
21341
|
});
|
|
21337
21342
|
data.commits = parseInt(commits.trim(), 10) || 0;
|
|
21338
|
-
const { stdout: contributors } = await
|
|
21343
|
+
const { stdout: contributors } = await execAsync7("git shortlog -sn --all | wc -l", {
|
|
21339
21344
|
cwd: this.projectPath
|
|
21340
21345
|
});
|
|
21341
21346
|
data.contributors = parseInt(contributors.trim(), 10) || 0;
|
|
21342
|
-
const { stdout: status } = await
|
|
21347
|
+
const { stdout: status } = await execAsync7("git status --porcelain", {
|
|
21343
21348
|
cwd: this.projectPath
|
|
21344
21349
|
});
|
|
21345
21350
|
const lines = status.trim().split("\n").filter(Boolean);
|
|
@@ -21355,7 +21360,7 @@ var init_sync_service = __esm({
|
|
|
21355
21360
|
data.untrackedFiles.push(file);
|
|
21356
21361
|
}
|
|
21357
21362
|
}
|
|
21358
|
-
const { stdout: log } = await
|
|
21363
|
+
const { stdout: log } = await execAsync7(
|
|
21359
21364
|
'git log --oneline -20 --pretty=format:"%h|%s|%ad" --date=short',
|
|
21360
21365
|
{ cwd: this.projectPath }
|
|
21361
21366
|
);
|
|
@@ -21363,7 +21368,7 @@ var init_sync_service = __esm({
|
|
|
21363
21368
|
const [hash, message, date] = line.split("|");
|
|
21364
21369
|
return { hash, message, date };
|
|
21365
21370
|
});
|
|
21366
|
-
const { stdout: weekly } = await
|
|
21371
|
+
const { stdout: weekly } = await execAsync7('git log --oneline --since="1 week ago" | wc -l', {
|
|
21367
21372
|
cwd: this.projectPath
|
|
21368
21373
|
});
|
|
21369
21374
|
data.weeklyCommits = parseInt(weekly.trim(), 10) || 0;
|
|
@@ -21385,7 +21390,7 @@ var init_sync_service = __esm({
|
|
|
21385
21390
|
frameworks: []
|
|
21386
21391
|
};
|
|
21387
21392
|
try {
|
|
21388
|
-
const { stdout } = await
|
|
21393
|
+
const { stdout } = await execAsync7(
|
|
21389
21394
|
'find . -type f \\( -name "*.js" -o -name "*.ts" -o -name "*.tsx" -o -name "*.py" -o -name "*.go" -o -name "*.rs" \\) -not -path "./node_modules/*" -not -path "./.git/*" | wc -l',
|
|
21390
21395
|
{ cwd: this.projectPath }
|
|
21391
21396
|
);
|
|
@@ -21985,7 +21990,7 @@ __export(uninstall_exports, {
|
|
|
21985
21990
|
UninstallCommands: () => UninstallCommands,
|
|
21986
21991
|
uninstall: () => uninstall
|
|
21987
21992
|
});
|
|
21988
|
-
import { execSync as
|
|
21993
|
+
import { execSync as execSync5 } from "node:child_process";
|
|
21989
21994
|
import fsSync2 from "node:fs";
|
|
21990
21995
|
import fs44 from "node:fs/promises";
|
|
21991
21996
|
import os12 from "node:os";
|
|
@@ -22033,7 +22038,7 @@ function detectInstallation() {
|
|
|
22033
22038
|
npm: false
|
|
22034
22039
|
};
|
|
22035
22040
|
try {
|
|
22036
|
-
const result =
|
|
22041
|
+
const result = execSync5("brew list prjct-cli 2>/dev/null", { encoding: "utf-8" });
|
|
22037
22042
|
if (result) {
|
|
22038
22043
|
info.homebrew = true;
|
|
22039
22044
|
info.homebrewFormula = "prjct-cli";
|
|
@@ -22041,7 +22046,7 @@ function detectInstallation() {
|
|
|
22041
22046
|
} catch {
|
|
22042
22047
|
}
|
|
22043
22048
|
try {
|
|
22044
|
-
const result =
|
|
22049
|
+
const result = execSync5("npm list -g prjct-cli --depth=0 2>/dev/null", { encoding: "utf-8" });
|
|
22045
22050
|
if (result.includes("prjct-cli")) {
|
|
22046
22051
|
info.npm = true;
|
|
22047
22052
|
}
|
|
@@ -22209,7 +22214,7 @@ async function performUninstall(items, installation, options) {
|
|
|
22209
22214
|
if (installation.homebrew && installation.homebrewFormula) {
|
|
22210
22215
|
try {
|
|
22211
22216
|
if (!options.dryRun) {
|
|
22212
|
-
|
|
22217
|
+
execSync5(`brew uninstall ${installation.homebrewFormula}`, { stdio: "pipe" });
|
|
22213
22218
|
}
|
|
22214
22219
|
deleted.push("Homebrew: prjct-cli");
|
|
22215
22220
|
} catch (error) {
|
|
@@ -22219,7 +22224,7 @@ async function performUninstall(items, installation, options) {
|
|
|
22219
22224
|
if (installation.npm) {
|
|
22220
22225
|
try {
|
|
22221
22226
|
if (!options.dryRun) {
|
|
22222
|
-
|
|
22227
|
+
execSync5("npm uninstall -g prjct-cli", { stdio: "pipe" });
|
|
22223
22228
|
}
|
|
22224
22229
|
deleted.push("npm: prjct-cli");
|
|
22225
22230
|
} catch (error) {
|
|
@@ -23255,7 +23260,7 @@ __export(setup_exports, {
|
|
|
23255
23260
|
needsWindsurfRegeneration: () => needsWindsurfRegeneration,
|
|
23256
23261
|
run: () => run
|
|
23257
23262
|
});
|
|
23258
|
-
import { execSync as
|
|
23263
|
+
import { execSync as execSync6 } from "node:child_process";
|
|
23259
23264
|
import fs45 from "node:fs";
|
|
23260
23265
|
import os13 from "node:os";
|
|
23261
23266
|
import path48 from "node:path";
|
|
@@ -23279,7 +23284,7 @@ async function installAICLI(provider) {
|
|
|
23279
23284
|
try {
|
|
23280
23285
|
console.log(chalk15.yellow(`\u{1F4E6} ${provider.displayName} not found. Installing...`));
|
|
23281
23286
|
console.log("");
|
|
23282
|
-
|
|
23287
|
+
execSync6(`npm install -g ${packageName}`, {
|
|
23283
23288
|
stdio: "inherit",
|
|
23284
23289
|
timeout: getTimeout("NPM_INSTALL")
|
|
23285
23290
|
});
|
|
@@ -24970,9 +24975,9 @@ async function undo(projectPath = process.cwd()) {
|
|
|
24970
24975
|
}
|
|
24971
24976
|
const snapshotsPath = path53.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
24972
24977
|
await file_helper_exports.ensureDir(snapshotsPath);
|
|
24973
|
-
const { execSync:
|
|
24978
|
+
const { execSync: execSync7 } = await import("node:child_process");
|
|
24974
24979
|
try {
|
|
24975
|
-
const status =
|
|
24980
|
+
const status = execSync7("git status --porcelain", {
|
|
24976
24981
|
cwd: projectPath,
|
|
24977
24982
|
encoding: "utf-8"
|
|
24978
24983
|
}).trim();
|
|
@@ -24982,7 +24987,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
24982
24987
|
}
|
|
24983
24988
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
24984
24989
|
const stashMessage = `prjct-undo-${timestamp}`;
|
|
24985
|
-
|
|
24990
|
+
execSync7(`git stash push -m "${stashMessage}"`, {
|
|
24986
24991
|
cwd: projectPath,
|
|
24987
24992
|
encoding: "utf-8"
|
|
24988
24993
|
});
|
|
@@ -25043,9 +25048,9 @@ async function redo(projectPath = process.cwd()) {
|
|
|
25043
25048
|
output_default.warn("nothing to redo");
|
|
25044
25049
|
return { success: false, message: "Nothing to redo" };
|
|
25045
25050
|
}
|
|
25046
|
-
const { execSync:
|
|
25051
|
+
const { execSync: execSync7 } = await import("node:child_process");
|
|
25047
25052
|
try {
|
|
25048
|
-
const stashList =
|
|
25053
|
+
const stashList = execSync7("git stash list", {
|
|
25049
25054
|
cwd: projectPath,
|
|
25050
25055
|
encoding: "utf-8"
|
|
25051
25056
|
}).trim();
|
|
@@ -25058,7 +25063,7 @@ async function redo(projectPath = process.cwd()) {
|
|
|
25058
25063
|
output_default.warn("no prjct undo point found");
|
|
25059
25064
|
return { success: false, message: "No prjct undo point found" };
|
|
25060
25065
|
}
|
|
25061
|
-
|
|
25066
|
+
execSync7("git stash pop", {
|
|
25062
25067
|
cwd: projectPath,
|
|
25063
25068
|
encoding: "utf-8"
|
|
25064
25069
|
});
|
|
@@ -25529,8 +25534,8 @@ var init_project_commands = __esm({
|
|
|
25529
25534
|
});
|
|
25530
25535
|
|
|
25531
25536
|
// core/workflow/workflow-preferences.ts
|
|
25532
|
-
import { exec as
|
|
25533
|
-
import { promisify as
|
|
25537
|
+
import { exec as exec13 } from "node:child_process";
|
|
25538
|
+
import { promisify as promisify13 } from "node:util";
|
|
25534
25539
|
import chalk17 from "chalk";
|
|
25535
25540
|
function prefKey(hook, command) {
|
|
25536
25541
|
return `workflow:${hook}_${command}`;
|
|
@@ -25602,7 +25607,7 @@ async function runWorkflowHooks(projectId, phase, command, options = {}) {
|
|
|
25602
25607
|
${chalk17.dim(`Running ${phase}-${command}: ${action}`)}`);
|
|
25603
25608
|
try {
|
|
25604
25609
|
const startTime = Date.now();
|
|
25605
|
-
await
|
|
25610
|
+
await execAsync8(action, {
|
|
25606
25611
|
timeout: 6e4,
|
|
25607
25612
|
cwd: options.projectPath || process.cwd(),
|
|
25608
25613
|
env: { ...process.env }
|
|
@@ -25666,12 +25671,12 @@ Set one: "p. workflow antes de ship corre los tests"`;
|
|
|
25666
25671
|
lines.push(chalk17.dim('Remove: "p. workflow quita el hook de ship"'));
|
|
25667
25672
|
return lines.join("\n");
|
|
25668
25673
|
}
|
|
25669
|
-
var
|
|
25674
|
+
var execAsync8, sessionPreferences, oncePreferences;
|
|
25670
25675
|
var init_workflow_preferences = __esm({
|
|
25671
25676
|
"core/workflow/workflow-preferences.ts"() {
|
|
25672
25677
|
"use strict";
|
|
25673
25678
|
init_memory_system();
|
|
25674
|
-
|
|
25679
|
+
execAsync8 = promisify13(exec13);
|
|
25675
25680
|
sessionPreferences = /* @__PURE__ */ new Map();
|
|
25676
25681
|
oncePreferences = /* @__PURE__ */ new Map();
|
|
25677
25682
|
__name(prefKey, "prefKey");
|
|
@@ -25952,14 +25957,14 @@ var init_cache2 = __esm({
|
|
|
25952
25957
|
});
|
|
25953
25958
|
|
|
25954
25959
|
// core/utils/keychain.ts
|
|
25955
|
-
import { exec as
|
|
25956
|
-
import { promisify as
|
|
25960
|
+
import { exec as exec14 } from "node:child_process";
|
|
25961
|
+
import { promisify as promisify14 } from "node:util";
|
|
25957
25962
|
async function getCredential(key) {
|
|
25958
25963
|
if (process.platform !== "darwin") {
|
|
25959
25964
|
return getEnvFallback(key);
|
|
25960
25965
|
}
|
|
25961
25966
|
try {
|
|
25962
|
-
const { stdout } = await
|
|
25967
|
+
const { stdout } = await execAsync9(
|
|
25963
25968
|
`security find-generic-password -s "${SERVICE_NAME}" -a "${key}" -w 2>/dev/null`
|
|
25964
25969
|
);
|
|
25965
25970
|
return stdout.trim() || null;
|
|
@@ -25975,11 +25980,11 @@ function getEnvFallback(key) {
|
|
|
25975
25980
|
const envVar = envMap[key];
|
|
25976
25981
|
return process.env[envVar] || null;
|
|
25977
25982
|
}
|
|
25978
|
-
var
|
|
25983
|
+
var execAsync9, SERVICE_NAME;
|
|
25979
25984
|
var init_keychain = __esm({
|
|
25980
25985
|
"core/utils/keychain.ts"() {
|
|
25981
25986
|
"use strict";
|
|
25982
|
-
|
|
25987
|
+
execAsync9 = promisify14(exec14);
|
|
25983
25988
|
SERVICE_NAME = "prjct-cli";
|
|
25984
25989
|
__name(getCredential, "getCredential");
|
|
25985
25990
|
__name(getEnvFallback, "getEnvFallback");
|
|
@@ -27334,7 +27339,7 @@ var require_package = __commonJS({
|
|
|
27334
27339
|
"package.json"(exports, module) {
|
|
27335
27340
|
module.exports = {
|
|
27336
27341
|
name: "prjct-cli",
|
|
27337
|
-
version: "1.2.
|
|
27342
|
+
version: "1.2.2",
|
|
27338
27343
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
27339
27344
|
main: "core/index.ts",
|
|
27340
27345
|
bin: {
|