prjct-cli 1.6.8 → 1.6.10
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 +82 -0
- package/README.md +46 -0
- package/core/ai-tools/registry.ts +2 -9
- package/core/bus/bus.ts +24 -0
- package/core/commands/planning.ts +3 -5
- package/core/infrastructure/agent-detector.ts +2 -2
- package/core/infrastructure/path-manager.ts +3 -17
- package/core/integrations/jira/client.ts +3 -77
- package/core/server/server.ts +2 -4
- package/core/server/sse.ts +115 -59
- package/core/services/context-generator.ts +22 -47
- package/core/services/diff-generator.ts +18 -43
- package/core/services/stack-detector.ts +4 -20
- package/core/services/sync-service.ts +35 -106
- package/core/services/sync-verifier.ts +17 -37
- package/core/services/watch-service.ts +20 -3
- package/core/types/citations.ts +22 -0
- package/core/types/commands.ts +10 -0
- package/core/types/diff.ts +41 -0
- package/core/types/errors.ts +111 -0
- package/core/types/index.ts +80 -0
- package/core/types/infrastructure.ts +14 -0
- package/core/types/jira.ts +51 -0
- package/core/types/logger.ts +17 -0
- package/core/types/output.ts +47 -0
- package/core/types/project-sync.ts +109 -0
- package/core/types/server.ts +28 -10
- package/core/types/services.ts +14 -0
- package/core/types/stack.ts +19 -0
- package/core/types/sync-verifier.ts +33 -0
- package/core/types/workflow.ts +23 -0
- package/core/utils/citations.ts +2 -16
- package/core/utils/error-messages.ts +5 -139
- package/core/utils/logger.ts +3 -11
- package/core/utils/output.ts +6 -45
- package/core/workflow/workflow-preferences.ts +14 -18
- package/dist/bin/prjct.mjs +137 -54
- package/package.json +1 -1
package/dist/bin/prjct.mjs
CHANGED
|
@@ -2020,6 +2020,13 @@ var init_logger = __esm({
|
|
|
2020
2020
|
}
|
|
2021
2021
|
});
|
|
2022
2022
|
|
|
2023
|
+
// core/types/server.ts
|
|
2024
|
+
var init_server = __esm({
|
|
2025
|
+
"core/types/server.ts"() {
|
|
2026
|
+
"use strict";
|
|
2027
|
+
}
|
|
2028
|
+
});
|
|
2029
|
+
|
|
2023
2030
|
// core/constants/index.ts
|
|
2024
2031
|
function getTimeout(key) {
|
|
2025
2032
|
const envVar = `PRJCT_TIMEOUT_${key}`;
|
|
@@ -2183,24 +2190,12 @@ var init_branding = __esm({
|
|
|
2183
2190
|
}
|
|
2184
2191
|
});
|
|
2185
2192
|
|
|
2186
|
-
// core/
|
|
2187
|
-
function getError(code, overrides) {
|
|
2188
|
-
const base = ERRORS[code];
|
|
2189
|
-
return { ...base, ...overrides };
|
|
2190
|
-
}
|
|
2191
|
-
function createError(message, hint, options) {
|
|
2192
|
-
return {
|
|
2193
|
-
message,
|
|
2194
|
-
hint,
|
|
2195
|
-
...options
|
|
2196
|
-
};
|
|
2197
|
-
}
|
|
2193
|
+
// core/types/errors.ts
|
|
2198
2194
|
var ERRORS;
|
|
2199
|
-
var
|
|
2200
|
-
"core/
|
|
2195
|
+
var init_errors2 = __esm({
|
|
2196
|
+
"core/types/errors.ts"() {
|
|
2201
2197
|
"use strict";
|
|
2202
2198
|
ERRORS = {
|
|
2203
|
-
// Project errors
|
|
2204
2199
|
NO_PROJECT: {
|
|
2205
2200
|
message: "No prjct project found in this directory",
|
|
2206
2201
|
hint: "Run 'prjct init' to set up a new project",
|
|
@@ -2221,7 +2216,6 @@ var init_error_messages = __esm({
|
|
|
2221
2216
|
hint: "Check JSON syntax or delete .prjct/ and run init again",
|
|
2222
2217
|
file: ".prjct/prjct.config.json"
|
|
2223
2218
|
},
|
|
2224
|
-
// Git errors
|
|
2225
2219
|
GIT_NOT_FOUND: {
|
|
2226
2220
|
message: "Git repository not detected",
|
|
2227
2221
|
hint: "Run 'git init' first, then 'prjct init'"
|
|
@@ -2242,7 +2236,6 @@ var init_error_messages = __esm({
|
|
|
2242
2236
|
message: "Git operation failed",
|
|
2243
2237
|
hint: "Check git status and resolve any conflicts"
|
|
2244
2238
|
},
|
|
2245
|
-
// Auth errors
|
|
2246
2239
|
GH_NOT_AUTHENTICATED: {
|
|
2247
2240
|
message: "GitHub CLI not authenticated",
|
|
2248
2241
|
hint: "Run 'gh auth login' to authenticate",
|
|
@@ -2256,7 +2249,6 @@ var init_error_messages = __esm({
|
|
|
2256
2249
|
message: "Linear API error",
|
|
2257
2250
|
hint: "Check your API key or network connection"
|
|
2258
2251
|
},
|
|
2259
|
-
// Task errors
|
|
2260
2252
|
NO_ACTIVE_TASK: {
|
|
2261
2253
|
message: "No active task",
|
|
2262
2254
|
hint: `Start a task with 'p. task "description"'`
|
|
@@ -2265,12 +2257,10 @@ var init_error_messages = __esm({
|
|
|
2265
2257
|
message: "A task is already in progress",
|
|
2266
2258
|
hint: "Complete it with 'p. done' or pause with 'p. pause'"
|
|
2267
2259
|
},
|
|
2268
|
-
// Sync errors
|
|
2269
2260
|
SYNC_FAILED: {
|
|
2270
2261
|
message: "Project sync failed",
|
|
2271
2262
|
hint: "Check file permissions and try again"
|
|
2272
2263
|
},
|
|
2273
|
-
// Ship errors
|
|
2274
2264
|
NOTHING_TO_SHIP: {
|
|
2275
2265
|
message: "Nothing to ship",
|
|
2276
2266
|
hint: "Make some changes first, then run ship"
|
|
@@ -2279,7 +2269,6 @@ var init_error_messages = __esm({
|
|
|
2279
2269
|
message: "Failed to create pull request",
|
|
2280
2270
|
hint: "Check GitHub auth and remote configuration"
|
|
2281
2271
|
},
|
|
2282
|
-
// Provider errors
|
|
2283
2272
|
NO_AI_PROVIDER: {
|
|
2284
2273
|
message: "No AI provider detected",
|
|
2285
2274
|
hint: "Install Claude Code or Gemini CLI, then run 'prjct start'",
|
|
@@ -2289,7 +2278,6 @@ var init_error_messages = __esm({
|
|
|
2289
2278
|
message: "AI provider not configured for prjct",
|
|
2290
2279
|
hint: "Run 'prjct start' to configure your provider"
|
|
2291
2280
|
},
|
|
2292
|
-
// Command errors
|
|
2293
2281
|
UNKNOWN_COMMAND: {
|
|
2294
2282
|
message: "Unknown command",
|
|
2295
2283
|
hint: "Run 'prjct --help' to see available commands"
|
|
@@ -2298,12 +2286,31 @@ var init_error_messages = __esm({
|
|
|
2298
2286
|
message: "Missing required parameter",
|
|
2299
2287
|
hint: "Check command usage below"
|
|
2300
2288
|
},
|
|
2301
|
-
// Generic
|
|
2302
2289
|
UNKNOWN: {
|
|
2303
2290
|
message: "An unexpected error occurred",
|
|
2304
2291
|
hint: "Check the error details and try again"
|
|
2305
2292
|
}
|
|
2306
2293
|
};
|
|
2294
|
+
}
|
|
2295
|
+
});
|
|
2296
|
+
|
|
2297
|
+
// core/utils/error-messages.ts
|
|
2298
|
+
function getError(code, overrides) {
|
|
2299
|
+
const base = ERRORS[code];
|
|
2300
|
+
return { ...base, ...overrides };
|
|
2301
|
+
}
|
|
2302
|
+
function createError(message, hint, options) {
|
|
2303
|
+
return {
|
|
2304
|
+
message,
|
|
2305
|
+
hint,
|
|
2306
|
+
...options
|
|
2307
|
+
};
|
|
2308
|
+
}
|
|
2309
|
+
var init_error_messages = __esm({
|
|
2310
|
+
"core/utils/error-messages.ts"() {
|
|
2311
|
+
"use strict";
|
|
2312
|
+
init_errors2();
|
|
2313
|
+
init_errors2();
|
|
2307
2314
|
__name(getError, "getError");
|
|
2308
2315
|
__name(createError, "createError");
|
|
2309
2316
|
}
|
|
@@ -13320,9 +13327,11 @@ var init_types3 = __esm({
|
|
|
13320
13327
|
"use strict";
|
|
13321
13328
|
init_agentic();
|
|
13322
13329
|
init_bus();
|
|
13330
|
+
init_errors2();
|
|
13323
13331
|
init_fs();
|
|
13324
13332
|
init_integrations();
|
|
13325
13333
|
init_memory();
|
|
13334
|
+
init_server();
|
|
13326
13335
|
}
|
|
13327
13336
|
});
|
|
13328
13337
|
|
|
@@ -22952,13 +22961,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
22952
22961
|
projectPath: this.projectPath,
|
|
22953
22962
|
globalPath: this.globalPath
|
|
22954
22963
|
});
|
|
22955
|
-
return generator.generate(
|
|
22956
|
-
{ branch: git.branch, commits: git.commits },
|
|
22957
|
-
stats,
|
|
22958
|
-
commands,
|
|
22959
|
-
agents,
|
|
22960
|
-
sources
|
|
22961
|
-
);
|
|
22964
|
+
return generator.generate(git, stats, commands, agents, sources);
|
|
22962
22965
|
}
|
|
22963
22966
|
// ==========================================================================
|
|
22964
22967
|
// PROJECT.JSON UPDATE
|
|
@@ -23750,6 +23753,8 @@ var init_watch_service = __esm({
|
|
|
23750
23753
|
};
|
|
23751
23754
|
isRunning = false;
|
|
23752
23755
|
syncCount = 0;
|
|
23756
|
+
sigintHandler = null;
|
|
23757
|
+
sigtermHandler = null;
|
|
23753
23758
|
/**
|
|
23754
23759
|
* Start watching for file changes
|
|
23755
23760
|
*/
|
|
@@ -23780,8 +23785,12 @@ var init_watch_service = __esm({
|
|
|
23780
23785
|
}
|
|
23781
23786
|
});
|
|
23782
23787
|
this.watcher.on("add", (filePath) => this.handleChange("add", filePath)).on("change", (filePath) => this.handleChange("change", filePath)).on("unlink", (filePath) => this.handleChange("unlink", filePath)).on("error", (error) => this.handleError(error));
|
|
23783
|
-
process.
|
|
23784
|
-
process.
|
|
23788
|
+
if (this.sigintHandler) process.off("SIGINT", this.sigintHandler);
|
|
23789
|
+
if (this.sigtermHandler) process.off("SIGTERM", this.sigtermHandler);
|
|
23790
|
+
this.sigintHandler = () => this.stop();
|
|
23791
|
+
this.sigtermHandler = () => this.stop();
|
|
23792
|
+
process.on("SIGINT", this.sigintHandler);
|
|
23793
|
+
process.on("SIGTERM", this.sigtermHandler);
|
|
23785
23794
|
return { success: true };
|
|
23786
23795
|
}
|
|
23787
23796
|
/**
|
|
@@ -23801,6 +23810,15 @@ var init_watch_service = __esm({
|
|
|
23801
23810
|
await this.watcher.close();
|
|
23802
23811
|
this.watcher = null;
|
|
23803
23812
|
}
|
|
23813
|
+
if (this.sigintHandler) {
|
|
23814
|
+
process.off("SIGINT", this.sigintHandler);
|
|
23815
|
+
this.sigintHandler = null;
|
|
23816
|
+
}
|
|
23817
|
+
if (this.sigtermHandler) {
|
|
23818
|
+
process.off("SIGTERM", this.sigtermHandler);
|
|
23819
|
+
this.sigtermHandler = null;
|
|
23820
|
+
}
|
|
23821
|
+
this.pendingChanges.clear();
|
|
23804
23822
|
this.isRunning = false;
|
|
23805
23823
|
process.exit(0);
|
|
23806
23824
|
}
|
|
@@ -28646,7 +28664,7 @@ var require_package = __commonJS({
|
|
|
28646
28664
|
"package.json"(exports, module) {
|
|
28647
28665
|
module.exports = {
|
|
28648
28666
|
name: "prjct-cli",
|
|
28649
|
-
version: "1.6.
|
|
28667
|
+
version: "1.6.10",
|
|
28650
28668
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
28651
28669
|
main: "core/index.ts",
|
|
28652
28670
|
bin: {
|
|
@@ -29665,9 +29683,47 @@ function createExtendedRoutes() {
|
|
|
29665
29683
|
__name(createExtendedRoutes, "createExtendedRoutes");
|
|
29666
29684
|
|
|
29667
29685
|
// core/server/sse.ts
|
|
29686
|
+
init_server();
|
|
29668
29687
|
import { streamSSE } from "hono/streaming";
|
|
29688
|
+
var MAX_CLIENT_TTL_MS = 60 * 60 * 1e3;
|
|
29689
|
+
var REAPER_INTERVAL_MS = 5 * 60 * 1e3;
|
|
29690
|
+
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
29669
29691
|
function createSSEManager() {
|
|
29670
29692
|
const clients = /* @__PURE__ */ new Map();
|
|
29693
|
+
let reaperInterval = null;
|
|
29694
|
+
function removeClient(clientId) {
|
|
29695
|
+
const entry = clients.get(clientId);
|
|
29696
|
+
if (!entry) return;
|
|
29697
|
+
clearInterval(entry.heartbeatInterval);
|
|
29698
|
+
clearTimeout(entry.ttlTimeout);
|
|
29699
|
+
entry.abortController.abort();
|
|
29700
|
+
clients.delete(clientId);
|
|
29701
|
+
}
|
|
29702
|
+
__name(removeClient, "removeClient");
|
|
29703
|
+
function startReaper() {
|
|
29704
|
+
if (reaperInterval) return;
|
|
29705
|
+
reaperInterval = setInterval(() => {
|
|
29706
|
+
const now = Date.now();
|
|
29707
|
+
for (const [id, entry] of clients) {
|
|
29708
|
+
const connectedMs = now - new Date(entry.client.connectedAt).getTime();
|
|
29709
|
+
if (connectedMs > MAX_CLIENT_TTL_MS) {
|
|
29710
|
+
removeClient(id);
|
|
29711
|
+
}
|
|
29712
|
+
}
|
|
29713
|
+
}, REAPER_INTERVAL_MS);
|
|
29714
|
+
if (reaperInterval && typeof reaperInterval === "object" && "unref" in reaperInterval) {
|
|
29715
|
+
reaperInterval.unref();
|
|
29716
|
+
}
|
|
29717
|
+
}
|
|
29718
|
+
__name(startReaper, "startReaper");
|
|
29719
|
+
function stopReaper() {
|
|
29720
|
+
if (reaperInterval) {
|
|
29721
|
+
clearInterval(reaperInterval);
|
|
29722
|
+
reaperInterval = null;
|
|
29723
|
+
}
|
|
29724
|
+
}
|
|
29725
|
+
__name(stopReaper, "stopReaper");
|
|
29726
|
+
startReaper();
|
|
29671
29727
|
return {
|
|
29672
29728
|
/**
|
|
29673
29729
|
* Handle a new SSE connection
|
|
@@ -29675,8 +29731,11 @@ function createSSEManager() {
|
|
|
29675
29731
|
handleConnection(c) {
|
|
29676
29732
|
return streamSSE(c, async (stream) => {
|
|
29677
29733
|
const clientId = crypto.randomUUID();
|
|
29734
|
+
const connectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
29735
|
+
const abortController = new AbortController();
|
|
29678
29736
|
const client = {
|
|
29679
29737
|
id: clientId,
|
|
29738
|
+
connectedAt,
|
|
29680
29739
|
send: /* @__PURE__ */ __name((event, data) => {
|
|
29681
29740
|
stream.writeSSE({
|
|
29682
29741
|
event,
|
|
@@ -29684,34 +29743,47 @@ function createSSEManager() {
|
|
|
29684
29743
|
});
|
|
29685
29744
|
}, "send"),
|
|
29686
29745
|
close: /* @__PURE__ */ __name(() => {
|
|
29687
|
-
|
|
29746
|
+
removeClient(clientId);
|
|
29688
29747
|
}, "close")
|
|
29689
29748
|
};
|
|
29690
|
-
|
|
29749
|
+
const heartbeatInterval = setInterval(async () => {
|
|
29750
|
+
try {
|
|
29751
|
+
await stream.writeSSE({
|
|
29752
|
+
event: "heartbeat",
|
|
29753
|
+
data: JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString() })
|
|
29754
|
+
});
|
|
29755
|
+
} catch {
|
|
29756
|
+
removeClient(clientId);
|
|
29757
|
+
}
|
|
29758
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
29759
|
+
const ttlTimeout = setTimeout(() => {
|
|
29760
|
+
removeClient(clientId);
|
|
29761
|
+
}, MAX_CLIENT_TTL_MS);
|
|
29762
|
+
if (typeof heartbeatInterval === "object" && "unref" in heartbeatInterval) {
|
|
29763
|
+
heartbeatInterval.unref();
|
|
29764
|
+
}
|
|
29765
|
+
if (typeof ttlTimeout === "object" && "unref" in ttlTimeout) {
|
|
29766
|
+
ttlTimeout.unref();
|
|
29767
|
+
}
|
|
29768
|
+
clients.set(clientId, {
|
|
29769
|
+
client,
|
|
29770
|
+
heartbeatInterval,
|
|
29771
|
+
ttlTimeout,
|
|
29772
|
+
abortController
|
|
29773
|
+
});
|
|
29691
29774
|
await stream.writeSSE({
|
|
29692
29775
|
event: "connected",
|
|
29693
29776
|
data: JSON.stringify({
|
|
29694
29777
|
clientId,
|
|
29695
|
-
timestamp:
|
|
29778
|
+
timestamp: connectedAt,
|
|
29696
29779
|
message: "Connected to prjct-cli server"
|
|
29697
29780
|
})
|
|
29698
29781
|
});
|
|
29699
|
-
const heartbeat = setInterval(async () => {
|
|
29700
|
-
try {
|
|
29701
|
-
await stream.writeSSE({
|
|
29702
|
-
event: "heartbeat",
|
|
29703
|
-
data: JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString() })
|
|
29704
|
-
});
|
|
29705
|
-
} catch (_error) {
|
|
29706
|
-
clearInterval(heartbeat);
|
|
29707
|
-
clients.delete(clientId);
|
|
29708
|
-
}
|
|
29709
|
-
}, 3e4);
|
|
29710
29782
|
stream.onAbort(() => {
|
|
29711
|
-
|
|
29712
|
-
clients.delete(clientId);
|
|
29783
|
+
removeClient(clientId);
|
|
29713
29784
|
});
|
|
29714
|
-
await new Promise(() => {
|
|
29785
|
+
await new Promise((resolve) => {
|
|
29786
|
+
abortController.signal.addEventListener("abort", () => resolve(), { once: true });
|
|
29715
29787
|
});
|
|
29716
29788
|
});
|
|
29717
29789
|
},
|
|
@@ -29724,11 +29796,11 @@ function createSSEManager() {
|
|
|
29724
29796
|
data,
|
|
29725
29797
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
29726
29798
|
};
|
|
29727
|
-
for (const
|
|
29799
|
+
for (const [id, entry] of clients) {
|
|
29728
29800
|
try {
|
|
29729
|
-
client.send(event, message);
|
|
29730
|
-
} catch
|
|
29731
|
-
|
|
29801
|
+
entry.client.send(event, message);
|
|
29802
|
+
} catch {
|
|
29803
|
+
removeClient(id);
|
|
29732
29804
|
}
|
|
29733
29805
|
}
|
|
29734
29806
|
},
|
|
@@ -29737,6 +29809,16 @@ function createSSEManager() {
|
|
|
29737
29809
|
*/
|
|
29738
29810
|
getClientCount() {
|
|
29739
29811
|
return clients.size;
|
|
29812
|
+
},
|
|
29813
|
+
/**
|
|
29814
|
+
* Shut down all clients and stop the reaper.
|
|
29815
|
+
* Called on server stop.
|
|
29816
|
+
*/
|
|
29817
|
+
shutdown() {
|
|
29818
|
+
stopReaper();
|
|
29819
|
+
for (const id of [...clients.keys()]) {
|
|
29820
|
+
removeClient(id);
|
|
29821
|
+
}
|
|
29740
29822
|
}
|
|
29741
29823
|
};
|
|
29742
29824
|
}
|
|
@@ -29818,6 +29900,7 @@ function createServer(config) {
|
|
|
29818
29900
|
console.log(` Dashboard: http://localhost:${port}`);
|
|
29819
29901
|
},
|
|
29820
29902
|
stop() {
|
|
29903
|
+
sseManager.shutdown();
|
|
29821
29904
|
if (server) {
|
|
29822
29905
|
server.stop();
|
|
29823
29906
|
server = null;
|