@awak-app/simy-cli 0.6.16 → 0.6.18

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.
Files changed (42) hide show
  1. package/README.md +99 -6
  2. package/package.json +1 -1
  3. package/src/agent.js +123 -28
  4. package/src/auto-update.js +15 -3
  5. package/src/cli-contract.js +1 -1
  6. package/src/codex-plugins/simy/hooks/connection-reminder.mjs +5 -2
  7. package/src/codex-plugins/simy/hooks/delivery-loop.mjs +30 -3
  8. package/src/codex-plugins/simy/hooks/dev-work.mjs +7 -1
  9. package/src/codex-plugins/simy/hooks/hooks.json +2 -2
  10. package/src/codex-work-pattern-sync.js +37 -9
  11. package/src/delivery-hooks/command.js +9 -2
  12. package/src/delivery-hooks/desktop.js +10 -12
  13. package/src/delivery-hooks/evidence.js +50 -0
  14. package/src/delivery-hooks/supervisor.js +8 -2
  15. package/src/desktop-access.js +4 -3
  16. package/src/desktop-host.js +669 -73
  17. package/src/doctor.js +2 -1
  18. package/src/host-exit-diagnostics.js +28 -0
  19. package/src/index.js +1 -0
  20. package/src/native-development-report-completion.js +143 -0
  21. package/src/native-development-reports.js +137 -0
  22. package/src/orchestrator/checklist-continuation.js +5 -0
  23. package/src/orchestrator/delivery/WORKFLOW.md +4 -0
  24. package/src/orchestrator/delivery/references/state-model.md +187 -0
  25. package/src/orchestrator/loop.js +119 -34
  26. package/src/provider-links.js +74 -0
  27. package/src/runner.js +31 -2
  28. package/src/session-supervision/automatic-continuation.js +31 -2
  29. package/src/session-supervision/claude-sessions.js +25 -15
  30. package/src/session-supervision/codex-app-server.js +27 -4
  31. package/src/session-supervision/index.js +163 -42
  32. package/src/session-supervision/statistics.js +76 -15
  33. package/src/sqm/command.js +58 -7
  34. package/src/sqm/evidence-client.js +11 -1
  35. package/src/sqm/failure-circuit.js +28 -6
  36. package/src/sqm/history-store.js +49 -18
  37. package/src/sqm/provider-diagnostics.js +1 -0
  38. package/src/sqm/review-worker.js +70 -21
  39. package/src/sqm/workflow-update.js +12 -3
  40. package/src/windows-bootstrap.js +2 -1
  41. package/src/windows-desktop-updater.js +6 -1
  42. package/src/windows-inbound.js +9 -0
@@ -1,3 +1,4 @@
1
+ import { setTimeout as delay } from "node:timers/promises";
1
2
  import { mkdir, readFile, realpath, rm, stat } from "node:fs/promises";
2
3
  import { homedir } from "node:os";
3
4
  import path from "node:path";
@@ -36,6 +37,7 @@ export async function syncInstalledWorkflows({ home = homedir(), installMissing
36
37
  claudeHome = process.env.CLAUDE_CONFIG_DIR || path.join(home, ".claude"),
37
38
  inspect = inspectSqmAgentSkill, install = installSqmAgentSkill,
38
39
  resolveExecutable = resolveBackendExecutable, run = runProviderCommand,
40
+ lockWaitMs = 0, wait = delay, now = Date.now,
39
41
  } = {}) {
40
42
  // Multiple daemons may share the same installation. Serialize updates and recover
41
43
  // an abandoned lock after more than the bounded Codex command timeouts.
@@ -44,9 +46,16 @@ export async function syncInstalledWorkflows({ home = homedir(), installMissing
44
46
  try {
45
47
  if (Date.now() - (await stat(lock)).mtimeMs > 5 * 60 * 1000) await rm(lock, { recursive: true, force: true });
46
48
  } catch (error) { if (error.code !== "ENOENT") throw error; }
47
- try { await mkdir(lock); } catch (error) {
48
- if (error.code === "EEXIST") return { outcome: "busy" };
49
- throw error;
49
+ const deadline = now() + (Number.isFinite(lockWaitMs) ? Math.max(0, Math.min(lockWaitMs, 30_000)) : 0);
50
+ for (;;) {
51
+ try { await mkdir(lock); break; } catch (error) {
52
+ if (error.code !== "EEXIST") throw error;
53
+ const remaining = deadline - now();
54
+ if (remaining <= 0) return { outcome: "busy" };
55
+ // Explicit setup can join an ongoing background update. Reinspect after
56
+ // acquiring the lock; a background update may not prepare missing sources.
57
+ await wait(Math.min(remaining, 250));
58
+ }
50
59
  }
51
60
  try {
52
61
  const migrated = await retireLegacySqmGate({ home });
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import { existsSync } from 'node:fs';
4
4
  import { spawn } from 'node:child_process';
5
5
  import { maintainWindowsUpdate, selectedWindowsRoot } from './windows-update.js';
6
+ import { desktopArguments } from './windows-inbound.js';
6
7
  const installation = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
7
8
  const stateRoot = path.join(process.env.LOCALAPPDATA, 'SIMY CLI', 'updates');
8
9
  const argv = process.argv.slice(2);
@@ -22,7 +23,7 @@ if (updating) {
22
23
  const desktop = argv[0] === '--desktop';
23
24
  if (desktop && !existsSync(path.join(root, 'simy-desktop.exe'))) root = installation;
24
25
  const child = spawn(path.join(root, desktop ? 'simy-desktop.exe' : 'runtime/node.exe'),
25
- desktop ? ['--selected'] : [path.join(root, 'cli/src/index.js'), ...argv], {
26
+ desktop ? desktopArguments(argv) : [path.join(root, 'cli/src/index.js'), ...argv], {
26
27
  stdio: 'inherit', env: { ...process.env, ...(desktop ? {} : { SIMY_AUTO_UPDATE: '0' }) },
27
28
  });
28
29
  // Windows console signals are already delivered to both processes.
@@ -31,7 +31,12 @@ export function createWindowsDesktopUpdater({ version, fetchImpl = fetch, open =
31
31
  } catch { update({ state: 'failed', message: 'Could not check for updates. Try again.', action: null }); }
32
32
  return events.snapshot();
33
33
  })().finally(() => { pending = null; });
34
- events.performAction = async () => { if (state.action?.url) await open(state.action.url); else await events.checkNow(); };
34
+ events.performAction = async () => {
35
+ if (state.action?.url) {
36
+ const result = await open(state.action.url);
37
+ if (result?.opened === false) throw new Error('Could not open the update installer download.');
38
+ } else await events.checkNow();
39
+ };
35
40
  events.maybeApply = events.performAction;
36
41
  events.beginWork = () => () => {};
37
42
  events.acceptsNewWork = () => true;
@@ -0,0 +1,9 @@
1
+ // Keep the URI handoff separate from update and launch code so its exact
2
+ // command shape is covered by a platform-neutral test. desktop.cs remains the
3
+ // authority that validates the URI before it changes a visible selection.
4
+ export function desktopArguments(argv) {
5
+ // This internal marker distinguishes the desktop spawned by the update
6
+ // bootstrap from the bootstrap itself. It carries no inbound URI.
7
+ if (argv.length === 1) return ['--selected'];
8
+ return ['--selected', ...argv.slice(1)];
9
+ }