@awak-app/simy-cli 0.5.8 → 0.5.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/README.md +41 -0
- package/package.json +7 -3
- package/src/agent.js +70 -9
- package/src/auto-update.js +312 -35
- package/src/browser.js +24 -7
- package/src/cli-contract.js +1 -1
- package/src/codex-plugins/simy/skills/agentic-delivery-loop/SKILL.md +172 -12
- package/src/codex-plugins/simy/skills/agentic-delivery-loop/references/acceptance-evidence.md +130 -0
- package/src/codex-plugins/simy/skills/agentic-delivery-loop/references/change-boundary-matrix.md +20 -1
- package/src/codex-plugins/simy/skills/agentic-delivery-loop/references/cross-repository-control.md +76 -0
- package/src/codex-plugins/simy/skills/agentic-delivery-loop/references/delivery-levels.md +76 -0
- package/src/codex-plugins/simy/skills/agentic-delivery-loop/references/state-and-receipts.md +15 -0
- package/src/codex-plugins/simy/skills/agentic-delivery-loop/scripts/check-acceptance.mjs +191 -0
- package/src/console/app.js +21 -2
- package/src/console/commands.js +3 -0
- package/src/desktop-host.js +220 -0
- package/src/desktop-process-lock.js +231 -0
- package/src/desktop-status.js +263 -0
- package/src/direct-executor.js +6 -0
- package/src/index.js +37 -11
- package/src/install-update.js +494 -0
package/README.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
Local execution agent for SIMY Local Tasks and Agentic Loop runs.
|
|
4
4
|
|
|
5
|
+
## Apple Silicon Mac app
|
|
6
|
+
|
|
7
|
+
The macOS installer includes a native status window and menu bar app. Open
|
|
8
|
+
SIMY CLI from Applications and choose **Sign in**. The window shows SIMY login,
|
|
9
|
+
the connected Web address and last successful heartbeat, Codex installation and
|
|
10
|
+
login status, tasks, and updates separately. A Codex login check does not prove
|
|
11
|
+
that a task can execute successfully; permissions and service availability are
|
|
12
|
+
checked when work starts.
|
|
13
|
+
|
|
14
|
+
Closing the window keeps the agent running. Open the app again or choose
|
|
15
|
+
**Show SIMY CLI** from its menu bar icon to return. **Quit SIMY CLI** asks before
|
|
16
|
+
interrupting active tasks. The normal `simy` command remains available.
|
|
17
|
+
|
|
18
|
+
Signed patch/minor updates wait for idle and verify the new runtime before
|
|
19
|
+
handoff; failed startup restores the previous installed version. After a runtime
|
|
20
|
+
update, quit and reopen the app to load an updated native interface. The status
|
|
21
|
+
window reports App and runtime versions separately while they differ.
|
|
22
|
+
|
|
23
|
+
For development, `npm run build:macos-installer:dev` creates an unsigned app/DMG;
|
|
24
|
+
production builds require Developer ID signing and notarization. Never publish
|
|
25
|
+
unsigned development artifacts through the stable update manifest.
|
|
26
|
+
|
|
5
27
|
For normal use, install SIMY globally and keep its background agent running:
|
|
6
28
|
|
|
7
29
|
```bash
|
|
@@ -373,6 +395,13 @@ processes, and exercises HIL plus lifecycle controls. It regenerates the
|
|
|
373
395
|
screenshots, terminal frames, raw transcript, and SHA-256 manifest under
|
|
374
396
|
`docs/pr-evidence/cli-agentic-loop-console/`.
|
|
375
397
|
|
|
398
|
+
## Delivery Loop design proposals
|
|
399
|
+
|
|
400
|
+
The [minimum completion plan](docs/delivery-minimum-completion/README.md) describes
|
|
401
|
+
proposed checks for omitted requirements, inactive controls, unsaved results, and
|
|
402
|
+
broken integrations at every delivery level, with workflow, sequence, and state
|
|
403
|
+
diagrams. This is a design proposal, not a shipped completion guarantee.
|
|
404
|
+
|
|
376
405
|
## Publishing
|
|
377
406
|
|
|
378
407
|
Publishing is handled by GitHub Actions in `.github/workflows/publish.yml`.
|
|
@@ -397,6 +426,18 @@ organization-wide bundle.
|
|
|
397
426
|
|
|
398
427
|
### Submit repaired local delivery evidence to SQM
|
|
399
428
|
|
|
429
|
+
The bundled Delivery Loop maintains an external acceptance checklist with separate
|
|
430
|
+
user-journey and technical-invariant results. It refreshes the table after each
|
|
431
|
+
evaluated action and marks evidence pending when the code or runtime context
|
|
432
|
+
changes. The [acceptance evidence guide](src/codex-plugins/simy/skills/agentic-delivery-loop/references/acceptance-evidence.md)
|
|
433
|
+
documents the offline validator shipped inside the skill. Its result establishes
|
|
434
|
+
record completeness and artifact integrity, not overall delivery or deployment.
|
|
435
|
+
At the start of each new run, the loop recommends and confirms one of five
|
|
436
|
+
[delivery levels](src/codex-plugins/simy/skills/agentic-delivery-loop/references/delivery-levels.md)
|
|
437
|
+
in chat. Risk-based ceilings keep sensitive or consequential changes on the
|
|
438
|
+
required safety level; the selection adjusts verification depth but grants no
|
|
439
|
+
additional authority.
|
|
440
|
+
|
|
400
441
|
`simy sqm submit-evidence --file delivery.json --host https://app-dev.simy.one`
|
|
401
442
|
submits an explicit bounded summary through your existing organization-bound device
|
|
402
443
|
session. `--dry-run` previews the exact document without uploading it. See the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awak-app/simy-cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.10",
|
|
4
4
|
"description": "Local SIMY executor for non-coding Local Tasks and Agentic Loop runs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -40,8 +40,12 @@
|
|
|
40
40
|
"check:auto-update": "node --check ./src/auto-update.js && node --check ./scripts/auto-update-e2e.js && npm run check:sqm",
|
|
41
41
|
"check:sqm": "node --check ./src/sqm/canonical.js && node --check ./src/sqm/validation.js && node --check ./src/sqm/reliability.js && node --check ./src/sqm/repository.js && node --check ./src/sqm/checkers.js && node --check ./src/sqm/bundle-store.js && node --check ./src/sqm/proof.js && node --check ./src/sqm/evidence-client.js && node --check ./src/sqm/session.js && node --check ./src/sqm/index.js && node --check ./src/sqm/command.js && node --check ./src/sqm/agent-skill.js && node --check ./src/sqm/workflow-onboarding.js && node --check ./src/sqm/workflow-update.js && node --check ./src/sqm/review-worker.js && node --check ./scripts/sqm-complete-loop-e2e.js && node --check ./scripts/sqm-local-review-e2e.js",
|
|
42
42
|
"check:real-provider-syntax": "node --check ./scripts/real-codex-probe.js && node --check ./scripts/real-claude-probe.js && node --check ./scripts/real-provider-console-fixture.js && node --check ./scripts/real-provider-console-e2e.js",
|
|
43
|
-
"check:syntax": "node --check ./src/index.js && node --check ./src/agent.js && node --check ./src/browser.js && node --check ./src/web-api.js && node --check ./src/durable-local-task-worker.js && node --check ./src/durable-local-task-steps-contract.js && node --check ./src/bounded-local-task-subtasks-contract.js && node --check ./src/bounded-local-task-subtask-pool.js && node --check ./src/local-task-artifact-contract.js && node --check ./src/execution-capability-contract.js && node --check ./src/shutdown.js && node --check ./src/run-registry.js && node --check ./src/direct-executor.js && node --check ./src/execution-guardrail.js && node --check ./src/backend-executable.js && node --check ./src/provider-stream.js && node --check ./src/console/index.js && node --check ./src/console/app.js && node --check ./src/console/commands.js && node --check ./src/local-attachments.js && node --check ./src/repository-inventory.js && node --check ./src/session-store.js && node --check ./src/web-origin.js && node --check ./src/workspace-context.js && node --check ./src/orchestrator/index.js && node --check ./src/orchestrator/shared.js && node --check ./src/orchestrator/recovery.js && node --check ./src/orchestrator/risk.js && node --check ./src/orchestrator/contract.js && node --check ./src/orchestrator/completion-contract.js && node --check ./src/orchestrator/instruction.js && node --check ./src/orchestrator/problem-solving.js && node --check ./src/orchestrator/budget.js && node --check ./src/orchestrator/execution-io.js && node --check ./src/orchestrator/presentation.js && node --check ./src/orchestrator/result.js && node --check ./src/orchestrator/retry.js && node --check ./src/orchestrator/evidence.js && node --check ./src/orchestrator/independent-audit.js && node --check ./src/orchestrator/audit.js && node --check ./src/orchestrator/loop.js && node --check ./src/runner.js && node --check ./scripts/fixtures/completion-contract-fixture.js && node --check ./scripts/fixtures/fake-coding-backend.js && node --check ./scripts/e2e-terminal-evidence.js && node --check ./scripts/audit-gate-e2e.js && node --check ./scripts/completion-contract-e2e.js && node --check ./scripts/retry-circuit-e2e.js && node --check ./scripts/follow-up-charter-e2e.js && node --check ./scripts/task-routing-e2e.js && node --check ./scripts/executor-version-preflight-e2e.js && node --check ./scripts/blocked-recovery-e2e.js && node --check ./scripts/process-localization-e2e.js && node --check ./scripts/hypothesis-retries-e2e.js && node --check ./scripts/budget-enforcement-e2e.js && node --check ./scripts/local-task-default-workspace-e2e.js && node --check ./scripts/local-task-idempotency-e2e.js && node --check ./scripts/console-e2e-fixture.js && node --check ./scripts/console-e2e.js && node --check ./scripts/console-recovery-e2e-fixture.js && node --check ./scripts/console-recovery-e2e.js && node --check ./scripts/real-provider-console-fixture.js && node --check ./scripts/real-provider-console-e2e.js && node --check ./scripts/fullstack-cli-smoke.js && node --check ./scripts/check-package-contents.js",
|
|
44
|
-
"check:package": "node ./scripts/check-package-contents.js"
|
|
43
|
+
"check:syntax": "node --check ./src/index.js && node --check ./src/install-update.js && node --check ./src/agent.js && node --check ./src/browser.js && node --check ./src/web-api.js && node --check ./src/durable-local-task-worker.js && node --check ./src/durable-local-task-steps-contract.js && node --check ./src/bounded-local-task-subtasks-contract.js && node --check ./src/bounded-local-task-subtask-pool.js && node --check ./src/local-task-artifact-contract.js && node --check ./src/execution-capability-contract.js && node --check ./src/shutdown.js && node --check ./src/run-registry.js && node --check ./src/direct-executor.js && node --check ./src/execution-guardrail.js && node --check ./src/backend-executable.js && node --check ./src/provider-stream.js && node --check ./src/console/index.js && node --check ./src/console/app.js && node --check ./src/console/commands.js && node --check ./src/local-attachments.js && node --check ./src/repository-inventory.js && node --check ./src/session-store.js && node --check ./src/web-origin.js && node --check ./src/workspace-context.js && node --check ./src/orchestrator/index.js && node --check ./src/orchestrator/shared.js && node --check ./src/orchestrator/recovery.js && node --check ./src/orchestrator/risk.js && node --check ./src/orchestrator/contract.js && node --check ./src/orchestrator/completion-contract.js && node --check ./src/orchestrator/instruction.js && node --check ./src/orchestrator/problem-solving.js && node --check ./src/orchestrator/budget.js && node --check ./src/orchestrator/execution-io.js && node --check ./src/orchestrator/presentation.js && node --check ./src/orchestrator/result.js && node --check ./src/orchestrator/retry.js && node --check ./src/orchestrator/evidence.js && node --check ./src/orchestrator/independent-audit.js && node --check ./src/orchestrator/audit.js && node --check ./src/orchestrator/loop.js && node --check ./src/runner.js && node --check ./scripts/fixtures/completion-contract-fixture.js && node --check ./scripts/fixtures/fake-coding-backend.js && node --check ./scripts/e2e-terminal-evidence.js && node --check ./scripts/audit-gate-e2e.js && node --check ./scripts/completion-contract-e2e.js && node --check ./scripts/retry-circuit-e2e.js && node --check ./scripts/follow-up-charter-e2e.js && node --check ./scripts/task-routing-e2e.js && node --check ./scripts/executor-version-preflight-e2e.js && node --check ./scripts/blocked-recovery-e2e.js && node --check ./scripts/process-localization-e2e.js && node --check ./scripts/hypothesis-retries-e2e.js && node --check ./scripts/budget-enforcement-e2e.js && node --check ./scripts/local-task-default-workspace-e2e.js && node --check ./scripts/local-task-idempotency-e2e.js && node --check ./scripts/console-e2e-fixture.js && node --check ./scripts/console-e2e.js && node --check ./scripts/console-recovery-e2e-fixture.js && node --check ./scripts/console-recovery-e2e.js && node --check ./scripts/real-provider-console-fixture.js && node --check ./scripts/real-provider-console-e2e.js && node --check ./scripts/fullstack-cli-smoke.js && node --check ./scripts/check-package-contents.js",
|
|
44
|
+
"check:package": "node ./scripts/check-package-contents.js",
|
|
45
|
+
"build:macos-installer:dev": "bash packaging/build-macos-arm64.sh --unsigned-dev",
|
|
46
|
+
"build:macos-installer": "bash packaging/build-macos-arm64.sh --production",
|
|
47
|
+
"test:macos-installer": "node --test packaging/test-macos-packaging.mjs",
|
|
48
|
+
"build:macos-installer:production": "bash packaging/build-macos-arm64.sh --production"
|
|
45
49
|
},
|
|
46
50
|
"engines": {
|
|
47
51
|
"node": ">=20"
|
package/src/agent.js
CHANGED
|
@@ -48,6 +48,12 @@ import {
|
|
|
48
48
|
inspectDesktopExecutor,
|
|
49
49
|
normalizeDesktopExecutionTarget,
|
|
50
50
|
} from "./desktop-executor.js";
|
|
51
|
+
import {
|
|
52
|
+
createCodexStatusInspector,
|
|
53
|
+
createConnectionStatusTracker,
|
|
54
|
+
desktopAuthStatus,
|
|
55
|
+
desktopTaskStatus,
|
|
56
|
+
} from "./desktop-status.js";
|
|
51
57
|
import { recoveryContractForPreflight } from "./orchestrator/recovery.js";
|
|
52
58
|
import {
|
|
53
59
|
DEFAULT_RETRY_BUDGET,
|
|
@@ -237,6 +243,25 @@ export async function startAgent({
|
|
|
237
243
|
let heartbeatInFlight = null;
|
|
238
244
|
let durableLocalTaskWorker = null;
|
|
239
245
|
let sqmLocalReviewWorker = null;
|
|
246
|
+
let loginUrl = null;
|
|
247
|
+
const connectionStatus = createConnectionStatusTracker({ now: dependencies.statusNow });
|
|
248
|
+
const codexStatus = createCodexStatusInspector({
|
|
249
|
+
inspect: dependencies.inspectCodexStatus,
|
|
250
|
+
now: dependencies.statusNowMs,
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
const requestDesktopLogin = () => {
|
|
254
|
+
if (isSessionValid(session, Date.now(), apiOrigin)) return null;
|
|
255
|
+
if (!loginUrl) {
|
|
256
|
+
loginUrl = new URL("/local-cli/connect", apiOrigin);
|
|
257
|
+
loginUrl.searchParams.set("port", String(port));
|
|
258
|
+
loginUrl.searchParams.set("nonce", authNonce);
|
|
259
|
+
loginUrl.searchParams.set("cli_version", CLI_VERSION);
|
|
260
|
+
loginUrl.searchParams.set("api_contract_version", String(CLI_API_CONTRACT_VERSION));
|
|
261
|
+
if (installMode) loginUrl.searchParams.set("install_mode", installMode);
|
|
262
|
+
}
|
|
263
|
+
return loginUrl.toString();
|
|
264
|
+
};
|
|
240
265
|
|
|
241
266
|
const restoreRemoteRuns = async () => {
|
|
242
267
|
if (!isSessionValid(session, Date.now(), apiOrigin) || !session?.device_id) return;
|
|
@@ -268,6 +293,8 @@ export async function startAgent({
|
|
|
268
293
|
const heartbeat = () => {
|
|
269
294
|
if (!isSessionValid(session, Date.now(), apiOrigin)) return Promise.resolve(false);
|
|
270
295
|
if (heartbeatInFlight) return heartbeatInFlight;
|
|
296
|
+
connectionStatus.attempt();
|
|
297
|
+
let deviceHeartbeatSucceeded = false;
|
|
271
298
|
heartbeatInFlight = Promise.resolve()
|
|
272
299
|
.then(() =>
|
|
273
300
|
heartbeatDevice({
|
|
@@ -280,12 +307,26 @@ export async function startAgent({
|
|
|
280
307
|
}),
|
|
281
308
|
)
|
|
282
309
|
.then(async () => {
|
|
310
|
+
deviceHeartbeatSucceeded = true;
|
|
311
|
+
connectionStatus.success();
|
|
283
312
|
const sqmResult = sqmLocalReviewWorker
|
|
284
313
|
? await sqmLocalReviewWorker.poll()
|
|
285
314
|
: null;
|
|
286
315
|
if (!sqmResult && durableLocalTaskWorker) await durableLocalTaskWorker.poll();
|
|
287
316
|
return true;
|
|
288
317
|
})
|
|
318
|
+
.catch((error) => {
|
|
319
|
+
if (!deviceHeartbeatSucceeded) {
|
|
320
|
+
const state = connectionStatus.failure(error);
|
|
321
|
+
if (state === "unauthorized") {
|
|
322
|
+
session = null;
|
|
323
|
+
loginUrl = null;
|
|
324
|
+
refreshAvailableCapabilities();
|
|
325
|
+
requestDesktopLogin();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
throw error;
|
|
329
|
+
})
|
|
289
330
|
.finally(() => {
|
|
290
331
|
heartbeatInFlight = null;
|
|
291
332
|
});
|
|
@@ -1530,14 +1571,8 @@ export async function startAgent({
|
|
|
1530
1571
|
console.log(`SIMY Web host: ${apiOrigin}`);
|
|
1531
1572
|
}
|
|
1532
1573
|
|
|
1533
|
-
let loginUrl = null;
|
|
1534
1574
|
if (!isSessionValid(session, Date.now(), apiOrigin)) {
|
|
1535
|
-
|
|
1536
|
-
loginUrl.searchParams.set("port", String(port));
|
|
1537
|
-
loginUrl.searchParams.set("nonce", authNonce);
|
|
1538
|
-
loginUrl.searchParams.set("cli_version", CLI_VERSION);
|
|
1539
|
-
loginUrl.searchParams.set("api_contract_version", String(CLI_API_CONTRACT_VERSION));
|
|
1540
|
-
if (installMode) loginUrl.searchParams.set("install_mode", installMode);
|
|
1575
|
+
requestDesktopLogin();
|
|
1541
1576
|
if (!quiet) {
|
|
1542
1577
|
console.log(`Sign in to SIMY: ${loginUrl.toString()}`);
|
|
1543
1578
|
console.log(`Session file: ${sessionPath(apiOrigin, sessionRoot)}`);
|
|
@@ -1571,6 +1606,21 @@ export async function startAgent({
|
|
|
1571
1606
|
server.on("close", () => {
|
|
1572
1607
|
void shutdown().catch((error) => reportDurableLocalTaskError(error, quiet));
|
|
1573
1608
|
});
|
|
1609
|
+
const getDesktopStatus = async () => {
|
|
1610
|
+
const auth = desktopAuthStatus(session, { webOrigin: apiOrigin });
|
|
1611
|
+
return {
|
|
1612
|
+
schemaVersion: 1,
|
|
1613
|
+
sampledAt: new Date().toISOString(),
|
|
1614
|
+
version: CLI_VERSION,
|
|
1615
|
+
webOrigin: apiOrigin,
|
|
1616
|
+
auth,
|
|
1617
|
+
connection: connectionStatus.snapshot({ authenticated: auth.state === "signed_in" }),
|
|
1618
|
+
tasks: desktopTaskStatus([registry, directRegistry, localTaskRegistry]),
|
|
1619
|
+
update: updateManager?.snapshot?.() ?? null,
|
|
1620
|
+
codex: await codexStatus(),
|
|
1621
|
+
loginUrl: auth.state === "signed_in" ? null : requestDesktopLogin(),
|
|
1622
|
+
};
|
|
1623
|
+
};
|
|
1574
1624
|
return {
|
|
1575
1625
|
server,
|
|
1576
1626
|
port,
|
|
@@ -1582,8 +1632,17 @@ export async function startAgent({
|
|
|
1582
1632
|
shutdown,
|
|
1583
1633
|
webOrigin: apiOrigin,
|
|
1584
1634
|
get loginUrl() {
|
|
1585
|
-
return
|
|
1635
|
+
return requestDesktopLogin();
|
|
1636
|
+
},
|
|
1637
|
+
requestDesktopLogin,
|
|
1638
|
+
getDesktopStatus,
|
|
1639
|
+
async refreshDesktopStatus() {
|
|
1640
|
+
if (isSessionValid(session, Date.now(), apiOrigin)) {
|
|
1641
|
+
await heartbeat().catch((error) => reportHeartbeatError(error, quiet));
|
|
1642
|
+
}
|
|
1643
|
+
return getDesktopStatus();
|
|
1586
1644
|
},
|
|
1645
|
+
refreshCodexStatus: () => codexStatus({ force: true }),
|
|
1587
1646
|
workspace,
|
|
1588
1647
|
repositoryScanRoot,
|
|
1589
1648
|
get capabilities() {
|
|
@@ -1778,7 +1837,9 @@ export async function heartbeatLocalDevice({
|
|
|
1778
1837
|
);
|
|
1779
1838
|
if (!response.ok) {
|
|
1780
1839
|
const payload = await response.json().catch(() => null);
|
|
1781
|
-
|
|
1840
|
+
const error = new Error(webApiErrorMessage(payload, response.status));
|
|
1841
|
+
error.status = response.status;
|
|
1842
|
+
throw error;
|
|
1782
1843
|
}
|
|
1783
1844
|
}
|
|
1784
1845
|
|