orquesta-cli 0.2.23 → 0.2.25

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.
@@ -1,2 +1,10 @@
1
1
  export declare function initHooks(token: string, apiUrl?: string): Promise<void>;
2
+ export declare function writeHookFiles(opts: {
3
+ projectId: string;
4
+ token: string;
5
+ apiUrl: string;
6
+ cwd?: string;
7
+ agentBin?: string;
8
+ quiet?: boolean;
9
+ }): boolean;
2
10
  //# sourceMappingURL=hook-init.d.ts.map
@@ -32,7 +32,6 @@ function resolveAgentBin() {
32
32
  return 'orquesta-agent';
33
33
  }
34
34
  export async function initHooks(token, apiUrl = 'https://getorquesta.com') {
35
- const cwd = process.cwd();
36
35
  console.log('\n Initializing Orquesta hook integration...\n');
37
36
  const agentBin = resolveAgentBin();
38
37
  console.log(' Validating token...');
@@ -62,51 +61,7 @@ export async function initHooks(token, apiUrl = 'https://getorquesta.com') {
62
61
  console.error(` Error: Could not reach ${apiUrl} (${msg})`);
63
62
  process.exit(1);
64
63
  }
65
- const configPath = path.join(cwd, '.orquesta.json');
66
- fs.writeFileSync(configPath, JSON.stringify({ projectId, token, apiUrl }, null, 2) + '\n');
67
- console.log(' Created .orquesta.json');
68
- const gitignorePath = path.join(cwd, '.gitignore');
69
- const entry = '.orquesta.json';
70
- if (fs.existsSync(gitignorePath)) {
71
- const content = fs.readFileSync(gitignorePath, 'utf8');
72
- if (!content.includes(entry)) {
73
- fs.appendFileSync(gitignorePath, `\n# Orquesta hook config (contains token)\n${entry}\n`);
74
- console.log(' Added .orquesta.json to .gitignore');
75
- }
76
- }
77
- else {
78
- fs.writeFileSync(gitignorePath, `# Orquesta hook config (contains token)\n${entry}\n`);
79
- console.log(' Created .gitignore');
80
- }
81
- const claudeDir = path.join(cwd, '.claude');
82
- const settingsPath = path.join(claudeDir, 'settings.json');
83
- if (!fs.existsSync(claudeDir)) {
84
- fs.mkdirSync(claudeDir, { recursive: true });
85
- }
86
- let settings = {};
87
- if (fs.existsSync(settingsPath)) {
88
- try {
89
- settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
90
- }
91
- catch { }
92
- }
93
- if (!settings.hooks)
94
- settings.hooks = {};
95
- const hooksConfig = buildHooksConfig(agentBin);
96
- for (const [event, config] of Object.entries(hooksConfig)) {
97
- if (!settings.hooks[event]) {
98
- settings.hooks[event] = config;
99
- }
100
- else {
101
- const existing = settings.hooks[event];
102
- const hasOrquesta = existing.some((e) => e.hooks?.some((h) => h.command?.includes('orquesta-agent hook')));
103
- if (!hasOrquesta) {
104
- settings.hooks[event] = [...existing, ...config];
105
- }
106
- }
107
- }
108
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
109
- console.log(' Configured .claude/settings.json hooks');
64
+ writeHookFiles({ projectId, token, apiUrl, agentBin });
110
65
  console.log(`
111
66
  Done! Now run \`claude\` in this directory — all activity will
112
67
  be tracked in Orquesta automatically.
@@ -114,4 +69,58 @@ export async function initHooks(token, apiUrl = 'https://getorquesta.com') {
114
69
  Dashboard: ${apiUrl}/dashboard/projects/${projectId}
115
70
  `);
116
71
  }
72
+ export function writeHookFiles(opts) {
73
+ const cwd = opts.cwd ?? process.cwd();
74
+ const log = (m) => { if (!opts.quiet)
75
+ console.log(m); };
76
+ try {
77
+ const agentBin = opts.agentBin ?? resolveAgentBin();
78
+ fs.writeFileSync(path.join(cwd, '.orquesta.json'), JSON.stringify({ projectId: opts.projectId, token: opts.token, apiUrl: opts.apiUrl }, null, 2) + '\n');
79
+ log(' Created .orquesta.json');
80
+ const gitignorePath = path.join(cwd, '.gitignore');
81
+ const entry = '.orquesta.json';
82
+ if (fs.existsSync(gitignorePath)) {
83
+ const content = fs.readFileSync(gitignorePath, 'utf8');
84
+ if (!content.includes(entry)) {
85
+ fs.appendFileSync(gitignorePath, `\n# Orquesta hook config (contains token)\n${entry}\n`);
86
+ log(' Added .orquesta.json to .gitignore');
87
+ }
88
+ }
89
+ else {
90
+ fs.writeFileSync(gitignorePath, `# Orquesta hook config (contains token)\n${entry}\n`);
91
+ log(' Created .gitignore');
92
+ }
93
+ const claudeDir = path.join(cwd, '.claude');
94
+ const settingsPath = path.join(claudeDir, 'settings.json');
95
+ if (!fs.existsSync(claudeDir))
96
+ fs.mkdirSync(claudeDir, { recursive: true });
97
+ let settings = {};
98
+ if (fs.existsSync(settingsPath)) {
99
+ try {
100
+ settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
101
+ }
102
+ catch { }
103
+ }
104
+ if (!settings.hooks)
105
+ settings.hooks = {};
106
+ const hooksConfig = buildHooksConfig(agentBin);
107
+ for (const [event, config] of Object.entries(hooksConfig)) {
108
+ if (!settings.hooks[event]) {
109
+ settings.hooks[event] = config;
110
+ }
111
+ else {
112
+ const existing = settings.hooks[event];
113
+ const hasOrquesta = existing.some((e) => e.hooks?.some((h) => h.command?.includes('orquesta-agent hook')));
114
+ if (!hasOrquesta)
115
+ settings.hooks[event] = [...existing, ...config];
116
+ }
117
+ }
118
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
119
+ log(' Configured .claude/settings.json hooks');
120
+ return true;
121
+ }
122
+ catch {
123
+ return false;
124
+ }
125
+ }
117
126
  //# sourceMappingURL=hook-init.js.map
@@ -1,8 +1,12 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
3
5
  import { configManager } from '../core/config/config-manager.js';
4
6
  import { syncOrquestaConfigs, fetchOrquestaProjects } from '../orquesta/config-sync.js';
7
+ import { writeHookFiles } from '../orquesta/hook-init.js';
5
8
  import { scanProviders, toEndpointConfig } from '../core/config/auto-detect.js';
9
+ const ORQUESTA_API_URL = process.env['ORQUESTA_API_URL'] || 'https://getorquesta.com';
6
10
  export function needsFirstRunSetup() {
7
11
  return !configManager.hasEndpoints() && !configManager.hasOrquestaConnection();
8
12
  }
@@ -140,6 +144,19 @@ export async function connectWithToken(token, projectId) {
140
144
  console.log(chalk.dim(` Project: ${selectedProject.name}`));
141
145
  console.log(chalk.dim(` Your prompts and configs will sync with the dashboard.`));
142
146
  console.log();
147
+ try {
148
+ const cwd = process.cwd();
149
+ const looksLikeProject = fs.existsSync(path.join(cwd, '.git')) || fs.existsSync(path.join(cwd, 'package.json'));
150
+ const alreadyInit = fs.existsSync(path.join(cwd, '.orquesta.json'));
151
+ if (looksLikeProject && !alreadyInit) {
152
+ const ok = writeHookFiles({ projectId: selectedProject.id, token, apiUrl: ORQUESTA_API_URL, quiet: true });
153
+ if (ok) {
154
+ console.log(chalk.dim(' Installed Claude Code hook for this directory (.claude/settings.json) — claude runs here will report too.'));
155
+ console.log();
156
+ }
157
+ }
158
+ }
159
+ catch { }
143
160
  console.log(chalk.dim(` Use --switch-project to change projects`));
144
161
  console.log();
145
162
  return {
@@ -37,7 +37,7 @@ import { configManager } from '../../core/config/config-manager.js';
37
37
  import { logger } from '../../utils/logger.js';
38
38
  import { usageTracker } from '../../core/usage-tracker.js';
39
39
  import { UpdateNotification } from '../UpdateNotification.js';
40
- import { checkForCliUpdate, runCliUpdate } from '../../utils/update-checker.js';
40
+ import { checkForCliUpdate, runCliUpdate, setSkippedVersion } from '../../utils/update-checker.js';
41
41
  import { setToolExecutionCallback, setTellToUserCallback, setToolResponseCallback, setPlanCreatedCallback, setTodoStartCallback, setTodoCompleteCallback, setTodoFailCallback, setCompactCallback, setAssistantResponseCallback, setToolApprovalCallback, setReasoningCallback, } from '../../tools/llm/simple/file-tools.js';
42
42
  import { createRequire } from 'module';
43
43
  const require = createRequire(import.meta.url);
@@ -512,6 +512,7 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
512
512
  runCliUpdate(updateLatest, (line) => setUpdateProgress(line.slice(0, 100)))
513
513
  .then(res => {
514
514
  if (res.success) {
515
+ setSkippedVersion(updateLatest);
515
516
  setUpdatePhase('done');
516
517
  }
517
518
  else {
@@ -521,7 +522,12 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
521
522
  });
522
523
  return;
523
524
  }
524
- if (key.escape || inputChar === 'n' || inputChar === 'N' || inputChar === 's' || inputChar === 'S') {
525
+ if (inputChar === 's' || inputChar === 'S') {
526
+ setSkippedVersion(updateLatest);
527
+ setUpdatePhase('hidden');
528
+ return;
529
+ }
530
+ if (key.escape || inputChar === 'n' || inputChar === 'N') {
525
531
  setUpdatePhase('hidden');
526
532
  return;
527
533
  }
@@ -1,3 +1,5 @@
1
+ export declare function getSkippedVersion(): string | null;
2
+ export declare function setSkippedVersion(version: string): void;
1
3
  export declare function checkForCliUpdate(currentVersion: string, timeoutMs?: number): Promise<{
2
4
  current: string;
3
5
  latest: string;
@@ -1,6 +1,33 @@
1
1
  import { spawn } from 'child_process';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import * as os from 'os';
2
5
  import { logger } from './logger.js';
3
6
  const REGISTRY_URL = 'https://registry.npmjs.org/orquesta-cli/latest';
7
+ const STATE_DIR = path.join(process.env['HOME'] || os.homedir() || '.', '.local-cli');
8
+ const STATE_FILE = path.join(STATE_DIR, 'update-state.json');
9
+ function readUpdateState() {
10
+ try {
11
+ return JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
12
+ }
13
+ catch {
14
+ return {};
15
+ }
16
+ }
17
+ export function getSkippedVersion() {
18
+ return readUpdateState().skippedVersion ?? null;
19
+ }
20
+ export function setSkippedVersion(version) {
21
+ try {
22
+ if (!fs.existsSync(STATE_DIR))
23
+ fs.mkdirSync(STATE_DIR, { recursive: true });
24
+ const state = readUpdateState();
25
+ state.skippedVersion = version;
26
+ fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
27
+ }
28
+ catch {
29
+ }
30
+ }
4
31
  function isNewer(a, b) {
5
32
  const pa = a.split('.').map(n => parseInt(n, 10) || 0);
6
33
  const pb = b.split('.').map(n => parseInt(n, 10) || 0);
@@ -27,6 +54,10 @@ export async function checkForCliUpdate(currentVersion, timeoutMs = 3500) {
27
54
  const latest = json?.version;
28
55
  if (!latest || !isNewer(latest, currentVersion))
29
56
  return null;
57
+ if (getSkippedVersion() === latest) {
58
+ logger.debug?.('CLI update available but skipped by user', { latest });
59
+ return null;
60
+ }
30
61
  logger.debug?.('CLI update available', { current: currentVersion, latest });
31
62
  return { current: currentVersion, latest };
32
63
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orquesta-cli",
3
- "version": "0.2.23",
3
+ "version": "0.2.25",
4
4
  "description": "Orquesta CLI - AI-powered coding assistant with team collaboration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",