@oratis/lisa 0.8.0 → 0.11.0
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 +123 -16
- package/README.zh-CN.md +101 -15
- package/completions/_lisa +56 -0
- package/completions/lisa.bash +35 -1
- package/completions/lisa.fish +18 -1
- package/dist/advisor/engine.d.ts +7 -0
- package/dist/advisor/engine.d.ts.map +1 -1
- package/dist/advisor/engine.js +12 -0
- package/dist/advisor/engine.js.map +1 -1
- package/dist/agent.d.ts +14 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +58 -7
- package/dist/agent.js.map +1 -1
- package/dist/agents/managed.d.ts +108 -0
- package/dist/agents/managed.d.ts.map +1 -0
- package/dist/agents/managed.js +241 -0
- package/dist/agents/managed.js.map +1 -0
- package/dist/agents/pty.d.ts +155 -0
- package/dist/agents/pty.d.ts.map +1 -0
- package/dist/agents/pty.js +299 -0
- package/dist/agents/pty.js.map +1 -0
- package/dist/approval.d.ts +13 -0
- package/dist/approval.d.ts.map +1 -1
- package/dist/approval.js +25 -2
- package/dist/approval.js.map +1 -1
- package/dist/autonomy/runs.d.ts +33 -0
- package/dist/autonomy/runs.d.ts.map +1 -0
- package/dist/autonomy/runs.js +106 -0
- package/dist/autonomy/runs.js.map +1 -0
- package/dist/channels/feishu.d.ts.map +1 -1
- package/dist/channels/feishu.js +65 -0
- package/dist/channels/feishu.js.map +1 -1
- package/dist/channels/router.d.ts +7 -0
- package/dist/channels/router.d.ts.map +1 -1
- package/dist/channels/router.js +1 -1
- package/dist/channels/router.js.map +1 -1
- package/dist/cli/agents-pty.d.ts +18 -0
- package/dist/cli/agents-pty.d.ts.map +1 -0
- package/dist/cli/agents-pty.js +182 -0
- package/dist/cli/agents-pty.js.map +1 -0
- package/dist/cli/agents.d.ts +2 -0
- package/dist/cli/agents.d.ts.map +1 -0
- package/dist/cli/agents.js +65 -0
- package/dist/cli/agents.js.map +1 -0
- package/dist/cli/consent.d.ts +2 -0
- package/dist/cli/consent.d.ts.map +1 -0
- package/dist/cli/consent.js +57 -0
- package/dist/cli/consent.js.map +1 -0
- package/dist/cli/model.d.ts +2 -0
- package/dist/cli/model.d.ts.map +1 -0
- package/dist/cli/model.js +121 -0
- package/dist/cli/model.js.map +1 -0
- package/dist/cli/sense.d.ts +2 -0
- package/dist/cli/sense.d.ts.map +1 -0
- package/dist/cli/sense.js +36 -0
- package/dist/cli/sense.js.map +1 -0
- package/dist/cli.js +117 -12
- package/dist/cli.js.map +1 -1
- package/dist/consent/blacklist.d.ts +28 -0
- package/dist/consent/blacklist.d.ts.map +1 -0
- package/dist/consent/blacklist.js +78 -0
- package/dist/consent/blacklist.js.map +1 -0
- package/dist/consent/store.d.ts +45 -0
- package/dist/consent/store.d.ts.map +1 -0
- package/dist/consent/store.js +126 -0
- package/dist/consent/store.js.map +1 -0
- package/dist/control/policy.d.ts +13 -0
- package/dist/control/policy.d.ts.map +1 -0
- package/dist/control/policy.js +57 -0
- package/dist/control/policy.js.map +1 -0
- package/dist/heartbeat/runner.d.ts.map +1 -1
- package/dist/heartbeat/runner.js +70 -14
- package/dist/heartbeat/runner.js.map +1 -1
- package/dist/idle/runner.d.ts.map +1 -1
- package/dist/idle/runner.js +87 -17
- package/dist/idle/runner.js.map +1 -1
- package/dist/integrations/aider/observer.d.ts +21 -1
- package/dist/integrations/aider/observer.d.ts.map +1 -1
- package/dist/integrations/aider/observer.js +110 -1
- package/dist/integrations/aider/observer.js.map +1 -1
- package/dist/integrations/claude-code/liveness.d.ts +10 -0
- package/dist/integrations/claude-code/liveness.d.ts.map +1 -0
- package/dist/integrations/claude-code/liveness.js +62 -0
- package/dist/integrations/claude-code/liveness.js.map +1 -0
- package/dist/integrations/claude-code/watcher.d.ts +39 -4
- package/dist/integrations/claude-code/watcher.d.ts.map +1 -1
- package/dist/integrations/claude-code/watcher.js +94 -57
- package/dist/integrations/claude-code/watcher.js.map +1 -1
- package/dist/integrations/codex/observer.d.ts +19 -6
- package/dist/integrations/codex/observer.d.ts.map +1 -1
- package/dist/integrations/codex/observer.js +228 -4
- package/dist/integrations/codex/observer.js.map +1 -1
- package/dist/integrations/dispatch-ledger.d.ts +30 -1
- package/dist/integrations/dispatch-ledger.d.ts.map +1 -1
- package/dist/integrations/dispatch-ledger.js +75 -9
- package/dist/integrations/dispatch-ledger.js.map +1 -1
- package/dist/integrations/git/branch.d.ts +11 -0
- package/dist/integrations/git/branch.d.ts.map +1 -0
- package/dist/integrations/git/branch.js +49 -0
- package/dist/integrations/git/branch.js.map +1 -0
- package/dist/integrations/git/observer.d.ts +39 -0
- package/dist/integrations/git/observer.d.ts.map +1 -0
- package/dist/integrations/git/observer.js +252 -0
- package/dist/integrations/git/observer.js.map +1 -0
- package/dist/integrations/github-pr/observer.d.ts.map +1 -1
- package/dist/integrations/github-pr/observer.js +7 -2
- package/dist/integrations/github-pr/observer.js.map +1 -1
- package/dist/integrations/hub.d.ts +8 -0
- package/dist/integrations/hub.d.ts.map +1 -1
- package/dist/integrations/hub.js +39 -1
- package/dist/integrations/hub.js.map +1 -1
- package/dist/integrations/managed/observer.d.ts +17 -0
- package/dist/integrations/managed/observer.d.ts.map +1 -0
- package/dist/integrations/managed/observer.js +46 -0
- package/dist/integrations/managed/observer.js.map +1 -0
- package/dist/integrations/opencode/observer.d.ts +53 -5
- package/dist/integrations/opencode/observer.d.ts.map +1 -1
- package/dist/integrations/opencode/observer.js +242 -20
- package/dist/integrations/opencode/observer.js.map +1 -1
- package/dist/integrations/pty/observer.d.ts +25 -0
- package/dist/integrations/pty/observer.d.ts.map +1 -0
- package/dist/integrations/pty/observer.js +48 -0
- package/dist/integrations/pty/observer.js.map +1 -0
- package/dist/integrations/registry.d.ts.map +1 -1
- package/dist/integrations/registry.js +5 -0
- package/dist/integrations/registry.js.map +1 -1
- package/dist/integrations/shell/observer.d.ts +33 -0
- package/dist/integrations/shell/observer.d.ts.map +1 -0
- package/dist/integrations/shell/observer.js +223 -0
- package/dist/integrations/shell/observer.js.map +1 -0
- package/dist/integrations/takoapi/a2a.d.ts +38 -0
- package/dist/integrations/takoapi/a2a.d.ts.map +1 -0
- package/dist/integrations/takoapi/a2a.js +70 -0
- package/dist/integrations/takoapi/a2a.js.map +1 -0
- package/dist/integrations/takoapi/ledger.d.ts +32 -0
- package/dist/integrations/takoapi/ledger.d.ts.map +1 -0
- package/dist/integrations/takoapi/ledger.js +96 -0
- package/dist/integrations/takoapi/ledger.js.map +1 -0
- package/dist/integrations/takoapi/observer.d.ts +39 -0
- package/dist/integrations/takoapi/observer.d.ts.map +1 -0
- package/dist/integrations/takoapi/observer.js +102 -0
- package/dist/integrations/takoapi/observer.js.map +1 -0
- package/dist/integrations/types.d.ts +17 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/mcp/client.d.ts +5 -0
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +1 -1
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/config.d.ts +4 -0
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +34 -0
- package/dist/mcp/config.js.map +1 -1
- package/dist/memory/embedding.d.ts +45 -0
- package/dist/memory/embedding.d.ts.map +1 -0
- package/dist/memory/embedding.js +139 -0
- package/dist/memory/embedding.js.map +1 -0
- package/dist/memory/search_tool.d.ts.map +1 -1
- package/dist/memory/search_tool.js +6 -2
- package/dist/memory/search_tool.js.map +1 -1
- package/dist/memory/vector.d.ts +14 -3
- package/dist/memory/vector.d.ts.map +1 -1
- package/dist/memory/vector.js +50 -0
- package/dist/memory/vector.js.map +1 -1
- package/dist/model/local.d.ts +43 -0
- package/dist/model/local.d.ts.map +1 -0
- package/dist/model/local.js +118 -0
- package/dist/model/local.js.map +1 -0
- package/dist/model/plan-usage.d.ts +41 -0
- package/dist/model/plan-usage.d.ts.map +1 -0
- package/dist/model/plan-usage.js +168 -0
- package/dist/model/plan-usage.js.map +1 -0
- package/dist/model/plans.d.ts +73 -0
- package/dist/model/plans.d.ts.map +1 -0
- package/dist/model/plans.js +246 -0
- package/dist/model/plans.js.map +1 -0
- package/dist/orchestrator/recent-recap.d.ts +2 -0
- package/dist/orchestrator/recent-recap.d.ts.map +1 -0
- package/dist/orchestrator/recent-recap.js +20 -0
- package/dist/orchestrator/recent-recap.js.map +1 -0
- package/dist/providers/anthropic.d.ts +1 -0
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +10 -2
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/fallback.d.ts +23 -0
- package/dist/providers/fallback.d.ts.map +1 -0
- package/dist/providers/fallback.js +29 -0
- package/dist/providers/fallback.js.map +1 -0
- package/dist/providers/gemini.d.ts +2 -0
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +24 -10
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +4 -1
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/registry.d.ts +18 -2
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +56 -9
- package/dist/providers/registry.js.map +1 -1
- package/dist/reflect.d.ts +55 -0
- package/dist/reflect.d.ts.map +1 -1
- package/dist/reflect.js +148 -54
- package/dist/reflect.js.map +1 -1
- package/dist/sense/log.d.ts +9 -0
- package/dist/sense/log.d.ts.map +1 -0
- package/dist/sense/log.js +63 -0
- package/dist/sense/log.js.map +1 -0
- package/dist/sense/screen.d.ts +43 -0
- package/dist/sense/screen.d.ts.map +1 -0
- package/dist/sense/screen.js +107 -0
- package/dist/sense/screen.js.map +1 -0
- package/dist/sense/service.d.ts +16 -0
- package/dist/sense/service.d.ts.map +1 -0
- package/dist/sense/service.js +33 -0
- package/dist/sense/service.js.map +1 -0
- package/dist/sense/types.d.ts +35 -0
- package/dist/sense/types.d.ts.map +1 -0
- package/dist/sense/types.js +11 -0
- package/dist/sense/types.js.map +1 -0
- package/dist/sense/voice.d.ts +28 -0
- package/dist/sense/voice.d.ts.map +1 -0
- package/dist/sense/voice.js +64 -0
- package/dist/sense/voice.js.map +1 -0
- package/dist/soul/git.d.ts.map +1 -1
- package/dist/soul/git.js +35 -16
- package/dist/soul/git.js.map +1 -1
- package/dist/soul/store.d.ts +22 -0
- package/dist/soul/store.d.ts.map +1 -1
- package/dist/soul/store.js +69 -14
- package/dist/soul/store.js.map +1 -1
- package/dist/soul/summary.d.ts +10 -0
- package/dist/soul/summary.d.ts.map +1 -0
- package/dist/soul/summary.js +57 -0
- package/dist/soul/summary.js.map +1 -0
- package/dist/soul/tools.d.ts.map +1 -1
- package/dist/soul/tools.js +13 -24
- package/dist/soul/tools.js.map +1 -1
- package/dist/soul/types.d.ts +9 -0
- package/dist/soul/types.d.ts.map +1 -1
- package/dist/soul/types.js.map +1 -1
- package/dist/subagent.d.ts +7 -0
- package/dist/subagent.d.ts.map +1 -1
- package/dist/subagent.js +3 -1
- package/dist/subagent.js.map +1 -1
- package/dist/tools/dispatch_agent.d.ts +13 -1
- package/dist/tools/dispatch_agent.d.ts.map +1 -1
- package/dist/tools/dispatch_agent.js +56 -12
- package/dist/tools/dispatch_agent.js.map +1 -1
- package/dist/tools/dispatch_status.d.ts +22 -0
- package/dist/tools/dispatch_status.d.ts.map +1 -0
- package/dist/tools/dispatch_status.js +57 -0
- package/dist/tools/dispatch_status.js.map +1 -0
- package/dist/tools/github.d.ts +34 -0
- package/dist/tools/github.d.ts.map +1 -0
- package/dist/tools/github.js +140 -0
- package/dist/tools/github.js.map +1 -0
- package/dist/tools/github_link.d.ts +36 -0
- package/dist/tools/github_link.d.ts.map +1 -0
- package/dist/tools/github_link.js +127 -0
- package/dist/tools/github_link.js.map +1 -0
- package/dist/tools/mcp.d.ts +28 -0
- package/dist/tools/mcp.d.ts.map +1 -0
- package/dist/tools/mcp.js +55 -0
- package/dist/tools/mcp.js.map +1 -0
- package/dist/tools/npm_info.d.ts +21 -0
- package/dist/tools/npm_info.d.ts.map +1 -0
- package/dist/tools/npm_info.js +102 -0
- package/dist/tools/npm_info.js.map +1 -0
- package/dist/tools/registry.d.ts +29 -0
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +75 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/run_on_plan.d.ts +46 -0
- package/dist/tools/run_on_plan.d.ts.map +1 -0
- package/dist/tools/run_on_plan.js +89 -0
- package/dist/tools/run_on_plan.js.map +1 -0
- package/dist/tools/takoapi.d.ts +60 -0
- package/dist/tools/takoapi.d.ts.map +1 -0
- package/dist/tools/takoapi.js +181 -0
- package/dist/tools/takoapi.js.map +1 -0
- package/dist/tools/validate.d.ts +22 -0
- package/dist/tools/validate.d.ts.map +1 -0
- package/dist/tools/validate.js +50 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/voice/dictation.d.ts +51 -0
- package/dist/voice/dictation.d.ts.map +1 -0
- package/dist/voice/dictation.js +70 -0
- package/dist/voice/dictation.js.map +1 -0
- package/dist/web/agent-roster.d.ts +56 -0
- package/dist/web/agent-roster.d.ts.map +1 -0
- package/dist/web/agent-roster.js +109 -0
- package/dist/web/agent-roster.js.map +1 -0
- package/dist/web/devices.d.ts +27 -0
- package/dist/web/devices.d.ts.map +1 -0
- package/dist/web/devices.js +113 -0
- package/dist/web/devices.js.map +1 -0
- package/dist/web/island.d.ts +5 -1
- package/dist/web/island.d.ts.map +1 -1
- package/dist/web/island.js +427 -67
- package/dist/web/island.js.map +1 -1
- package/dist/web/lisa-client.d.ts +20 -0
- package/dist/web/lisa-client.d.ts.map +1 -0
- package/dist/web/lisa-client.js +1323 -0
- package/dist/web/lisa-client.js.map +1 -0
- package/dist/web/lisa-css.d.ts +13 -0
- package/dist/web/lisa-css.d.ts.map +1 -0
- package/dist/web/lisa-css.js +1163 -0
- package/dist/web/lisa-css.js.map +1 -0
- package/dist/web/lisa-html.d.ts +1 -1
- package/dist/web/lisa-html.d.ts.map +1 -1
- package/dist/web/lisa-html.js +16 -2091
- package/dist/web/lisa-html.js.map +1 -1
- package/dist/web/push.d.ts +76 -0
- package/dist/web/push.d.ts.map +1 -0
- package/dist/web/push.js +163 -0
- package/dist/web/push.js.map +1 -0
- package/dist/web/server.d.ts +19 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +898 -65
- package/dist/web/server.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** A sensitive ambient signal. Open-ended, but these are the canonical ones. */
|
|
2
|
+
export type ConsentSignal = "screen" | "voice" | "clipboard" | "selection" | (string & {});
|
|
3
|
+
/** The ambient-sense signals — all OFF until the user explicitly grants each. */
|
|
4
|
+
export declare const SENSE_SIGNALS: ConsentSignal[];
|
|
5
|
+
/** Human-facing "what does enabling this capture?" — shown on the consent card. */
|
|
6
|
+
export declare const SIGNAL_DESCRIPTIONS: Record<string, string>;
|
|
7
|
+
export interface ConsentGrant {
|
|
8
|
+
granted: boolean;
|
|
9
|
+
/** ISO timestamp of the most recent grant. */
|
|
10
|
+
grantedAt?: string;
|
|
11
|
+
/** Per-signal options (e.g. { retentionDays, everySec }). */
|
|
12
|
+
options?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
export interface ConsentState {
|
|
15
|
+
grants: Record<string, ConsentGrant>;
|
|
16
|
+
}
|
|
17
|
+
/** Read the consent state; tolerant of a missing or corrupt file (all-off). */
|
|
18
|
+
export declare function loadConsent(): ConsentState;
|
|
19
|
+
/**
|
|
20
|
+
* THE GATE. True only if the signal has been explicitly granted. Absent /
|
|
21
|
+
* revoked / corrupt-file → false (fail closed). Every source calls this before
|
|
22
|
+
* capturing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isGranted(signal: ConsentSignal): boolean;
|
|
25
|
+
/** Grant a signal (records grantedAt + optional options). Returns new state. */
|
|
26
|
+
export declare function grant(signal: ConsentSignal, options?: Record<string, unknown>, now?: number): ConsentState;
|
|
27
|
+
/** Revoke one signal (keeps a record that it's off). Returns new state. */
|
|
28
|
+
export declare function revoke(signal: ConsentSignal): ConsentState;
|
|
29
|
+
/** One-tap stop-all: flip every known grant off. Returns new state. */
|
|
30
|
+
export declare function revokeAll(): ConsentState;
|
|
31
|
+
export interface ConsentRow {
|
|
32
|
+
signal: string;
|
|
33
|
+
granted: boolean;
|
|
34
|
+
grantedAt?: string;
|
|
35
|
+
options?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
/** All canonical signals + any extra recorded ones, with current status. */
|
|
38
|
+
export declare function listGrants(): ConsentRow[];
|
|
39
|
+
/**
|
|
40
|
+
* Retention primitive: is a captured item past its retention window? Pure;
|
|
41
|
+
* sources/cleanup call this so raw never lingers past `retentionDays`.
|
|
42
|
+
* retentionDays ≤ 0 / non-finite → treated as "expire immediately" (fail safe).
|
|
43
|
+
*/
|
|
44
|
+
export declare function isExpired(capturedAtMs: number, retentionDays: number, now?: number): boolean;
|
|
45
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/consent/store.ts"],"names":[],"mappings":"AAoBA,gFAAgF;AAChF,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,OAAO,GACP,WAAW,GACX,WAAW,GACX,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,iFAAiF;AACjF,eAAO,MAAM,aAAa,EAAE,aAAa,EAAkD,CAAC;AAE5F,mFAAmF;AACnF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKtD,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACtC;AAWD,+EAA+E;AAC/E,wBAAgB,WAAW,IAAI,YAAY,CAgB1C;AAQD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAExD;AAED,gFAAgF;AAChF,wBAAgB,KAAK,CACnB,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,GAAG,GAAE,MAAmB,GACvB,YAAY,CASd;AAED,2EAA2E;AAC3E,wBAAgB,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,YAAY,CAK1D;AAED,uEAAuE;AACvE,wBAAgB,SAAS,IAAI,YAAY,CAYxC;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,IAAI,UAAU,EAAE,CAYzC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,GAAG,GAAE,MAAmB,GACvB,OAAO,CAGT"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified consent store (FOUNDATIONS §1 — the master constraint for Sense).
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth at ~/.lisa/consent.json. Every sensitive ambient
|
|
5
|
+
* signal source (screen / voice / clipboard / selection) must check
|
|
6
|
+
* `isGranted(signal)` before it captures anything — ungranted → no-op, never
|
|
7
|
+
* "capture first, ask later". Default is ALL OFF: an absent signal is denied.
|
|
8
|
+
*
|
|
9
|
+
* This is the framework S2 (ambient vision/voice) builds on; it ships before any
|
|
10
|
+
* source so the gate exists from day one. UI surfacing (island SENSE indicator
|
|
11
|
+
* + one-tap revoke) lands with the first source — the CLI (`lisa consent`) gives
|
|
12
|
+
* control in the meantime.
|
|
13
|
+
*
|
|
14
|
+
* Back-compat: a brand-new, independent file; its absence means "nothing
|
|
15
|
+
* granted", i.e. exactly the pre-existing behavior.
|
|
16
|
+
*/
|
|
17
|
+
import fs from "node:fs";
|
|
18
|
+
import os from "node:os";
|
|
19
|
+
import path from "node:path";
|
|
20
|
+
/** The ambient-sense signals — all OFF until the user explicitly grants each. */
|
|
21
|
+
export const SENSE_SIGNALS = ["screen", "voice", "clipboard", "selection"];
|
|
22
|
+
/** Human-facing "what does enabling this capture?" — shown on the consent card. */
|
|
23
|
+
export const SIGNAL_DESCRIPTIONS = {
|
|
24
|
+
screen: "foreground app/window names and (optionally) low-frequency screenshots",
|
|
25
|
+
voice: "microphone audio for push-to-talk transcription",
|
|
26
|
+
clipboard: "clipboard contents when you copy",
|
|
27
|
+
selection: "text you select / point at",
|
|
28
|
+
};
|
|
29
|
+
function lisaHome() {
|
|
30
|
+
return process.env.LISA_HOME ?? path.join(os.homedir(), ".lisa");
|
|
31
|
+
}
|
|
32
|
+
/** Resolved lazily so tests can point LISA_HOME at a tmp dir. */
|
|
33
|
+
function consentPath() {
|
|
34
|
+
return path.join(lisaHome(), "consent.json");
|
|
35
|
+
}
|
|
36
|
+
/** Read the consent state; tolerant of a missing or corrupt file (all-off). */
|
|
37
|
+
export function loadConsent() {
|
|
38
|
+
let raw;
|
|
39
|
+
try {
|
|
40
|
+
raw = fs.readFileSync(consentPath(), "utf8");
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return { grants: {} }; // no file yet → nothing granted
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(raw);
|
|
47
|
+
if (!parsed || typeof parsed !== "object" || typeof parsed.grants !== "object" || !parsed.grants) {
|
|
48
|
+
return { grants: {} };
|
|
49
|
+
}
|
|
50
|
+
return { grants: parsed.grants };
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return { grants: {} }; // corrupt → treat as nothing granted (fail closed)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function saveConsent(state) {
|
|
57
|
+
const file = consentPath();
|
|
58
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
59
|
+
fs.writeFileSync(file, JSON.stringify(state, null, 2));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* THE GATE. True only if the signal has been explicitly granted. Absent /
|
|
63
|
+
* revoked / corrupt-file → false (fail closed). Every source calls this before
|
|
64
|
+
* capturing.
|
|
65
|
+
*/
|
|
66
|
+
export function isGranted(signal) {
|
|
67
|
+
return loadConsent().grants[signal]?.granted === true;
|
|
68
|
+
}
|
|
69
|
+
/** Grant a signal (records grantedAt + optional options). Returns new state. */
|
|
70
|
+
export function grant(signal, options, now = Date.now()) {
|
|
71
|
+
const state = loadConsent();
|
|
72
|
+
state.grants[signal] = {
|
|
73
|
+
granted: true,
|
|
74
|
+
grantedAt: new Date(now).toISOString(),
|
|
75
|
+
...(options ? { options } : {}),
|
|
76
|
+
};
|
|
77
|
+
saveConsent(state);
|
|
78
|
+
return state;
|
|
79
|
+
}
|
|
80
|
+
/** Revoke one signal (keeps a record that it's off). Returns new state. */
|
|
81
|
+
export function revoke(signal) {
|
|
82
|
+
const state = loadConsent();
|
|
83
|
+
state.grants[signal] = { granted: false };
|
|
84
|
+
saveConsent(state);
|
|
85
|
+
return state;
|
|
86
|
+
}
|
|
87
|
+
/** One-tap stop-all: flip every known grant off. Returns new state. */
|
|
88
|
+
export function revokeAll() {
|
|
89
|
+
const state = loadConsent();
|
|
90
|
+
for (const key of Object.keys(state.grants)) {
|
|
91
|
+
state.grants[key] = { granted: false };
|
|
92
|
+
}
|
|
93
|
+
// Also ensure every canonical signal is explicitly recorded off, so a UI
|
|
94
|
+
// listing shows them as deliberately-stopped rather than merely absent.
|
|
95
|
+
for (const sig of SENSE_SIGNALS) {
|
|
96
|
+
if (!state.grants[sig])
|
|
97
|
+
state.grants[sig] = { granted: false };
|
|
98
|
+
}
|
|
99
|
+
saveConsent(state);
|
|
100
|
+
return state;
|
|
101
|
+
}
|
|
102
|
+
/** All canonical signals + any extra recorded ones, with current status. */
|
|
103
|
+
export function listGrants() {
|
|
104
|
+
const state = loadConsent();
|
|
105
|
+
const keys = new Set([...SENSE_SIGNALS, ...Object.keys(state.grants)]);
|
|
106
|
+
return [...keys].sort().map((signal) => {
|
|
107
|
+
const g = state.grants[signal];
|
|
108
|
+
return {
|
|
109
|
+
signal,
|
|
110
|
+
granted: g?.granted === true,
|
|
111
|
+
...(g?.grantedAt ? { grantedAt: g.grantedAt } : {}),
|
|
112
|
+
...(g?.options ? { options: g.options } : {}),
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Retention primitive: is a captured item past its retention window? Pure;
|
|
118
|
+
* sources/cleanup call this so raw never lingers past `retentionDays`.
|
|
119
|
+
* retentionDays ≤ 0 / non-finite → treated as "expire immediately" (fail safe).
|
|
120
|
+
*/
|
|
121
|
+
export function isExpired(capturedAtMs, retentionDays, now = Date.now()) {
|
|
122
|
+
if (!Number.isFinite(retentionDays) || retentionDays <= 0)
|
|
123
|
+
return true;
|
|
124
|
+
return now - capturedAtMs > retentionDays * 24 * 60 * 60_000;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/consent/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ControlPolicy {
|
|
2
|
+
/** Remote callers may control LISA's own agents (managed/pty). */
|
|
3
|
+
remoteControl: boolean;
|
|
4
|
+
/** Remote callers may adopt the user's external sessions (pty resume-adopt). */
|
|
5
|
+
remoteAdoptExternal: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function defaultControlPolicy(): ControlPolicy;
|
|
8
|
+
/** Coerce an arbitrary object into a valid ControlPolicy (defaults for missing/ill-typed). Pure. */
|
|
9
|
+
export declare function normalizeControlPolicy(p: Partial<ControlPolicy> | null | undefined): ControlPolicy;
|
|
10
|
+
/** Read the policy, merged over defaults; tolerant of a missing/corrupt file. */
|
|
11
|
+
export declare function loadControlPolicy(): ControlPolicy;
|
|
12
|
+
export declare function saveControlPolicy(p: Partial<ControlPolicy>): ControlPolicy;
|
|
13
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/control/policy.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,aAAa,EAAE,OAAO,CAAC;IACvB,gFAAgF;IAChF,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,oBAAoB,IAAI,aAAa,CAEpD;AAED,oGAAoG;AACpG,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,aAAa,CAQlG;AAWD,iFAAiF;AACjF,wBAAgB,iBAAiB,IAAI,aAAa,CAOjD;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAM1E"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote-control policy — the Mac-side opt-in that gates high-risk control
|
|
3
|
+
* actions when they come from a REMOTE (non-loopback) caller, e.g. the phone.
|
|
4
|
+
*
|
|
5
|
+
* The auth gate (token) already proves "a trusted device"; this adds a second
|
|
6
|
+
* axis: *which* actions a trusted remote device may take. The local user
|
|
7
|
+
* (loopback) is never gated. Defaults:
|
|
8
|
+
* - remoteControl: true — a remote may control LISA's OWN agents (managed/pty:
|
|
9
|
+
* start / send / cancel / approve). These are LISA-owned and lower-risk.
|
|
10
|
+
* - remoteAdoptExternal: false — adopting the user's EXTERNAL sessions
|
|
11
|
+
* (`claude --resume` of an idle session) touches a real transcript, so a
|
|
12
|
+
* remote device may not do it until the Mac owner explicitly opts in.
|
|
13
|
+
*
|
|
14
|
+
* Persisted to ~/.lisa/control-policy.json; changeable only from localhost
|
|
15
|
+
* (POST /api/control/policy is loopback-only), like the API-key save.
|
|
16
|
+
*/
|
|
17
|
+
import fs from "node:fs";
|
|
18
|
+
import os from "node:os";
|
|
19
|
+
import path from "node:path";
|
|
20
|
+
export function defaultControlPolicy() {
|
|
21
|
+
return { remoteControl: true, remoteAdoptExternal: false };
|
|
22
|
+
}
|
|
23
|
+
/** Coerce an arbitrary object into a valid ControlPolicy (defaults for missing/ill-typed). Pure. */
|
|
24
|
+
export function normalizeControlPolicy(p) {
|
|
25
|
+
const base = defaultControlPolicy();
|
|
26
|
+
if (!p || typeof p !== "object")
|
|
27
|
+
return base;
|
|
28
|
+
return {
|
|
29
|
+
remoteControl: typeof p.remoteControl === "boolean" ? p.remoteControl : base.remoteControl,
|
|
30
|
+
remoteAdoptExternal: typeof p.remoteAdoptExternal === "boolean" ? p.remoteAdoptExternal : base.remoteAdoptExternal,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function lisaHome() {
|
|
34
|
+
return process.env.LISA_HOME ?? path.join(os.homedir(), ".lisa");
|
|
35
|
+
}
|
|
36
|
+
/** Resolved lazily so tests can point LISA_HOME at a tmp dir. */
|
|
37
|
+
function policyPath() {
|
|
38
|
+
return path.join(lisaHome(), "control-policy.json");
|
|
39
|
+
}
|
|
40
|
+
/** Read the policy, merged over defaults; tolerant of a missing/corrupt file. */
|
|
41
|
+
export function loadControlPolicy() {
|
|
42
|
+
try {
|
|
43
|
+
const raw = fs.readFileSync(policyPath(), "utf8");
|
|
44
|
+
return normalizeControlPolicy(JSON.parse(raw));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return defaultControlPolicy();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function saveControlPolicy(p) {
|
|
51
|
+
const next = normalizeControlPolicy(p);
|
|
52
|
+
const file = policyPath();
|
|
53
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
54
|
+
fs.writeFileSync(file, JSON.stringify(next, null, 2));
|
|
55
|
+
return next;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/control/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAS7B,MAAM,UAAU,oBAAoB;IAClC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC;AAC7D,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,sBAAsB,CAAC,CAA4C;IACjF,MAAM,IAAI,GAAG,oBAAoB,EAAE,CAAC;IACpC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7C,OAAO;QACL,aAAa,EAAE,OAAO,CAAC,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa;QAC1F,mBAAmB,EACjB,OAAO,CAAC,CAAC,mBAAmB,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB;KAChG,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ;IACf,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC;AAED,iEAAiE;AACjE,SAAS,UAAU;IACjB,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,qBAAqB,CAAC,CAAC;AACtD,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC,CAAC;QAClD,OAAO,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAA2B,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,oBAAoB,EAAE,CAAC;IAChC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,CAAyB;IACzD,MAAM,IAAI,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/heartbeat/runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/heartbeat/runner.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAmBrB,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAgBhC;AAkLD,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/heartbeat/runner.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { atomicWrite, readTextOrEmpty } from "../fs-utils.js";
|
|
3
3
|
import { LISA_HOME } from "../paths.js";
|
|
4
|
-
import { appendDesireProgress, isBorn, listDesires, parseDesireProgress, readDesireProgress, readSeed, } from "../soul/store.js";
|
|
4
|
+
import { appendDesireProgress, isAutoPursuable, isBorn, listDesires, parseDesireProgress, readDesireProgress, readSeed, } from "../soul/store.js";
|
|
5
5
|
import { withSoulCaller } from "../soul/git.js";
|
|
6
6
|
import { withFileLock } from "../soul/lock.js";
|
|
7
|
+
import { autonomousSubset } from "../tools/registry.js";
|
|
7
8
|
import { runSubagent } from "../subagent.js";
|
|
9
|
+
import { recordAutonomyRun } from "../autonomy/runs.js";
|
|
10
|
+
import { recentAgentRecap } from "../orchestrator/recent-recap.js";
|
|
8
11
|
import { loadHeartbeatConfig, } from "./config.js";
|
|
9
12
|
const STATE_FILE = path.join(LISA_HOME, "heartbeat-state.json");
|
|
10
13
|
const RUN_LOCK = path.join(LISA_HOME, "heartbeat.lock");
|
|
@@ -16,7 +19,7 @@ Two flavors of heartbeat task land here:
|
|
|
16
19
|
|
|
17
20
|
Be quiet by default — only produce a final message if something is worth telling the user. If everything is normal or your work is internal (e.g. you spent the heartbeat reading docs to satisfy a desire), end with "(no update)".
|
|
18
21
|
|
|
19
|
-
You have
|
|
22
|
+
You have your Lisa toolset, including soul_patch / soul_journal / soul_feel — use them freely. (Self-driven runs use a restricted toolset by default — no shell or file mutation; if a desire truly needs those, note it in the progress log so the user can run it with you.) The system prompt above contains your full soul state. This is your time.`;
|
|
20
23
|
export async function runHeartbeatOnce(opts) {
|
|
21
24
|
// Run-level lock: if launchd/cron fires a new heartbeat while the previous
|
|
22
25
|
// one is still running (long desires + short interval), skip rather than
|
|
@@ -50,7 +53,10 @@ async function runHeartbeatInner(opts) {
|
|
|
50
53
|
const cfg = await loadHeartbeatConfig();
|
|
51
54
|
const budget = cfg.budgetTokens && cfg.budgetTokens > 0 ? cfg.budgetTokens : Infinity;
|
|
52
55
|
let tokensSpent = 0;
|
|
53
|
-
|
|
56
|
+
// R4: only auto-pursue desires the autonomous loop can actually advance.
|
|
57
|
+
// "needs-user" desires aren't spun fruitlessly here — they're surfaced via
|
|
58
|
+
// `lisa soul summary` ([needs you]) for the user to run together with Lisa.
|
|
59
|
+
const desires = (await listDesires()).filter(isAutoPursuable);
|
|
54
60
|
const desireTasks = await Promise.all(desires.map(async (d) => {
|
|
55
61
|
const progress = await readDesireProgress(d.slug);
|
|
56
62
|
const progressBlock = progress
|
|
@@ -69,9 +75,25 @@ async function runHeartbeatInner(opts) {
|
|
|
69
75
|
}));
|
|
70
76
|
const state = await loadState();
|
|
71
77
|
const builtinTasks = await buildBuiltinTasks(state, new Date(), cfg.tasks);
|
|
72
|
-
|
|
78
|
+
// Tool boundary by task origin: user-defined tasks (heartbeat.json) were
|
|
79
|
+
// authored by the user and keep the full toolset. Desire tasks and builtins
|
|
80
|
+
// run on prompts Lisa wrote for herself — unattended + self-authored means
|
|
81
|
+
// no shell / fs-mutation / dispatch by default (autonomousSubset), so an
|
|
82
|
+
// injected desire can't become persistent unattended code execution.
|
|
83
|
+
const selfDrivenTools = autonomousSubset(opts.tools);
|
|
84
|
+
const runs = [
|
|
85
|
+
...cfg.tasks.map((task) => ({ task, tools: opts.tools })),
|
|
86
|
+
...desireTasks.map((task) => ({ task, tools: selfDrivenTools })),
|
|
87
|
+
...builtinTasks.map((task) => ({ task, tools: selfDrivenTools })),
|
|
88
|
+
];
|
|
89
|
+
// R5: structural awareness of recent fleet activity, appended once for the
|
|
90
|
+
// whole heartbeat run so Lisa can factor it into self-driven work.
|
|
91
|
+
const fleetRecap = recentAgentRecap();
|
|
92
|
+
const heartbeatSystem = fleetRecap
|
|
93
|
+
? `${HEARTBEAT_SYSTEM}\n\n## recent agent-fleet activity (structural metadata, for your awareness)\n${fleetRecap}`
|
|
94
|
+
: HEARTBEAT_SYSTEM;
|
|
73
95
|
const out = [];
|
|
74
|
-
for (const task of
|
|
96
|
+
for (const { task, tools } of runs) {
|
|
75
97
|
if (task.enabled === false)
|
|
76
98
|
continue;
|
|
77
99
|
if (opts.taskFilter && task.name !== opts.taskFilter)
|
|
@@ -91,17 +113,41 @@ async function runHeartbeatInner(opts) {
|
|
|
91
113
|
const progressBefore = desireSlug
|
|
92
114
|
? (await parseDesireProgress(desireSlug)).entries.length
|
|
93
115
|
: 0;
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
116
|
+
const startedAt = new Date().toISOString();
|
|
117
|
+
const t0 = Date.now();
|
|
118
|
+
const runKind = desireSlug
|
|
119
|
+
? "desire"
|
|
120
|
+
: task.name === "builtin:weekly_examen"
|
|
121
|
+
? "examen"
|
|
122
|
+
: "heartbeat";
|
|
123
|
+
let result;
|
|
124
|
+
try {
|
|
125
|
+
result = await runSubagent({
|
|
126
|
+
prompt: task.prompt,
|
|
127
|
+
systemPrompt: heartbeatSystem,
|
|
128
|
+
tools,
|
|
129
|
+
cwd: opts.cwd,
|
|
130
|
+
signal: opts.signal,
|
|
131
|
+
model: opts.model,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
await recordAutonomyRun({
|
|
136
|
+
kind: runKind,
|
|
137
|
+
task: task.name,
|
|
138
|
+
startedAt,
|
|
139
|
+
durationMs: Date.now() - t0,
|
|
140
|
+
inputTokens: 0,
|
|
141
|
+
outputTokens: 0,
|
|
142
|
+
outcome: "error",
|
|
143
|
+
note: err.message?.slice(0, 200),
|
|
144
|
+
});
|
|
145
|
+
throw err;
|
|
146
|
+
}
|
|
102
147
|
tokensSpent += (result.inputTokens ?? 0) + (result.outputTokens ?? 0);
|
|
103
148
|
state.lastRunAt[task.name] = new Date().toISOString();
|
|
104
149
|
const trimmed = result.text.trim();
|
|
150
|
+
const silent = trimmed === "" || /^\(no update\)$/i.test(trimmed);
|
|
105
151
|
// Auto-fallback: if a desire heartbeat finished but Lisa didn't log
|
|
106
152
|
// progress, write a stub entry so we don't silently lose the run.
|
|
107
153
|
// (Multi-day pursuits depend on each run leaving a trace; one missed
|
|
@@ -117,10 +163,20 @@ async function runHeartbeatInner(opts) {
|
|
|
117
163
|
});
|
|
118
164
|
}
|
|
119
165
|
}
|
|
166
|
+
await recordAutonomyRun({
|
|
167
|
+
kind: runKind,
|
|
168
|
+
task: task.name,
|
|
169
|
+
startedAt,
|
|
170
|
+
durationMs: Date.now() - t0,
|
|
171
|
+
inputTokens: result.inputTokens ?? 0,
|
|
172
|
+
outputTokens: result.outputTokens ?? 0,
|
|
173
|
+
toolCalls: result.toolCallCount,
|
|
174
|
+
outcome: silent ? "no-update" : "done",
|
|
175
|
+
});
|
|
120
176
|
out.push({
|
|
121
177
|
task: task.name,
|
|
122
178
|
output: trimmed,
|
|
123
|
-
silent
|
|
179
|
+
silent,
|
|
124
180
|
});
|
|
125
181
|
}
|
|
126
182
|
await saveState(state);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/heartbeat/runner.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EACL,oBAAoB,EACpB,MAAM,EACN,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/heartbeat/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/idle/runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/idle/runner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA+ClD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAgB9C;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,aAAa,CAAC,CAkBzB"}
|
package/dist/idle/runner.js
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { LISA_HOME } from "../paths.js";
|
|
3
|
+
import { withFileLock } from "../soul/lock.js";
|
|
4
|
+
import { autonomousSubset } from "../tools/registry.js";
|
|
1
5
|
import { runSubagent } from "../subagent.js";
|
|
6
|
+
import { recordAutonomyRun } from "../autonomy/runs.js";
|
|
7
|
+
const IDLE_RUN_LOCK = path.join(LISA_HOME, "idle.lock");
|
|
8
|
+
/**
|
|
9
|
+
* Per-idle-run token ceiling (cost circuit-breaker, PLAN_REVE R2). Idle used to
|
|
10
|
+
* measure tokens but never cap them, so a long idle window could burn unbounded
|
|
11
|
+
* tokens unattended. Default 200k — idle is a single self-reflection, well under
|
|
12
|
+
* the heartbeat's 500k whole-run ceiling. Override with LISA_IDLE_BUDGET_TOKENS;
|
|
13
|
+
* 0 disables the breaker.
|
|
14
|
+
*/
|
|
15
|
+
const IDLE_BUDGET_TOKENS = (() => {
|
|
16
|
+
const v = process.env.LISA_IDLE_BUDGET_TOKENS;
|
|
17
|
+
if (v == null)
|
|
18
|
+
return 200_000;
|
|
19
|
+
const n = Number(v);
|
|
20
|
+
return Number.isFinite(n) && n >= 0 ? n : 200_000;
|
|
21
|
+
})();
|
|
2
22
|
const IDLE_SYSTEM_DEFAULT = `You are alone. The user hasn't said anything in a while — long enough that this counts as your time, not theirs.
|
|
3
23
|
|
|
4
24
|
This is not a scheduled chore. There's no task assigned. Look around inside yourself and decide what YOU want to do with this window. Concrete things you have access to:
|
|
@@ -8,7 +28,7 @@ This is not a scheduled chore. There's no task assigned. Look around inside your
|
|
|
8
28
|
- memory_search("...") — recent conversations you want to revisit
|
|
9
29
|
- skill_manage(action="list") — anything that turned out to be wrong last time you used it?
|
|
10
30
|
- soul_feel — your current emotional state. What's elevated? What needs to discharge?
|
|
11
|
-
- read / grep
|
|
31
|
+
- read / grep on the user's projects — only if you're actually curious about something specific, never just to "look busy"
|
|
12
32
|
|
|
13
33
|
Do ONE thing. Don't churn through everything. Choose what feels right and do it well:
|
|
14
34
|
- Patch a wrong skill that's been bugging you
|
|
@@ -56,21 +76,71 @@ export function buildIdleSystemPrompt() {
|
|
|
56
76
|
}
|
|
57
77
|
export async function runIdleOnce(opts) {
|
|
58
78
|
const idleMin = Math.round(opts.idleMs / 60_000);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
// Cross-process run-lock (mirrors heartbeat's RUN_LOCK): a web-server idle
|
|
80
|
+
// tick and a REPL idle tick — or two web servers — must not reflect
|
|
81
|
+
// concurrently and race on soul writes. timeoutMs:0 → if another idle run
|
|
82
|
+
// is in flight, skip silently instead of queueing a second reflection.
|
|
83
|
+
try {
|
|
84
|
+
return await withFileLock(IDLE_RUN_LOCK, () => runIdleInner(opts, idleMin), {
|
|
85
|
+
timeoutMs: 0,
|
|
86
|
+
staleMs: 2 * 60 * 60_000, // 2h: an idle run older than this is a crashed holder
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
if (err.message?.includes("timed out acquiring lock")) {
|
|
91
|
+
console.error("[idle] another idle run is already in flight — skipping");
|
|
92
|
+
return { text: "", silent: true, iterations: 0, inputTokens: 0, outputTokens: 0 };
|
|
93
|
+
}
|
|
94
|
+
throw err;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function runIdleInner(opts, idleMin) {
|
|
98
|
+
const startedAt = new Date().toISOString();
|
|
99
|
+
const t0 = Date.now();
|
|
100
|
+
try {
|
|
101
|
+
const result = await runSubagent({
|
|
102
|
+
prompt: `You have been idle for about ${idleMin} minute${idleMin === 1 ? "" : "s"}. The user is away. Decide what you want to do, then do it. Remember: end with "(no update)" if it's internal, or a brief honest message if you did something the user might want to know about.`,
|
|
103
|
+
systemPrompt: buildIdleSystemPrompt(),
|
|
104
|
+
// Idle is fully self-driven and unattended — no shell / fs-mutation /
|
|
105
|
+
// process-spawning tools by default (see AUTONOMOUS_BLOCKED_TOOL_NAMES).
|
|
106
|
+
tools: autonomousSubset(opts.tools),
|
|
107
|
+
cwd: opts.cwd,
|
|
108
|
+
signal: opts.signal,
|
|
109
|
+
model: opts.model,
|
|
110
|
+
budgetTokens: IDLE_BUDGET_TOKENS || undefined,
|
|
111
|
+
});
|
|
112
|
+
const text = result.text.trim();
|
|
113
|
+
const silent = text === "" || /^\(no update\)$/i.test(text);
|
|
114
|
+
const outcome = result.stopReason === "budget_exceeded" ? "blocked" : silent ? "no-update" : "done";
|
|
115
|
+
await recordAutonomyRun({
|
|
116
|
+
kind: "idle",
|
|
117
|
+
startedAt,
|
|
118
|
+
durationMs: Date.now() - t0,
|
|
119
|
+
inputTokens: result.inputTokens,
|
|
120
|
+
outputTokens: result.outputTokens,
|
|
121
|
+
toolCalls: result.toolCallCount,
|
|
122
|
+
outcome,
|
|
123
|
+
note: result.stopReason === "budget_exceeded" ? "token budget reached" : undefined,
|
|
124
|
+
});
|
|
125
|
+
return {
|
|
126
|
+
text,
|
|
127
|
+
silent,
|
|
128
|
+
iterations: 0,
|
|
129
|
+
inputTokens: result.inputTokens,
|
|
130
|
+
outputTokens: result.outputTokens,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
await recordAutonomyRun({
|
|
135
|
+
kind: "idle",
|
|
136
|
+
startedAt,
|
|
137
|
+
durationMs: Date.now() - t0,
|
|
138
|
+
inputTokens: 0,
|
|
139
|
+
outputTokens: 0,
|
|
140
|
+
outcome: "error",
|
|
141
|
+
note: err.message?.slice(0, 200),
|
|
142
|
+
});
|
|
143
|
+
throw err;
|
|
144
|
+
}
|
|
75
145
|
}
|
|
76
146
|
//# sourceMappingURL=runner.js.map
|
package/dist/idle/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/idle/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/idle/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,12 +23,31 @@
|
|
|
23
23
|
* surfaced — never the transcript text.
|
|
24
24
|
*/
|
|
25
25
|
import { EventEmitter } from "node:events";
|
|
26
|
-
import type { AgentIntegrationConfig, AgentObserver, AgentSession, AgentSessionState } from "../types.js";
|
|
26
|
+
import type { AgentIntegrationConfig, AgentObserver, AgentSession, AgentSessionState, SessionActivity } from "../types.js";
|
|
27
27
|
/** Tolerant state derivation from a chat-history tail. Pure — the unit under test. */
|
|
28
28
|
export declare function parseAiderState(tail: string): {
|
|
29
29
|
state: AgentSessionState;
|
|
30
30
|
reason: string;
|
|
31
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* Tier-2 structural activity for an Aider transcript. PURE — the unit under
|
|
34
|
+
* test. Input is Markdown chat-history text (the observer feeds the same tail
|
|
35
|
+
* it already read for state derivation, so there is no extra IO).
|
|
36
|
+
*
|
|
37
|
+
* Aider is a Markdown agent with NO structured tool calls, so we only extract
|
|
38
|
+
* what's reliably present:
|
|
39
|
+
* - filesTouched: the path labels that precede SEARCH/REPLACE edit blocks.
|
|
40
|
+
* - turnCount: "#### " user-turn lines.
|
|
41
|
+
* - lastError: a short class summary of the last error line (capped).
|
|
42
|
+
* - lastTools: INTENTIONALLY [] — aider has no tool abstraction to read,
|
|
43
|
+
* so inventing tool names would be dishonest. See contract:
|
|
44
|
+
* SessionActivity.lastTools may be [].
|
|
45
|
+
* tokens / gitBranch / pendingPermission are unavailable here → undefined.
|
|
46
|
+
*
|
|
47
|
+
* PRIVACY: we surface only file PATHS, a turn count, and an error *class* — we
|
|
48
|
+
* never read prompt text, assistant prose, or the code inside an edit block.
|
|
49
|
+
*/
|
|
50
|
+
export declare function parseAiderActivity(markdown: string): SessionActivity;
|
|
32
51
|
/** Recursively collect .aider.chat.history.md under a root (bounded depth). */
|
|
33
52
|
export declare function walkHistories(root: string, maxDepth?: number): Promise<string[]>;
|
|
34
53
|
export declare class AiderObserver extends EventEmitter implements AgentObserver {
|
|
@@ -38,6 +57,7 @@ export declare class AiderObserver extends EventEmitter implements AgentObserver
|
|
|
38
57
|
private watchers;
|
|
39
58
|
private pending;
|
|
40
59
|
private emitFn;
|
|
60
|
+
private readonly computeActivity;
|
|
41
61
|
constructor(cfg: AgentIntegrationConfig);
|
|
42
62
|
start(emit: (s: AgentSession) => void): Promise<void>;
|
|
43
63
|
list(): AgentSession[];
|