arcane-os 0.1.0-dev.5

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 (248) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/COMMERCIAL-LICENSE.md +13 -0
  3. package/LICENSE +661 -0
  4. package/NOTICE +70 -0
  5. package/README.md +448 -0
  6. package/bin/arcane-test.mjs +741 -0
  7. package/bin/arcane.mjs +5 -0
  8. package/docs/architecture.md +234 -0
  9. package/docs/compatibility.md +36 -0
  10. package/docs/event-manager.md +166 -0
  11. package/docs/platform-targets.md +108 -0
  12. package/docs/publishing.md +203 -0
  13. package/docs/reference/README.md +117 -0
  14. package/docs/reference/arcane-ollama.md +288 -0
  15. package/docs/reference/availability-and-normalization.md +123 -0
  16. package/docs/reference/behavioral-testing.md +86 -0
  17. package/docs/reference/cli.md +569 -0
  18. package/docs/reference/core/README.md +62 -0
  19. package/docs/reference/core/arcane-ai-contracts.md +873 -0
  20. package/docs/reference/core/arcane-api.md +601 -0
  21. package/docs/reference/core/arcane-entities.md +65 -0
  22. package/docs/reference/core/arcane-events.md +134 -0
  23. package/docs/reference/core/ollama-module.md +181 -0
  24. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +1909 -0
  25. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +1057 -0
  26. package/docs/reference/core/reference/arcane-api/core-and-events.md +320 -0
  27. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +610 -0
  28. package/docs/reference/core/reference/arcane-api/namespaces.md +1157 -0
  29. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +1423 -0
  30. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +315 -0
  31. package/docs/reference/event-manager.md +957 -0
  32. package/docs/reference/inventory/package-api.json +2632 -0
  33. package/docs/reference/inventory/runtime-components.json +934 -0
  34. package/docs/reference/inventory/runtime-entities.json +26 -0
  35. package/docs/reference/inventory/runtime-modules.json +1249 -0
  36. package/docs/reference/protocols.md +242 -0
  37. package/docs/reference/runtime-components.md +1098 -0
  38. package/docs/reference/runtime-entities.md +303 -0
  39. package/docs/reference/runtime-modules.md +2010 -0
  40. package/docs/reference/sdk-api.md +4901 -0
  41. package/docs/roadmap.md +79 -0
  42. package/docs/work-amplification.md +124 -0
  43. package/node_modules/event-pubsub/CHANGELOG.md +55 -0
  44. package/node_modules/event-pubsub/MIGRATION.md +70 -0
  45. package/node_modules/event-pubsub/README.md +363 -0
  46. package/node_modules/event-pubsub/SECURITY.md +37 -0
  47. package/node_modules/event-pubsub/index.js +141 -0
  48. package/node_modules/event-pubsub/licence +21 -0
  49. package/node_modules/event-pubsub/package.json +59 -0
  50. package/node_modules/strong-type/README.md +408 -0
  51. package/node_modules/strong-type/assets/strong-type-header.png +0 -0
  52. package/node_modules/strong-type/index.js +1151 -0
  53. package/node_modules/strong-type/licence +21 -0
  54. package/node_modules/strong-type/node.js +125 -0
  55. package/node_modules/strong-type/package.json +61 -0
  56. package/package.json +95 -0
  57. package/runtime/ARCANE_RUNTIME_RELEASE.json +791 -0
  58. package/runtime/arcane/components/app-bar.html +468 -0
  59. package/runtime/arcane/components/assistant-panel.html +715 -0
  60. package/runtime/arcane/components/calculator.html +8 -0
  61. package/runtime/arcane/components/chart.html +655 -0
  62. package/runtime/arcane/components/chat.html +1225 -0
  63. package/runtime/arcane/components/conversation-view.html +13 -0
  64. package/runtime/arcane/components/dashboard-config.html +341 -0
  65. package/runtime/arcane/components/data-maintenance.html +112 -0
  66. package/runtime/arcane/components/data-view.html +92 -0
  67. package/runtime/arcane/components/directory-picker.html +197 -0
  68. package/runtime/arcane/components/document-inspector.html +252 -0
  69. package/runtime/arcane/components/file-drop.html +264 -0
  70. package/runtime/arcane/components/file-inspector.html +293 -0
  71. package/runtime/arcane/components/file-manager.html +1715 -0
  72. package/runtime/arcane/components/header.html +142 -0
  73. package/runtime/arcane/components/integration-settings.html +14 -0
  74. package/runtime/arcane/components/local-ai-status.html +360 -0
  75. package/runtime/arcane/components/markdown-document.html +1048 -0
  76. package/runtime/arcane/components/markdown-editor.html +360 -0
  77. package/runtime/arcane/components/media-embed.html +8 -0
  78. package/runtime/arcane/components/modal.html +402 -0
  79. package/runtime/arcane/components/output-panel.html +259 -0
  80. package/runtime/arcane/components/preferences-form.html +135 -0
  81. package/runtime/arcane/components/record-timeline.html +105 -0
  82. package/runtime/arcane/components/relationship-board.html +116 -0
  83. package/runtime/arcane/components/screen-capture.html +8 -0
  84. package/runtime/arcane/components/source-code-viewer.html +441 -0
  85. package/runtime/arcane/components/source-explanation.html +124 -0
  86. package/runtime/arcane/components/speech.html +365 -0
  87. package/runtime/arcane/components/summary-strip.html +177 -0
  88. package/runtime/arcane/components/table.html +77 -0
  89. package/runtime/arcane/components/task-progress.html +282 -0
  90. package/runtime/arcane/components/terminal-workspace.html +65 -0
  91. package/runtime/arcane/components/theme-editor.html +41 -0
  92. package/runtime/arcane/components/theme-switcher.html +46 -0
  93. package/runtime/arcane/components/unified-inbox.html +20 -0
  94. package/runtime/arcane/components/voice-transcription.html +476 -0
  95. package/runtime/arcane/components/weather-widget.html +8 -0
  96. package/runtime/arcane/components/web-navigator.html +239 -0
  97. package/runtime/arcane/css/communications.css +1 -0
  98. package/runtime/arcane/css/dashboard-config.css +45 -0
  99. package/runtime/arcane/css/document-site.css +981 -0
  100. package/runtime/arcane/css/layout.css +438 -0
  101. package/runtime/arcane/css/primitives.css +321 -0
  102. package/runtime/arcane/css/theme.css +112 -0
  103. package/runtime/arcane/css/utility-workspace.css +1 -0
  104. package/runtime/arcane/entities/ApiModelRecord.js +20 -0
  105. package/runtime/arcane/entities/Calculation.js +13 -0
  106. package/runtime/arcane/entities/Chat.js +581 -0
  107. package/runtime/arcane/entities/CommunicationMessage.js +29 -0
  108. package/runtime/arcane/entities/CommunicationThread.js +21 -0
  109. package/runtime/arcane/entities/Document.js +10 -0
  110. package/runtime/arcane/entities/File.js +143 -0
  111. package/runtime/arcane/entities/Image.js +135 -0
  112. package/runtime/arcane/entities/IntentEnvelope.js +834 -0
  113. package/runtime/arcane/entities/Preference.js +83 -0
  114. package/runtime/arcane/entities/TWiNPolicyDecision.js +1092 -0
  115. package/runtime/arcane/entities/TerminalSession.js +46 -0
  116. package/runtime/arcane/entities/Theme.js +107 -0
  117. package/runtime/arcane/entities/User.js +1046 -0
  118. package/runtime/arcane/entities/Weather.js +23 -0
  119. package/runtime/arcane/img/arcane-os-everywhere.png +0 -0
  120. package/runtime/arcane/img/arrow-left.png +0 -0
  121. package/runtime/arcane/img/arrow-right.png +0 -0
  122. package/runtime/arcane/img/doc.svg +5 -0
  123. package/runtime/arcane/img/folder.svg +4 -0
  124. package/runtime/arcane/img/image.svg +5 -0
  125. package/runtime/arcane/img/refresh.png +0 -0
  126. package/runtime/arcane/img/send.svg +9 -0
  127. package/runtime/arcane/img/trash.svg +5 -0
  128. package/runtime/arcane/img/upload.svg +5 -0
  129. package/runtime/arcane/modules/AI.js +2048 -0
  130. package/runtime/arcane/modules/AIPreferenceRuntime.js +32 -0
  131. package/runtime/arcane/modules/AIPreferenceTuple.js +92 -0
  132. package/runtime/arcane/modules/AIResponseLength.js +42 -0
  133. package/runtime/arcane/modules/AIResponseURLPolicy.js +626 -0
  134. package/runtime/arcane/modules/AnsiText.js +53 -0
  135. package/runtime/arcane/modules/ApiModelDatabase.js +25 -0
  136. package/runtime/arcane/modules/AppDataScope.js +245 -0
  137. package/runtime/arcane/modules/AppearancePreferences.js +28 -0
  138. package/runtime/arcane/modules/ArcaneCommunicationBridge.js +22 -0
  139. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +135 -0
  140. package/runtime/arcane/modules/ArcaneNetworkPolicy.js +255 -0
  141. package/runtime/arcane/modules/AsyncBoundary.js +161 -0
  142. package/runtime/arcane/modules/BrowserTestSuite.js +326 -0
  143. package/runtime/arcane/modules/CalculatorEngine.js +20 -0
  144. package/runtime/arcane/modules/CaseEvidenceIndexer.js +134 -0
  145. package/runtime/arcane/modules/ChartLibrary.js +35 -0
  146. package/runtime/arcane/modules/ChatRecords.js +13 -0
  147. package/runtime/arcane/modules/CommunicationAppController.js +43 -0
  148. package/runtime/arcane/modules/CommunicationHub.js +16 -0
  149. package/runtime/arcane/modules/CommunicationPreferences.js +13 -0
  150. package/runtime/arcane/modules/CommunicationProviderRegistry.js +16 -0
  151. package/runtime/arcane/modules/ComponentContracts.js +586 -0
  152. package/runtime/arcane/modules/ConfiguredAIChatSession.js +288 -0
  153. package/runtime/arcane/modules/ConversationActionItems.js +488 -0
  154. package/runtime/arcane/modules/ConversationClosingReport.js +274 -0
  155. package/runtime/arcane/modules/ConversationTimebox.js +527 -0
  156. package/runtime/arcane/modules/CoreLocalModelCatalog.js +255 -0
  157. package/runtime/arcane/modules/DBLS.js +171 -0
  158. package/runtime/arcane/modules/DBOPFS.js +1154 -0
  159. package/runtime/arcane/modules/DBOPFSWorker.js +116 -0
  160. package/runtime/arcane/modules/DataMaintenance.js +91 -0
  161. package/runtime/arcane/modules/DevelopmentWorkspace.js +74 -0
  162. package/runtime/arcane/modules/DirectoryPicker.js +109 -0
  163. package/runtime/arcane/modules/DocumentNavigation.js +223 -0
  164. package/runtime/arcane/modules/Errors.js +1025 -0
  165. package/runtime/arcane/modules/GifEncoder.js +29 -0
  166. package/runtime/arcane/modules/HTMLImport.js +114 -0
  167. package/runtime/arcane/modules/InMemoryCommunicationProvider.js +14 -0
  168. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +275 -0
  169. package/runtime/arcane/modules/LocalAIReadiness.js +870 -0
  170. package/runtime/arcane/modules/LocalAIReadinessController.js +156 -0
  171. package/runtime/arcane/modules/MD.js +111 -0
  172. package/runtime/arcane/modules/Mail.js +352 -0
  173. package/runtime/arcane/modules/MailTransport.mjs +180 -0
  174. package/runtime/arcane/modules/Marked.min.js +71 -0
  175. package/runtime/arcane/modules/MemoryRecords.js +44 -0
  176. package/runtime/arcane/modules/MessageAdvisory.js +38 -0
  177. package/runtime/arcane/modules/ModelDefinition.js +189 -0
  178. package/runtime/arcane/modules/Ollama.js +74 -0
  179. package/runtime/arcane/modules/OllamaModelIdentifier.js +21 -0
  180. package/runtime/arcane/modules/OllamaSettings.js +24 -0
  181. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +14 -0
  182. package/runtime/arcane/modules/PreferenceStore.js +109 -0
  183. package/runtime/arcane/modules/QRCode.min.js +1 -0
  184. package/runtime/arcane/modules/Questionnaire.js +61 -0
  185. package/runtime/arcane/modules/RecordLinkIndex.js +24 -0
  186. package/runtime/arcane/modules/RecordPassageIndex.js +222 -0
  187. package/runtime/arcane/modules/RecordReviewStore.js +94 -0
  188. package/runtime/arcane/modules/RevocableProjectionLedger.js +1623 -0
  189. package/runtime/arcane/modules/RiskSignalAnalyzer.js +37 -0
  190. package/runtime/arcane/modules/ScamRiskPolicy.js +62 -0
  191. package/runtime/arcane/modules/ScopedOPFSCache.js +183 -0
  192. package/runtime/arcane/modules/ScreenCapture.js +20 -0
  193. package/runtime/arcane/modules/SpeechPlayback.js +581 -0
  194. package/runtime/arcane/modules/StaticDocumentCatalog.js +1248 -0
  195. package/runtime/arcane/modules/SystemAppearance.js +20 -0
  196. package/runtime/arcane/modules/SystemPlatformPresentation.js +51 -0
  197. package/runtime/arcane/modules/SystemToolRegistry.js +28 -0
  198. package/runtime/arcane/modules/TerminalClient.js +52 -0
  199. package/runtime/arcane/modules/TerminalCommandRegistry.js +50 -0
  200. package/runtime/arcane/modules/ThemeBootstrap.js +26 -0
  201. package/runtime/arcane/modules/ThemeManager.js +131 -0
  202. package/runtime/arcane/modules/TimeGuard.js +149 -0
  203. package/runtime/arcane/modules/ToolCallRouter.js +83 -0
  204. package/runtime/arcane/modules/WaitForComponent.js +102 -0
  205. package/runtime/arcane/modules/YouTubeMedia.js +16 -0
  206. package/runtime/arcane/modules/uPlot.LICENSE.txt +21 -0
  207. package/runtime/arcane/modules/uPlot.iife.min.js +2 -0
  208. package/runtime/arcane/modules/uPlot.min.css +1 -0
  209. package/runtime/arcane/security/arcane-network-policy.json +6 -0
  210. package/runtime/strong-type/index.js +352 -0
  211. package/runtime/strong-type/licence +21 -0
  212. package/runtime/strong-type/package.json +45 -0
  213. package/schemas/arcane-app-bundle.schema.json +125 -0
  214. package/schemas/arcane-app.schema.json +329 -0
  215. package/schemas/arcane-lock.schema.json +86 -0
  216. package/schemas/arcane-package.schema.json +224 -0
  217. package/schemas/cli-event.schema.json +122 -0
  218. package/schemas/event-stack.schema.json +152 -0
  219. package/schemas/native-build-plan.schema.json +176 -0
  220. package/schemas/target-adapter.schema.json +117 -0
  221. package/src/app-descriptor.mjs +500 -0
  222. package/src/cli/main.mjs +561 -0
  223. package/src/constants.mjs +31 -0
  224. package/src/dev-server.mjs +718 -0
  225. package/src/doctor.mjs +315 -0
  226. package/src/dom-event-instrumentation.mjs +594 -0
  227. package/src/errors.mjs +75 -0
  228. package/src/event-manager.mjs +1342 -0
  229. package/src/event-queue.mjs +138 -0
  230. package/src/events.mjs +219 -0
  231. package/src/index.mjs +177 -0
  232. package/src/integrated-provider-loader.mjs +432 -0
  233. package/src/native-plan.mjs +698 -0
  234. package/src/native-provider-loader.mjs +1126 -0
  235. package/src/packager/core.mjs +2691 -0
  236. package/src/process.mjs +353 -0
  237. package/src/release-bundle.mjs +2523 -0
  238. package/src/repository.mjs +90 -0
  239. package/src/runtime.mjs +452 -0
  240. package/src/scaffold.mjs +380 -0
  241. package/src/targets/index.mjs +436 -0
  242. package/src/templates/assets/app-icon.png +0 -0
  243. package/src/templates/workspace-template.mjs +388 -0
  244. package/src/testing-loader.mjs +9 -0
  245. package/src/testing.mjs +427 -0
  246. package/src/toolchain.mjs +1335 -0
  247. package/src/update-check.mjs +307 -0
  248. package/src/workspace.mjs +449 -0
package/src/doctor.mjs ADDED
@@ -0,0 +1,315 @@
1
+ import path from 'node:path';
2
+ import {access} from 'node:fs/promises';
3
+ import {verifyRuntime} from './runtime.mjs';
4
+ import {validateWorkspace} from './workspace.mjs';
5
+ import {runProcess} from './process.mjs';
6
+ import {ARCANE_PROTOCOL,SDK_VERSION} from './constants.mjs';
7
+ import {ERROR_CODES,ArcaneError,throwIfAborted} from './errors.mjs';
8
+
9
+ const MINIMUM_NODE=[22,14,0];
10
+ const WINDOWS_SERVICE_NAME='ArcaneOllama';
11
+ const WINDOWS_SERVICE_HOST='C:\\Program Files\\Ollama\\ArcaneOllamaService.exe';
12
+ const WINDOWS_SERVICE_COMMAND=`"${WINDOWS_SERVICE_HOST}"`;
13
+ const OLLAMA_ENDPOINT='http://127.0.0.1:11434';
14
+
15
+ function parseVersion(value){
16
+ const match=String(value??'').match(/(\d+)\.(\d+)\.(\d+)/u);
17
+ return match?match.slice(1).map(Number):null;
18
+ }
19
+
20
+ function versionAtLeast(actual,minimum){
21
+ if(!actual){
22
+ return false;
23
+ }
24
+ for(let index=0;index<minimum.length;index+=1){
25
+ if((actual[index]??0)!==minimum[index]){
26
+ return (actual[index]??0)>minimum[index];
27
+ }
28
+ }
29
+ return true;
30
+ }
31
+
32
+ async function exists(filePath){
33
+ try{
34
+ await access(filePath);
35
+ return true;
36
+ }catch{
37
+ return false;
38
+ }
39
+ }
40
+
41
+ function check(id,status,message,{required=true,details}={}){
42
+ return {id,status,message,required,...(details===undefined?{}:{details})};
43
+ }
44
+
45
+ async function commandCheck(id,command,args,{signal,onEvent,minimum,run=runProcess}={}){
46
+ try{
47
+ const result=await run(command,args,{signal,onEvent});
48
+ const version=(result.stdout||result.stderr).trim();
49
+ const supported=!minimum||versionAtLeast(parseVersion(version),minimum);
50
+ return check(
51
+ id,
52
+ supported?'pass':'fail',
53
+ supported?`${id} is available (${version}).`:`${id} ${version} is older than the supported minimum.`,
54
+ {details:{version,minimum:minimum?.join('.')??null}}
55
+ );
56
+ }catch(error){
57
+ return check(id,'fail',`${id} is unavailable: ${error.message}`,{
58
+ details:{code:error.code??ERROR_CODES.prerequisiteMissing}
59
+ });
60
+ }
61
+ }
62
+
63
+ function parseServiceCommand(configOutput){
64
+ const line=String(configOutput).split(/\r?\n/u)
65
+ .find(value=>value.includes('BINARY_PATH_NAME'));
66
+ if(!line){
67
+ return {raw:null,binaryPath:null,arguments:null,argumentFree:false,exact:false};
68
+ }
69
+ const raw=line.slice(line.indexOf(':')+1).trim();
70
+ const quoted=raw.match(/^"([^"]+)"(?:\s+(.+))?$/u);
71
+ const unquoted=quoted?null:raw.match(/^(\S+?\.exe)(?:\s+(.+))?$/iu);
72
+ const executable=quoted?.[1]??unquoted?.[1]??null;
73
+ const argumentsText=quoted?.[2]??unquoted?.[2]??null;
74
+ const binaryPath=executable?path.win32.normalize(executable):null;
75
+ const argumentFree=Boolean(binaryPath)&&argumentsText===null;
76
+ return {
77
+ raw,
78
+ binaryPath,
79
+ arguments:argumentsText,
80
+ argumentFree,
81
+ exact:argumentFree&&raw.toLowerCase()===WINDOWS_SERVICE_COMMAND.toLowerCase()
82
+ };
83
+ }
84
+
85
+ function serviceDefinition(configOutput,sidOutput){
86
+ const text=String(configOutput);
87
+ const command=parseServiceCommand(text);
88
+ const ownProcess=/TYPE\s*:\s*10\s+WIN32_OWN_PROCESS/iu.test(text);
89
+ const automatic=/START_TYPE\s*:\s*2\s+AUTO_START/iu.test(text);
90
+ const localService=/SERVICE_START_NAME\s*:\s*(?:NT AUTHORITY\\)?LocalService\s*$/imu.test(text);
91
+ const dependenciesLine=text.split(/\r?\n/u)
92
+ .find(line=>/DEPENDENCIES\s*:/iu.test(line));
93
+ const dependencies=dependenciesLine
94
+ ?dependenciesLine.slice(dependenciesLine.indexOf(':')+1).trim()
95
+ :null;
96
+ const noUnexpectedDependencies=dependencies==='';
97
+ const unrestrictedSid=/SERVICE_SID_TYPE\s*:\s*UNRESTRICTED/iu.test(String(sidOutput));
98
+ return {
99
+ binaryPath:command.binaryPath,
100
+ command:command.raw,
101
+ commandArguments:command.arguments,
102
+ argumentFree:command.argumentFree,
103
+ exactCommand:command.exact,
104
+ ownProcess,
105
+ automatic,
106
+ localService,
107
+ noUnexpectedDependencies,
108
+ dependencies,
109
+ unrestrictedSid
110
+ };
111
+ }
112
+
113
+ function parseProbe(text){
114
+ let value;
115
+ try{
116
+ value=JSON.parse(String(text).trim());
117
+ }catch{
118
+ return null;
119
+ }
120
+ if(!value||typeof value!=='object'||Array.isArray(value)
121
+ ||Object.getPrototypeOf(value)!==Object.prototype
122
+ ||JSON.stringify(Object.keys(value).sort())!==JSON.stringify(['endpoint','ready','service'])
123
+ ||value.service!==WINDOWS_SERVICE_NAME
124
+ ||value.ready!==true
125
+ ||value.endpoint!==OLLAMA_ENDPOINT){
126
+ return null;
127
+ }
128
+ return Object.freeze({
129
+ service:WINDOWS_SERVICE_NAME,
130
+ ready:true,
131
+ endpoint:OLLAMA_ENDPOINT
132
+ });
133
+ }
134
+
135
+ async function assessWindowsOllama({
136
+ signal,
137
+ onEvent,
138
+ run=runProcess,
139
+ fileExists=exists
140
+ }={}){
141
+ const queried=await run('sc.exe',['query',WINDOWS_SERVICE_NAME],{
142
+ signal,onEvent,allowNonzero:true
143
+ });
144
+ if(queried.code!==0){
145
+ return check('arcane-ollama','missing',`${WINDOWS_SERVICE_NAME} is not installed.`,{
146
+ required:false,
147
+ details:{service:WINDOWS_SERVICE_NAME}
148
+ });
149
+ }
150
+
151
+ const configured=await run('sc.exe',['qc',WINDOWS_SERVICE_NAME],{
152
+ signal,onEvent,allowNonzero:true
153
+ });
154
+ const sid=await run('sc.exe',['qsidtype',WINDOWS_SERVICE_NAME],{
155
+ signal,onEvent,allowNonzero:true
156
+ });
157
+ const definition=serviceDefinition(configured.stdout,sid.stdout);
158
+ const binaryPath=definition.binaryPath;
159
+ const expectedPath=path.win32.normalize(WINDOWS_SERVICE_HOST);
160
+ const registrationVerified=Boolean(configured.code===0
161
+ &&sid.code===0
162
+ &&binaryPath?.toLowerCase()===expectedPath.toLowerCase()
163
+ &&definition.exactCommand
164
+ &&definition.ownProcess
165
+ &&definition.automatic
166
+ &&definition.localService
167
+ &&definition.noUnexpectedDependencies
168
+ &&definition.unrestrictedSid);
169
+ const running=/STATE\s*:\s*\d+\s+RUNNING/iu.test(queried.stdout);
170
+ let probe=null;
171
+ let probeExitCode=null;
172
+
173
+ if(registrationVerified&&await fileExists(WINDOWS_SERVICE_HOST)){
174
+ const probed=await run(WINDOWS_SERVICE_HOST,['--probe'],{
175
+ signal,onEvent,allowNonzero:true
176
+ });
177
+ probeExitCode=probed.code;
178
+ probe=parseProbe(probed.stdout);
179
+ }
180
+
181
+ const probeVerified=probeExitCode===0&&probe!==null;
182
+ const ready=running&&registrationVerified&&probeVerified;
183
+ return check(
184
+ 'arcane-ollama',
185
+ ready?'pass':'warning',
186
+ ready
187
+ ?`${WINDOWS_SERVICE_NAME} is registered and its managed wrapper reports ready.`
188
+ :`${WINDOWS_SERVICE_NAME} is present but did not satisfy every managed-service readiness check.`,
189
+ {
190
+ required:false,
191
+ details:{
192
+ service:WINDOWS_SERVICE_NAME,
193
+ running,
194
+ registrationVerified,
195
+ binaryPath,
196
+ serviceDefinition:definition,
197
+ probeExitCode,
198
+ probeVerified,
199
+ probe
200
+ }
201
+ }
202
+ );
203
+ }
204
+
205
+ export async function assessArcaneOllama({
206
+ signal,
207
+ onEvent,
208
+ platform=process.platform,
209
+ run=runProcess,
210
+ fileExists=exists
211
+ }={}){
212
+ throwIfAborted(signal);
213
+ if(platform==='win32'){
214
+ return assessWindowsOllama({signal,onEvent,run,fileExists});
215
+ }
216
+ return check(
217
+ 'arcane-ollama',
218
+ 'unsupported',
219
+ 'Managed ArcaneOllama service inspection is not implemented on this host.',
220
+ {required:false,details:{platform}}
221
+ );
222
+ }
223
+
224
+ export async function runDoctor({
225
+ workspaceRoot,
226
+ appId,
227
+ arcaneRoot,
228
+ requireLocalAI=false,
229
+ signal,
230
+ onEvent,
231
+ platform=process.platform,
232
+ run=runProcess
233
+ }={}){
234
+ throwIfAborted(signal);
235
+ const checks=[];
236
+ const nodeVersion=process.versions.node;
237
+ const nodeSupported=versionAtLeast(parseVersion(nodeVersion),MINIMUM_NODE);
238
+ checks.push(check(
239
+ 'node',
240
+ nodeSupported?'pass':'fail',
241
+ nodeSupported
242
+ ?`Node.js ${nodeVersion} satisfies the SDK minimum.`
243
+ :`Node.js ${nodeVersion} does not satisfy the SDK minimum ${MINIMUM_NODE.join('.')}.`,
244
+ {details:{version:nodeVersion,minimum:MINIMUM_NODE.join('.')}}
245
+ ));
246
+
247
+ checks.push(await commandCheck('npm','npm',['--version'],{signal,onEvent,run}));
248
+ checks.push(await commandCheck('git','git',['--version'],{signal,onEvent,run}));
249
+
250
+ try{
251
+ const receipt=await verifyRuntime({signal,onEvent});
252
+ checks.push(check('sdk-runtime','pass','The packaged Arcane runtime inventory is verified.',{
253
+ details:{sdkVersion:SDK_VERSION,contentSha256:receipt.contentSha256}
254
+ }));
255
+ }catch(error){
256
+ checks.push(check('sdk-runtime','fail',`The packaged Arcane runtime failed verification: ${error.message}`));
257
+ }
258
+
259
+ const resolvedWorkspace=path.resolve(workspaceRoot??process.cwd());
260
+ if(await exists(path.join(resolvedWorkspace,'arcane-packager.json'))){
261
+ try{
262
+ const result=await validateWorkspace({
263
+ workspaceRoot:resolvedWorkspace,
264
+ appId,
265
+ signal,
266
+ onEvent
267
+ });
268
+ checks.push(check('workspace','pass',`The ${result.workspaceMode} Arcane app workspace is valid.`,{
269
+ details:{workspaceRoot:result.workspaceRoot,appId:result.appId,workspaceMode:result.workspaceMode}
270
+ }));
271
+ }catch(error){
272
+ checks.push(check('workspace','fail',`The Arcane app workspace is invalid: ${error.message}`));
273
+ }
274
+ }else{
275
+ checks.push(check(
276
+ 'workspace',
277
+ 'skipped',
278
+ 'No arcane-packager.json was found at the selected workspace.',
279
+ {required:false,details:{workspaceRoot:resolvedWorkspace}}
280
+ ));
281
+ }
282
+
283
+ if(arcaneRoot){
284
+ const resolvedArcaneRoot=path.resolve(arcaneRoot);
285
+ const lifecycle=path.join(resolvedArcaneRoot,'docs','development-lifecycle.md');
286
+ const recognized=await exists(lifecycle);
287
+ checks.push(check(
288
+ 'arcane-source',
289
+ recognized?'pass':'warning',
290
+ recognized
291
+ ?'The optional Arcane OS source checkout was found.'
292
+ :'The selected Arcane OS source checkout was not recognized.',
293
+ {required:false,details:{arcaneRoot:resolvedArcaneRoot}}
294
+ ));
295
+ }
296
+
297
+ const ollama=await assessArcaneOllama({signal,onEvent,platform,run});
298
+ if(requireLocalAI){
299
+ ollama.required=true;
300
+ if(ollama.status!=='pass'){
301
+ ollama.status='fail';
302
+ }
303
+ }
304
+ checks.push(ollama);
305
+
306
+ const failed=checks.filter(item=>item.required&&item.status==='fail');
307
+ return {
308
+ schemaVersion:1,
309
+ sdkVersion:SDK_VERSION,
310
+ arcaneProtocol:ARCANE_PROTOCOL,
311
+ platform,
312
+ ok:failed.length===0,
313
+ checks
314
+ };
315
+ }