@awak-app/simy-cli 0.5.64 → 0.5.65

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awak-app/simy-cli",
3
- "version": "0.5.64",
3
+ "version": "0.5.65",
4
4
  "description": "Local SIMY executor for non-coding Local Tasks and Agentic Loop runs.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,7 @@ import {
13
13
  } from "./durable-local-task-steps-contract.js";
14
14
  import { buildExecutionCapabilityContract } from "./execution-capability-contract.js";
15
15
 
16
- export const CLI_VERSION = "0.5.64";
16
+ export const CLI_VERSION = "0.5.65";
17
17
  export const CLI_API_CONTRACT_VERSION = 10;
18
18
 
19
19
  export function withCliContract(
@@ -152,15 +152,21 @@ export async function startDesktopHost({ input = process.stdin, output = process
152
152
  }
153
153
  return sessionStatus;
154
154
  };
155
- const selectedSession = async (command, { reuseDiscovery = false } = {}) => {
155
+ const selectedSession = async (command, { reuseDiscovery = false, preferObserved = false } = {}) => {
156
156
  const scope = await authorizeWork();
157
- // Analysis joins an existing discovery instead of scheduling a second
158
- // full scan. Enrollment retains its existing fresh-discovery boundary.
159
- if (!reuseDiscovery || !sessionRefresh) refreshSessions(true);
160
- await sessionRefresh;
161
- // A forced refresh requested during discovery schedules one follow-up.
162
- if (!reuseDiscovery && sessionRefresh) await sessionRefresh;
163
- const candidate = sessionStatus.sessions.find(item => item.provider === command.provider && item.session === command.session);
157
+ // Preference changes may use the observation already displayed by the UI.
158
+ // Execution still takes the fresh-discovery path and rechecks opt-in epochs.
159
+ const matches = item => item.provider === command.provider && item.session === command.session;
160
+ let candidate = preferObserved ? sessionStatus.sessions.find(matches) : null;
161
+ if (!candidate) {
162
+ // Analysis joins an existing discovery instead of scheduling a second
163
+ // full scan. Enrollment retains its fresh-discovery boundary.
164
+ if (!reuseDiscovery || !sessionRefresh) refreshSessions(true);
165
+ await sessionRefresh;
166
+ // A forced refresh requested during discovery schedules one follow-up.
167
+ if (!reuseDiscovery && sessionRefresh) await sessionRefresh;
168
+ candidate = sessionStatus.sessions.find(matches);
169
+ }
164
170
  if (!candidate) throw new Error('This conversation is unavailable; refresh its provider.');
165
171
  await authorizeWork(scope);
166
172
  const selected = { ...candidate };
@@ -389,6 +395,8 @@ export async function startDesktopHost({ input = process.stdin, output = process
389
395
  // Keep these commands ordered with each other; the agent still owns all
390
396
  // membership, active-work and nonce checks.
391
397
  let authorizationQueue = Promise.resolve();
398
+ // Saving/revoking opt-in must not queue behind provider or remote work.
399
+ let preferenceQueue = Promise.resolve();
392
400
  let activeQueuedAction = null;
393
401
  commands = createInterface({ input, crlfDelay: Infinity });
394
402
  commands.on("line", (line) => {
@@ -495,18 +503,20 @@ export async function startDesktopHost({ input = process.stdin, output = process
495
503
  } else if (action === "session_set_auto_continue") {
496
504
  if (typeof command.enabled !== 'boolean') throw new Error('Choose whether automatic continuation is enabled.');
497
505
  if (command.enabled) {
498
- const candidate = await selectedSession(command);
506
+ const candidate = await selectedSession(command, { preferObserved: true });
499
507
  if (candidate.capabilities?.canAutoContinue !== true) throw new Error('Automatic continuation is unavailable for this conversation.');
500
508
  }
501
509
  if (command.enabled) await authorizeWork(commandScope);
502
510
  await (dependencies.setSessionAutoContinue || setSessionAutoContinue)({ root: join(root, 'delivery-hooks'),
503
511
  provider: command.provider, session: command.session, enabled: command.enabled });
504
512
  if (!command.enabled) automaticContinuation.revoke(command.provider, command.session);
513
+ // Acknowledge the durable preference before discovery or analysis.
514
+ emit({ type: "result", id: command.id, ok: true });
505
515
  refreshSessions(true);
506
- if (command.enabled) {
507
- const fresh = await selectedSession(command);
508
- if (fresh.capabilities?.canAnalyze === true) await analysisManager.request(fresh);
509
- }
516
+ // Discovery's tracking transition schedules analysis. A second
517
+ // forced request could invalidate a concurrent manual recommendation.
518
+ void publish().catch(() => {});
519
+ return;
510
520
  } else if (action === "session_deadline_decide") {
511
521
  if (command.cancel === true) { emit({ type: "result", id: command.id, ok: true }); return; }
512
522
  const candidate = await selectedSession(command);
@@ -569,6 +579,8 @@ export async function startDesktopHost({ input = process.stdin, output = process
569
579
  };
570
580
  if (["login", "organization_select", "organization_cancel", "authorization_open"].includes(command.action)) {
571
581
  authorizationQueue = authorizationQueue.then(execute).catch(() => {});
582
+ } else if (command.action === "session_set_auto_continue") {
583
+ preferenceQueue = preferenceQueue.then(execute).catch(() => {});
572
584
  } else {
573
585
  queue = queue.then(async () => {
574
586
  activeQueuedAction = command.action;